0

我写了一个自定义指标Speed.mq4如下:

double         SpeedBuffer[];                     // a Custom Indicator BUFFER
int OnInit() {
    SetIndexBuffer( 0, SpeedBuffer );             // an access INDEX 0->BUFFER
    ...
    }
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[] 
                 ) {
   int start;
   if (   prev_calculated == 0 ) start = 1;
   else                          start = prev_calculated - 1;

   for ( int i = start; i < rates_total - 1 ; i++ ) {                   // CPU-WASTED BY AN INEFFICIENT BACK-STEPPING IN TIME
         double curTypical  = typical( high[i],  low[i],  close[i]   );
         double prevTypical = typical( high[i+1],low[i+1],close[i+1] ); // CPU-WASTED, NO NEED TO RECALC ...
         double curSpeed    = curTypical - prevTypical;
         SpeedBuffer[i]     = curSpeed;
     }
//--- return value of prev_calculated for next call
   return( rates_total );
  }

该指标在应用程序中运行良好,并且图表绘制正确。

当我尝试检索 ExpertAdvisor 中的最后一个值时,我总是收到相同的值:

double speed = iCustom( NULL, 0, "Speed", 2, 0, 0 );
Print( "speed is: " + speed );

印刷:

速度是:2147483647

它总是相同的数字。我不确定问题出在哪里。

Print指标中我可以看到这些值计算正确。但是当我使用 iCustom 时,我只收到那个值。

4

3 回答 3

2

MQL4 自定义指标iCustom()机制

MQL4 甚至 New-MQL4(有时称为 MQL4.5)使用相当复杂的接口模型来处理 EA 调用/自定义指标计算。

首先要实现的是,这iCustom()不是对函数的调用,而是一种方法,它间接地“要求”按文件名引用的自定义指标从“预先计算的”DataSTORE中检索一个特定的值.

虽然听起来可能很复杂,但在 MQL4 世界的早期,自定义指标是为 CPU 高效计算工厂设计的。

iCustom()因此,它只是启动检索方法的语法糖,它将相关的预先计算的值返回到 EA 交易的手中。

自定义指标将所有预先计算的值放入BUFFER (s),与排序 DataSTORE 单元格的 TimeSeries 样式一致([0] == "Now, the current Bar",向前 [1],[2] , [3], ... 越来越深地回到历史)

iCustom()传递shift值,作为许多条形 - 即检索方法必须进入历史的深度,以便从相应的缓冲区中选择请求的值,以及缓冲区标识索引(在我们上面的例子中为 0 ,因为只有一个缓冲区,带有 INDEX == 0)。这是因为 EA 完全不知道自定义指标内部变量名称等。

只需询问要从哪个BufferINDEX 读取哪个BarNUMBER 的值。

缓冲区是那个应该为(错误的)值负责的人

代码的第一行说:

double         SpeedBuffer[];                     // a Custom Indicator BUFFER

如果OnInit(){}在 SpeedBuffer 中的所有单元格中未进行其他处理,则将具有 EMPTY_VALUE

指标缓冲区中的空值默认具有此值== 2147483647 (0x7FFFFFFF),如上文所反对。

量子点

可以声明OnInit(){ ArrayInitialize( SpeedBuffer, 0.123456 ); }对于单元初始化具有任何其他值(对于 TimeSeries 对齐的 BUFFERs 发生在每个新柱事件上(所有单元被一个向后重新洗牌并且单元 [0] 变为“空”,预加载使用此处讨论的默认值))。

还可以在指示符中添加一个步骤,OnCalculate(){ ... SpeedBuffer[0] = -9.87654; ...}以避免使单元[0] 处于上下文不一致的状态,而不是处于“刚刚”初始化的状态/值。


调用方接口(如何降低弱集成接口的风险)

然而,值检索的责任在 EA 交易端,因为它填充了iCustom()接口代理的参数。

可以使用>>> https://stackoverflow.com/a/26389823/3666197中所示的预防措施, 以最大限度地降低调用外部自定义指标检索一组值时参数排序/值不正确的风险。

extern一旦具有多个指标缓冲区的丰富参数化自定义指标由于提供“错误”数字(仅由于iCustom()调用参数不可见而受到怀疑),这种简单的方法可能会为您节省数十人*天的测试/调试正确的顺序/上下文)

于 2014-10-22T13:11:26.327 回答
2

当自定义指标在图表上显示不同的值然后报告给智能交易系统时,要记住的另一件事是,通过 OnCalculate() 的执行流程对于智能交易系统需要与图表不同;具体来说,图表最初以 prev_calculated = 0 启动对 OnCalculate() 的调用,而 EA(无论是使用 Strategy Tester 运行还是实时运行)将始终具有 prev_calculated = rates_total-1,以便计算指标值的柱数因为是rates_total - prev_calcualted = 1(即只是当前柱)。

您确实通过设置 start 在代码中考虑了这一点,但通常对于一个复杂的指标(通常涉及引用的不仅仅是前一个柱),需要注意这种差异,并且永远不要假设指标看起来不错表示它实际上在工作的图表。它需要使用 EA 单独测试。

于 2018-01-27T05:48:22.920 回答
0

我查看了我的代码,最后发现:

 double speed=iCustom(NULL,0,"Speed",2,0,0);

正在使用自定义指标尚未计算的最后一个值,

将其更改为:

 double speed=iCustom(NULL,0,"Speed",2,0,1);

成功了。

于 2014-10-21T18:50:14.320 回答