TradingView在使用的条形图上计算它们的DMI (相当于MT4 ADX),即当您选择海肯阿什条形图作为价格显示时,用于ADX计算的打开和关闭值是修改后的HA值。此外,他们的DMI需要一个额外的输入,一个平滑周期,通过它来平滑ADX线,如果设置为1,将保持传统ADX线不变,就像Metatrader一样。
他们的DMI代码是免费提供的。我尝试在下面引用的脚本中复制他们的DMI在Heiken Ashi栏上的使用。
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), timeframe.period, 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,0,ADXperiod,0,1,i);//trur = rma(tr, len) -- line 122
ExtMapBufferPDI[i] = !(100*iMAOnArray(ExtMapBufferPDM,0,ADXperiod,0,1,i)/trur) ? ExtMapBufferPDI[i+1] : 100*iMAOnArray(ExtMapBufferPDM,0,ADXperiod,0,1,i)/trur;//plus = fixnan(100 * rma(plusDM, ADXperiod) / trur)
ExtMapBufferNDI[i] = !(100*iMAOnArray(ExtMapBufferMDM,0,ADXperiod,0,1,i)/trur) ? ExtMapBufferNDI[i+1] : 100*iMAOnArray(ExtMapBufferMDM,0,ADXperiod,0,1,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,0,ADXsmperiod,0,1,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在上面所反映的各种提示/建议
发布于 2021-08-04 05:07:41
将所有iMAOnArray()从MODE_EMA或1更改为MODE_SMMA或2
https://stackoverflow.com/questions/66337390
复制相似问题