stack debugging in VS2008 - debugging

I am doing some editings with an original source code in OpenCV package to do my tasks. There have been some other compilation errors after my modification. But I've already fixed them. Here comes the last one that I don't know how to remove it:
moreover, this run-time error does not give any output to the command line to ease the debugging
Is there any solution when bugs come out like this??
PS: the original code is the function cvFindExtrinsicCameraParams2 of calib3d.cpp
for convinience, I post the original OpenCV function here:
CV_IMPL void cvFindExtrinsicCameraParams2( const CvMat* objectPoints,
const CvMat* imagePoints, const CvMat* A,
const CvMat* distCoeffs, CvMat* rvec, CvMat* tvec,
int useExtrinsicGuess )
{
const int max_iter = 20;
Ptr<CvMat> matM, _Mxy, _m, _mn, matL, matJ;
int i, count;
double a[9], ar[9]={1,0,0,0,1,0,0,0,1}, R[9];
double MM[9], U[9], V[9], W[3];
CvScalar Mc;
double param[6];
CvMat matA = cvMat( 3, 3, CV_64F, a );
CvMat _Ar = cvMat( 3, 3, CV_64F, ar );
CvMat matR = cvMat( 3, 3, CV_64F, R );
CvMat _r = cvMat( 3, 1, CV_64F, param );
CvMat _t = cvMat( 3, 1, CV_64F, param + 3 );
CvMat _Mc = cvMat( 1, 3, CV_64F, Mc.val );
CvMat _MM = cvMat( 3, 3, CV_64F, MM );
CvMat matU = cvMat( 3, 3, CV_64F, U );
CvMat matV = cvMat( 3, 3, CV_64F, V );
CvMat matW = cvMat( 3, 1, CV_64F, W );
CvMat _param = cvMat( 6, 1, CV_64F, param );
CvMat _dpdr, _dpdt;
CV_Assert( CV_IS_MAT(objectPoints) && CV_IS_MAT(imagePoints) &&
CV_IS_MAT(A) && CV_IS_MAT(rvec) && CV_IS_MAT(tvec) );
count = MAX(objectPoints->cols, objectPoints->rows);
matM = cvCreateMat( 1, count, CV_64FC3 );
_m = cvCreateMat( 1, count, CV_64FC2 );
cvConvertPointsHomogeneous( objectPoints, matM );
cvConvertPointsHomogeneous( imagePoints, _m );
cvConvert( A, &matA );
CV_Assert( (CV_MAT_DEPTH(rvec->type) == CV_64F || CV_MAT_DEPTH(rvec->type) == CV_32F) &&
(rvec->rows == 1 || rvec->cols == 1) && rvec->rows*rvec->cols*CV_MAT_CN(rvec->type) == 3 );
CV_Assert( (CV_MAT_DEPTH(tvec->type) == CV_64F || CV_MAT_DEPTH(tvec->type) == CV_32F) &&
(tvec->rows == 1 || tvec->cols == 1) && tvec->rows*tvec->cols*CV_MAT_CN(tvec->type) == 3 );
_mn = cvCreateMat( 1, count, CV_64FC2 );
_Mxy = cvCreateMat( 1, count, CV_64FC2 );
// normalize image points
// (unapply the intrinsic matrix transformation and distortion)
cvUndistortPoints( _m, _mn, &matA, distCoeffs, 0, &_Ar );
if( useExtrinsicGuess )
{
CvMat _r_temp = cvMat(rvec->rows, rvec->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(rvec->type)), param );
CvMat _t_temp = cvMat(tvec->rows, tvec->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(tvec->type)), param + 3);
cvConvert( rvec, &_r_temp );
cvConvert( tvec, &_t_temp );
}
else
{
Mc = cvAvg(matM);
cvReshape( matM, matM, 1, count );
cvMulTransposed( matM, &_MM, 1, &_Mc );
cvSVD( &_MM, &matW, 0, &matV, CV_SVD_MODIFY_A + CV_SVD_V_T );
// initialize extrinsic parameters
if( W[2]/W[1] < 1e-3 || count < 4 )
{
// a planar structure case (all M's lie in the same plane)
double tt[3], h[9], h1_norm, h2_norm;
CvMat* R_transform = &matV;
CvMat T_transform = cvMat( 3, 1, CV_64F, tt );
CvMat matH = cvMat( 3, 3, CV_64F, h );
CvMat _h1, _h2, _h3;
if( V[2]*V[2] + V[5]*V[5] < 1e-10 )
cvSetIdentity( R_transform );
if( cvDet(R_transform) < 0 )
cvScale( R_transform, R_transform, -1 );
cvGEMM( R_transform, &_Mc, -1, 0, 0, &T_transform, CV_GEMM_B_T );
for( i = 0; i < count; i++ )
{
const double* Rp = R_transform->data.db;
const double* Tp = T_transform.data.db;
const double* src = matM->data.db + i*3;
double* dst = _Mxy->data.db + i*2;
dst[0] = Rp[0]*src[0] + Rp[1]*src[1] + Rp[2]*src[2] + Tp[0];
dst[1] = Rp[3]*src[0] + Rp[4]*src[1] + Rp[5]*src[2] + Tp[1];
}
cvFindHomography( _Mxy, _mn, &matH );
if( cvCheckArr(&matH, CV_CHECK_QUIET) )
{
cvGetCol( &matH, &_h1, 0 );
_h2 = _h1; _h2.data.db++;
_h3 = _h2; _h3.data.db++;
h1_norm = sqrt(h[0]*h[0] + h[3]*h[3] + h[6]*h[6]);
h2_norm = sqrt(h[1]*h[1] + h[4]*h[4] + h[7]*h[7]);
cvScale( &_h1, &_h1, 1./MAX(h1_norm, DBL_EPSILON) );
cvScale( &_h2, &_h2, 1./MAX(h2_norm, DBL_EPSILON) );
cvScale( &_h3, &_t, 2./MAX(h1_norm + h2_norm, DBL_EPSILON));
cvCrossProduct( &_h1, &_h2, &_h3 );
cvRodrigues2( &matH, &_r );
cvRodrigues2( &_r, &matH );
cvMatMulAdd( &matH, &T_transform, &_t, &_t );
cvMatMul( &matH, R_transform, &matR );
}
else
{
cvSetIdentity( &matR );
cvZero( &_t );
}
cvRodrigues2( &matR, &_r );
}
else
{
// non-planar structure. Use DLT method
double* L;
double LL[12*12], LW[12], LV[12*12], sc;
CvMat _LL = cvMat( 12, 12, CV_64F, LL );
CvMat _LW = cvMat( 12, 1, CV_64F, LW );
CvMat _LV = cvMat( 12, 12, CV_64F, LV );
CvMat _RRt, _RR, _tt;
CvPoint3D64f* M = (CvPoint3D64f*)matM->data.db;
CvPoint2D64f* mn = (CvPoint2D64f*)_mn->data.db;
matL = cvCreateMat( 2*count, 12, CV_64F );
L = matL->data.db;
for( i = 0; i < count; i++, L += 24 )
{
double x = -mn[i].x, y = -mn[i].y;
L[0] = L[16] = M[i].x;
L[1] = L[17] = M[i].y;
L[2] = L[18] = M[i].z;
L[3] = L[19] = 1.;
L[4] = L[5] = L[6] = L[7] = 0.;
L[12] = L[13] = L[14] = L[15] = 0.;
L[8] = x*M[i].x;
L[9] = x*M[i].y;
L[10] = x*M[i].z;
L[11] = x;
L[20] = y*M[i].x;
L[21] = y*M[i].y;
L[22] = y*M[i].z;
L[23] = y;
}
cvMulTransposed( matL, &_LL, 1 );
cvSVD( &_LL, &_LW, 0, &_LV, CV_SVD_MODIFY_A + CV_SVD_V_T );
_RRt = cvMat( 3, 4, CV_64F, LV + 11*12 );
cvGetCols( &_RRt, &_RR, 0, 3 );
cvGetCol( &_RRt, &_tt, 3 );
if( cvDet(&_RR) < 0 )
cvScale( &_RRt, &_RRt, -1 );
sc = cvNorm(&_RR);
cvSVD( &_RR, &matW, &matU, &matV, CV_SVD_MODIFY_A + CV_SVD_U_T + CV_SVD_V_T );
cvGEMM( &matU, &matV, 1, 0, 0, &matR, CV_GEMM_A_T );
cvScale( &_tt, &_t, cvNorm(&matR)/sc );
cvRodrigues2( &matR, &_r );
}
}
cvReshape( matM, matM, 3, 1 );
cvReshape( _mn, _mn, 2, 1 );
// refine extrinsic parameters using iterative algorithm
CvLevMarq solver( 6, count*2, cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER,max_iter,FLT_EPSILON), true);
cvCopy( &_param, solver.param );
for(;;)
{
CvMat *matJ = 0, *_err = 0;
const CvMat *__param = 0;
bool proceed = solver.update( __param, matJ, _err );
cvCopy( __param, &_param );
if( !proceed || !_err )
break;
cvReshape( _err, _err, 2, 1 );
if( matJ )
{
cvGetCols( matJ, &_dpdr, 0, 3 );
cvGetCols( matJ, &_dpdt, 3, 6 );
cvProjectPoints2( matM, &_r, &_t, &matA, distCoeffs,
_err, &_dpdr, &_dpdt, 0, 0, 0 );
}
else
{
cvProjectPoints2( matM, &_r, &_t, &matA, distCoeffs,
_err, 0, 0, 0, 0, 0 );
}
cvSub(_err, _m, _err);
cvReshape( _err, _err, 1, 2*count );
}
cvCopy( solver.param, &_param );
_r = cvMat( rvec->rows, rvec->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(rvec->type)), param );
_t = cvMat( tvec->rows, tvec->cols,
CV_MAKETYPE(CV_64F,CV_MAT_CN(tvec->type)), param + 3 );
cvConvert( &_r, rvec );
cvConvert( &_t, tvec );
}
I guess it is pretty complicated! :(

What's going wrong here is that in one of the function calls the compiler is putting local variables, including tvecmat_ar on the stack, but in a debug build it is also putting some guard blocks after the variables. When the function is about to return and the stack is popped the debug runtime checks the status of the guard blocks. If they have a different value then this generates the stack corruption error that you are seeing. So this means that code in that function is corrupting memory. I would bet that you are writing to an array beyond the size of that array.
You haven't attached the source of the code containing the variable that it is warning you about, so it's impossible to tell any further, but I would advise checking all array allocations and indexes in your function.

Related

how to group by columnA and sum columnB, columnC in mixpanel JQL

I have a JQL in mixpanel. I managed to get to a result in the following format:
key, count1, count2, count3
a , 10, 0, 0
a , 0, 3, 0
a , 0, 0, 7
b , 2, 0, 0
b , 0, 3, 0
b , 0, 0, 5
And I'd like to get the results like:
key, count1, count2, count3
a , 10, 3, 7
b , 2, 3, 5
In other words: groupBy(['key'], WHAT_REDUCER_DO_I_NEED???)
You can use multiple reducers in your groupBy statement like this
.groupBy(['key'], [
mixpanel.reducer.sum('count1'),
mixpanel.reducer.sum('count2'),
mixpanel.reducer.sum('count3')
])
.groupBy(["key"], function(accumulators, events){
var sum = {"count1":0,"count2":0,"count3":0};
for (var i = 0; i < accumulators.length; ++i) {
sum["count1"] += accumulators[i]["count1"];
sum["count2"] += accumulators[i]["count2"];
sum["count3"] += accumulators[i]["count3"];
}
for (i = 0; i < events.length; ++i) {
var event = events[i];
sum["count1"] += event["count1"];
sum["count2"] += event["count2"];
sum["count3"] += event["count3"];
}
return sum;
})

How to get the highest value of a standard deviation for last 2 hours in MQL4?

I'm trying to develop an Expert Advisor, so far I can understand and write this which will place orders when a new bar opens.
int BarsCount = 0;
int start()
{ if ( Bars > BarsCount )
{ OrderSend( Symbol(), OP_BUY, 0.01, Ask, 2, NULL, NULL );
BarsCount = Bars;
}
return( 0 );
}
how to get the highest value of standard deviation for last 2 hours to a variable?
E.g.: lets say the EA runs in a 30 mins chart and the bar1 has the standard deviation value 0.003, and bar2 has 0.001, bar3 has 0.004 and bar4 has 0.001.
So, the highest value for past 4 hours is bar3 which has the value of 0.004, so how to get that value to a variable?
I'm trying to make the EA place orders when this formula is true:
( ( current_value_of_standard_deviation
/ highest_value_of_standard_deviation_for_last_2_hours
)
* 100
) > 10
Use built-in tools:
input int MA_period = 27;
int BarsCount = 0;
int nCells2CMP= ( PERIOD_H1 * 2 / PERIOD_CURRENT ) - 1;
double Sig2H[100];
void OnInit(){
...
}
void OnTick(){
if ( Bars > BarsCount ){
if ( BarsCount == 0 ){
for ( int i = MA_period; i > 0; i-- ){
Sig2H[i] = iStdDev( _Symbol,
PERIOD_CURRENT,
0,
MODE_SMA,
PRICE_CLOSE,
i
);
}
}
for ( int i = MA_period; i > 1; i-- ) Sig2H[i] = Sig2H[i-1];
Sig2H[1] = iStdDev( _Symbol, // symbol
PERIOD_CURRENT, // timeframe
MA_period, // MA averaging period
0, // MA shift
MODE_SMA, // MA averaging method
PRICE_CLOSE, // applied price
1 // shift
);
}
Sig2H[0] = iStdDev( _Symbol, // symbol
PERIOD_CURRENT, // timeframe
MA_period, // MA averaging period
0, // MA shift
MODE_SMA, // MA averaging method
PRICE_CLOSE, // applied price
0 // shift
);
if ( 0.1 < ( Sig2H[0]
/ Sig2H[ArrayMaximum( Sig2H,
nCells2CMP,
1
)
]
)
){...}
}

How to open a Buy when a Buy-order hits a T/P, Sell if a Buy-order hits a S/L; a Sell if Sell-order hits a T/P and open Buy if Sell reaches S/L?

I have tried many things but can't get it to work with the code below.
I've tried variations of the logic of the code below but have failed and am not sure where to implement it:
if ( OrderSelect( OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY ) )
{
if ( OrderType() == OP_BUY )
{
if ( OrderClosePrice() > OrderStopLoss() ) Print( "Hit TP" );
else Print( "Hit SL" );
}
else if ( OrderType() == OP_SELL )
{
if ( OrderClosePrice() < OrderStopLoss() ) Print( "Hit TP" );
else Print( "Hit SL" );
}
}
or
Orderselect...
if ( MathAbs( OrderClosePrice()
- OrderTakeProfit()
) > MathAbs( OrderClosePrice()
- OrderStopLoss()
)
) Print( "StopLoss" );
if ( MathAbs( OrderClosePrice()
- OrderTakeProfit()
) < MathAbs( OrderClosePrice()
- OrderStopLoss()
)
) Print( "TakeProfit" );
The OrderSelect() has been an issue for me, so any help will be greatly appreciated.
Below is the EA I'm trying to add it to, but just knowing how and where to put it will help.
extern int MagicNumber = 10001;
extern double Lots = 0.01;
extern double StopLoss = 1;
extern double TakeProfit = 1;
extern int TrailingStop = 0;
extern int Slippage = 3;
//+------------------------------------------------------------------+
// expert start function
//+------------------------------------------------------------------+
int start() // New-MQL4.56789 #strict uses another constructor: int OnTick(){...}
{
double MyPoint = Point;
if ( Digits == 3
|| Digits == 5
) MyPoint = Point*10;
double TheStopLoss = 0;
double TheTakeProfit = 0;
if ( TotalOrdersCount() == 0 )
{
int result = 0;
if ( ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) < iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
&& ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) > iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open BUY rule
{
result = OrderSend( Symbol(),
OP_BUY,
Lots,
Ask,
Slippage,
0,
0,
"Buy",
MagicNumber,
0,
Blue
);
if ( result > 0 )
{
TheStopLoss = 0;
TheTakeProfit = 0;
if ( TakeProfit > 0 ) TheTakeProfit = Ask + TakeProfit * MyPoint;
if ( StopLoss > 0 ) TheStopLoss = Ask - StopLoss * MyPoint;
OrderSelect( result, SELECT_BY_TICKET );
OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( TheStopLoss, Digits ),
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
}
return(0);
}
if ( ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 1 ) > iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 1 ) )
&& ( iMA( NULL, 0, 30, 0, MODE_SMA, PRICE_CLOSE, 0 ) < iMA( NULL, 0, 200, 0, MODE_SMA, PRICE_CLOSE, 0 ) )
) // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here is your open SELL rule
{
result = OrderSend( Symbol(),
OP_SELL,
Lots,
Bid,
Slippage,
0,
0,
"Sell",
MagicNumber,
0,
Red
);
if ( result > 0 )
{
TheStopLoss = 0;
TheTakeProfit = 0;
if ( TakeProfit > 0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
if ( StopLoss > 0 ) TheStopLoss = Bid + StopLoss * MyPoint;
OrderSelect( result, SELECT_BY_TICKET );
OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( TheStopLoss, Digits ),
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
}
return(0);
}
}
for ( int cnt = 0; cnt < OrdersTotal(); cnt++ )
{
OrderSelect( cnt, SELECT_BY_POS, MODE_TRADES );
if ( OrderType() <= OP_SELL
&& OrderSymbol() == Symbol()
&& OrderMagicNumber() == MagicNumber
)
{
if ( OrderType() == OP_BUY )
{
if ( TrailingStop > 0 )
{
if ( Bid - OrderOpenPrice() > MyPoint * TrailingStop )
{
if ( OrderStopLoss() < Bid - MyPoint * TrailingStop )
{
OrderModify( OrderTicket(),
OrderOpenPrice(),
Bid - TrailingStop * MyPoint,
OrderTakeProfit(),
0,
Green
);
return(0);
}
}
}
}
else
{
if ( TrailingStop > 0 )
{
if ( ( OrderOpenPrice() - Ask ) > ( MyPoint * TrailingStop ) )
{
if ( ( OrderStopLoss() > ( Ask + MyPoint * TrailingStop ) )
|| ( OrderStopLoss() == 0 )
)
{
OrderModify( OrderTicket(),
OrderOpenPrice(),
Ask + MyPoint * TrailingStop,
OrderTakeProfit(),
0,
Red
);
return(0);
}
}
}
}
}
}
return(0);
}
int TotalOrdersCount()
{
int result = 0;
for ( int i = 0; i < OrdersTotal(); i++ )
{
OrderSelect( i, SELECT_BY_POS, MODE_TRADES );
if ( OrderMagicNumber() == MagicNumber ) result++;
}
return( result );
}
... open WHEN ... is the key part of the goal
OrderSelect() is not of much help for you to solve the "Open WHEN" puzzle. It just crawls accross a db.POOL of records, that MetaTrader Terminal 4 localhost internal DBMS takes care of, which is slow and very, very inefficient way to handle event the order-management tasks, so try to avoid any arbitrary scans thereof in a production-grade system. Here, you even will not get any cardinal piece of information you need for your task from such devastating db.POOL scans, so let's focus on the goal first.
... WHAT ... is the idea behind the goal?
The EA is a scholastically trivial variation on a slow-200 / fast-30 simple moving average cross.
There I guess you would like to add your additional idea of opening additional trades on condition the underlying SMA-cross-originated trade has reached it's { SL | TP }-termination respectively, right?
For such case, Brokers with a MetaTrader Server 4 typically allow you to place a so called pending order, which instructs a Broker, to maintain a record about your will to enter market, supposing a price reaches a pre-defined level -- ( guess what, these would be the { SL | TP } as you requested in the title -- and such record is waiting ( with some more configurable options ), until a such price movement happens or not, during which such position is waiting in an inactive state, called a pending order ...
For Terms & Conditions, kindly check your Broker's contract and/or ask their Customer Care representative. Some special limitations may apply ( better to know a-priori ).
... WHERE ... to put the code?
Without re-designing the provided code ( some minor errors/inefficiencies there ) the code shall go here:
result = OrderSend( Symbol(),
OP_SELL, // PRIMARY SELL <<<AT-MARKET>>>
Lots,
Bid,
Slippage,
0,
0,
"Sell",
MagicNumber,
0,
Red
);
if ( result > 0 )
{
TheStopLoss = 0;
TheTakeProfit = 0;
if ( TakeProfit > 0 ) TheTakeProfit = Bid - TakeProfit * MyPoint;
if ( StopLoss > 0 ) TheStopLoss = Bid + StopLoss * MyPoint;
OrderSelect( result, SELECT_BY_TICKET );
OrderModify( OrderTicket(),
OrderOpenPrice(),
NormalizeDouble( TheStopLoss, Digits ),
NormalizeDouble( TheTakeProfit, Digits ),
0,
Green
);
// ---------------------------------------------------- HERE ADD
OrderSend( Symbol(),
OP_SELLSTOP, // SELL-STOP PENDING ORDER ON SELL.TP
Lots,
NormalizeDouble( TheTakeProfit
- MarketInfo( _Symbol, MODE_SPREAD ),
Digits
),
Slippage,
0, // SL: T.B.D.
0, // TP: T.B.D.
"Sell on Sell.TP",
sTpMagicNumber, // avoid collisions with other logic
0, // never expires
Red
);
OrderSend( Symbol(),
OP_BUYSTOP, // BUY-STOP PENDING ORDER ON SELL.SL
Lots,
NormalizeDouble( TheStopLoss
- MarketInfo( _Symbol, MODE_SPREAD ),
Digits
),
Slippage,
0, // SL: T.B.D.
0, // TP: T.B.D.
"Buy on Sell.SL",
bSlMagicNumber, // avoid collisions with other logic
0, // never expires
Red
);
}
The spread-adjustment is not absolute, as during instable periods of time, the market is exposed to spurious spread volatilities. Again, Brokers' Terms & Conditions apply here, so be carefull.

How to Quantise an indicator in MQL4?

I am failing over and over trying to get this indicator to run quantised with 2 buffers in mql4. After a long time reading I have put 2 extra buffers in to squish it :/ because:
the indicator is sitting between 0.1430-0.1427 at present but doesn't have a fixed top and bottom.
I can't seem to suss it; cool indicator but won't play fair!
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 CLR_NONE
#property indicator_color4 CLR_NONE
//#property indicator_minimum 0
//#property indicator_maximum 100
extern int P = 13;
extern int T = 3000;
extern double P2 = 0.001;
//int MIN = 0;
//int MAX = 100;
double G[];
double R[];
double B3[];
double B4[];
int init(){
IndicatorBuffers(4);
SetIndexBuffer( 0, G );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
SetIndexBuffer( 1, R );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red );
SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
return(0);
}
int start(){
if ( T >= Bars ) T = Bars;
SetIndexDrawBegin( 0, Bars - T + P + 1 );
SetIndexDrawBegin( 1, Bars - T + P + 1 );
SetIndexDrawBegin( 2, Bars - T + P + 1 );
SetIndexDrawBegin( 3, Bars - T + P + 1 );
int Z, C, Opt = IndicatorCounted();
if ( Bars <= 38 ) return(0);
if ( Opt < P ){
for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0;
for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0;
}
Z = T - P - 1;
while( Z >= 0 ){
double A, S1, S2;
S1 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S1 = S1 + ( High[Z+C] + Low[Z+C] ) / 2;}
S2 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
A = S1 / S2;
// if ( A < MIN ){ MIN = A;}
// if ( A > MAX ){ MAX = A;}
// A = ( MIN / MAX ) * 100;
G[Z] = A;
if ( Z > 0 ){ R[Z-1] = A;}
Z--;
}
for ( int N = T-P-2; N >= 0; N-- ){
if ( N > 0 ){
if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;}
if ( G[N-1] < G[N] ){ G[N] = R[N]; continue;}
}
B3[0] = G[0] + P2;
B4[0] = G[0] - P2; //forced quantise using 2 extra buffers
}
return(0);
}
Let´s split the task first
0) indicator logic
1) indicator quantisation step
2) indicator performance
MQL4 Custom Indicator programming relies on deeper understanding of underlying MetaTrader4 Terminal platform. Each external Market Event, changing a traded instrument price, is signalled to a lcoalhost by a network delivery of a QUOTE ... message from MetaTrader4 Server. This is aka Tick and it triggers a call to a function originally called start(), in newer New-MQL4.56789 renamed to OnTick().
The below modified MQL4 listing contains remarks for core-logic disambiguation, which must precede all the below listed steps.
1) indicator quantisation step
While the code is still very inefficient ( as per [2] below ) the logic does not include any straight hurdle form having the output quantised to any form thereof { binary | ternary | arbitrary-number-of-states }-quantised system. Whence the indicator core-logic is cleared, the quantisation step is just a trivial conversion from R(1) to I(1).
2) indicator performance
Any Tick arrival may, but need not modify either High[0] or Low[0], which are the only variable parts of the proposed Custom Indicator calculus.
This is the core idea on how to reduce the scope of re-calculations, that the MQL4 code has to realise per tick. In recent versions of MT4, all Custom Indicators share a single thread, the more stress has been put on efficient algorithmisation of Custom Indicators, at these may block the platform's trading decisions on poor, inefficient code-loops and convolution/recursion re-executions.
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 CLR_NONE
#property indicator_color4 CLR_NONE
extern int P = 13;
extern int T = 3000;
extern double P2 = 0.001;
double G[]; // 0: LINE
double R[]; // 1: LINE
double B3[]; // 2: BUT NEVER PAINTED, NEVER CONSUMED _?_
double B4[]; // 3: BUT NEVER PAINTED, NEVER CONSUMED _?_
int init(){
IndicatorBuffers(4);
SetIndexBuffer( 0, G );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
SetIndexBuffer( 1, R );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red );
SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
return(0);
}
int start(){
if ( Bars <= 38 ) return(0); // JIT/RET in case Bars < 39 --^ --^ --^ --^
if ( T >= Bars ) T = Bars; // (TRIM´d) T < Bars .OR. = Bars
int aDrawBegins = Bars - T + P + 1; // ( extern P = 13 ) + 1 + ( Bars - ( extern T = 3000 if T < Bars else Bars ) )
//tIndexDrawBegin( 0, Bars - T + P + 1 ); // PREF: ( reused 4x )
SetIndexDrawBegin( 0, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
SetIndexDrawBegin( 1, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
SetIndexDrawBegin( 2, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
SetIndexDrawBegin( 3, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
double A, S1, S2; // auxiliary var for bar-mid-price calculi
int Z; // auxiliary stepper
int Opt = IndicatorCounted(); // Opt ( NEVER RE-USED )
if ( Opt < P ){ // if ( ( extern P = 13 ) > IndicatorCounted() )
// ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0; // .STO G[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0; // .STO R[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
// ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
}
Z = T - P - 1; // .STO Z, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 1
while( Z >= 0 ){ // .DEC Z
// !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !!
S1 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S1 = S1 + ( High[Z+C] + Low[Z+C] ) / 2; }
S2 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
// !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !!
A = S1 / S2;
G[Z] = A; // .STO G[Z], A if Z >= 0
if ( Z > 0 ){ R[Z-1] = A;} // .STO R[Z-1], A if Z > 0
Z--;
}
for ( int N = T - P - 2; N >= 0; N-- ){ // .STO N, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 2
if ( N > 0 ){ // N > 0:
if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;} // .BLNK R[N], EMPTY if G[N-1] > G[N]
if ( G[N-1] < G[N] ){ G[N] = R[N]; continue;} // .SET G[N], R[N] if G[N-1] < G[N]
}
// ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ??
B3[0] = G[0] + P2; // .STO B3[0], G[0] + ( extern P2 = 0.001 )
B4[0] = G[0] - P2; // .STO B4[0], G[0] - ( extern P2 = 0.001 )
// forced quantise using 2 extra buffers
// ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ??
}
return(0);
}
New-MQL4.56789 syntax
The OnCalculate() function is called only in custom indicators when it's necessary to calculate the indicator values by the Calculate event. This usually happens when a new tick is received for the symbol, for which the indicator is calculated. This indicator is not required to be attached to any price chart of this symbol.
The first rates_total parameter contains the number of bars, available to the indicator for calculation, and corresponds to the number of bars available in the chart.
We should note the connection between the return value of OnCalculate() and the second input parameter prev_calculated. During the OnCalculate() function call, the prev_calculated parameter contains a value returned by OnCalculate() during previous call. This allows for economical algorithms for calculating the custom indicator in order to avoid repeated calculations for those bars that haven't changed since the previous run of this function.
For this, it is usually enough to return the value of the rates_total parameter, which contains the number of bars in the current function call. If since the last call of OnCalculate() the price data has changed (a deeper history downloaded or history blanks filled), the value of the input parameter prev_calculated will be set to zero by the terminal.
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate( const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[]
)
{
// Get the number of bars available now for the current Symbol and chart period
int barsNow = Bars( _Symbol, PERIOD_CURRENT );
// .RET value of prev_calculated for a next call
return( rates_total );
}

EAN 8 : How to calculate checksum digit?

I need to create EAN 8 bar code programmatically.
I search an algorithm to calculate the checksum digit.
The algorithm is covered in this wikipedia article on EAN, note that EAN-8 is calculated in the same way as EAN-13.
Here's a worked example from http://www.barcodeisland.com/ean8.phtml :
Assuming we wish to encode the 7-digit message "5512345", we would calculate the checksum in the following manner:
Barcode 5 5 1 2 3 4 5
Odd/Even Pos? O E O E O E O
Weighting 3 1 3 1 3 1 3
Calculation 5*3 5*1 1*3 2*1 3*3 4*1 5*3
Weighted Sum 15 5 3 2 9 4 15
The total is 15 + 5 + 3 + 2 + 9 + 4 + 15 = 53. 7 must be added to 53 to produce a number evenly divisible by 10, thus the checksum digit is 7 and the completed bar code value is "55123457".
string code="55123457";
int sum1 = code[1] + code[3] + code[5]
int sum2 = 3 * (code[0] + code[2] + code[4] + code[6]);
int checksum_value = sum1 + sum2;
int checksum_digit = 10 - (checksum_value % 10);
if (checksum_digit == 10)
checksum_digit = 0;
int checkSum(const std::vector<int>& code) const
{
if (code.size() < 8) return false;
for( SIZE_T i = 0; i< code.size(); i++ )
{
if( code[i] < 0 ) return false;
}
int sum1 = code[1] + code[3] + code[5]
int sum2 = 3 * (code[0] + code[2] + code[4] + code[6]);
int checksum_value = sum1 + sum2;
int checksum_digit = 10 - (checksum_value % 10);
if (checksum_digit == 10) checksum_digit = 0;
return checksum_digit;
}
Sorry for re-opening
JAVA VERSION
public int checkSum(String code){
int val=0;
for(int i=0;i<code.length();i++){
val+=((int)Integer.parseInt(code.charAt(i)+""))*((i%2==0)?1:3);
}
int checksum_digit = 10 - (val % 10);
if (checksum_digit == 10) checksum_digit = 0;
return checksum_digit;
}
Reawakened with a C# version:
public static bool IsValidEan13(string eanBarcode)
{
return IsValidEan(eanBarcode, 13);
}
public static bool IsValidEan12(string eanBarcode)
{
return IsValidEan(eanBarcode, 12);
}
public static bool IsValidEan14(string eanBarcode)
{
return IsValidEan(eanBarcode, 14);
}
public static bool IsValidEan8(string eanBarcode)
{
return IsValidEan(eanBarcode, 8);
}
private static bool IsValidEan(string eanBarcode, int length)
{
if (eanBarcode.Length != length) return false;
var allDigits = eanBarcode.Select(c => int.Parse(c.ToString(CultureInfo.InvariantCulture))).ToArray();
var s = length%2 == 0 ? 3 : 1;
var s2 = s == 3 ? 1 : 3;
return allDigits.Last() == (10 - (allDigits.Take(length-1).Select((c, ci) => c*(ci%2 == 0 ? s : s2)).Sum()%10))%10;
}
Here is a MySQL version for EAN13:
SET #first12digits="123456789012";
SELECT #first12digits,
IF (
(#check:=10-MOD(
(CAST(SUBSTRING(#first12digits, 1, 1) AS DECIMAL))+
(CAST(SUBSTRING(#first12digits, 2, 1) AS DECIMAL) * 3)+
(CAST(SUBSTRING(#first12digits, 3, 1) AS DECIMAL))+
(CAST(SUBSTRING(#first12digits, 4, 1) AS DECIMAL) * 3)+
(CAST(SUBSTRING(#first12digits, 5, 1) AS DECIMAL))+
(CAST(SUBSTRING(#first12digits, 6, 1) AS DECIMAL) * 3)+
(CAST(SUBSTRING(#first12digits, 7, 1) AS DECIMAL))+
(CAST(SUBSTRING(#first12digits, 8, 1) AS DECIMAL) * 3)+
(CAST(SUBSTRING(#first12digits, 9, 1) AS DECIMAL))+
(CAST(SUBSTRING(#first12digits, 10, 1) AS DECIMAL) * 3)+
(CAST(SUBSTRING(#first12digits, 11, 1) AS DECIMAL))+
(CAST(SUBSTRING(#first12digits, 12, 1) AS DECIMAL) * 3)
,10)) = 10, 0, #check
) AS checkDigit;
There was a bug. If Calc result = 10 then check digit = 0.
Here below a better version for EAN14.
SET #first13digits="1234567890123";
SELECT #txCode13:=#first13digits,
#iCheck := (
10 - (
(
MID(#txCode13, 2, 1) +
MID(#txCode13, 4, 1) +
MID(#txCode13, 6, 1) +
MID(#txCode13, 8, 1) +
MID(#txCode13, 10, 1) +
MID(#txCode13, 12, 1)
) + (
MID(#txCode13, 1, 1) +
MID(#txCode13, 3, 1) +
MID(#txCode13, 5, 1) +
MID(#txCode13, 7, 1) +
MID(#txCode13, 9, 1) +
MID(#txCode13, 11, 1) +
MID(#txCode13, 13, 1)
) * 3 ) % 10
) AS iCheck,
#iCheckDigit := IF(#iCheck = 10, 0, #iCheck) AS checkDigit,
CONCAT(#t
xCode13, CAST(#iCheckDigit AS CHAR)) AS EAN14WithCheck
Here is the Java version for EAN13
private int calcChecksum(String first12digits) {
char[] char12digits = first12digits.toCharArray();
int[] ean13 = {1,3};
int sum = 0;
for(int i = 0 ; i<char12digits.length; i++){
sum += Character.getNumericValue(char12digits[i]) * ean13[i%2];
}
int checksum = 10 - sum%10;
if(checksum == 10){
checksum = 0;
}
return checksum;
}
class GTIN(object):
def __init__(self, barcode=''):
self.barcode = barcode
def __checkDigit(self, digits):
total = sum(digits) + sum(map(lambda d: d*2, digits[-1::-2]))
return (10 - (total % 10)) % 10
def validateCheckDigit(self, barcode=''):
barcode = (barcode if barcode else self.barcode)
if len(barcode) in (8,12,13,14) and barcode.isdigit():
digits = map(int, barcode)
checkDigit = self.__checkDigit( digits[0:-1] )
return checkDigit == digits[-1]
return False
def addCheckDigit(self, barcode=''):
barcode = (barcode if barcode else self.barcode)
if len(barcode) in (7,11,12,13) and barcode.isdigit():
digits = map(int, barcode)
return barcode + str(self.__checkDigit(digits))
return ''
Today I need a PHP version, I remember about this page and copy from the Java version. Thank you.
function getEAN13($txEan12)
{
$iVal=0;
for($i=0; $i<strlen($txEan12); $i++)
{
$iSingleCharVal = intval(substr($txEan12, $i, 1)); // extract value of one char
$iSingleCharMult = $iSingleCharVal * ($i%2==0 ? 1 : 3); // calculate depending from position
$iVal+= $iSingleCharMult; // sum
}
$iCheckDigit = 10 - ($iVal % 10);
if ($iCheckDigit == 10) $iCheckDigit = 0;
return $txEan12 . $iCheckDigit;
}
Java Version:
It works perfectly
public static int checkSum(String code){
int val=0;
for(int i=0; i<code.length()-1; i++){
val+=((int)Integer.parseInt(code.charAt(i)+""))*((i%2==0)?1:3);
}
int checksum_digit = (10 - (val % 10)) % 10;
return checksum_digit;
}
Python EAN13 check-digit calculation based on Najoua Mahi's Java function:
def generateEAN13CheckDigit(self, first12digits):
charList = [char for char in first12digits]
ean13 = [1,3]
total = 0
for order, char in enumerate(charList):
total += int(char) * ean13[order % 2]
checkDigit = 10 - total % 10
if (checkDigit == 10):
return 0
return checkDigit
This works on both EAN 13 and EAN8:
public static String generateEAN(String barcode) {
int first = 0;
int second = 0;
if(barcode.length() == 7 || barcode.length() == 12) {
for (int counter = 0; counter < barcode.length() - 1; counter++) {
first = (first + Integer.valueOf(barcode.substring(counter, counter + 1)));
counter++;
second = (second + Integer.valueOf(barcode.substring(counter, counter + 1)));
}
second = second * 3;
int total = second + first;
int roundedNum = Math.round((total + 9) / 10 * 10);
barcode = barcode + String.valueOf(roundedNum - total);
}
return barcode;
}
This is a code I wrote in VFP (Visual FoxPro 9), for both EAN-8 and EAN-13
Lparameters lcBarcode,llShowErrorMessage
If Vartype(m.lcBarcode)<>'C'
If m.llShowErrorMessage
MessageBox([Type of parameter is incorect!],0+16,[Error Message])
EndIf
Return .f.
EndIf
If Len(Chrtran(Alltrim(m.lcBarcode),[0123456789],[]))>0
If m.llShowErrorMessage
MessageBox([Provided barcode contains invalid characters!],0+16,[Error Message])
EndIf
Return .f.
EndIf
If Len(Alltrim(m.lcBarcode))=0
If m.llShowErrorMessage
MessageBox([The length of provided barcode is 0 (zero)!],0+16,[Error Message])
EndIf
Return .f.
EndIf
If !InList(Len(Alltrim(m.lcBarcode)),8,13)
If m.llShowErrorMessage
MessageBox([Provided barcode is not an EAN-8 or EAN-13 barcode!],0+16,[Error Message])
EndIf
Return .f.
EndIf
Local lnCheck as Integer, lnSum as Integer, lnOriginalCheck as Integer,jj as Integer
jj=0
lnSum=0
m.lnOriginalCheck = Cast(Right(Alltrim(m.lcBarcode),1) as Integer)
m.lcBarcode = Left(Alltrim(m.lcBarcode),Len(Alltrim(m.lcBarcode))-1)
For ii = Len(m.lcBarcode) to 1 step -1
jj=jj+1
lnSum = lnSum + Cast(Substr(m.lcBarcode,ii,1) as Integer) * Iif(Mod(jj,2)=0,1,3)
Next
lnCheck = 10-Mod(lnSum,10)
lnCheck = Iif(lnCheck =10,0,lnCheck)
Return (lnCheck = lnOriginalCheck)
JavaScript version for EAN-8 and EAN-13
function checksum(code) {
const sum = code.split('').reverse().reduce((sum, char, idx) => {
let digit = Number.parseInt(char);
let weight = (idx + 1) % 2 === 0 ? 1 : 3;
let partial = digit * weight;
return sum + partial;
}, 0);
const remainder = sum % 10;
const checksum = remainder ? (10 - remainder) : 0;
return checksum;
}
Mini Javascript Version
function checksum(code){
return (10 - (code.split('').reduce((s, e, i) => { return s + parseInt(e) * ((i%2==0)?1:3) },0) % 10)) % 10;
}
=INT(CONCAT([#Code],MOD(10 - MOD((MID([#Code], 2, 1) + MID([#Code], 4, 1) + MID([#Code], 6, 1)) + (3*(MID([#Code], 1, 1) + MID([#Code], 3, 1) + MID([#Code], 5, 1) + MID([#Code], 7, 1))),10), 10)))
The above formula will calculate the check character without the need to use a macro or change to XLSM.
Note: Only works for EAN-8.

Resources