MT4 计算指标时的回调函数,到底该更新几根 bar 的计算

新版的 MT4 指标计算在 OnCalculate 函数中,每次 tick 数据变动,相当于刷新最后一根 bar 的 Close。这时只需要重新计算最后一根的 bar 上的数据。显然不希望在最后一根 bar 上不断更新收盘价时,均线缺不变化。

但是如果在 EA 中用 iCustom 来引用这根均线时,可以采用上一根已收盘的 bar 的来计算。

采用 Bars - IndicatorCounted() - 1 的方式

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[]) {

    // 每次响应 tick 数据时都会回调

    // 未计算的 bars
    int limit = Bars - IndicatorCounted() - 1;              // 这种方式如果计算过, limit = 0

    LOG_INFO(StringFormat("limit: %d", limit));

    // 从前往后算
    for (int i = limit; i >= 0; i--) {

        log_info(log_handle, StringFormat(
                 "Open: %f\tHigh: %f\tLow: %f\tClose: %f", Open[i], High[i], Low[i], Close[i]
             ));

        BufUP[i] = iBands(NULL, 0, BB_Period, 3, 0, PRICE_CLOSE, 1, i); 
        BufCenter[i] = iBands(NULL, 0, BB_Period, 3, 0, PRICE_CLOSE, 0, i); 
        BufDOWN[i] = iBands(NULL, 0, BB_Period, 3, 0, PRICE_CLOSE, 2, i); 

        BufDOWN_Arrow[i] = EMPTY_VALUE;
        BufUP_Arrow[i] = EMPTY_VALUE;
        if(BufUP[i] < High[i]) { 
            BufDOWN_Arrow[i] = High[i] + 30 * Point; 
        }
        if(BufDOWN[i] > Low[i]) { 
            BufUP_Arrow[i] = Low[i] - 30 * Point; 
        }

    }

    return(rates_total);
}

采用 rates_total - prev_calculated - 1 的方式

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[]) {

    // 每次响应 tick 数据时都会回调

    // 未计算的 bars
    int limit = rates_total - prev_calculated - 1;        // 这种方式必须 -1, 不然第一次计算引用第一根 bar 会出现错误,limit = -1
    if (limit < 0) 
        limit = 0;

    LOG_INFO(StringFormat("limit: %d", limit));

    // 从前往后算
    for (int i = limit; i >= 0; i--) {

        log_info(log_handle, StringFormat(
                 "Open: %f\tHigh: %f\tLow: %f\tClose: %f", Open[i], High[i], Low[i], Close[i]
             ));

        BufUP[i] = iBands(NULL, 0, BB_Period, 3, 0, PRICE_CLOSE, 1, i); 
        BufCenter[i] = iBands(NULL, 0, BB_Period, 3, 0, PRICE_CLOSE, 0, i); 
        BufDOWN[i] = iBands(NULL, 0, BB_Period, 3, 0, PRICE_CLOSE, 2, i); 

        BufDOWN_Arrow[i] = EMPTY_VALUE;
        BufUP_Arrow[i] = EMPTY_VALUE;
        if(BufUP[i] < High[i]) { 
            BufDOWN_Arrow[i] = High[i] + 30 * Point; 
        }
        if(BufDOWN[i] > Low[i]) { 
            BufUP_Arrow[i] = Low[i] - 30 * Point; 
        }

    }

    return(rates_total);
}

另外一种写法

   int limit;
   if (prev_calculated == 0)
      limit = rates_total - 1;
   else
      limit = rates_total - prev_calculated;

总结

  • 不管用何种方式,都要使 limit = 0,这样在正向循环计算时始终计算最后一根。
  • 有也从后往前计算的方式,但是像 supertrend 这样的指标需要前一根 bar 的数据,不能倒着计算。均线可以倒着计算。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇