How to accumulate and retain records in Buffer[] - in a MQL4 Custom Indicator? - buffer

I am making a custom indicator, that displays the change in the closing price of a certain currency.
for ( i = limit; i >= 0; i-- ) {
totaleur = 0;
for ( x = i; x < i + 1; x++ ) {
totaleur = ( ( iClose( "EURUSD", 0, x )
- iClose( "EURUSD", 0, x - 1 )
)
/ iClose( "EURUSD", 0, x - 1 )
);
}
ExtMapBuffer1[i] = totaleur;
return(0);
}
in this case the indicator displays only the change in price of each observation.
Any ideas how to make it display the change in an observation plus all previous observations?

There are several important points to realise, so as to make the goal achieved:
1: do not prematurely escape in the first round, via return(0)
moving the command return(0); outside the code-execution block {...}from the forward-stepping ( i decreases ) for( i = limit ;...; i--){...} code-execution block will let the pointer step forward in (i),as the Custom Indicator uses a progressive, discontinuous, per-partes incremental ( in time ), evaluation ( ref. MQL4 documentation on Custom Indicator iCustom(...) calling interface parameters )
2: decide, whether the inner-loop ( a sum of fractions ) was correctly coded
the proposed expression providesa sum of N, per-Bar relative differences,nota sum of N absolute-differences, divided by a net price change over N bars.
While this might be working, the point is, whether the intended model is correct to sum relative differences ( percent change over different, variable individual bases ), or whether the sum ob absolute differences ought be only at the very end of the loop divided by a one, common, base -- the net price difference between the first and the last point ( over the N-bars base ), which is commonly a quantitative modelling practice when a noisy signal is subject to some cheap smoothing technique.
3: correct problems in accessing TimeSeries vectors ( negative index )
given the outer for ( i = limit; i >= 0; i-- ) loop permits the i to become zero,
given the inner for ( x = i; ... ) thus permits x == 0,
the x - 1 < 0 becomes a problem,
wherethe instruction iClose( _Symbol, PERIOD_CURRENT, x - 1 ) requests to access a value, that does not yet exist ( has a negative index into TimeSeries vector ).
for ( i = limit; // SET:_______________________ START at BAR[i == limit]
i >= 0; // PRE: PRE-CONDITION i >= 0
i-- // UPD: POST-UPDATE i-- STEP FORWARD IN TIME
) { // ___________________________________________________________
totaleur = 0; // ZEROISED
for ( x = i; // SET:_________________ START at BAR[x = (i)]
x < i + 1; // PRE: PRE-CONDITION x < (i)+1
x++ // UPD: POST-UPDATE x++ +1 STEP ( ONCE )
) { // _____________________________________________________
totaleur = ( ( iClose( "EURUSD", 0, x )
- iClose( "EURUSD", 0, x - 1 )
)
/ iClose( "EURUSD", 0, x - 1 )
);
} // LOOP KEPT STORING ANY INTERIM VALUE FOR EACH x INTO THE SAME <var>
ExtMapBuffer1[i] = totaleur;
return(0); //___________________________________DO NOT PREMATURELY RET/EXIT RIGHT FROM THE 1st LOOP
}
As you might have already noticed, the code permits just one loop in the inner for(){...}

If you need a sum of N previous observations - you need something like this:
for(i=limit; i>=0; i--) {
double totaleur = 0;
for(x=i; x<i+N; x++) {
totaleur += ((iClose("EURUSD", 0, x)- iClose("EURUSD", 0, x-1))/iClose("EURUSD", 0, x-1));
}
ExtMapBuffer1[i]=totaleur;
}
when you have return(0); inside loop - indicator will stop there and do not run that cycle with next parameter - so be careful with it

Related

Training Lloyd-Max quatizer with PDF from histogram of sampled data

I'm trying to code basic scalar Lloy-Max qunatizer... and have the possibility to initialize it by:
range-min, range-max, pdf(x).
I know that LM can be trained directly on given training-set (I already have with) but I want to have also possibility to "train" it via provided probability-density-function.
It seams that I have bug in "approximation" of PDF from histrogram of sampled-data or in training LM via PDF.
I construct histogram from training-set used to train 1st LM, train 2nd LM with PDF approximated "by" historgram and compare the difference (final ranges and theirs reconstruction value).
1)
Function that I pass to initialization of 2nd LM is Histogram.PDF(x):
for 'x' it locates corresponding bin and returns:
bin-counter / ( total-histogram-counter * bin-range-width )
It is alright? If I integrate this function on [0,1] it yields 1.0 as proper PDF(x) should do.
2) I train LM this way... Do you see anybody problem in it?
Func< float,float > x_pdf = (x) => x * pdf( x );
for( var iter = maxIters; iter --> 0; )
{
for( var i = 0; i < levels; ++i ) // update values
{
var r0 = m_Ranges[ i ];
var r1 = m_Ranges[ i+1 ];
var denom = Integrate( pdf, r0, r1 );
if( denom != 0f )
{
var numer = Integrate( x_pdf, r0, r1 );
m_Values[ i ] = numer / denom;
}
else
{
m_Values[ i ] = 0.5f * ( r0 + r1 );
}
}
var finished = true;
for( var i = 1; i < levels; ++i ) // update ranges
{
var r = 0.5f * ( m_Values[ i-1 ] + m_Values[ i ] );
var diff = m_Ranges[ i ] - r;
m_Ranges[ i ] = r;
finished &= Abs( diff ) <= eps;
}
if( finished == true )
break;
}
m_Values : float[n]
m_Ranges : float[n+1] ... initialized before training loop to uniformly divide given range (range-min, range-min + step, range-min + 2*step, ..., range-max)
What wories me is that ranges&values after training 1st and 2nd LM are for some inputs realy quite different. And LM trained with PDF(x) (provided by histogram of training-set) has sometimes reconstruction-values outside corresponding sub-ranges.

warning X3557: loop only executes for 0 iteration(s), forcing loop to unroll

The compiler produce a "warning X3557: loop only executes for 0 iteration(s), forcing loop to unroll" and I don't understand why.
Here is the source code. It is a revisited itoa() function for HLSL producing resulting ascii codes in an array of uint.
#define ITOA_BUFFER_SIZE 16
// Convert uint to ascii and return number of characters
uint UIntToAscii(
in uint Num, // Number to convert
out uint Buf[ITOA_BUFFER_SIZE], // Where to put resulting ascii codes
in uint Base) // Numeration base for convertion
{
uint I, J, K;
I = 0;
while (I < (ITOA_BUFFER_SIZE - 1)) { // <==== Warning X3557
uint Digit = Num % Base;
if (Digit < 10)
Buf[I++] = '0' + Digit;
else
Buf[I++] = 'A' + Digit - 10;
if ((Num /= Base) == 0)
break;
}
// Reverse buffer
for (K = 0, J = I - 1; K < J; K++, J--) { // <==== Warning X3557
uint T = Buf[K];
Buf[K] = Buf[J];
Buf[J] = T;
}
// Fill remaining of buffer with zeros to make compiler happy
K = I;
while (K < ITOA_BUFFER_SIZE)
Buf[K++] = 0;
return I;
}
I tried to rewrite the while loop but this doesn't change anything. Also tried to use attribute [fastopt] without success. As far as I can see the function produce the correct result.
Any help appreciated.
The warning you are getting is
WAR_TOO_SIMPLE_LOOP 3557 The loop only executes for a limited number
of iterations or doesn't seem to do anything so consider removing it
or forcing it to unroll.
The warning is pretty much self explanatory, if you consider that loops are considered inefficient in GPGPU, so the compiler tries to unroll them when it's possible. What the compiler is telling you is that you created some loops that can run more efficiently if unrolled, or can be removed because they never run. If a loop is unrollable, it means that you can predict at compile time the number of times it will run. Your loops on first look should not fulfill this criterium.
I = 0;
while (I < (ITOA_BUFFER_SIZE - 1)) { // <==== Warning X3557
uint Digit = Num % Base;
if (Digit < 10)
Buf[I++] = '0' + Digit;
else
Buf[I++] = 'A' + Digit - 10;
if ((Num /= Base) == 0)
break;
}
This while loop runs up to 15 times I < (ITOA_BUFFER_SIZE - 1), depending on (Num /= Base) == 0. Final value of I is between 1 and 15, depending on how if ((Num /= Base) == 0) evaluates on each cycle. Nonetheless, it still is unrollable, because the compiler may still insert a conditional jump over the iterations.
// Reverse buffer
for (K = 0, J = I - 1; K < J; K++, J--) { // <==== Warning X3557
uint T = Buf[K];
Buf[K] = Buf[J];
Buf[J] = T;
}
This second loop, instead should not be unrollable, because I should not be known to the compiler.
The warning you reported
warning X3557: loop only executes for 0 iteration(s), forcing loop to unroll
might refer to the first loop if if ((Num /= Base) == 0) always evaluates to true on first iteration. In that case, I would be equal to 1, and J would be equal to 0 on the second loop. That second loop would not run because K < J would evaluate to false on first iteration.
What you get in the end if you let it [unroll] is probably a single iteration on the while loop and the complete removal of the subsequent for loop. I highly suspect this is not your intended behaviour, and while it might suppress the warning, you might want to check the code and see if something does not run the way it should.

How can I use iOpen(), iClose(), iLow() and iHigh() to find these pinbars?

I want to find the pinbars circled in the attached image below. For the one on the right, the body is about 1/5th of the candle size and for the one on the left, let's say the body is 1/7th the size candle size and it also has a wick of 1/7th the candle size at the bottom. How can I use the iOpen(), iLow() and other similar functions to find these two types of pinbars?
Q : How can I use the iOpen(), iLow() and other similar functions to find these two types of pinbars?
May use a working template like this WasThisTheUserDefinedBearishPATTERN() function and having defined all your user-specific conditions and constants, just call if ( WasThisTheUserDefinedBearishPATTERN( aShift, 4.5, 0.1, 2000 ) ) { do_something(); } when using it for trading:
bool WasThisTheUserDefinedBearishPATTERN( const int aBarNUMBER,
const double aBody2uWICK_MUL,
const double min_FRACTION,
const double MAX_FRACTION
) {
// BAR-UPPER-wick:
double aBarUpWK = ( iHigh( _Symbol, PERIOD_CURRENT, aBarNUMBER )
- iClose( _Symbol, PERIOD_CURRENT, aBarNUMBER )
);
// BAR-body:
double aBarBODY = ( iClose( _Symbol, PERIOD_CURRENT, aBarNUMBER )
- iOpen( _Symbol, PERIOD_CURRENT, aBarNUMBER )
);
// BAR-LOWER-wick:
double aBarLoWK = ( iLow( _Symbol, PERIOD_CURRENT, aBarNUMBER )
- iClose( _Symbol, PERIOD_CURRENT, aBarNUMBER )
);
// FLAG:
bool aBearishFLAG = FALSE;
// -----------------------------------------------------------------
// USER-DEFINE-ABLE SET OF SHAPE-CONDITIONS ..... = add all that apply
// BEARISH BODY:
// has body
// has body BEARISH
// has body not more than about a lo-wick size * < min_FRACTION, MAX_FRACTION >
// has body not less than about a hi-wick size * _MUL
// -------------
if ( aBarBODY >= 0 // not BEARISH
|| aBarUpWK < aBarBODY * aBody2uWICK_MUL // not long enough UpperWICK
){
aBearishFLAG = FALSE; // (NO)
}
else { if ( aBarBODY < 0 // has BEARISH CANDLE
&& ( aBarLoWK == 0 // and may LO-WICK ZERO
|| ( aBarLoWk / aBarBODY > min_FRACTION // .GT. min-WICK-2-BODY-FRACTION
&& aBarLoWk / aBarBODY < MAX_FRACTION // .LT. MAX-WICK-2-BODY-FRACTION
)
)
){ aBearishFLAG = TRUE; } // (YES)
else { aBearishFLAG = FALSE; } // ( NO) OTHERWISE
}
return( aBearishFLAG );
}
Ex-post :
I did WasThisTheUserDefinedBearishPATTERN( aShift, 1, 1/6, 2/6 ) and was expecting it to result in something...
Besides the comment below, kindly also respect The Rules of the World of MQL4 language:
Print( "DIV( 1 / 7 ) == ", 1 / 7 ); // will show you The Rules
Print( "DIV( 1. / 7. ) == ", 1. / 7. ); // will show you The Rules
So the way I would approach this is as follows:
1) What are the characteristics of each candle I am trying to define?
a) Down or up (I prefer 1 or -1)
b) Large rejection tail relative to the body
c) Large rejection tail relative to the non-rejection tail
d) Small body relative to the rejection tail
2) How do we code this in MQL4 using predefined functions?
Let's first make a few assumptions...
First, you are wanting to define these candles in real-time so you can execute when they form.
Second, let's go off the M30 for any given Symbol().
The below function (not tested) will return a 1 when there is a buy signal, and a -1 for a sell signal, and 0 if no signal. You will need to adjust the extern variables accordingly as this is more of a science than a "one-size-fits-all". Also, you might need to use IsNewBar.
//the values below should sum to 100
extern int RTail_To_Range_Ratio = 80; //rejection tail ratio to range of candle
extern int Body_To_Range_Ratio = 10; //body size ratio to range of candle
extern int NRTail_To_Range_Ratio = 10; //non-rejection tail ratio to range of candle
int Signal()
{
//candle information
double dOpen = iOpen(Symbol(),PERIOD_M30,0);
double dHigh = iHigh(Symbol(),PERIOD_M30,0);
double dLow = iLow(Symbol(),PERIOD_M30,0);
double dClose = iClose(Symbol(),PERIOD_M30,0);
double dBody = MathAbs(dOpen - dClose);
double dRange = dHigh - dLow;
double dRTail = 0, dTail = 0;
//green candle
if(dClose > dOPen){
dRTail = dOPen - dLow;
dTail = dHigh - dClose;
//now check ratios
if((dTail / dRange) <= (NRTail_To_Range_Ratio / 100) && (dBody / dRange) <= (Body_To_Range_Ratio / 100) && (dRTail / dRange) >= (RTail_To_Range_Ratio / 100)){
return 1;
}
}
//red candle
else{
dRTail = dHigh - dOpen;
dTail = dClose - dLow;
//now check ratios
if((dTail / dRange) <= (NRTail_To_Range_Ratio / 100) && (dBody / dRange) <= (Body_To_Range_Ratio / 100) && (dRTail / dRange) >= (RTail_To_Range_Ratio / 100)){
return -1;
}
}
return 0;
}
Let me know if this solves your problem #SuperHueman.

How to automatically calculate fibonnacci levels from yesterday/prev day in MQL4?

how do I calculate the fibo levels from yesterday/previous day.
This is how far I am currently:
int shift = iBarShift( NULL, PERIOD_D1, Time[0] ) + 1; // yesterday
HiPrice = iHigh( NULL, PERIOD_D1, shift);
LoPrice = iLow ( NULL, PERIOD_D1, shift);
StartTime = iTime( NULL, PERIOD_D1, shift);
if ( TimeDayOfWeek( StartTime ) == 0 /* Sunday */ )
{ // Add fridays high and low
HiPrice = MathMax( HiPrice, iHigh( NULL, PERIOD_D1, shift + 1 ) );
LoPrice = MathMin( LoPrice, iLow( NULL, PERIOD_D1, shift + 1 ) );
}
Range = HiPrice - LoPrice;
I think now I should have all values necessary for calculating it.
I am not sure on how I now can calculate the different levels now:
23.6 38.2 50.0 61.8 76.4 and -23.6 -38.2 -50.0 -61.8 -76.4 -100
All necessary Fibo-levels can be added manually as an array - this is the easiest way as far as I know. Then simply loop over such array and
+values are ( high + array[i] / 100 * range ),
values below the fibo - ( low - array[i] / 100 * range ),
where
array[] = { 23.6, 38.2, .. } ( only positive values are enough )
Fibonacci Levels need a direction, so in your above code you will either want to swap to using open and close values of the previous bar or impose a direction onto the high and low. This will let you know which way to draw the extensions and retraces.
Here is a function I have written previously for this question. This function assumes price1 is at an earlier timepoint than price2 then calculates the direction and levels, returning a FibLevel structure.
struct FibLevel {
double retrace38;
double retrace50;
double retrace61;
double extension61;
double extension100;
double extension138;
double extension161;
};
void FibLevel(double price1, double price2,FibLevel &fiblevel)
{
double range = MathAbs(price1-price2);
fiblevel.retrace38 =(price1<price2)?price2-range*0.382:price1+range*0.382;
fiblevel.retrace50 =(price1<price2)?price2-range*0.500:price1+range*0.500;
fiblevel.retrace61 =(price1<price2)?price2-range*0.618:price1+range*0.618;
fiblevel.extension61 =(price1<price2)?price2+range*0.618:price1-range*0.618;
fiblevel.extension100=(price1<price2)?price2+range :price1-range;
fiblevel.extension138=(price1<price2)?price2+range*1.382:price1-range*1.382;
fiblevel.extension161=(price1<price2)?price2+range*1.618:price1-range*1.618;
}

Can template matching in OpenCV deal with two same-sized images?

I want to use template matching in OpenCV to get the similarity of two images. As we all know,template matching is usually used to find smaller image parts in a bigger one. Here is my question. I find when template image and source image are same-sized, the result matrix get from function matchTemplate() is always 0, even if the two images are exactly the same one.
Can template matching in OpenCV deal with two same-sized images?
Perhaps I should apologize first: the value of the matrix is indeed zero after normalization, as long as the two pictures are of the same size. I was wrong about that:)
Check out this page:
OpenCV - Normalize
Part of the OpenCV source code:
void cv::normalize( InputArray _src, OutputArray _dst, double a, double b,
int norm_type, int rtype, InputArray _mask )
{
Mat src = _src.getMat(), mask = _mask.getMat();
double scale = 1, shift = 0;
if( norm_type == CV_MINMAX )
{
double smin = 0, smax = 0; //Records the maximum and minimum value in the _src matrix
double dmin = MIN( a, b ), dmax = MAX( a, b );
minMaxLoc( _src, &smin, &smax, 0, 0, mask ); //Find the minimum and maximum value
scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0);
shift = dmin - smin*scale;
}
//...
if( !mask.data )
src.convertTo( dst, rtype, scale, shift );
else
{
//...
}
}
Since there is only one element in the result array, smin = smax = result[0][0]
scale = (dmax - dmin)*(smax - smin > DBL_EPSILON ? 1./(smax - smin) : 0);
= (1 - 0 ) * (0) = 0
shift = dmin - smin*scale
= 0 - result[0][0] * 0
= 0
After that, void Mat::convertTo(OutputArray m, int rtype, double alpha, double beta) uses the following formula: (saturate_cast has nothing to do with your problem, so we can ignore it for now.)
When you call normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() ), whatever the element in the matrix is, it will execute src.convertTo( dst, rtype, scale, shift ); with scale = 0, shift = 0.
In this convertTo function,
alpha = 0, beta = 0
result[0][0] = result[0][0] * alpha + beta
= result[0][0] * 0 + 0
= 0
So, whatever the value in the result matrix is:
As long as the image and the template are of the same size, size of the result matrix will be 1x1, and after normalization, the result matrix will become a [0].

Resources