Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 12

 
Artyom Trishkin:

La logique est la suivante :

  1. trouver le dernier ordre clôturé par son type et l'heure de sa clôture
  2. nous trouvons la barre à laquelle il était fermé au moment où cette commande a été fermée.
  3. Si la valeur obtenue de la barre est supérieure à zéro, nous pouvons ouvrir une nouvelle position, sinon, nous ne pouvons pas.
Je m'excuse pour cette impertinence) Puis-je voir un exemple d'un tel code quelque part ?
 
Viachaslau Baiko:
Pardonnez mon impertinence) Puis-je voir un exemple de ce code quelque part ?

C'est 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));
}


Je suis désolé, peut-être que je parle de la mauvaise chose.

 
Dmitry Fedoseev:

Méditez sur cet indicateur. Il a beaucoup de variables statiques :

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

Ils sont réalisés à la place des tampons.

Lorsque IndicatorCounted()=0 LastTime doit être mis à zéro (les autres ne sont pas nécessaires, mais souhaitables).

Puis, au début de la boucle, déplacez les valeurs :

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

        }
      else
        {
         cDir=pDir;
        }

Les variables commençant par "c" sont la valeur actuelle et par "p" la valeur précédente.

Ce lien ne s'ouvre pas - erreur 404.

J'ai essayé d'expérimenter avec le temps, mais ça n'a pas marché... Je pensais dans la direction de "comment arrêter les calculs à la dernière mesure", je pense que c'est mon erreur. Je vais maintenant réfléchir à la manière de ne pas modifier la dernière étape du calcul avant de modifier la barre actuelle.

 
Alekseu Fedotov:

C'est 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));
}


Je suis désolé, peut-être que je parle de la mauvaise chose.

Merci, je vais tenter le coup !
 

Bonjour, aidez-moi avec l'algorithme !
J'ai écrit un script simple, qui calcule le coefficient de corrélation de Pearson. Les tableaux sont basés sur les prix de clôture, à partir de la première barre.

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;
 }

Le tableau des prix est pris de la première barre à la 24ème barre.
Maintenant, je veux calculer la corrélation également pour 24 barres, mais prendre le tableau des prix de la SECONDE ( !) barre.

Ne connaissant pas l'algorithme, j'ai saisi manuellement chaque tableau de prix :

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 barres, c'est une corvée, et si je veux connaître la corrélation pour 100 barres, c'est un calvaire d'entrer chaque tableau.
Que faire, les gens ?)

 
Timur1988:

Bonjour ! Pourriez-vous m'aider avec l'algorithme ?
J'ai écrit un script qui calcule le coefficient de corrélation de Pearson. J'ai pris des tableaux par prix de clôture, en commençant par la première barre.

for(int p=1 ; p<n ; p++)
{
Prix_Close_x[p]=iClose(sym_x, PERIOD_H1, p) ;
Prix_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++)

{

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

Prix_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] ;

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

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

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

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

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

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

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


Tableau à deux dimensions

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];
   }
 

Je ne sais pas où je vais mal...

//+------------------------------------------------------------------+
//|                                                       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);
  }
//+------------------------------------------------------------------+

les résultats sont différents de l'option 4 - qu'est-ce qui ne va pas ?

 
-Aleks-:

Le lien ne s'ouvre pas - erreur 404

J'ai essayé d'expérimenter le timing, mais ça n'a pas marché... Je pensais dans le sens de "comment arrêter le calcul à la dernière mesure", je pense que c'est mon erreur. Je vais maintenant réfléchir à la manière de ne pas modifier la dernière étape du calcul avant de modifier la barre actuelle.

Pourquoi es-tu si lourd et ne pivote pas ? On vous a déjà donné une solution, il ne vous reste plus qu'à vous asseoir et à réfléchir. Conclusion, bien sûr, il n'y a pas de mots - vous avez vu le mot Time, et avez immédiatement conclu que c'était vous...

Vous n'avez pas besoin de lien, sinon vous allez vous perdre. Tout ce dont vous avez besoin est décrit dans ce post, laissez-moi le répéter en détail :

1. déclarer une variable statique LastTime.

2. déclarer une paire de variables statiques avec les préfixes s et p.

3. Lorsque IndicatorCounted()=0, annuler toutes les variables créées aux étapes 1 et 2.

4. Au début du cycle, remettez les valeurs à zéro :

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

        }
      else
        {
         cDir=pDir;
        }
 
Dmitry Fedoseev:

Pourquoi êtes-vous si lourde et pas pivotante ? On vous a déjà donné une décision, il ne vous reste plus qu'à vous asseoir et à réfléchir. La conclusion, bien sûr, il n'y a pas de mots - le mot Time a vu, et a immédiatement conclu que vous l'avez fait...

Vous n'avez pas besoin de lien, sinon vous allez vous perdre. Tout ce dont vous avez besoin est écrit dans ce post, laissez-moi le répéter en détail :

1. déclarer une variable statique LastTime.

2. déclarer une paire de variables statiques avec les préfixes s et p.

3. Lorsque IndicatorCounted()=0, annuler toutes les variables créées aux étapes 1 et 2.

4. Au début de la boucle, remettez les valeurs à zéro :

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

        }
      else
        {
         cDir=pDir;
        }

Merci de vouloir aider !

Je n'ai pas beaucoup d'expérience dans l'écriture d'indicateurs, il y a donc quelques difficultés - dont je cherche la solution - comme le prouve mon dernier code ci-dessus.

La variante que vous proposez me pose problème car je ne comprends pas quelles sont les variables que l'on me propose de mettre à zéro - alors que l'idée est claire - conserver les valeurs initialement calculées.

Si vous pouvez expliquer pourquoi ma variante ne fonctionne pas - je limite également le calcul à un tick par barre et les variables ne doivent pas changer, et on s'attend à ce que cette variante soit moins coûteuse car la boucle ne sera pas au repos à chaque tick, contrairement à la variante que vous avez proposée.

 
Artyom Trishkin:

La logique est la suivante :

  1. trouver le dernier ordre clôturé par son type et son heure de clôture
  2. nous trouvons la barre à laquelle il était fermé au moment de la fermeture de cet ordre.
  3. Si la valeur obtenue de la barre est supérieure à zéro, nous pouvons ouvrir une nouvelle position, sinon, nous ne pouvons pas.

La nuance est la suivante : j'ai pris ce code (merci à 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));
}

Et maintenant je mets un chèque :

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

Et c'est là que le bât blesse, car initialement NumberOfBarCloseLastPos sera défini à "-1". Et par conséquent, la première commande ne sera jamais ouverte.

Que pouvons-nous faire dans une telle situation ? Ou peut-être ai-je mal compris quelque chose ?