Array out of range in Need of help - ページ 9

 
Aleksei Stepanenko:

ArrayCopyRatesについて、Alexeyは正しく述べています。ヘルプに書いてあります。

だから、書かなきゃいけないんです。

しかし、それは経済的なコードではありません。

そうですね、1つだけ必要なら、6つのバーメトリクスをすべてドラッグする意味はありません。低い。

それに、ひとつの尺度で深追いしても意味がない(TF)。四分の一を過ぎると週、月となり、132ヶ月で11年になります。

一般的には、チャート全体でカウントしても意味がない、ヒストリカルデータの 量は基本的にランダムであり、70年からかもしれないし2000年からかもしれない、データプロバイダーによって計測器のデータが異なる、ロジックはどのケースでも同じである方が良い、という考え方があるようです。

 

ヴァレリーさん、まさにその通りですね。

このヒストリーバーだけでいいという考え方です。


残りはアレイから落とすことができる。そのときが経済的なのでしょう。

 
Aleksei Stepanenko:

ヴァレリーさん、まさにその通りですね。

このヒストリーバーだけでいいという考え方です。


あとは配列から取り出せばいい。そのときが経済的なのでしょう。

そういう描き方だったんですね。このアイデアはまだTopekStarterから声があがっていない)

TCにとって意味のある極値を求め、比較する必要がある。遠目には同じLowがたくさんあります。1本のローソク足のOpenとCloseが同じであることがかなり多く、かなり離れたところにあるその日の最低 価格を何と言うか。

 

サイクルに誤りがあることに気づきました。そして、比較対象を現在の日ではなく、昨日に変更しました。トライ

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

皆さん、こんにちは。

仕事で不在です。

本格的に始動しています。

 

テストしてみました

その結果、こうなりました。

テスターを停止し、手動で履歴を確認しました。Max_Dの値はここから取得する必要があります。

 

何が問題なのか理解できない。ミニマムのラインです。

念のため、もう一度コードをコピーしてください。私はそこを周期的に変更しました。

 
Valeriy Yastremskiy:

そう、1つだけ必要なら、バーの6つのインジケータをすべてドラッグする意味はありません。低い。

それに、ひとつの尺度で深追いしても意味がない(TF)。四分の一を過ぎると週、月となり、132ヶ月で11年になります。

一般的には、チャート全体でカウントしても意味がない、ヒストリカルデータの 量は基本的にランダムであり、70年からのものかもしれないし、2000年からのものかもしれない、データプロバイダーによって、商品によってデータが異なる、どのケースでも同じロジックであれば良いという考え方があります。

もっと具体的に説明するようにします。

1.これはアイデアではなく、私が自動化することを決めた取引の5年間の経験です(すなわち、それはすべての時間をモニタに座って良いではありません、あなたは長年にわたってそれを理解する)。

2.このラインを使ってフォルスブレイクのシグナルを形成し、それが機能する(適用方法を知っていればよい)、今後全く出力しないこともあり得るのです。

3.2020年、2月10日、初めてこの不正確さに気づきました。そんな遠い歴史から不必要だと思うのか

Min_Dがどこにあるか注意してください、それは年に1回かもしれないし、10年かもしれません(結果的に)。

さらに、あなたはイベント12000ポイントショート(私はこのような動きを見逃すことは許されないと思う)の開発を参照してくださいこのケースでは、配列を超えた出口は、私はこの機会を逃すことはなかった。

現在もその方法で 一般的には何の問題も生じていません


でも、今はもう、MQL4を勉強する時期なんです


4.ロードまたはどのようなそこ(24.00で一日一回再計算することができ、10回私は20.00後の金曜日に取引していない、と23.00から3.00に平日)としては、自分が数えることができます。

5.アイデアがまだ声になっていない TopikStarter。

途中からではなく、最初から読めば全ては明らかです。

1.Low_D1とHigh_D1(D1最終日)、Min_DとMax_D(直近の履歴、これはシンボルで利用できるもの)Min_D <Low_D1 とMax_D >High_D1

2.Low_W1、High_W1(さらに週単位で上記と同様)

3.Low_MN1とHigh_MN1(月が比較的似ている)。

 

コード内の a for // 説明文を読む

それを修正する方法についてのアドバイスのために来た、多分何か私は知らない(いくつかの履歴ファイルをロードするように、または配列自体がサポートしていない、または多分aperitifの16ギガは十分ではありません、それは質問です、等)。

今のところ、行の値が変化しないときはAlertだけです。

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

何が問題なのか理解できない。ミニマムのラインです。

念のため、もう一度コードをコピーしてください。定期的に変更しているので、もしかしたら古いバージョンを持っているかもしれません。

よし、もう一度やってみよう。