Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 12

 
Artyom Trishkin:

La logica è questa:

  1. trova l'ultimo ordine chiuso in base al suo tipo e al tempo della sua chiusura
  2. troviamo il bar al quale è stato chiuso al momento in cui questo ordine è stato chiuso
  3. Se il valore ottenuto della barra è superiore a zero, possiamo aprire una nuova posizione, altrimenti no.
Mi scuso per l'impertinenza) Posso vedere un esempio di tale codice da qualche parte?
 
Viachaslau Baiko:
Scusate la mia impertinenza) Posso vedere un esempio di questo codice da qualche parte?

È semplice.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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));
}


Mi dispiace, forse sto parlando della cosa sbagliata.

 
Dmitry Fedoseev:

Meditate su questo indicatore. Ha molte variabili statiche:

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

Sono fatti al posto dei buffer.

Quando IndicatorCounted()=0 LastTime dovrebbe essere azzerato (gli altri non sono necessari, ma desiderabili).

Poi, all'inizio del ciclo, sposta i valori:

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

        }
      else
        {
         cDir=pDir;
        }

Le variabili che iniziano con "c" sono il valore attuale e con "p" il valore precedente.

Questo link non si apre - errore 404.

Ho provato a sperimentare con il tempo, ma non ha funzionato... Stavo pensando nella direzione di "come fermare i calcoli all'ultima barra", penso che questo sia il mio errore. Ora penserò a come non fare una modifica all'ultimo passo del calcolo prima che la barra corrente cambi.

 
Alekseu Fedotov:

È semplice.

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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));
}


Mi dispiace, forse sto parlando della cosa sbagliata.

Grazie, ci proverò!
 

Ciao, per favore aiutami con l'algoritmo!
Ho scritto un semplice script che calcola il coefficiente di correlazione di Pearson. Gli array sono basati sui prezzi di chiusura, a partire dalla prima barra.

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

L'array di prezzi è preso dalla prima barra alla 24esima barra.
Ora voglio calcolare la correlazione anche per 24 barre, ma prendere l'array di prezzi dalla SECONDA(!) barra.

Non conoscendo l'algoritmo, ho inserito ogni array di prezzi manualmente:

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 barre sono una seccatura, e se voglio conoscere la correlazione per 100 barre, è una rottura di palle inserire ogni array.
Cosa fare, gente?)

 
Timur1988:

Ciao, potresti aiutarmi con l'algoritmo?
Ho scritto uno script che calcola il coefficiente di correlazione di Pearson. Ho preso gli array per i prezzi di chiusura, partendo dalla prima barra

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

{

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

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

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

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

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

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

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

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

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


Matrice bidimensionale

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

Non so dove sto sbagliando...

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

i risultati sono diversi dall'opzione 4 - cosa c'è di sbagliato?

 
-Aleks-:

Il link non si apre - errore 404

Ho provato a sperimentare con i tempi, ma non ha funzionato... Stavo pensando nella direzione di "come fermare il calcolo all'ultima barra", penso che questo sia il mio errore. Ora penserò a come non fare una modifica all'ultimo passo del calcolo prima di cambiare la barra corrente.

Perché è così pesante e non fa perno? Vi è già stata data una soluzione, tutto quello che dovete fare è sedervi e pensare. Conclusione ovviamente, beh non ci sono parole - hai visto la parola Tempo, e hai concluso immediatamente che sei stato tu...

Non hai bisogno di un link, altrimenti ti perdi. Tutto quello che ti serve è descritto in questo post, lascia che lo ripeta nei dettagli:

1. dichiarare una variabile statica LastTime.

2. dichiarare una coppia di variabili statiche con i prefissi s e p.

3. Quando IndicatorCounted()=0, annulla tutte le variabili create al passo 1 e 2.

4. All'inizio del ciclo, azzerare i valori:

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

        }
      else
        {
         cDir=pDir;
        }
 
Dmitry Fedoseev:

Perché è così pesante e non fa perno? Vi è già stata data una decisione, tutto quello che dovete fare è sedervi e pensare. La conclusione naturalmente, beh non ci sono parole - la parola Time ha visto, e ha concluso immediatamente che sei stato tu...

Non hai bisogno di un link, ti perderesti. Tutto ciò di cui hai bisogno è scritto in questo post, lascia che lo ripeta in dettaglio:

1. dichiarare una variabile statica LastTime.

2. dichiarare una coppia di variabili statiche con i prefissi s e p.

3. Quando IndicatorCounted()=0, annulla tutte le variabili create al passo 1 e 2.

4. All'inizio del ciclo resetta i valori:

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

        }
      else
        {
         cDir=pDir;
        }

Grazie per aver voluto aiutare!

Non ho molta esperienza nello scrivere indicatori, quindi ci sono alcune difficoltà - la cui soluzione sto cercando - come dimostra il mio ultimo codice sopra.

La variante suggerita da voi causa difficoltà perché non riesco a capire quali variabili mi vengono proposte per azzerare - anche se l'idea è chiara - per mantenere i valori calcolati originariamente.

Se puoi spiegare perché la mia variante non funziona - limito anche il calcolo a un tick per barra e le variabili non dovrebbero cambiare, e ci si aspetta che questa variante sia meno costosa poiché il ciclo non sarà inattivo su ogni tick, a differenza della variante che hai proposto.

 
Artyom Trishkin:

La logica è questa:

  1. trova l'ultimo ordine chiuso in base al suo tipo e al tempo di chiusura
  2. troviamo il bar al quale era chiuso al momento della chiusura di questo ordine
  3. Se il valore ottenuto della barra è superiore a zero, possiamo aprire una nuova posizione, altrimenti no.

Qui ho la seguente sfumatura: ho preso questo codice (grazie a 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));
}

E ora ho messo un assegno:

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

Ed ecco l'intoppo, perché inizialmente NumberOfBarCloseLastPos sarà impostato su "-1". E di conseguenza, il primo ordine non si aprirà mai.

Cosa possiamo fare in una tale situazione? O forse ho capito male qualcosa?

Motivazione: