MQL4 多时间框架指标

MQL4 multi-timeframe indicator

我想编写一个指标,可以输入指定时间范围的 int shift,并得出与另一个时间范围相关的值。

例如,我想在 M15 的 100 个周期上编写一个 MACD 指标,它可以 return 得出其值 1,2,3,4,5,6,7...当前蜡烛之前的分钟数。

因为在当前蜡烛中这个指标 "changes" 它的值,逐笔报价,我认为应该可以写出这样的指标,但我不知道该怎么做。

MQL4 语言主要有用于此的工具:

但是,如上所述,您的实验将需要彻底的量化验证,因为早期版本在 [MT4-Strategy Tester] 代码执行环境(和最近转向 New-MQL4.56789 对所有 [CustomIndicators]、所有 [MT4 -graph]-GUI-s 加上所有 [Expert Advisor]-s 一起使用,因为所有这些突然共享一个(是的,唯一的)计算线程.

好的,您已收到警告:o)

所以,
如果确实热衷于装备你的 [CustomIndicator] 以便独立于 GUI-native-TimeFrame,那么你在此类 [CustomIndicator] 代码中的所有计算都必须使用间接访问工具来获取源代码PriceDOMAIN 数据 - 所以永远不要直接使用任何 { Open[] | High[] | Low[] | Close[] }-TimeSeries 数据,而 使用 { iOpen() | iHigh() | iLow() | iClose() }

所有这些访问工具在概念上都有一个共同的特征:

double  iLow( string   symbol,          // symbol 
              int      timeframe,       // timeframe 
              int      shift            // shift
              );


如果你的代码
服从这个职责,
您的 [CustomIndicator]( iff​​ StrategyTester 最终不会破坏游戏——由于量化测试会显示这一点 )
将根据您的意愿处理来自 timeframeshift 的数据。


执行备注:

您的 [CustomIndicator]-代码必须独立于 GUI-native-TimeFrame shift-计数实现 "non-GUI-shift"。请参阅 iCustom() 签名模板以获取灵感。 GUI-TimeFrame-shift 就像在 GUI 屏幕上移动线图,即在 GUI-native-TimeFrame 步骤中,不考虑您的 [CustomIndicator] "internal"- "non-GUI-shift" 值,因此您的代码必须更智能,以便在值生成期间处理此 "internal"-"non-GUI-shift" .如果有疑问,在原型制作过程中,在 Time[aShiftINTENDED]iTime( _Symbol, PERIOD_INTENDED, aShiftINTENDED )

上验证正确的 "mechanics"

由于很多点,其中iCustom()调用接口可能有点误导,或者修订变更管理容易出错,我们习惯于为每个使用正式模板[Custom Indicator] 代码,在实际 [ExpertAdvisor] 代码中使用 iCustom() 帮助维护参照完整性。这可能看起来有点愚蠢,但是那些花费了 man*hours 来寻找 { un- | 中的错误的人ill- }-propagated 调用接口更改,这可能会成为救命稻草。

我们以这种方式形式化调用接口,即在 [CustomIndicator] 代码中维护的这一部分始终可以复制到 [ExpertAdviser] 代码中,以便 iCustom() 签名 -可以检查匹配。

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!
//---- indicator parameters -------------------------------------------------
//                          POSITIONAL ORDINAL-NUMBERED CALLING INTERFACE
//                      all iCustom() calls MUST BE REVISED ON REVISION
//!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define          XEMA_CUSTOM_INDICATOR_NAME    "EMA_DEMA_TEMA_XEMA_wShift"   // this.
//--- input parameters ------------------------------------------------------   iCustom( ) CALL INTERFACE
input  int                 nBARs_period      = 8;
extern double              MUL_SIGMA         = 2.5;
sinput ENUM_APPLIED_PRICE  aPriceTYPE        = PRICE_CLOSE;
extern int                 ShiftBARs         = 0;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/*      = iCustom( _Symbol,
                   PERIOD_CURRENT, XEMA_CUSTOM_INDICATOR_NAME,  // |-> iCustom INDICATOR NAME
                                   XEMA_nBARs_period,           // |->                         input    nBARs_period
                                   XEMA_MUL_SIGMA,              // |->                         input    MUL_SIGMA
                                   XEMA_PRICE_TYPE,             // |->                         input    aPriceTYPE       from: ENUM_APPLIED_PRICE
                                   XEMA_ShiftBARs,              // |->                         input    ShiftBARs
                                   XEMA_<_VALUE_>_BUFFER_ID,    // |-> line# --------------------------------------------from: { #define'd (e)nums ... }
                                   0                            // |-> [0]-aTimeDOMAIN-offset
                                   );                           //                                                                                      
*/                                                              
#define                            XEMA_Main_AXIS_BUFFER_ID  0  // <----xEMA<maxEMAtoCOMPUTE>[]
#define                            XEMA_UpperBAND_BUFFER_ID  1  
#define                            XEMA_LowerBAND_BUFFER_ID  2  
#define                            XEMA_StdDEV____BUFFER_ID  3  
#define                            XEMA_SimpleEMA_BUFFER_ID  4  // sEMA
#define                            XEMA_DoubleEMA_BUFFER_ID 10  // dEMA
#define                            XEMA_TripleEMA_BUFFER_ID 11  // tEMA

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
//!!!!
//---- indicator parameters -------------------------------------------------
//                          POSITIONAL ORDINAL-NUMBERED CALLING INTERFACE
//                      all iCustom() calls MUST BE REVISED ON REVISION
//!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

找到了一个很简单的写法:

double M1  (int shift) {double val = iCustom(NULL,PERIOD_M1, "my_indicator",100,2.0,30.0,0,shift); return(val);}
double M15 (int shift) {double val = iCustom(NULL,PERIOD_M15,"my_indicator",100,2.0,30.0,0,shift); return(val);}

int s1_15;
double B_M1_M15(int i) {

                          if (i>=0  && i<15 ) s1_15=0;
                     else if (i>=15 && i<30 ) s1_15=1;
                     else if (i>=30 && i<45 ) s1_15=2;
                     else if (i>=45 && i<60 ) s1_15=3;
                     else if (i>=60 && i<75 ) s1_15=4;

                     return NormalizeDouble(MathAbs(M1(i) - M15(s1_15)),Digits);

                     } 

每隔几个时间段依此类推。