Array außerhalb der Reichweite in Need of help - Seite 9

 
Aleksei Stepanenko:

In Bezug auf ArrayCopyRates, Alexey richtig gesagt. Das steht in der Hilfe:

Sie müssen es also schreiben:

Aber es ist kein wirtschaftlicher Code.

Ja, es macht keinen Sinn, alle 6 Balkenmetriken zu ziehen, wenn man nur eine braucht. Niedrig.

Und es macht keinen Sinn, auf einer Skala (TF) in die Tiefe zu gehen. Nach einem Quartal kann man zu Wochen, dann zu Monaten und 132 Monaten übergehen, das sind 11 Jahre.

Im Allgemeinen ist die Idee, dass es keinen Sinn macht, auf dem gesamten Diagramm zu zählen, die Menge der historischen Daten ist im Wesentlichen zufällig, es kann aus dem Jahr 70 oder aus dem Jahr 2000 sein, auf verschiedenen Instrumenten haben verschiedene Datenanbieter unterschiedliche Daten, und Logik ist immer besser, wenn es für alle Fälle gleich ist.

 

Valery, du sagst genau das!

Die Idee ist, dass wir nur diese Geschichtsleisten brauchen:


Der Rest kann aus dem Array gestrichen werden. Dann wäre es wirtschaftlich.

 
Aleksei Stepanenko:

Valery, du sagst genau das!

Die Idee ist, dass wir nur diese Geschichtsleisten brauchen:


Der Rest kann aus dem Array gestrichen werden. Dann wäre es wirtschaftlich.

Das ist die Art und Weise, wie sie gezeichnet wurde. Die Idee wurde von TopekStarter noch nicht geäußert)

Wir müssen die für TC bedeutsamen Extrema finden und sie vergleichen. Es gibt eine Menge identischer Lows in der Ferne. Oft sind Open und Close auf einer Kerze gleich, und was sagt das über die Mindestpreise des Tages in einem beträchtlichen Abstand aus.

 

Es wurde ein Fehler in den Zyklen festgestellt. Und ich habe den Vergleich auf gestern statt auf den heutigen Tag geändert. Versuchen Sie

#property version   "1.00"
#property strict

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

long ChartId;
int Window;
string Name="MiniMax";

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)
      {
      if(eTime==0) return;
      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(index==0)
            {
            max=eHigh;
            time_max=eTime;
            min=eLow;
            time_min=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(index>0)
         {
         max=Arr[index-1].high;
         time_max=Arr[index-1].time_high;
         for(int i=index-2; i>=0; i--)
            {
            if(Arr[i].high-Arr[index-1].high>0)
               {
               max=Arr[i].high;
               time_max=Arr[i].time_high;
               break;
               }
            }
         }
      //если произошло обновление предыдущего минимума
      if(index>0)
         {
         min=Arr[index-1].low;
         time_min=Arr[index-1].time_low;
         for(int i=index-2; i>=0; i--)
            {
            if(Arr[index-1].low-Arr[i].low>0)
               {
               min=Arr[i].low;
               time_min=Arr[i].time_low;
               break;
               }
            }
         }
      }
      
   double GetHigh() {return(index>0?Arr[index-1].high:Arr[index].high);}
   double GetLow() {return(index>0?Arr[index-1].low:Arr[index].low);}
   } day, month, year;

int OnInit()
   {
   symbol=Symbol();
   frame=(ENUM_TIMEFRAMES)Period();
   digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
   //идентификатор графика и номер окна индикатора
   ChartId=ChartID();
   Window=0;
   return(INIT_SUCCEEDED);
   }

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);
   
   RedrawHLine(ChartId,Window,Name+" High",day.GetHigh(),clrBlue,1,DoubleToString(day.GetHigh(),digits),digits);
   RedrawHLine(ChartId,Window,Name+" Low",day.GetLow(),clrBlue,1,DoubleToString(day.GetLow(),digits),digits);
   RedrawText(ChartId,Window,Name+" High_Text",iTime(symbol,frame,30),day.GetHigh(),"Day 1:  "+DoubleToString(day.GetHigh(),digits),ANCHOR_RIGHT_LOWER,"Arial",8,clrBlue,"",digits);
   RedrawText(ChartId,Window,Name+" Low_Text",iTime(symbol,frame,30),day.GetLow(),"Day 1:  "+DoubleToString(day.GetLow(),digits),ANCHOR_RIGHT_UPPER,"Arial",8,clrBlue,"",digits);

   RedrawHLine(ChartId,Window,Name+" Max",day.max,clrRed,1,DoubleToString(day.max,digits),digits);
   RedrawHLine(ChartId,Window,Name+" Min",day.min,clrRed,1,DoubleToString(day.max,digits),digits);
   RedrawText(ChartId,Window,Name+" Max_Text",iTime(symbol,frame,30),day.max,"Day Max:  "+DoubleToString(day.max,digits),ANCHOR_RIGHT_LOWER,"Arial",8,clrRed,"",digits);
   RedrawText(ChartId,Window,Name+" Min_Text",iTime(symbol,frame,30),day.min,"Day Min:  "+DoubleToString(day.min,digits),ANCHOR_RIGHT_UPPER,"Arial",8,clrRed,"",digits);
   }

//перерисовывает линию по новым координатам, если её нет, то создаёт
void RedrawHLine(long eChartId, int eWindow, string eName, double ePrice, color eColor, int eWidth, string eTooltip, int eDigits)
   {
   if(ObjectFind(eChartId,eName)==-1)
      {
      if(!ObjectCreate(eChartId,eName,OBJ_HLINE,eWindow,0,0)) return;
      ObjectSetInteger(eChartId,eName,OBJPROP_STYLE,STYLE_SOLID);
      ObjectSetInteger(eChartId,eName,OBJPROP_WIDTH,eWidth);
      ObjectSetInteger(eChartId,eName,OBJPROP_BACK,true);
      ObjectSetInteger(eChartId,eName,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(eChartId,eName,OBJPROP_SELECTED,false);
      ObjectSetInteger(eChartId,eName,OBJPROP_HIDDEN,true);
      }
   if(ObjectFind(eChartId,eName)==-1) return;   
   if(NormalizeDouble(ObjectGetDouble(eChartId,eName,OBJPROP_PRICE)-ePrice,eDigits)!=0) ObjectSetDouble(eChartId,eName,OBJPROP_PRICE,ePrice);
   if(ObjectGetInteger(eChartId,eName,OBJPROP_COLOR)!=eColor) ObjectSetInteger(eChartId,eName,OBJPROP_COLOR,eColor);
   if(ObjectGetString(eChartId,eName,OBJPROP_TOOLTIP)!=eTooltip) ObjectSetString(eChartId,eName,OBJPROP_TOOLTIP,eTooltip);
   }

//перерисовываем текст по новым координатам, если его нет, то создаём
void RedrawText(long eChartId, int eWindow, string eName, datetime eTime, double ePrice, string eText, ENUM_ANCHOR_POINT eAnchor, string eFont, int eSize, color eColor, string eTooltip, int eDigits)
   {
   if(ObjectFind(eChartId,eName)==-1)
      {
      if(!ObjectCreate(eChartId,eName,OBJ_TEXT,eWindow,0,0)) return;
      ObjectSetString(eChartId,eName,OBJPROP_FONT,eFont);
      ObjectSetInteger(eChartId,eName,OBJPROP_FONTSIZE,eSize);
      ObjectSetDouble(eChartId,eName,OBJPROP_ANGLE,0.0);
      ObjectSetInteger(eChartId,eName,OBJPROP_ANCHOR,eAnchor);
      //на переднем  плане
      ObjectSetInteger(eChartId,eName,OBJPROP_BACK,false);
      ObjectSetInteger(eChartId,eName,OBJPROP_SELECTABLE,false);
      ObjectSetInteger(eChartId,eName,OBJPROP_SELECTED,false);
      ObjectSetInteger(eChartId,eName,OBJPROP_HIDDEN,true);
      ObjectSetString(eChartId,eName,OBJPROP_TOOLTIP,eTooltip);
      }
   if(ObjectFind(eChartId,eName)==-1) return;
   //координаты метки
   if(ObjectGetInteger(eChartId,eName,OBJPROP_TIME)!=eTime) ObjectSetInteger(eChartId,eName,OBJPROP_TIME,eTime);
   if(NormalizeDouble(ObjectGetDouble(eChartId,eName,OBJPROP_PRICE)-ePrice,eDigits)!=0) ObjectSetDouble(eChartId,eName,OBJPROP_PRICE,ePrice);
   if(ObjectGetInteger(eChartId,eName,OBJPROP_COLOR)!=eColor) ObjectSetInteger(eChartId,eName,OBJPROP_COLOR,eColor);
   if(ObjectGetString(eChartId,eName,OBJPROP_TEXT)!=eText) ObjectSetString(eChartId,eName,OBJPROP_TEXT,eText);
   }
 

Grüße an alle !!!

Ich war auf Geschäftsreise.

Der Prozess ist in vollem Gange.

 

Getestet!

Das Ergebnis ist wie folgt.

Das Testgerät wurde gestoppt und der Verlauf manuell durchgesehen. Der Max_D-Wert sollte hier entnommen werden.

 

Ich verstehe nicht, was los ist. Es ist eine Linie von Minima.

Kopieren Sie den Code vorsichtshalber noch einmal, ich habe ihn dort regelmäßig geändert, vielleicht haben Sie eine alte Version

 
Valeriy Yastremskiy:

Ja, es macht keinen Sinn, alle sechs Indikatoren des Balkens zu ziehen, wenn Sie nur einen benötigen. Niedrig.

Und es macht keinen Sinn, auf einer Skala (TF) in die Tiefe zu gehen. Nach einem Quartal kann man zu Wochen, dann zu Monaten und 132 Monaten übergehen, das sind 11 Jahre.

Im Allgemeinen ist die Idee, dass es keinen Sinn macht, auf dem gesamten Diagramm zu zählen, die Menge der historischen Daten ist im Wesentlichen zufällig, kann aus dem Jahr 70 sein, und kann aus dem Jahr 2000 sein, verschiedene Datenanbieter haben unterschiedliche Daten auf verschiedenen Instrumenten, und die Logik ist immer besser, wenn es die gleiche für alle Fälle ist.

Ich werde versuchen, genauer zu sein.

1. Dies ist keine Idee, sondern eine 5-jährige Erfahrung im Handel, die ich beschlossen, zu automatisieren (dh es ist nicht gut zu sitzen an den Monitor die ganze Zeit, Sie verstehen es mit Jahren).

2. Wir verwenden diese Linien, um ein False-Break-Signal zu bilden, und es funktioniert (man muss nur wissen, wie man sie anwendet), Sie können sie in Zukunft überhaupt nicht mehr ausgeben.

3. Im Jahr 2020, am 10. Februar, habe ich zum ersten Mal diese Ungenauigkeit bemerkt, die Ihrer Meinung nach bei einer so weit zurückliegenden Geschichte unnötig ist

Notieren Sie sich, wo Min_D ist , und es kann einmal im Jahr oder sogar in 10 Jahren sein (wie sich herausstellt ).

Ferner sehen Sie die Entwicklung der Ereignisse 12000 Punkte kurz (Ich denke, es ist nicht akzeptabel, eine solche Bewegung zu verpassen) In diesem Fall ist der Ausgang über das Array und ließ mich nicht verpassen diese Gelegenheit.

So funktioniert es auch heute noch , und im Allgemeinen hat es keine Probleme verursacht.


Aber jetzt ist es an der Zeit, weiterzumachen und MQL4 zu studieren.


4. Wie für das Laden oder was auch immer es (einmal am Tag um 24.00 Uhr neu berechnet werden kann und 10 Mal habe ich nicht den Handel am Freitag nach 20.00 Uhr, und an Wochentagen von 23.00 bis 3.00) lassen Sie mich zählen.

5. die Idee wurde noch nicht geäußert TopikStarter.

Wenn Sie den Beitrag von Anfang an lesen und nicht von der Mitte an, ist alles klar.

1. niedrig_D1 und hoch_D1 (D1 letzter Tag), Min_D und Max_D (dies ist die nächstliegende Historie, die für das Symbol verfügbar ist) Min_D < niedrig_D1 undMax_D > hoch_D1

2. low_W1 und high_W1 (im Übrigen ähnlich wie oben beschrieben, nur für Wochen)

3. niedrig_MN1 und hoch_MN1 (Monat ist relativ ähnlich)

 

Im Code a for // lesen Sie die Beschreibung

Kam für Ratschläge, wie es zu beheben, vielleicht etwas, das ich nicht weiß (wie laden einige Geschichte Datei, oder das Array selbst nicht unterstützt, oder vielleicht 16 Gig von Aperitif ist nicht genug, das ist die Frage, etc.)

Im Moment ist es nur Alert, wenn sich der Wert der Zeile nicht ändert.

//+------------------------------------------------------------------+
//|                                                   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;
int      A_C_R;             // возвращает количество скопированных баров D1
//+------------------------------------------------------------------+
//| 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()
{
  A_C_R = 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();
   }
}
 
Aleksei Stepanenko:

Ich verstehe nicht, was los ist. Es ist eine Linie von Minima.

Kopieren Sie den Code vorsichtshalber noch einmal, ich habe ihn regelmäßig geändert, vielleicht haben Sie eine alte Version

Okay, ich versuch's noch mal.