Array fuori portata in Bisogno di aiuto - pagina 8

 
Aleksei Stepanenko:

È stato seduto qui per un po':

Dovremmo cercare di evitare cicli inutili. Abbiamo una marea di citazioni, ed è necessario fare le voci giuste al volo, in modo da non dover scavare nella storia e sprecare risorse del computer.

Mi sento come un bambino di prima elementare, anche se ho 42 anni.

 
Dark Kchlyzov:

Mi sento come un bambino di prima elementare, anche se ho 42 anni.

Questa è una buona cosa. Significa che tutto è davanti a me.

 
Алексей Тарабанов:

Questo è un bene. Quindi tutto è davanti a noi.

La cosa più importante è il risultato!!!

 
Dark Kchlyzov:

3.47 Vado a letto.

Digerirò tutto domani e se avrò delle domande te lo farò sapere!

Grazie mille a tutti!

Omsk?

 
Aleksei Stepanenko:

Sedersi per un po':

Dovremmo cercare di evitare i loop inutili. Abbiamo citazioni che arrivano a fiumi, e abbiamo bisogno di fare le voci giuste al volo, in modo da non dover scavare nella storia e sprecare risorse del computer.

Ho eseguito il tuo codice.

C'è qualcosa di sbagliato qui?

#property version   "1.00"
#property strict

//символ и таймфрейм текущего графика
string symbol;
ENUM_TIMEFRAMES frame;
datetime time;
   

struct BarData
   {
   struct Elem
      {
      int      number;     //порядковый номер периода (дня, месяца или года)
      double   high;       //максимум периода
      double   low;        //минимум периода
      datetime time_high;  //время максимума
      datetime time_low;   //время минимума
      } Arr[];             //массив периода
   int index;              //текущий индекс массива
   double   max;           //последнее максимальное значение периода
   double   min;           //последнее минимальное значение периода
   datetime time_max;      //время максимума
   datetime time_min;      //время минимума

   //при создании структуры указываем, что массив пустой
   BarData(){index=-1;}    
   
   //функция записывает текущие экстремумы
   void WriteBar(int eNumber, string eSymbol, ENUM_TIMEFRAMES eFrame, datetime eTime)
      {
      int eShift=iBarShift(eSymbol,eFrame,eTime);
      double eHigh=iHigh(eSymbol,eFrame,eShift);
      double eLow=iLow(eSymbol,eFrame,eShift);
      //если элементов ещё нет или период сменился
      if(index<0 || eNumber!=Arr[index].number)
         {
         ArrayResize(Arr,++index+1);
         Arr[index].number=eNumber;
         Arr[index].high=eHigh;
         Arr[index].low=eLow;
         Arr[index].time_high=eTime;
         Arr[index].time_low=eTime;
         }
      //если произошло обновление текущего максимума
      if(eHigh-Arr[index].high>0)
         {
         Arr[index].high=eHigh;
         Arr[index].time_high=eTime;
         }
      //если произошло обновление текущего минимума
      if(Arr[index].low-eLow>0)
         {
         Arr[index].low=eLow;
         Arr[index].time_low=eTime;
         }
      //если произошло обновление предыдущего максимума
      if(eHigh-max>0)
         {
         for(int i=index+1; i>=0; i--)
            {
            if(Arr[index].high-eHigh>0)
               {
               max=Arr[index].high;
               time_max=Arr[index].time_high;
               break;
               }
            }
         }
      //если произошло обновление предыдущего минимума
      if(min-eLow>0)
         {
         for(int i=index+1; i>=0; i--)
            {
            if(eLow-Arr[index].low>0)
               {
               min=Arr[index].low;
               time_min=Arr[index].time_low;
               break;
               }
            }
         }
      }
   } day, month, year;

int OnInit()
   {
   symbol=Symbol();
   frame=(ENUM_TIMEFRAMES)Period();
   return(INIT_SUCCEEDED);
   }

void OnTick()
   {
   //текущее время закрытого бара
   time=iTime(symbol,frame,1);
   
   MqlDateTime date; 
   TimeToStruct(time,date);
   
   //делаем записи каждого периода
   day.WriteBar(date.day,symbol,frame,time);
   month.WriteBar(date.mon,symbol,frame,time);
   year.WriteBar(date.year,symbol,frame,time);
   
   //теперь имеем значения   
   Comment(TimeToString(day.time_max)+" : "+DoubleToString(day.max)+" : "+DoubleToString(day.Arr[day.index].high)+"\n"+TimeToString(day.time_min)+" : "+DoubleToString(day.Arr[day.index].low)+" : "+DoubleToString(day.min));
   }


Ecco come appare

1) Livello Low_D1 del giorno precedente

2) Min_D il minimo giornaliero più vicino sulla storia



//+------------------------------------------------------------------+
//|                                                   Test_Level.mq4 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
double   Bar_data_D1 [][6]; // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров D1
double   Low_D1_Level;      // Возвращает значение минимальной цены бара  D1
double   Min_D_Level ;      // ближайшей минимальный  D уровень
datetime  Time_Day;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   Level();
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
  On_Timer();
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|                        Функция Level 
//+------------------------------------------------------------------+
void Level()
{
 ArrayCopyRates(Bar_data_D1,_Symbol,PERIOD_D1); // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров

 Low_D1_Level   = iLow (_Symbol,PERIOD_D1,1);   // Возвращает значение минимальной цены бара  D1
    
//--- Min_D_Leve  
 //for(int i = 1; i<ArrayRange(Bar_data_D1,0) ;i++)
 for(int i = 1; ;i++)
    {
     Print(" i = ",i," Bar_data_D1 [i][2] = ",Bar_data_D1 [i][2]);
     if(Bar_data_D1 [i][2]>=0)
       {
        if( Bar_data_D1 [i][2] < Low_D1_Level)
          {
           Min_D_Level = Bar_data_D1 [i][2];break;
          }
       }   
    } 

 //+-------------------------Low_D1_Level----------------------------+ 
 if(ObjectFind("Low_D1")!=Low_D1_Level) 
   {
    ObjectDelete("Low_D1");
    if(ObjectFind("Low_D1")!=0)
      {
       ObjectCreate("Low_D1",OBJ_HLINE, 0, Time[0],Low_D1_Level);
       ObjectSet("Low_D1", OBJPROP_COLOR, clrMaroon);
       ObjectSet("Low_D1", OBJPROP_WIDTH, 1);
      }
   } 
   
 if(ObjectFind("Low_D1_label")!=Low_D1_Level)
   {
    ObjectDelete("Low_D1_label"); 
    if(ObjectFind("Low_D1_label") != 0)
      {
       ObjectCreate("Low_D1_label", OBJ_TEXT, 0, Time[13], Low_D1_Level);
       ObjectSetText("Low_D1_label", "Low_D1: " + DoubleToStr(Low_D1_Level,_Digits), 8,"Verdana", Brown);
      }
   } 
   
 //+-------------------------Min_D_Level----------------------------+ 
 if(ObjectFind("Min_D")!= Min_D_Level) 
   {
    ObjectDelete("Min_D");
    if(ObjectFind("Min_D")!=0)
      {
       ObjectCreate("Min_D",OBJ_HLINE, 0, Time[0],Min_D_Level);
       ObjectSet("Min_D", OBJPROP_COLOR, clrMaroon);
       ObjectSet("Min_D", OBJPROP_WIDTH, 1);
      }
   } 
   
 if(ObjectFind("Min_D_label")!=Min_D_Level)
   {
    ObjectDelete("Min_D_label"); 
    if(ObjectFind("Min_D_label") != 0)
      {
       ObjectCreate("Min_D_label", OBJ_TEXT, 0, Time[30], Min_D_Level);
       ObjectSetText("Min_D_label", "Min_D: " + DoubleToStr(Min_D_Level,_Digits), 8,"Verdana", Brown);
      }
   }  
 
}
//+------------------------------------------------------------------+
//|        функция удаление всех объектов созданных советником
//+------------------------------------------------------------------+
void DestroyObject()
{
 int tot=ObjectsTotal();
 for( int i=tot; i>=0; i--)
    {
     
     if(ObjectName(i)=="Low_MN1"){ObjectDelete(0,"Low_MN1");Print("<< Объект Low_MN удалён >>");}
     if(ObjectName(i)=="Low_MN1_label"){ObjectDelete(0,"Low_MN1_label");Print("<< Объект Low_MN1_label удалён >>");}
     

     if(ObjectName(i)=="Min_D"){ObjectDelete(0,"Min_D");Print("<< Объект Min_D удалён >>");}
     if(ObjectName(i)=="Min_D_label"){ObjectDelete(0,"Min_D_label");Print("<< Объект Min_D_label удалён >>");}


   }
}
//+-------------------------------------------------------------------------+   
//                         функция Timer                    
//+-------------------------------------------------------------------------+
void On_Timer()
{

     
 if(Day()!= Time_Day)
   {
    Level();
    Time_Day = Day();
   }
}
 
Valeriy Yastremskiy:

Omsk?

 
Dark Kchlyzov:

a +3 in qualche modo non molte città)

L'algoritmo non sempre disegna e conta come previsto, ma come scritto. Scrivere come scritto è di solito difficile.

Nell'immagine hai mostrato i minimi, e nella condizione hai il prezzo minimo della barra giornaliera Low. E l'algoritmo l'ha trovato nella zona di tendenza, e non è il minimo tra 2 barre adiacenti.

[Eliminato]  
Dark Kchlyzov:

Ho eseguito il tuo codice.

C'è qualcosa che non va qui?

La prima sfumatura, finora l'algoritmo non conta dall'inizio della storia del tester, ma dall'inizio. Pertanto, appare la data 1970.01.01, che è zero.

Per farlo contare dall'inizio della storia, è necessario inserire un ciclo in OnTick. Qualcosa del genere:

datetime time=0, current;


void OnTick()
   {
   //текущее время закрытого бара
   current=iTime(symbol,frame,1);

   do
      {   
      MqlDateTime date; 
      TimeToStruct(time,date);
   
      //делаем записи каждого периода
      day.WriteBar(date.day,symbol,frame,time);
      month.WriteBar(date.mon,symbol,frame,time);
      year.WriteBar(date.year,symbol,frame,time);
   
      if(time<current) {time=iTime(symbol,frame,(iBarShift(symbol,frame,time)-1));} else break;
      }
   while(time<=current);

   //теперь имеем значения   
   Comment(TimeToString(day.time_max)+" : "+DoubleToString(day.max)+" : "+DoubleToString(day.Arr[day.index].high)+"\n"+TimeToString(day.time_min)+" : "+DoubleToString(day.Arr[day.index].low)+" : "+DoubleToString(day.min));
   }

E nella funzione di record bar aggiungere un controllo per la data zero:

   //функция записывает текущие экстремумы
   void WriteBar(int eNumber, string eSymbol, ENUM_TIMEFRAMES eFrame, datetime eTime)
      {
      if(eTime==0) return;
      int eShift=iBarShift(eSymbol,eFrame,eTime);

E in secondo luogo, in day.Arr[day.index].high è il giorno corrente. Se vuoi ieri, è nell'elemento precedente:

if(day.index>0)
   {
   printf(day.Arr[day.index-1].high);
   }

Credo che la logica dovrebbe essere corretta ora. Non ho controllato troppo bene, ma sembra essere corretto.

[Eliminato]  
Dark Kchlyzov:

Mi sento come un bambino di 1a elementare anche se ho 42 anni.

:) tutto viene con l'esperienza, anch'io non capisco molte cose e sto imparando man mano che vado avanti. Non dovrebbe essere una struttura, dovrebbe essere una classe. Siamo quasi al livello di OOP. In cui sto ancora galleggiando.
[Eliminato]  

Per quanto riguarda ArrayCopyRates, Alexey ha detto correttamente. È scritto nell'aiuto:

Копирует в двумерный массив вида double RateInfo[][6] данные баров указанного графика и возвращает количество скопированных баров.

Quindi devi scriverlo:

 int total=ArrayCopyRates(Bar_data_D1,_Symbol,PERIOD_D1); // Копирует в массив данные баров указанного графика и возвращает количество скопированных баров

 Low_D1_Level   = iLow (_Symbol,PERIOD_D1,1);   // Возвращает значение минимальной цены бара  D1
    
 for(int i = 1; i<total ;i++)
    {
    

Ma questo non è un codice economico.