Any questions from newcomers on MQL4 and MQL5, help and discussion on algorithms and codes - page 566

 
Vitaly Muzichenko:

Try the function:

It's not so simple if you use the function on both currencies and futures. There is a margin percentage to consider.


 
Alexey Viktorov:

It is not so simple if you use the function on both currencies and futures. You have to consider the percentage of margin.

If we are talking about the percentage loss, we are not interested in the margin, it will return when the position is closed

 
Vitaly Muzichenko:

If we are talking about percentage loss, we are not interested in margin, it will come back when the position is closed

I must have overslept... or haven't woken up yet...
 
Alekseu Fedotov:

Perhaps

How? Please tell me!
 
Nikolay Gaylis:

I'm sorry that's all you noticed.)

I'm not the only one, the Terminal can't see the difference either, in essence. The exit outside the array is still there.

 
Vitaly Muzichenko:

Try the function:

Thank you for your help! Unfortunately it was not possible to implement a universal solution, I had to do it this way:

input double MaximumRisk=0.02;                  //Риск в сделке от депозита

{
 double TickValue   =MarketInfo(Symbol(),MODE_TICKVALUE),
        TickSize    =MarketInfo(Symbol(),MODE_TICKSIZE),
        ContractSize=MarketInfo(Symbol(),MODE_LOTSIZE),
        Min_Lot     =MarketInfo(Symbol(),MODE_MINLOT),
        Max_Lot     =MarketInfo(Symbol(),MODE_MAXLOT),
        Step        =MarketInfo(Symbol(),MODE_LOTSTEP);

 {
//Для пар XXXUSD, USDXXX, XAUUSD, XAGUSD, CRYPTO, для кроссов
Lots = NormalizeDouble((((AccountBalance()*MaximumRisk)/(MathAbs(Price-SL)/Point))/TickValue),int(MathAbs(log(Step))));
//Для перечисленного в if
if (Symbol() == "BRN" || Symbol() == "WTI" || Symbol() == "NG" || Symbol() == "NIKK225" || Symbol() == "SPX500")
{Lots = NormalizeDouble(((((AccountBalance()*MaximumRisk))/MathAbs(Price-SL)))/(ContractSize/TickValue),1);}
//Для перечисленного в if
if (Symbol() == "ASX200" || Symbol() == "CAC40" || Symbol() == "NQ100" || Symbol() == "STOXX50" || Symbol() == "DAX30"
 || Symbol() == "FTSE100"  || Symbol() == "IBEX35")
{Lots = NormalizeDouble(((((AccountBalance()*MaximumRisk))/MathAbs(Price-SL)))/(TickValue/TickSize/Point),1);}
 }
}

Can you please tell me if my broker has floating leverage, how can I take it into account in lot calculation? Or it will not affect, if you go for the above option?

 

Another indicator, also array out of range.

It goes to the chart without problems, but when I call it from the EA it says ...array out of range in 'HiLo.mq4' (121,15)

What's the problem?

#property copyright "Copyright ©  november 2015"
#property strict 

#property indicator_chart_window
#property indicator_buffers 6

#property indicator_color1 RoyalBlue       //DodgerBlue
#property indicator_color2 Crimson         //OrangeRed
#property indicator_color3 Black  //White
#property indicator_color4 Black  //White
#property indicator_color5 Black            //White
#property indicator_color6 Black         //Red

#property indicator_width1 2
#property indicator_width2 2

#property indicator_style3 STYLE_DOT
#property indicator_style4 STYLE_DOT

input int    p        = 10;    // Период
input int    s        = 5;     // Угол наклона
input double distance = 2.0;   // Ширина канала
input bool   showBb   = false;  // Границы канала
input bool   showCl   = true;  // Центральная линия
input int    barsig   = 1;     // Сигнальная свеча (номер)
input int    arrots   = 0;    // Стрелка (отступ)
input int    arrsz    = 0;     // Стрелка (размер)
input int    ATR      = 1000;  // Период ATR
input int    cb       = 1000;  // Сколько свечей в истории

double fx1[],fx2[],hp[];
double z1,z2,ki;
int fs;

double upper[],lower[];
double upar[],dnar[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- indicator buffers mapping
IndicatorBuffers(7);
SetIndexBuffer(0,fx1);
SetIndexBuffer(1,fx2);
SetIndexBuffer(2,lower);
SetIndexBuffer(3,upper);
SetIndexBuffer(4,upar);
SetIndexBuffer(5,dnar);
SetIndexBuffer(6,hp);

SetIndexStyle (4,DRAW_ARROW,0,arrsz);
SetIndexArrow (4,233);
SetIndexStyle (5,DRAW_ARROW,0,arrsz);
SetIndexArrow (5,234);

   if(showBb)
   {SetIndexStyle(2,DRAW_LINE);
    SetIndexStyle(3,DRAW_LINE);
   }
   else
   {SetIndexStyle(2,DRAW_NONE);
    SetIndexStyle(3,DRAW_NONE);
   }
   
    if(showCl)
   {SetIndexStyle(0,DRAW_LINE);
    SetIndexStyle(1,DRAW_LINE);
   }
   else
   {SetIndexStyle(0,DRAW_NONE);
    SetIndexStyle(1,DRAW_NONE);
   }

SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);

//---
   return(INIT_SUCCEEDED);
  }
  
//+------------------------------------------------------------------+
//| 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[])
  {
//---
   int i;
   
   SetIndexDrawBegin(0,Bars-cb);
   SetIndexDrawBegin(1,Bars-cb);

double avg;

ki=2.0/(p+1);

for (i=cb; i>=0; i--) {fx1[i]=Close[i];}

for (int m=0; m<=s; m++)
{
z1=fx1[0];
for (i=0; i<=cb; i++) {z1=z1+(fx1[i]-z1)*ki; hp[i]=z1;}

z2=fx1[cb];
for (i=cb; i>=0; i--) {z2=z2+(fx1[i]-z2)*ki; fx1[i]=(hp[i]+z2)/2;}
}

fs=0;
for (i=cb; i>=0; i--)
{
if (fx1[i]>fx1[i+1]) fs=1;
if (fx1[i]<fx1[i+1]) {if (fs==1) fx2[i+1]=fx1[i+1]; fs=2;}
if (fs==2) fx2[i]=fx1[i]; else fx2[i]=0.0;

avg = iATR(NULL,0,ATR, i+10);
upper[i] = hp[i] + distance*avg;
lower[i] = hp[i] - distance*avg;

if(Close[i+1+barsig]<upper[i+1+barsig] && Close[i+barsig]>upper[i+barsig])
 dnar[i] = High[i]+arrots*Point; else dnar[i] = EMPTY_VALUE;
 
if(Close[i+1+barsig]>lower[i+1+barsig] && Close[i+barsig]<lower[i+barsig])
 upar[i] = Low[i]-arrots*Point; else upar[i] = EMPTY_VALUE; 
}

//--- return value of prev_calculated for next call
   return(rates_total);
  }

 
PolarSeaman:

Another indicator, also array out of range.

It goes to the chart without problems, but when I call it from the EA it says ...array out of range in 'HiLo.mq4' (121,15)

What's the problem?


It doesn't check if there are 1000 bars on the chart. For example, at the moment of terminal opening there are 0 bars in all charts, but terminal has already started indicators (I do not know why it does that, but it's a fact). Therefore, any access to indicator buffers causes exceeding of time series arrays.

 
Ihor Herasko:

There is no check that there are 1000 bars on the chart. For example, at the moment of terminal opening there are 0 bars in all charts, but terminal has already started indicators (it is unclear why it does it, but it is a fact). Therefore, any access to indicator buffers causes exit of time series arrays.

if(Bars<cb)return(0);

It still crashes.

 
PolarSeaman:

It still crashes.

Because the check is fundamentally wrong. Let's say Bars returns 1000 and cb also returns 1000. Then in the loop on the first iteration i gets the value 1000. In the first condition of the loop body:

if (fx1[i]>fx1[i+1]) fs=1;

Two exits outside the array at once : accessing a bar with index 1000 and one with index 1001. For if the chart has 1000 bars, the first bar has index 0 and the last one has index 999.

Further on through the loop body there is a reference to the even more distant bars in the history:

if(Close[i+1+barsig]<upper[i+1+barsig] && Close[i+barsig]>upper[i+barsig])

All of this needs to be taken into account in the initial check.

For a proper check, see the example of the IndicatorCounted() function in MQL4 Reference. Only now, IndicatorCounted() better be replaced by joint use of rates_total (this is Bars) and prev_calculated (this is IndicatorCounted()) variables.