Yardım Gerekiyor'da dizi aralık dışında - sayfa 8

 
Aleksei Stepanenko :

Burada biraz oturdu.

Gereksiz döngülerden kaçınmaya çalışmalıyız. Bir akışta gelen alıntılarımız var ve daha sonra geçmişe dalıp bilgisayar kaynaklarını boşa harcamamak için gerekli girişleri hemen yapmanız gerekiyor.

42 yaşında olmama rağmen kendimi 1. sınıf gibi hissediyorum.

 
Dark Kchlyzov :

42 yaşında olmama rağmen kendimi 1. sınıf gibi hissediyorum.

Bu iyi. Yani her şey önde.

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

Bu iyi. Yani her şey önde.

En önemli sonuç!

 
Dark Kchlyzov :

3.47 Yatağa gidiyorum.

Her şeyi yarın çözeceğim, herhangi bir sorunuz olursa bana bildirin!

Hepinize çok teşekkürler!!!

Omsk?

 
Aleksei Stepanenko :

Burada biraz oturdu.

Gereksiz döngülerden kaçınmaya çalışmalıyız. Bir akışta gelen alıntılarımız var ve daha sonra geçmişe dalıp bilgisayar kaynaklarını boşa harcamamak için gerekli girişleri hemen yapmanız gerekiyor.

Kodunuzu çalıştırın.

burada biraz yanlış bir şey var mı?

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


Bunun gibi fikirler

1) Önceki günün Low_D1 seviyesi

2) Min_D tarihteki en yakın günlük düşük



 //+------------------------------------------------------------------+
//|                                                   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?

Evet

 
Dark Kchlyzov :

Evet

+3)'te birkaç şehir var

Algoritma her zaman amaçlandığı gibi değil, yazıldığı gibi çizer ve sayar. Amaçlandığı gibi yazmak genellikle zordur.

Şekilde, tam olarak en düşükleri gösterdiniz ve günlük Düşük çubuğunun minimum fiyatına sahip olmanız durumunda. Algoritma onu trend bölgesinde buldu ve en az 2 komşu çubuk arasında değil.

 
Dark Kchlyzov :

Kodunuzu çalıştırın.

burada biraz yanlış bir şey var mı?

İlk nüans, algoritmanın test cihazının tarihinin başlangıcından itibaren değil, başlatıldığı andan itibaren sayılmasıdır. Bu nedenle, 1970.01.01 tarihi, yani sıfır görünür.

Geçmişin başından itibaren saymak için OnTick'e bir döngü eklemeniz gerekir. Bunun gibi:

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

ve çubuk kayıt işlevinde sıfır tarih kontrolü ekleyin:

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

İkincisi, day.Arr[day.index].high içinde geçerli gündür. Dünün ihtiyacı varsa, o zaman önceki öğededir:

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

Belki de şimdi mantık doğru olmalıdır. Çok fazla test etmedim, ama doğru gibi görünüyor.

 
Dark Kchlyzov :

42 yaşında olmama rağmen kendimi 1. sınıf gibi hissediyorum.

:) hepsi deneyimle geliyor, ben de pek bir şey alamıyorum ve yol boyunca öğreniyorum. Teoride bir yapıya değil, bir sınıfa sahip olmamız gerekir. Neredeyse OOP'ye geldik. Hala içinde yüzüyorum.
 

ArrayCopyRates'e gelince , Aleksey doğru konuştu. Yardım diyor ki:

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

Yani şunu yazmanız gerekiyor:

 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++)
    {
    

Ama bu israf koddur.