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

 
Artyom Trishkin:

The logic is this:

  1. find the last closed order by its type and time of its closing
  2. we find the bar at which it was closed by the time this order was closed
  3. If the obtained value of the bar is higher than zero, we can open a new position, otherwise, we can't.
I apologize for the impertinence) Can I see an example of such a code somewhere?
 
Viachaslau Baiko:
Pardon my impertinence) Can I see an example of this code somewhere?

It's simple.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}


I'm sorry, maybe I'm talking about the wrong thing.

 
Dmitry Fedoseev:

Meditate on this indicator. It has a lot of static variables:

   static datetime LastTime=0;
   static int cDir=0;
   static int pDir=0;

They are made instead of buffers.

When IndicatorCounted()=0 LastTime should be zeroed (the others are not necessary, but desirable).

Then at the beginning of the loop, move the values:

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }

Variables starting with "c" are the current value and with "p" the previous value.

This link won't open - error 404.

I tried experimenting with time, but it didn't work... I was thinking in the direction of "how to stop calculations at the last bar", I think that's my mistake. I will now think about how not to make a change to the last step in the calculation before changing the current bar.

 
Alekseu Fedotov:

It's simple.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}


I'm sorry, maybe I'm talking about the wrong thing.

Thanks, I'll give it a go!
 

Hello! Please help me with the algorithm!
I wrote a simple script, which calculates Pearson's correlation coefficient. The arrays are based on closing prices, starting from the first bar.

int start()
   {
   int n=25;
   int w=18;
   double sum_x=0;                                                // Сумма цен закрытия для пары 1
   double sum_y=0;                                                // Сумма цен закрытия для пары 2
   double Price_Close_x[];                                        // Массив Price_Close для пары 1
   double Price_Close_y[];                                        // Массив Price_Close для пары 2
   double dx[];                                                   // Отклонение от среднего значения для пары 1 dx
   double dy[];                                                   // Отклонение от среднего значения для пары 2 dy
   double dx2[];                                                  // Квадрат отклонения ср.значения dx2
   double dy2[];                                                  // Квадрат отклонения ср.значения dy2
   double dxdy[];                                                 // Произведение dx и dy



   ArrayResize(Price_Close_x, n);
   ArrayResize(Price_Close_y, n);
   ArrayResize(dx, n);
   ArrayResize(dy, n);  
   ArrayResize(dx2, n);
   ArrayResize(dy2, n);
   ArrayResize(dxdy, n);
   string sym_x="EURUSD";
   string sym_y="GBPUSD";
  
   for(int p=1; p<n; p++)
      {
      Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);
      Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);
      sum_x=sum_x+Price_Close_x[p];
      sum_y=sum_y+Price_Close_y[p];
      }
      
   Alert("Sum_x равно ", sum_x);
   Alert("Sum_y равно ", sum_y);
   double Mx=sum_x/(n-1);                                         // Среднее значение цен закрытия пары 1 Mx
   double My=sum_y/(n-1);                                         // Среднее значение цен закрытия пары 2 My
   Alert("Mx равно ", Mx);
   Alert("My равно ", My);  
  
   for(int i=1; i<n; i++)
      {
      dx[i]=Price_Close_x[i]-Mx;
      dy[i]=Price_Close_y[i]-My;
      dx2[i]=DoubleToString(dx[i]*dx[i], w);
      dy2[i]=DoubleToString(dy[i]*dy[i], w);
      dxdy[i]=DoubleToString(dx[i]*dy[i], w);
      Alert("Отклонение dx на баре ", i, " равно ", DoubleToString(dx[i], w));
      Alert("Отклонение dy на баре ", i, " равно ", DoubleToString(dy[i], w));
      Alert("Квадрат dx на баре ", i, " равен ", DoubleToString(dx2[i], w));
      Alert("Квадрат dy на баре ", i, " равен ", DoubleToString(dy2[i], w));
      Alert("dxdy на баре ", i, " равен ", DoubleToString(dxdy[i], w));    
      }
   double Edx2=0;                                                 // Сумма квадратов отклонений Edx2
   double Edy2=0;                                                 // Сумма квадратов отклонений Edy2
   double Edxdy=0;                                                // Сумма произведений отклонений Edxdy
   for(int q=0; q<n; q++)
      {
      Edx2=DoubleToString((Edx2+dx2[q]), w);
      Edy2=DoubleToString((Edy2+dy2[q]), w);
      Edxdy=DoubleToString((Edxdy+dxdy[q]), w);
      }  
   Alert("Сумма Edx2 равна ", DoubleToString(Edx2, w));
   Alert("Сумма Edy2 равна ", DoubleToString(Edy2, w));
   Alert("Сумма Edxdy равна ", DoubleToString(Edxdy, w));
  
   double Koef;                                                    // Коэффициент Пирсона
   Koef=Edxdy/(sqrt(DoubleToString((Edx2*Edy2), w)));
   Alert("Коэффициент корреляции Пирсона между ", sym_x, " и ", sym_y, " равен ", DoubleToString(Koef, w));    
   return;
 }

The price array is taken from the first bar to the 24th bar.
Now I want to calculate the correlation for 24 bars as well, but take the price array from the SECOND(!) bar.

Not knowing the algorithm, I entered each price array manually:

for(int p=1; p<n; p++)

      {

      Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);

      Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);

      sum_x=sum_x+Price_Close_x[p];

      sum_y=sum_y+Price_Close_y[p];

         Price_Close_x1[p]=iClose(sym_x, PERIOD_H1, p+1);

         Price_Close_y1[p]=iClose(sym_y, PERIOD_H1, p+1);

         Price_Close_x2[p]=iClose(sym_x, PERIOD_H1, p+2);

         Price_Close_y2[p]=iClose(sym_y, PERIOD_H1, p+2);

         Price_Close_x3[p]=iClose(sym_x, PERIOD_H1, p+3);

         Price_Close_y3[p]=iClose(sym_y, PERIOD_H1, p+3);
         ...
   
         ...
         Price_Close_x24[p]=iClose(sym_x, PERIOD_H1, p+24);

         Price_Close_y24[p]=iClose(sym_y, PERIOD_H1, p+24);
}

24 bars is a drag, and if I want to know the correlation for 100 bars, it's a pain in the ass to enter each array.
What to do, people?)

 
Timur1988:

Hi! Could you please help me with the algorithm!
I wrote a script that calculates Pearson correlation coefficient. I took arrays by close prices, starting from first bar

for(int p=1; p<n; p++)
{
Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);
Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);
sum_x=sum_x+Price_Close_x[p];
sum_y=sum_y+Price_Close_y[p];
}
_______________________________________

for(int p=1; p<n; p++)

{

Price_Close_x[p]=iClose(sym_x, PERIOD_H1, p);

Price_Close_y[p]=iClose(sym_y, PERIOD_H1, p);

sum_x=sum_x+Price_Close_x[p];

sum_y=sum_y+Price_Close_y[p];

Price_Close_x1[p]=iClose(sym_x, PERIOD_H1, p+1);

Price_Close_y1[p]=iClose(sym_y, PERIOD_H1, p+1);

Price_Close_x2[p]=iClose(sym_x, PERIOD_H1, p+2);

Price_Close_y2[p]=iClose(sym_y, PERIOD_H1, p+2);

Price_Close_x3[p]=iClose(sym_x, PERIOD_H1, p+3);

Price_Close_y3[p]=iClose(sym_y, PERIOD_H1, p+3);
...
Price_Close_x24[p]=iClose(sym_x, PERIOD_H1, p+24);

Price_Close_y24[p]=iClose(sym_y, PERIOD_H1, p+24);
}
____________________________________________________________________________


Two-dimensional array

PriceClose[][2];

double PriceClose[][2];
int n=24;
ArrayResize(PriceClose,n);
for(int p=0; p<n; p++) {
   PriceClose[p][0]=iClose(sym_x, PERIOD_H1, p);
   PriceClose[p][1]=iClose(sym_y, PERIOD_H1, p);
   sum_x+=PriceClose[p][0];
   sum_y+=PriceClose[p][1];
   }
 

I don't know where I'm going wrong...

//+------------------------------------------------------------------+
//|                                                       SVA_03.mq4 |
//|                      Copyright © 2006, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"
#property strict

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Yellow

//---- input parameters
extern int RSIPeriod=14;
extern int Levl=50;
extern int TF=0;
//---- buffers
double MABuffer[];
static datetime TimeN=0;
static datetime TimeX=0;
int StopCalc=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   string short_name;
   IndicatorBuffers(1);
   SetIndexBuffer(0,MABuffer);

//---- indicator line
   SetIndexStyle(0,DRAW_LINE);
//----
//---- name for DataWindow and indicator subwindow label
//   short_name="RSI("+IntegerToString(RSIPeriod)+")";
   short_name="RSI("+RSIPeriod+")";
   IndicatorShortName(short_name);
   SetIndexLabel(0,short_name);

   return(0);
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int start()
  {
   int    i,counted_bars=IndicatorCounted();
   double rel,negative,positive,sma,x,y,Pos,Neg;
   double sumn=0.0,sump=0.0;
//----
   if(Bars<=RSIPeriod) return(0);
   if(TF!=0)
     {
      string name=WindowExpertName();
      for(i=0; i<Bars-counted_bars+1; i++)
        {
         int barIndex=iBarShift(NULL,TF,Time[i],false);
         MABuffer[i]=iCustom(Symbol(),TF,name,RSIPeriod,Levl,0,0,barIndex);
        }
      return(0);
     }

   i=Bars-RSIPeriod-1;
   if(counted_bars>=RSIPeriod) i=Bars-counted_bars-1;
   datetime TimeC=iTime(NULL,TF,0);
   while(i>=0)
     {
      if(i!=0 && StopCalc==0)
        {
         sumn=0.0;sump=0.0;
         if(i==Bars-RSIPeriod-1)
           {
            int k=Bars-2;
            //---- initial accumulation
            while(k>=i)
              {
               rel=Close[k]-Close[k+1];
               if(rel>0) sump+=rel;
               else      sumn-=rel;
               k--;
              }
            positive=sump/RSIPeriod;
            negative=sumn/RSIPeriod;
           }
         else
           {
            //---- smoothed moving average
            rel=Close[i]-Close[i+1];
            if(rel>0) sump=rel;
            else      sumn=-rel;
            positive=(Pos*(RSIPeriod-1)+sump)/RSIPeriod;
            negative=(Neg*(RSIPeriod-1)+sumn)/RSIPeriod;
           }

         x=Pos;
         y=Neg;
         Pos=positive;
         Neg=negative;
         if(x>0)sma=Close[i+1]+x;
         else sma=Close[i+1]-y;
         MABuffer[i]=sma;
         Print("Этап 01 i=",i);      
        }

      if(i==0)
        {
          if(TimeC!=TimeX)
          {
        
            rel=Close[i+1]-Close[i+2];
            if(rel>0) sump=rel;
            else      sumn=-rel;
            positive=(Pos*(RSIPeriod-1)+sump)/RSIPeriod;
            negative=(Neg*(RSIPeriod-1)+sumn)/RSIPeriod;
            x=Pos;
            y=Neg;
            Pos=positive;
            Neg=negative;
            Print("positive=",positive);
            Print("negative=",negative);


            if(x>0)sma=Close[i+1]+x;
            else sma=Close[i+1]-y;
            MABuffer[i]=sma;
            Print("Этап 2 i=",i);          
            TimeX=iTime(NULL,TF,0);
            StopCalc=1;
          }          
        }
      i--;
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+

the results are different from option 4 - what's wrong?

 
-Aleks-:

The link won't open - 404 error

Tried experimenting with timing, but it didn't work... I was thinking in the direction of "how to stop the calculation at the last bar", I think that's my mistake. I will now think about how not to make a change to the last step in the calculation before changing the current bar.

Why are you so heavy and not pivoting? You have already been given a solution, all you have to do is sit back and think. Conclusion of course, well there are no words - you saw the word Time, and immediately concluded that you did it...

You don't need a link, you'll get lost. Everything you need is written in this post, let me repeat it in details:

1. declare a static variable LastTime.

2. declare a pair of static variables with the prefixes s and p.

3. When IndicatorCounted()=0, null all the variables created at step 1 and 2.

4. At the beginning of the cycle, reset the values:

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }
 
Dmitry Fedoseev:

Why are you so heavy-handed and not pivotal? You have already been given a decision, all you have to do is sit back and think. The conclusion of course, well there are no words - the word Time saw, and immediately concluded that you did it...

You don't need a link, or you'll get lost. Everything you need is written in this post, let me repeat it in details:

1. declare a static variable LastTime.

2. declare a pair of static variables with the prefixes s and p.

3. When IndicatorCounted()=0, null all the variables created at step 1 and 2.

4. At the beginning of the loop reset the values:

if(Time[i]>LastTime)
        {
         LastTime=Time[i];
         pDir=cDir;

        }
      else
        {
         cDir=pDir;
        }

Thank you for wanting to help!

I have not much experience in writing indicators, so there are some difficulties - the solution to which I am looking for - as shown by my last code above.

The variant suggested by you causes difficulty as I cannot understand which variables I am offered to zero - although the idea is clear - to retain the originally calculated values.

If you can explain why my variant does not work - I also limit the calculation to one tick per bar and the variables should not change, and it is expected that this variant is less costly as the loop will not be idle on every tick, unlike the variant you have proposed.

 
Artyom Trishkin:

The logic is this:

  1. find the last closed order by its type and closing time
  2. we find the bar at which it was closed by the time this order closed
  3. If the obtained value of the bar is higher than zero, we can open a new position, otherwise, we can't.

I have the following nuance here: I took this code (thanks to Alekseu Fedotov):

//+----------------------------------------------------------------------------+
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает номер бара закрытия последней позиции или -1.       |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   ("" или NULL - текущий символ)          |
//|    tf - таймфрейм                  (    0       - текущий таймфрейм)       |
//|    op - операция                   (   -1       - любая позиция)           |
//|    mn - MagicNumber                (   -1       - любой магик)             |
//+----------------------------------------------------------------------------+
int NumberOfBarCloseLastPos(string sy="0", int tf=0, int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersHistoryTotal();

  if (sy=="" || sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) {
      if (OrderSymbol()==sy) {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderCloseTime()) t=OrderCloseTime();
            }
          }
        }
      }
    }
  }
  return(iBarShift(sy, tf, t, True));
}

And now I put a check:

if(УСЛОВИЕ && NumberOfBarCloseLastPos()>0)

And here is the hitch, because initially NumberOfBarCloseLastPos will be set to "-1". And consequently, the first order will never open.

What can we do in such a situation? Or maybe I have misunderstood something?

Reason: