感谢您的又一篇好文章。传统上,MQL 社区的文章已成为我接受高等教育 的途径(指内置的 MQL 编辑指南)。
关于这一点,我注意到代码中有一个小缺陷。根据作者的想法
//--- 一次性输出 price[] 值的标志变量
bool printed=false;变量应该移到OnCalculate() 函数 之外,否则每次事件都会发生数组打印。
这里还有一处错误
Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN нулевого графического построения базового индикатора B.
因此,如果我们创建了一个周期为 14 的RSI 指标(指标 A),然后根据 RSI(14) 指标数据创建了我们的自定义指标真强指数(指标 B),那么:
根据规则和逻辑判断,指标 A 是自定义 TSI,指标 B(基本)是 RSI。
- www.mql5.com
这篇文章包含了详细的知识。
谢谢。
你好、
这篇文章非常有趣,为管理指标提供了新的机会。
由于我是 MQL5 的初学者,我试图实现将一个指标应用到另一个指标的可能性。我写了一段代码,只复制了
一个自适应移动平均线,希望将其用于图表中的任何指标。
不幸的是,在启动指标时出现的参数列表中,我没有 "应用于:前一个指标的数据 "的情况。
如何组织代码才能将其应用到另一个指标上?
以下是我的代码:
#property indicator_separate_window #property indicator_minimum 1.3 #property indicator_maximum 1.35 //#perty indicator_chart_window #property indicator_buffers 2 #property indicator_plots 1 //--- 绘制 dMA #property indicator_label1 "dAMA" #property indicator_type1 DRAW_LINE #property indicator_color1 Red #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- 输入参数 input int AMAPeriod=9; input int FastEMA=2; input int SlowEMA=20; //--- 指示器缓冲区 double AMABuffer[]; double dAMABuffer[]; int h_dAMA; int h_AMA; //+------------------------------------------------------------------+ //| 自定义指示器初始化函数 //+------------------------------------------------------------------+ int OnInit() { //--- 指示器缓冲区映射 SetIndexBuffer(0,dAMABuffer,INDICATOR_DATA); SetIndexBuffer(1,AMABuffer,INDICATOR_CALCULATIONS); //PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod+1); h_AMA=iAMA(_Symbol,PERIOD_CURRENT,AMAPeriod,FastEMA,SlowEMA,0,PRICE_CLOSE); if(h_AMA == INVALID_HANDLE) { Print("AMA indicator initialization error, Code = ", GetLastError()); return(-1); } ArraySetAsSeries(AMABuffer,true); ArraySetAsSeries(dAMABuffer,true); PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MathMax(AMAPeriod,SlowEMA)); //--- return(0); } //+------------------------------------------------------------------+ //| 自定义指标迭代函数| //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, // 价格[]数组的大小 const int prev_calculated,// 上次调用时处理的条数 const int begin, // 重要数据的起始位置 const double &price[] // 用于计算的数组 ) { if(BarsCalculated(h_AMA)<rates_total) return(0); //--- 我们不能复制所有数据 int to_copy; if(prev_calculated>rates_total || prev_calculated<=0) { to_copy=rates_total; if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); for (int i=0;i<to_copy-MathMax(AMAPeriod,SlowEMA);i++) { dAMABuffer[i]=AMABuffer[i]; } } else { to_copy=rates_total-prev_calculated+MathMax(AMAPeriod,SlowEMA)-1; //--- 最后一个值总是被复制 to_copy++; if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); for (int i=0;i<to_copy;i++) { dAMABuffer[i]=AMABuffer[i]; } } //--- 尝试复制 Print(dAMABuffer[0]); //看看我们是否能走到最后 //--- 为下一次调用返回 prev_calculated 的值 //--- //--- 为下一次调用返回 prev_calculated 的值 return(rates_total); } //+------------------------------------------------------------------+
你好、
这是一篇非常好的文章,但我有一些问题。
1. 只有使用简式 OnCalculate() 函数调用 的指标 才能 应用 到另一个指标,还是使用长式 OnCalculate() 函数调用 的指标 也可以应用?如果可以,Haw 可以将一个使用长形式OnCalculate() 函数调用 的 指标应用到另一个指标吗?
2.将一个指标应用于另一个指标(TSI 超过 RSI)会产生一些显示问题(见附图)。当 RSI 在 0 到 100 之间绘制时,第二个指标(TSI)也有低于 0 的值,这些值在图表上不可见。这就是问题所在,也是为什么图表不能正确调整以正确显示两个指标。我们能否解决这个问题,或者这是 MetaTrader 的一个错误?
这两个指标都是基于
int OnCalculate (const int rates_total, // 价格[] 数组大小 const int prev_calculated, // 在前一次呼叫中处理的条形图 const int begin, // 重要数据的起始索引 в массиве price[] const double& price[] // 用于计算的数组 );
因此,用户可以在参数中设置 applied_price 字段。
我的难题是如何将 applied_price 字段传递给内部指标(外部指标就是根据内部指标构建的)?
最简单的办法是创建一个输入,并警告用户 applied_price 输入和 applied_price 参数应相同,但这有点不妥。
您看过OnCalculate() 的 示例吗?
Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке входных переменных пользовательского индикатора.
Пример:
void OnStart() { //--- string terminal_path=StatusInfoString(STATUS_TERMINAL_PATH); int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL); if(handle_customMA>0) Print("handle_customMA = ",handle_customMA); else Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'"); }
在这个示例中,最后一个传递的参数是 PRICE_TYPICAL 值(来自ENUM_APPLIED_PRICE 枚举),表示自定义指标将根据典型价格(High+Low+Close)/3 生成。如果未指定该参数,则将根据 PRICE_CLOSE 值(即每个条形图的收盘价)构建指标。
看了、
int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
在调用 iCustom 时,applied_price 是明确指定的,但在调用 iCustom 的指标中,从哪里获取呢?
因为用户是在参数中设置的,而不是在输入中。
int OnInit() { //--- 指示器缓冲区映射 SetIndexBuffer(0,Buffer,INDICATOR_DATA); hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь); //--- return(0); } //+------------------------------------------------------------------+ //| 自定义指标迭代函数 //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //... return(rates_total); }
PS 的诀窍在于,用户一旦设置了 applied_price 参数,就不会再去管它了,因为这个值在整个金字塔调用过程中都会出现。
新文章 将指标应用至其他指标已发布:
在编写使用 OnCalculate() 函数调用的简短形式的指标时,您可能会忽略这样一个事实,即指标的计算不仅可以通过价格数据完成,还可以通过其他指标(无论是内置指标还是自定义指标)的数据实现。是否要改进指标以使其可以正确应用至其他指标的数据?在本文中,我们将回顾修改所需的所有步骤。
作者:MetaQuotes Software Corp.