[英]How to Quantise an indicator in MQL4?
I am failing over and over trying to get this indicator to run quantised with 2 buffers in mql4 . 我一遍又一遍地尝试使该指标运行在mql4中的 2个缓冲区中进行量化 。 After a long time reading I have put 2 extra buffers in to squish it :/ because:
经过长时间的阅读,我放入了2个额外的缓冲区来压缩它:/因为:
the indicator is sitting between 0.1430-0.1427 at present but doesn't have a fixed top and bottom .
该指标目前位于0.1430-0.1427之间,但没有固定的顶部和底部 。
I can't seem to suss it; 我似乎没什么好怀疑的。 cool indicator but won't play fair!
很酷的指标,但不能公平竞争!
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 CLR_NONE
#property indicator_color4 CLR_NONE
//#property indicator_minimum 0
//#property indicator_maximum 100
extern int P = 13;
extern int T = 3000;
extern double P2 = 0.001;
//int MIN = 0;
//int MAX = 100;
double G[];
double R[];
double B3[];
double B4[];
int init(){
IndicatorBuffers(4);
SetIndexBuffer( 0, G );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
SetIndexBuffer( 1, R );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red );
SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
return(0);
}
int start(){
if ( T >= Bars ) T = Bars;
SetIndexDrawBegin( 0, Bars - T + P + 1 );
SetIndexDrawBegin( 1, Bars - T + P + 1 );
SetIndexDrawBegin( 2, Bars - T + P + 1 );
SetIndexDrawBegin( 3, Bars - T + P + 1 );
int Z, C, Opt = IndicatorCounted();
if ( Bars <= 38 ) return(0);
if ( Opt < P ){
for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0;
for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0;
}
Z = T - P - 1;
while( Z >= 0 ){
double A, S1, S2;
S1 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S1 = S1 + ( High[Z+C] + Low[Z+C] ) / 2;}
S2 = 0.0; for ( C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
A = S1 / S2;
// if ( A < MIN ){ MIN = A;}
// if ( A > MAX ){ MAX = A;}
// A = ( MIN / MAX ) * 100;
G[Z] = A;
if ( Z > 0 ){ R[Z-1] = A;}
Z--;
}
for ( int N = T-P-2; N >= 0; N-- ){
if ( N > 0 ){
if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;}
if ( G[N-1] < G[N] ){ G[N] = R[N]; continue;}
}
B3[0] = G[0] + P2;
B4[0] = G[0] - P2; //forced quantise using 2 extra buffers
}
return(0);
}
0 ) indicator logic 0 )指示器逻辑
1 ) indicator quantisation step 1 )指标量化步骤
2 ) indicator performance 2 )指标表现
MQL4
Custom Indicator programming relies on deeper understanding of underlying MetaTrader4 Terminal platform. MQL4
自定义指标编程依赖对底层MetaTrader4终端平台的更深入了解。 Each external Market Event, changing a traded instrument price, is signalled to a lcoalhost by a network delivery of a QUOTE ...
message from MetaTrader4 Server . 通过从MetaTrader4服务器通过网络传递
QUOTE ...
消息将每个更改的交易工具价格的外部市场事件通知给lcoalhost。 This is aka Tick and it triggers a call to a function originally called start()
, in newer New - MQL4.56789
renamed to OnTick()
. 这就是Tick,它会触发对最初名为
start()
的函数的调用,在较新的New - MQL4.56789
重命名为OnTick()
。
The below modified MQL4
listing contains remarks for core-logic disambiguation, which must precede all the below listed steps. 下面修改后的
MQL4
清单包含有关核心逻辑歧义消除的注释,这些注释必须在以下所有列出的步骤之前。
While the code is still very inefficient ( as per [2] below ) the logic does not include any straight hurdle form having the output quantised to any form thereof { binary | 虽然代码仍然非常低效(按照下面的[2]所述),但逻辑不包括任何直接的障碍形式,其输出被量化为其任何形式。 ternary |
三元| arbitrary-number-of-states }-quantised system.
状态的任意数量}的系统。 Whence the indicator core-logic is cleared, the quantisation step is just a trivial conversion from R(1) to I(1) .
一旦清除了指示符核心逻辑,量化步骤就是从R(1)到I(1)的简单转换。
Any Tick arrival may, but need not modify either High[0]
or Low[0]
, which are the only variable parts of the proposed Custom Indicator calculus. 任何滴答声到达都可以但不必修改
High[0]
或Low[0]
,这是建议的“自定义指标”演算的唯一可变部分。
This is the core idea on how to reduce the scope of re-calculations, that the MQL4
code has to realise per tick. 这是关于如何减少重新计算范围的核心思想,即
MQL4
代码必须在每个滴答中实现。 In recent versions of MT4, all Custom Indicators share a single thread , the more stress has been put on efficient algorithmisation of Custom Indicators, at these may block the platform's trading decisions on poor, inefficient code-loops and convolution/recursion re-executions. 在最新版本的MT4中, 所有自定义指标共享一个线程 ,对自定义指标的高效算法施加了更大的压力,因为这可能会阻止平台在不良,低效的代码循环和卷积/递归重新执行方面的交易决策。
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 Lime
#property indicator_color2 Red
#property indicator_color3 CLR_NONE
#property indicator_color4 CLR_NONE
extern int P = 13;
extern int T = 3000;
extern double P2 = 0.001;
double G[]; // 0: LINE
double R[]; // 1: LINE
double B3[]; // 2: BUT NEVER PAINTED, NEVER CONSUMED _?_
double B4[]; // 3: BUT NEVER PAINTED, NEVER CONSUMED _?_
int init(){
IndicatorBuffers(4);
SetIndexBuffer( 0, G );SetIndexStyle( 0, DRAW_LINE, STYLE_SOLID, 1, Lime );
SetIndexBuffer( 1, R );SetIndexStyle( 1, DRAW_LINE, STYLE_SOLID, 1, Red );
SetIndexBuffer( 2, B3 );SetIndexStyle( 2, DRAW_NONE );
SetIndexBuffer( 3, B4 );SetIndexStyle( 3, DRAW_NONE );
return(0);
}
int start(){
if ( Bars <= 38 ) return(0); // JIT/RET in case Bars < 39 --^ --^ --^ --^
if ( T >= Bars ) T = Bars; // (TRIM´d) T < Bars .OR. = Bars
int aDrawBegins = Bars - T + P + 1; // ( extern P = 13 ) + 1 + ( Bars - ( extern T = 3000 if T < Bars else Bars ) )
//tIndexDrawBegin( 0, Bars - T + P + 1 ); // PREF: ( reused 4x )
SetIndexDrawBegin( 0, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
SetIndexDrawBegin( 1, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
SetIndexDrawBegin( 2, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
SetIndexDrawBegin( 3, aDrawBegins ); // Draw 14+ last candles -- PREF: why a per tick hard-coded SHIFTING / enforced re-draw?
double A, S1, S2; // auxiliary var for bar-mid-price calculi
int Z; // auxiliary stepper
int Opt = IndicatorCounted(); // Opt ( NEVER RE-USED )
if ( Opt < P ){ // if ( ( extern P = 13 ) > IndicatorCounted() )
// ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
for ( Z = 1; Z <= 0; Z++ ) G[T-Z] = 0.0; // .STO G[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
for ( Z = 1; Z <= 0; Z++ ) R[T-Z] = 0.0; // .STO R[T-Z], 0., BUT NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
// ----------------------- ??? ----------------------------------------------------- NEVER EXEC´d: for( Z = 1++ v/s Z <= 0 )
}
Z = T - P - 1; // .STO Z, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 1
while( Z >= 0 ){ // .DEC Z
// !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !!
S1 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S1 = S1 + ( High[Z+C] + Low[Z+C] ) / 2; }
S2 = 0.0; for ( int C = 0; C <= P - 1; C++ ){ S2 = S2 + ( ( High[Z+C] + Low[Z+C] ) * ( C+1 ) / 2 );}
// !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // PERF: very inefficient to RE-calc STATIC ( ( extern P = 13 ) - 1 )-DEEP CONVOLUTIONS per tick !!
A = S1 / S2;
G[Z] = A; // .STO G[Z], A if Z >= 0
if ( Z > 0 ){ R[Z-1] = A;} // .STO R[Z-1], A if Z > 0
Z--;
}
for ( int N = T - P - 2; N >= 0; N-- ){ // .STO N, ( T = Bars (TRIM´d) ) - ( extern P = 13 ) - 2
if ( N > 0 ){ // N > 0:
if ( G[N-1] > G[N] ){ R[N] = EMPTY_VALUE; continue;} // .BLNK R[N], EMPTY if G[N-1] > G[N]
if ( G[N-1] < G[N] ){ G[N] = R[N]; continue;} // .SET G[N], R[N] if G[N-1] < G[N]
}
// ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ??
B3[0] = G[0] + P2; // .STO B3[0], G[0] + ( extern P2 = 0.001 )
B4[0] = G[0] - P2; // .STO B4[0], G[0] - ( extern P2 = 0.001 )
// forced quantise using 2 extra buffers
// ?? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // WHY MANY-TIMES RE-ASSIGNED A CONST. VALUE HERE, INSIDE A FOR(){...}-loop body? -------------- ??
}
return(0);
}
MQL4.56789
syntax MQL4.56789
语法 The OnCalculate()
function is called only in custom indicators when it's necessary to calculate the indicator values by the Calculate event . 仅在需要通过Calculate事件计算指标值时,才在自定义指标中调用
OnCalculate()
函数。 This usually happens when a new tick is received for the symbol, for which the indicator is calculated. 这通常发生在为该符号接收到新的价格变动时,为此计算指标。 This indicator is not required to be attached to any price chart of this symbol.
不需要将该指标附加到该符号的任何价格图表上。
The first rates_total
parameter contains the number of bars
, available to the indicator for calculation, and corresponds to the number of bars available in the chart. 第一
rates_total
参数包含的数bars
,提供给用于计算指标,并且对应于图表中可用的条的数量。
We should note the connection between the return value of OnCalculate()
and the second input parameter prev_calculated
. 我们应该注意
OnCalculate()
的返回值和第二个输入参数prev_calculated
。 During the OnCalculate()
function call, the prev_calculated
parameter contains a value returned by OnCalculate()
during previous call. 在
OnCalculate()
函数调用期间, prev_calculated
参数包含上一次调用期间OnCalculate()
返回的值。 This allows for economical algorithms for calculating the custom indicator in order to avoid repeated calculations for those bars that haven't changed since the previous run of this function. 这允许使用经济的算法来计算自定义指标,以避免重复计算自该函数上一次运行以来未发生变化的柱线。
For this, it is usually enough to return the value of the rates_total
parameter, which contains the number of bars in the current function call. 为此,通常返回
rates_total
参数的值就足够了,其中包含当前函数调用中的柱数。 If since the last call of OnCalculate()
the price data has changed (a deeper history downloaded or history blanks filled), the value of the input parameter prev_calculated
will be set to zero by the terminal. 如果自从上次调用
OnCalculate()
以来价格数据已更改(下载了更深的历史记录或填充了历史记录空白),则prev_calculated
将把输入参数prev_calculated
的值设置为零。
//+------------------------------------------------------------------+
//| 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[]
)
{
// Get the number of bars available now for the current Symbol and chart period
int barsNow = Bars( _Symbol, PERIOD_CURRENT );
// .RET value of prev_calculated for a next call
return( rates_total );
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.