简体   繁体   English

MQL4多时间段指标

[英]MQL4 multi-timeframe indicator

I would like to write out an indicator that can take in input the int shift of an assigned timeframe, and turns out a value related to another timeframe. 我想写出一个指标,该指标可以输入指定时间范围的int shift ,并得出与另一个时间范围相关的值。

As an example, I would like to write an MACD indicator over a 100 periods of M15, that can return out its value 1,2,3,4,5,6,7... minutes before the current candle. 举例来说,我想在100个M15周期内编写一个MACD指标,该指标可以返回其值在当前蜡烛之前的1,2,3,4,5,6,7 ...分钟。

Since in the current candle this indicator "changes" its value, tick by tick, I think that should be possible to write out such an indicator, but I can not figure out how to do it. 由于在当前蜡烛中该指标“逐个滴答地变化”其值,我认为应该可以写出这样的指标,但是我不知道该怎么做。

MQL4 language principally has tools for this: MQL4语言主要具有用于以下目的的工具:

However, as noted above, your experimentation will need thorough quant validations, as the earlier Builds did not support this in [MT4-Strategy Tester] code-execution environment ( and more recent shifts into New- MQL4.56789 have devastated performance constraints for all [CustomIndicators] , the all [MT4-graph] -GUI-s together plus the all [Expert Advisor] -s use, since all these suddenly share one ( yes, ONE and THE ONLY ) computing thread. 但是,如上所述,您的实验将需要进行全面的定量验证,因为较早的Builds在[MT4-Strategy Tester]代码执行环境中不支持此操作(最近对New- MQL4.56789已破坏了所有产品的性能。 [CustomIndicators] ,所有[MT4-graph] -GUI-s以及所有[Expert Advisor] -s一起使用,因为所有这些突然共享一个(是,一个和唯一)计算线程。

Ok, you have been warned :o) 好的,您已经被警告过:o)

So, 所以,
if indeed keen to equip your [CustomIndicator] so as to be independent of the GUI-native-TimeFrame, all your calculations inside such [CustomIndicator]-code must use indirect access-tools to source the PriceDOMAIN data - so never use any { Open[] | High[] | Low[] | Close[] } 如果确实希望装备您的[CustomIndicator]以使其独立于GUI-native-TimeFrame,则在[CustomIndicator]代码中的所有计算都必须使用间接访问工具来获取PriceDOMAIN数据-因此切勿使用任何{ Open[] | High[] | Low[] | Close[] } { Open[] | High[] | Low[] | Close[] } { Open[] | High[] | Low[] | Close[] } -TimeSeries data directly, but only using { iOpen() | iHigh() | iLow() | iClose() } { Open[] | High[] | Low[] | Close[] } -TimeSeries数据直接,但使用{ iOpen() | iHigh() | iLow() | iClose() } { iOpen() | iHigh() | iLow() | iClose() }

All these access tools conceptually have a common signature: 所有这些访问工具在概念上都有一个共同的签名:

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

and
if your code 如果你的代码
obeys this duty, 遵守这项义务
your [CustomIndicator] ( iff the StrategyTester will not finally spoil the game -- due quant testing will show this ) 您的[CustomIndicator] 如果 StrategyTester最终不会破坏游戏-定量测试将显示此内容)
will be working with data from timeframe & shift of your wish. 将使用timeframe数据和您希望的shift


Implementation remarks: 实施说明:

Your [CustomIndicator]-code has to implement a "non-GUI-shift" independently from the GUI-native-TimeFrame shift -counting. 您的[CustomIndicator]代码必须独立于GUI-native-TimeFrame shift计数实现"non-GUI-shift" See an iCustom() signature template for inspiration. 请参阅iCustom()签名模板以获取灵感。 The GUI-TimeFrame- shift is like moving the line-graph on GUI-screen, ie in GUI-native-TimeFrame steps, not taking into account your [CustomIndicator] "internal"- "non-GUI-shift" values, so your code has to be smarter, so as to process this "internal"- "non-GUI-shift" during a value generation. GUI-TimeFrame- shift就像在GUI屏幕上移动线图一样,即在GUI-native-TimeFrame步骤中,不考虑您的[CustomIndicator]“内部”- "non-GUI-shift"值,因此您的代码必须更智能,以便在值生成期间处理此“内部”- "non-GUI-shift" If in doubts, during prototyping, validate the proper "mechanics" on Time[aShiftINTENDED] vs iTime( _Symbol, PERIOD_INTENDED, aShiftINTENDED ) 如有疑问,请在原型制作过程中验证Time[aShiftINTENDED]iTime( _Symbol, PERIOD_INTENDED, aShiftINTENDED )上的正确“力学”

Due to quite a lot of points, where an iCustom() call-interface may be a bit misleading, or a revision-change-management error-prone, we got used to use a formal template for each [Custom Indicator] code, helping to maintain referential integrity with a iCustom() use in the actual [ExpertAdvisor] code. 由于很多地方, iCustom()调用界面可能会产生误导,或者易于发生版本变更管理错误,因此我们习惯于为每个[Custom Indicator]代码使用正式的模板,使用实际[ExpertAdvisor]代码中的iCustom()来维护参照完整性。 It might seem a bit dumb, but those, who have spent man*hours in search for a bug in { un- | 看起来有些愚蠢,但是那些花了数小时*在{un- | ill- }-propagated call-interface changes, this may become a life-saver. 不适当地传播的呼叫接口更改,可能会挽救生命。

We formalise the call-interface in such a way, that this section, maintained in the [CustomIndicator]-code, can always be copied into the [ExpertAdviser] code, so that the iCustom() signature-match can be inspected. 我们以这种方式对调用接口进行形式化,使得可以将在[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
//!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Found a way to write it in a very simple way: 找到了一种非常简单的方式编写它:

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);

                     } 

and so on for every others couples of timeframe. 以此类推。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM