Fora de alcance em Necessidade de ajuda - página 8

 
Aleksei Stepanenko:

Já faz um tempo que estou aqui sentado:

Devemos tentar evitar ciclos desnecessários. Temos uma enchente de citações, e você precisa fazer as entradas corretas na hora, para que não tenha que escavar a história e desperdiçar recursos do computador.

Eu me sinto como um aluno de 1ª série, mesmo tendo 42 anos.

 
Dark Kchlyzov:

Eu me sinto como um aluno de 1ª série, mesmo tendo 42 anos.

Isso é uma coisa boa. Isso significa que tudo está à minha frente.

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

Isso é bom. Portanto, tudo está à nossa frente.

O mais importante é o resultado!!!

 
Dark Kchlyzov:

3.47 Vou para a cama.

Eu vou digerir tudo amanhã e se eu tiver alguma pergunta, eu avisarei você!

Muito obrigado a todos!

Omsk?

 
Aleksei Stepanenko:

Ficar sentado por um tempo:

Devemos tentar evitar loops desnecessários. Temos citações que vêm em fluxo e precisamos fazer as entradas certas na hora certa, para não termos que cavar a história e desperdiçar recursos computacionais.

Eu analisei seu código.

Há algo um pouco errado aqui?

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


Veja como fica

1) Nível baixo_D1 do dia anterior

2) Min_D mais próximo diariamente de um mínimo histórico



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

Sim

 
Dark Kchlyzov:

Sim

em +3, de alguma forma não muitas cidades)

O algoritmo nem sempre desenha e conta como pretendido, mas como escrito. Escrever como escrito geralmente é difícil.

Na figura você mostrou os mínimos, e na condição de ter o preço mínimo da barra diária Baixo. E o algoritmo o encontrou na zona de tendência, e não é o mínimo entre 2 barras adjacentes.

 
Dark Kchlyzov:

Eu analisei seu código.

Há algo de um pouco errado aqui?

A primeira nuance, até agora o algoritmo não conta desde o início da história do testador, mas desde o início. Portanto, a data 1970.01.01.01, que é zero, aparece.

Para que isso conte desde o início da história, é preciso inserir um laço no OnTick. Algo parecido com isto:

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 na função de registro de barra adicionar um cheque para data zero:

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

E segundo, no dia.Arr[day.index].high é o dia atual. Se você quiser ontem, está no elemento anterior:

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

Acho que a lógica deve estar correta agora. Não foi muito difícil verificá-lo, mas parece estar correto.

 
Dark Kchlyzov:

Eu me sinto como um aluno de 1ª série, embora tenha 42 anos.

:) tudo isso vem com experiência, eu também não entendo muitas coisas e estou aprendendo à medida que vou avançando. Não é suposto ser uma estrutura, é suposto ser uma classe. Estamos quase no nível do OOP. No qual eu ainda estou flutuando.
 

Com relação ao ArrayCopyRates, Alexey disse corretamente. Está escrito na ajuda:

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

Portanto, você tem que escrevê-lo:

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

Mas isso não é um código econômico.