如何计算移动平均线最后交叉了多少根柱线?

How to count how many bars back the moving average crossed last?

我正在编写一个 MQL4 自定义指标,它会告诉我们有多少根柱线在一组特定的移动平均线之前交叉。

具体来说,我希望输出显示

"The 20 period MA( .. PRICE_OPEN ) is below MA( .. PRICE_CLOSE ) for the past 10 bars".

int 数字的形式。

double ma1 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_OPEN,  0 );
double ma2 = iMA( Symbol(), 10080, 20, 0, 0, PRICE_CLOSE, 0 );

我想知道 ma1 自当前柱以来已高于或低于 ma2 多少柱。

TLDR;

MQL4 自定义指标 设计是一个有点精神分裂的任务,有 2 个部分

一旦决定设计一个自定义指标,就必须注意硬币的两面。

MQL4 代码对调用方
(通常是 Expert AdvisorScript 类型的 MQL4 代码)
and
自定义指标,它自己,
在一种特殊模式下运行,它计算并将其值存储到一个或多个名为 [=19= 的数组中]-s.

Phase I.: design Caller-side interface ( what all do we need to set / receive ? )
Phase II.: design Custom Indicator implementation side

这样,给定的指标应

  • 设置只是一个参数:一个period ... 20
  • 收到刚一int天的价值{ +:above | 0: xoss | -: under}

Phase I. : 设计调用方接口

鉴于上述参数化和 自定义指标 构造的 MQL4 概念,以下通用模板(建议在 CustomIndicator-file ) 反映调用方接口所需的详细信息(仅通过复制粘贴机制从中受益,而实现完整性责任由 CustomIndicator 维护者承担):

// CALL-er SIDE INTERFACE |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
                                                // 
                                                // #define sIndicatorPathNAME             "#AliceInTheWonderlands_msMOD_0.00"
                                                // 
                                                // //_____________________________________INPUT(s)
                                                // // iMA_PERIOD:
                                                // extern int   iMA_PERIOD    = 20;
                                                // 
                                                // //_____________________________________OUTPUT(s):
                                                // #define iOutputDoubleUpOrDnBUFFER     0
                                                // 
                                                // //_____________________________________CALL-SIGNATURE:
                                                // 
                                                //                            double  iCustom(  _Symbol,                      // string       symbol,           // symbol:                                                 Symbol name on the data of which the indicator will be calculated. NULL means the current symbol.
                                                //                                              PERIOD_W1,                    // int          timeframe,        // timeframe
                                                //                                              sIndicatorPathNAME,           // string       name,             // path/name of the custom indicator compiled program:     Custom indicator compiled program name, relative to the root indicators directory (MQL4/Indicators/). If the indicator is located in subdirectory, for example, in MQL4/Indicators/Examples, its name must be specified as "Examples\indicator_name" (double backslash "\"must be specified as separator instead of a single one).
                                                //                                              iMA_PERIOD,                   // ...[1]       ...,              // custom indicator [1]-st input parameter
                                                //                                              <<N/A>>,                      // ...[2+]                        // custom indicator further input parameters (if necessary)
                                                //                                              iOutputDoubleUpOrDnBUFFER,    // int          mode,             // line index:                                             Line index. Can be from 0 to 7 and must correspond with the index, specified in call of the SetIndexBuffer() function.
                                                //                                              i                             // int          bar_shift         // shift
                                                //                                              );
                                                // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

典型的 EA 交易 调用如下所示:

int anIndicatorVALUE = iCustom( _Symbol,
                                PERIOD_W1,
                                sIndicatorPathNAME,
                                iMA_PERIOD,
                                iOutputDoubleUpOrDnBUFFER,
                                aCurrentBarPTR
                                );
if ( 0 > anIndicatorVALUE ) // on "line" under for <anIndicatorVALUE> [PERIOD]-s
{ ...
}

Phase II. : 设计 自定义指标 实施方

预设总容量

#property indicator_buffers 1            // compile time directive

分配 内存 IndexBuffer(s) 需要

IndicatorBuffers( 1 );                   // upper limit of 512 is "far" enough

声明 IndexBuffer

double UpOrDnBUFFER[];                   // mandatory to be a double

关联 IndexBuffer 与索引

SetIndexBuffer( 0, UpOrDnBUFFER );       // index 0: UpOrDnBUFFER[]
ArraySetAsSeries(  UpOrDnBUFFER, True ); // reverse AFTER association

任何自定义指标的核心逻辑都在OnCalculate()函数中,您
- 实现所需的微积分

-结果值存储到[的相应单元格中=37=]

根据要求编写完整的代码并不是 Whosebug 的关键 objective,但让我就此做一些说明,因为 Custom Indicator 实施方面需要一点练习:

  • 因为 Custom Indicator OnCalculate() 运行 "progressively",所以请设计您的计算策略并牢记无状态- "blocks" 个前向计算块之间的关系。

  • 正如给定的那样,交叉是三态系统,因此请注意案例问题,其中决策是在 "live" 条上做出的,其中状态 { above | cross | under } 可能会在 bar-evolution 过程中发生多次变化。