我写了一个自定义指标 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时,我只收到那个值。
答案 0 :(得分:2)
iCustom()
机制MQL4甚至New-MQL4(有时称为MQL4.5)使用相当复杂的接口模型来处理EA交易调用/自定义指标计算。
首先要意识到的是, iCustom()
不是对函数的调用,而是一种方法,间接地“询问” by-a-filename 将自定义指标引用检索来自“预先计算的”DataSTORE的一个特定值。
虽然听起来很复杂,但这是CPU效率计算工厂的本质,自定义指标是在MQL4世界的早期设计的。
因此, iCustom()
只是一种启动检索方法的语法糖,可以将相关的预先计算的值返回给EA交易。
自定义指标将所有预先计算的值放入 BUFFER (s),与订购DataSTORE单元格的TimeSeries样式共同对齐([0] ==“现在,当前条形码” ,前进[1],[2],[3],......深入和深入回到历史中)
iCustom()
传递 shift
值,作为一些条形图 - 即检索方法必须走多远的历史记录,以便选择来自相应BUFFER的请求值,以及BUFFER标识INDEX(在我们的上述情况下为0,因为只有一个BUFFER,INDEX == 0
)。这是为了使EA完全不知道自定义指标内部变量名称等。
只需询问哪个 BufferINDEX 哪个 BarNUMBER想要读取该值。
代码的第一行说:
double SpeedBuffer[]; // a Custom Indicator BUFFER
如果在 OnInit(){}
中没有另外处理,SpeedBuffer中的所有单元格都会有
的 EMPTY_VALUE
强>
指标缓冲区中的空值默认具有此值 == 2147483647 (0x7FFFFFFF)
,如上所述。
<强> Q.E.D。强>
可以在OnInit(){ ArrayInitialize( SpeedBuffer, 0.123456 ); }
中声明对于单元初始化具有任何其他值(对于TimeSeries-alligned BUFFER,每个new-Bar事件发生一次(所有单元格都被一个向后和单元格重新调整[0] ]变为“空”,预装了这里讨论的默认值))。
还可以在指标OnCalculate(){ ... SpeedBuffer[0] = -9.87654; ...}
中添加一个步骤,以避免单元格[0]处于上下文不一致状态,而不是处于“正常”初始化状态/值。
尽管如此,值检索的责任在于EA交易,因为它填充了iCustom()
interface-proxy的参数。
可以使用预防措施,如&gt;&gt;&gt;所示https://stackoverflow.com/a/26389823/3666197 一旦调用外部自定义指标来检索一组值,最小化参数排序/值不正确的风险。
这个简单的方法可以为您节省数十天*的测试/调试时间一旦富有 - extern
- 参数化的自定义指标与多个指标缓冲区由于服务“错误”数字而陷入嫌疑(仅由于iCustom()
调用参数“无形”超出正确的顺序/上下文)
答案 1 :(得分:1)
当自定义指标在图表上显示不同的值然后向ExpertAdvisor报告时要记住的另一件事是,通过OnCalculate()的执行流程对于ExpertAdvisor而言需要与图表不同;具体来说,图表最初通过prev_calculated = 0启动对OnCalculate()的调用,而EA(无论是使用策略测试程序还是实时运行)将始终具有prev_calculated = rates_total-1,以便计算指标值的柱数for是rates_total - prev_calcualted = 1(即只是当前的栏)。
您在代码中通过设置start来确定这一点,但一般来说,对于复杂的指标(通常涉及的不仅仅是前一个条形图),您需要注意这种差异并且永远不要假设如果指标在图表上看起来很好,这意味着它实际上正在工作。它需要与EA分开测试。
答案 2 :(得分:0)
我查看了我的代码,最后想出了:
double speed=iCustom(NULL,0,"Speed",2,0,0);
正在使用最后一个值,该值尚未由自定义指标计算
将其更改为:
double speed=iCustom(NULL,0,"Speed",2,0,1);
做了这个伎俩。