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 最终不会破坏游戏——由于量化测试会显示这一点 )
将根据您的意愿处理来自 timeframe
和 shift
的数据。
执行备注:
您的 [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);
}
每隔几个时间段依此类推。
我想编写一个指标,可以输入指定时间范围的 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 最终不会破坏游戏——由于量化测试会显示这一点 )
将根据您的意愿处理来自 timeframe
和 shift
的数据。
执行备注:
您的 [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 )
由于很多点,其中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);
}
每隔几个时间段依此类推。