如何解决将 DMI 从 Tradingview 移植到 MQL4 中修订的 ADX - 未给出等效结果
TradingView 在所使用的柱上计算其 DMI(相当于 MT4 ADX),即当您选择 Heiken Ashi 柱作为价格显示时,ADX 计算的开盘和收盘值是修改后的 HA 值。此外,他们的 DMI 需要一个额外的输入,即一个平滑周期,通过该周期平滑 ADX 线,如果设置为 1,则将保持不变的传统 ADX 线作为 Metatrader。
他们的 DMI 代码是免费提供的。我试图在下面引用的脚本中复制他们的 DMI 在 Heiken Ashi Bars 上的使用。
Metatrader 和 Tradingview 之间的情节非常不同(见图片)。
为了清晰起见,我整理了代码并添加了原始 PINE 脚本。
相关行号在注释中,其中也包含原始 PINE 代码中的行。
//+------------------------------------------------------------------+
//| SmoothedHAADX.mq4 |
//| Copyright 2021,andydoc1@gmail.com |
//| mailto://andydoc1@gmail.com |
//+------------------------------------------------------------------+
//---- port of DMI from Tradingview
//---- (https://www.tradingview.com/pine-script-reference/v4/#fun_dmi)
//---- applied to Heiken-Ashi Candles.
//---- Still not correct as plots differently.
//----
//---- PINE source code for DMI:
//---- up = change(security(heikinashi(syminfo.tickerid),timeframe.period,high))
//---- down = -change(security(heikinashi(syminfo.tickerid),low))
//---- plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
//---- minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
//---- trur = rma(tr,di_len)
//---- plus = fixnan(100 * rma(plusDM,di_len) / trur)
//---- minus = fixnan(100 * rma(minusDM,di_len) / trur)
//---- sum = plus + minus
//---- adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum),adx_len)
//----
//---- na fills an empty value with NULL
//---- tr is true range
//---- rma is EMA
//---- fixnan fills empty value with previous value
//----
//---- original inputs:
//---- di_len = ADX period
//---- adx_len = ADX Smoothing period
#property copyright "Copyright 2020,andydoc1"
#property link "mailto://andydoc1@gmail.com"
#property version "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 9
#property indicator_color1 White
#property indicator_width1 2
#property indicator_color2 Green
#property indicator_width2 1
#property indicator_style2 1
#property indicator_color3 Red
#property indicator_width3 1
#property indicator_style3 2
//---- buffers
double ExtMapBufferADX[]; //ADX
double ExtMapBufferPDI[]; //+DI
double ExtMapBufferNDI[]; //-DI
double ExtMapBufferHAO[]; //O
double ExtMapBufferHAC[]; //C
double ExtMapBufferTR[]; //tr
double ExtMapBufferPDM[]; //plusDM
double ExtMapBufferMDM[]; //minusDM
double ExtMapBufferDIratio[]; //DI ratio
double up,down,trur,sum,diff;
extern int ADXperiod=14;
extern int ADXsmperiod =14;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---- indicators
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBufferADX); //ADX
SetIndexLabel(0,"ADX");
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,ExtMapBufferPDI); //+DI
SetIndexLabel(1,"Plus DI");
SetIndexStyle(2,DRAW_LINE);
SetIndexBuffer(2,ExtMapBufferNDI); //-DI
SetIndexLabel(2,"Minus DI");
SetIndexBuffer(3,ExtMapBufferHAO); //Heiken-Ashi Open
SetIndexBuffer(4,ExtMapBufferHAC); //Heiken-Ashi Close
SetIndexBuffer(5,ExtMapBufferTR); //True Range
SetIndexBuffer(6,ExtMapBufferPDM); //+DM
SetIndexBuffer(7,ExtMapBufferMDM); //-DM
SetIndexBuffer(8,ExtMapBufferDIratio); //Ratio of Diff(+DI,-DI):Sum(+DI,-DI)
IndicatorShortName("ADX("+IntegerToString(ADXperiod)+"),based on Heiken Ashi Candles,smoothed over "+IntegerToString(14)+" periods.");
//----
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
int counted_bars=IndicatorCounted();
if(counted_bars < 0) return(-1);
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
if(counted_bars==0) limit-=1+ADXperiod+ADXsmperiod;
//---- main loop
for(int i=limit-1; i>=0; i--)
{
ExtMapBufferHAO[i] = (Open[i+1]+Close[i+1])/2;
ExtMapBufferHAC[i] = (Open[i]+High[i]+Low[i]+Close[i])/4;
}
for(int i=limit-1; i>=0; i--)
{
up = High[i]-High[i+1]; //up = change(high)
down = -(Low[i]-Low[i+1]); //down = -change(low)
ExtMapBufferPDM[i] = !up ? NULL : (up > down && up > 0 ? up : 0); //+DM = na(up) ? na : (up > down and up > 0 ? up : 0)
ExtMapBufferMDM[i] = !down ? NULL : (down > up && down > 0 ? down : 0);//-DM = na(down) ? na : (down > up and down > 0 ? down : 0)
ExtMapBufferTR[i] = MathMax(High[i] - Low[i+1],MathMax(MathAbs(High[i] - ExtMapBufferHAC[i+1]),MathAbs(Low[i+1] - ExtMapBufferHAC[i+1])));// --tr definition for line 122
} // -- line 94
for(int i=limit-(2+ADXperiod); i>=0; i--)
{
trur = iMAOnArray(ExtMapBufferTR,ADXperiod,1,i);//trur = rma(tr,len) -- line 122
ExtMapBufferPDI[i] = !(100*iMAOnArray(ExtMapBufferPDM,i)/trur) ? ExtMapBufferPDI[i+1] : 100*iMAOnArray(ExtMapBufferPDM,i)/trur;//plus = fixnan(100 * rma(plusDM,ADXperiod) / trur)
ExtMapBufferNDI[i] = !(100*iMAOnArray(ExtMapBufferMDM,i)/trur) ? ExtMapBufferNDI[i+1] : 100*iMAOnArray(ExtMapBufferMDM,i)/trur;//minus = fixnan(100 * rma(minusDM,len) / trur)
sum = ExtMapBufferPDI[i] + ExtMapBufferNDI[i] == 0.0 ? 1.0 : ExtMapBufferPDI[i] + ExtMapBufferNDI[i];//sum == 0 ? 1 : sum -- for line 127
diff = MathAbs(ExtMapBufferPDI[i] - ExtMapBufferNDI[i]);//abs(plus - minus) -- for line 127
ExtMapBufferDIratio[i] = diff / sum;//abs(plus - minus) / (sum == 0 ? 1 : sum) -- line 127 for line 131
}
for(int i=limit-(3+ADXperiod+ADXsmperiod); i>=0; i--)
{
ExtMapBufferADX[i] = 100*iMAOnArray(ExtMapBufferDIratio,ADXsmperiod,i);//adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum),adxlen) -- line 131
}
//--- Debugging
for(int i = 0;i<100;i++)
{
//Print(ExtMapBufferHAO[i],",ExtMapBufferHAC[i],ExtMapBufferPDM[i],ExtMapBufferMDM[i],ExtMapBufferTR[i],ExtMapBufferPDI[i],ExtMapBufferNDI[i],ExtMapBufferDIratio[i],ExtMapBufferADX[i]);
}
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
有关如何使其工作的任何想法?该指标是 Tradingview 中非常有利可图的回测的基础,我很乐意与任何帮助实现此目标的人分享该策略...
感谢 AnyDozer 提供上述反映的各种提示/建议
解决方法
将所有 iMAOnArray() 从 MODE_EMA 或 1 更改为 MODE_SMMA 或 2
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。