错误、漏洞、问题 - 页 1986

 
Alexey Kozitsyn:

在第一次运行时,OnCalculate()中有初始化(prev_calculated == 0)。你认为把它移到OnInit()会有什么变化吗?好吧,我当然会尝试,但这是超出幻想范围的事情......。

削减。正如我所说,在OnDeinit()中,数组被初始化,在下次启动时不再使用(改变输入参数)。如果这样做(初始化一个不用作缓冲区的数组)有帮助的话--这也会是一个MT的bug。结果是,不仅数组没有被使用,而且它们(未分配的)仍然可以被初始化,这将影响到映射......

没有代码就很难。让我们知道服务台事后是怎么说的。
 
Anatoli Kazharski:
没有代码,这很难。让我知道服务部门事后怎么说。
我会的。
 
Anatoli Kazharski:
没有代码是很难的。稍后让我知道服务台怎么说。

这是测试代码,如果你有兴趣的话。

最初,指标参数为假。

我们把指标放在图表上。它绘制了一个直方图。

我们将参数设置为真。

它画出了直方图和箭头。

使该参数为假。在当前的TF上,箭头消失了(不一定)。如果我们切换到不同的TFs,箭头会混乱地出现在一些TFs中,尽管缓冲区在去初始化时被清除。

#property indicator_separate_window
#property indicator_plots 3
#property indicator_buffers 4
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
input bool inpUseArrows=false;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double bufGisto[];
double bufGistoColor[];
double bufArrowUp[];
double bufArrowDn[];
//---
const double EMPTY=EMPTY_VALUE;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Размечаем массив цветов
   color colors[2];
   colors[ 0 ]= clrLime;
   colors[ 1 ] = clrRed;
//--- Устанавливаем параметры графических серий
   SetPlotParametersColorHistogram(0,0,bufGisto,bufGistoColor,false,"test gisto",colors,EMPTY,2);
//--- Проверяем, нужно ли отображать объемы
   if(inpUseArrows) // Если отображать нужно
     {
      SetPlotParametersArrow(1,2,bufArrowUp,false,"test up",EMPTY,clrLime,233,10);
      SetPlotParametersArrow(2,3,bufArrowDn,false,"test dn",EMPTY,clrRed,234,-10);
     }
//---
   IndicatorSetInteger(INDICATOR_DIGITS,0);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   if(inpUseArrows)
     {
      ArrayInitialize(bufArrowUp,EMPTY);
      ArrayInitialize(bufArrowDn,EMPTY);
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      ArrayInitialize(bufGisto,EMPTY);
      //---
      if(inpUseArrows)
        {
         ArrayInitialize(bufArrowUp,EMPTY);
         ArrayInitialize(bufArrowDn,EMPTY);
        }
      //---
      for(int i=0; i<rates_total; i++)
        {
         bufGisto[i]=(open[i]-close[i])/_Point;
         bufGistoColor[i]=(bufGisto[i]<0) ? 1 : 0;
         //---
         if(inpUseArrows)
           {
            if(bufGisto[i]>20)
               bufArrowDn[i]=bufGisto[i];
            else if(bufGisto[i]<-20)
               bufArrowUp[i]=bufGisto[i];
           }
        }
     }
   else if(rates_total>prev_calculated)
     {
      bufGisto[rates_total-1]=EMPTY;
      //---
      if(inpUseArrows)
        {
         bufArrowUp[ rates_total-1 ] = EMPTY;
         bufArrowDn[ rates_total-1 ] = EMPTY;
        }
     }
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Параметры графического построения: цветная гист-а от 0 линии                |
//+------------------------------------------------------------------+
void SetPlotParametersColorHistogram(const int plotIndex,// Индекс графической серии
                                     const int bufferNum,// Номер первого буфера серии
                                     double& value[],                              // Буфер значений
                                     double& clr[],                                 // Буфер цветов
                                     const bool asSeries,                           // Флаг нумерации как в таймсерии
                                     const string label,                           // Имя серии
                                     const color& colors[],                        // Цвета линии
                                     const double emptyValue = EMPTY_VALUE,         // Пустые значения серии
                                     const int width = 0,                           // Толщина линии
                                     const ENUM_LINE_STYLE style = STYLE_SOLID,      // Стиль линии
                                     const int drawBegin = 0,                        // Количество баров без отрисовки
                                     const int shift=0                           // Сдвиг построения в барах
                                     )
  {
//--- Привязываем буферы
   SetIndexBuffer(bufferNum,value,INDICATOR_DATA);
   SetIndexBuffer(bufferNum+1,clr,INDICATOR_COLOR_INDEX);
//--- Устанавливаем порядок нумерации в массивах-буферах
   ArraySetAsSeries(value,asSeries);
   ArraySetAsSeries(clr,asSeries);
//--- Устанавливаем тип графического построения
   PlotIndexSetInteger(plotIndex,PLOT_DRAW_TYPE,DRAW_COLOR_HISTOGRAM);
//--- Устанавливаем имя графической серии
   PlotIndexSetString(plotIndex,PLOT_LABEL,label);
//--- Устанавливаем пустые значения в буферах
   PlotIndexSetDouble(plotIndex,PLOT_EMPTY_VALUE,emptyValue);
//--- Устанавливаем количество цветов индикатора
   const int size=ArraySize(colors);
   PlotIndexSetInteger(plotIndex,PLOT_COLOR_INDEXES,size);
//--- Устанавливаем цвета индикатора
   for(int i=0; i<size; i++)
      PlotIndexSetInteger(plotIndex,PLOT_LINE_COLOR,i,colors[i]);
//--- Устанавливаем толщину линии
   PlotIndexSetInteger(plotIndex,PLOT_LINE_WIDTH,width);
//--- Устанавливаем стиль линии
   PlotIndexSetInteger(plotIndex,PLOT_LINE_STYLE,style);
//--- Устанавливаем количество баров без отрисовки и значений в DataWindow
   PlotIndexSetInteger(plotIndex,PLOT_DRAW_BEGIN,drawBegin);
//--- Устанавливаем сдвиг графического построения по оси времени в барах
   PlotIndexSetInteger(plotIndex,PLOT_SHIFT,shift);
  }
//+------------------------------------------------------------------+
//| Параметры графического построения: стрелки                                                          |
//+------------------------------------------------------------------+
void SetPlotParametersArrow(const int plotIndex,// Индекс графической серии
                            const int bufferNum,// Номер первого буфера серии
                            double &value[],// Буфер значений
                            const bool asSeries,// Флаг нумерации как в таймсерии
                            const string label,// Имя серии
                            const double emptyValue=EMPTY_VALUE,// Пустые значения серии
                            const color clr=clrRed,// Цвет стрелок
                            const int arrowCode= 159,// Код стрелок
                            const int arrowShift = 0,// Сдвиг стрелок по вертикали
                            const int width=0,// Толщина стрелок
                            const int drawBegin=0,// Количество баров без отрисовки
                            const int shift=0                     // Сдвиг построения в барах
                            )
  {
//--- Привязываем буферы
   SetIndexBuffer(bufferNum,value,INDICATOR_DATA);
//--- Устанавливаем порядок нумерации в массивах-буферах
   ArraySetAsSeries(value,asSeries);
//--- Устанавливаем тип графического построения
   PlotIndexSetInteger(plotIndex,PLOT_DRAW_TYPE,DRAW_ARROW);
//--- Устанавливаем имя графической серии
   PlotIndexSetString(plotIndex,PLOT_LABEL,label);
//--- Устанавливаем пустые значения в буферах
   PlotIndexSetDouble(plotIndex,PLOT_EMPTY_VALUE,emptyValue);
//--- Устанавливаем цвет индикатора
   PlotIndexSetInteger(plotIndex,PLOT_LINE_COLOR,0,clr);
//--- Устанавливаем код стрелок
   PlotIndexSetInteger(plotIndex,PLOT_ARROW,arrowCode);
//--- Устанавливаем смещение стрелок по вертикали
   PlotIndexSetInteger(plotIndex,PLOT_ARROW_SHIFT,arrowShift);
//--- Устанавливаем толщину стрелок
   PlotIndexSetInteger(plotIndex,PLOT_LINE_WIDTH,width);
//--- Устанавливаем количество баров без отрисовки и значений в DataWindow
   PlotIndexSetInteger(plotIndex,PLOT_DRAW_BEGIN,drawBegin);
//--- Устанавливаем сдвиг графического построения по оси времени в барах
   PlotIndexSetInteger(plotIndex,PLOT_SHIFT,shift);
  }
//+------------------------------------------------------------------+
 
Anatoli Kazharski:
它不会去任何地方。服务台#1832411x64, 1643.
 
Alexey Kozitsyn:
它不会以任何方式去。服务台#1832411x64, 1643。

无论你是否为箭头指定数组作为缓冲区,它们仍然是硬连接的。

#property indicator_plots   3
#property indicator_buffers 4

//---

另外,如果不需要显示箭头,可以简单地用DRAW_NONE 将其排除在显示之外。

试试这个方法

...
//--- Проверяем, нужно ли отображать объемы
   if(inpUseArrows) // Если отображать нужно
     {
      SetPlotParametersArrow(1,2,bufArrowUp,false,"test up",EMPTY,clrLime,233,10);
      SetPlotParametersArrow(2,3,bufArrowDn,false,"test dn",EMPTY,clrRed,234,-10);
     }
   else
     {
      //--- Устанавливаем тип графического построения
      PlotIndexSetInteger(1,PLOT_DRAW_TYPE,DRAW_NONE);
      PlotIndexSetInteger(2,PLOT_DRAW_TYPE,DRAW_NONE);
     }

...

 
Anatoli Kazharski:

无论你是否为箭头指定数组作为缓冲区,它们仍然是硬连接的。

//---

另外,如果不需要显示箭头,可以简单地用DRAW_NONE 将其排除在显示之外。

试试这个变体

我想过这个问题,但这里有一个缺点。数组将被自动标记和扩展,消耗资源。开发人员最好让这个错误得到修复。

那么被硬编码的情况呢...如果我不把缓冲区与图形系列绑定--为什么我看到一些未知的垃圾,我无法摆脱这些垃圾。

否则就会发现,动态指标无法正常建立。

最理想的选择是在deinit中清理缓冲区,仅此而已。但清算并没有帮助...

 

在ME中,请在函数/方法的列表中显示ALT+M的返回值类型。

 

如果能像其他语言中使用的那样,在字符串类型 上引入普通字符串和 "原始 "字符串的区别,那就更好了。我认为我们无论如何都会走到这一步,但在最初阶段,它将消除未来的许多问题。

例如,Python使用r "string " 来创建一个 "原始 "字符串
 

在测试器中不能完全输出日志的原因是什么?你能看到的所有东西都已经看过并检查过了,不能不说。

 
Andrey Dik:

日志没有完全显示在测试器中的原因是什么?所有可以看的东西--看了又看,检查了又检查,不能不说。

很多条目。见日志文件。