阵列超出范围,需要帮助 - 页 9

 
Aleksei Stepanenko:

关于ArrayCopyRates,Alexey正确地说。它写在帮助中。

所以你必须要写。

但这不是经济法则。

是的,如果你只需要一个指标,就没有必要拖动所有6个条形指标。低。

而且在一个尺度上深入研究是没有意义的(TF)。在一个季度之后,你可以转到周,然后是月,132个月,那就是11年。

一般来说,在整个图表上计算是没有意义的,历史数据 的数量基本上是随机的,可能是从70年开始,也可能是从2000年开始,在不同的仪器上,不同的数据提供者有不同的数据,当它对所有情况都相同时,逻辑总是更好。

 

瓦莱里,你说的正是这个意思!

我们的想法是,我们只需要这些历史条。


其余的可以从阵列中取出。这时就会很经济。

 
Aleksei Stepanenko:

瓦莱里,你说的正是这个意思!

我们的想法是,我们只需要这些历史条。


其余的可以从阵列中删除。这时就会很经济。

这就是它被画出来的方式。这个想法还没有被TopekStarter表达出来)

我们需要找到对TC有意义的极值并进行比较。有很多相同的Low,距离很远。很多时候,一根蜡烛上的开盘价和收盘价是相等的,在相当长的距离内,对当天的最低价格 该怎么说呢。

 

注意到周期中的一个错误。并把比较对象改为昨天而不是今天。尝试

#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:

是的,如果你只需要一个指标,拖动所有六个指标的条子是没有意义的。低。

而且在一个尺度上深入研究是没有意义的(TF)。在一个季度之后,你可以转到周,然后是月,132个月,那就是11年。

总的来说,在整个图表上计算是没有意义的,历史数据 的数量基本上是随机的,可能是70年的,也可能是2000年的,不同的数据提供者对不同的工具有不同的数据,在所有情况下,逻辑总是更好的。

我会试着说得更具体一些。

这不是一个想法,而是我决定将5年的交易经验自动化(也就是说,一直坐在显示器前是不可取的,你会在多年后理解它)。

2.我们用这些线来形成假突破信号,而且很有效(你只需要知道如何应用它们),你将来可能根本不会输出它们。

3.2020年,2月10日,我第一次注意到这个不准确的地方,你认为从这么遥远的历史来看是不必要的

注意Min_D的位置,它可能是一年一次,甚至是10年一次(如是)。

进一步说,你会看到事件的发展,12000点的空头(我认为错过这样的举动是不可接受的)在这种情况下,超越阵列的退出并没有让我错过这个机会。

这就是至今为止的工作方式 一般来说,它没有引起任何问题。


但现在是时候继续前进,研究MQL4了


4.至于那里的加载或什么的(每天24点可以重新计算一次,周五20点后我不交易10次,工作日从23点到3点)让我自己计算。

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(月份相对相似)。

 

在代码中,一个为//阅读描述

来咨询如何解决这个问题,也许是我不知道的事情(比如加载一些历史文件,或者阵列本身不支持,或者也许16G的Aperitif不够,这就是问题所在,等等)。

目前,它只是警报,当该行不改变价值时。

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

我不明白什么是错的。这是一条最低限度的线。

以防万一,再次复制代码,我已经定期修改了,也许你有一个旧的版本

好吧,我再试试。