恥は/dev/nullへ by 初心者

プログラミング素人がのろのろと学んだことをつづっています♪

MT5でspreadを取得する際の注意点

MT5でspreadの値を取得する方法はいくつかありますが、以下の記事によると、取得する方法によって値が異なる場合があるようです。

https://fmdsm.blog.fc2.com/blog-entry-94.html

上記記事の内容から「MqlRates.spread」「iSpread()」「spread[]」を使って取得したspreadの値は余り信用できないので、以下の2つを使って調べた方が無難だと感じました。

SymbolInfoInteger
SymbolInfoTick


spreadの値に疑問を感じたのは、OnCalculate関数の中にあるspread[]を使ってみたからです。そこで、ちょっと実験をしてみました。

実験したこと

以下のコードを実行してみました。

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[])
{
    ArraySetAsSeries(spread, true);

    double iclose  = iClose(NULL, PERIOD_M5, 0);
    double sp  = spread[0] * _Point;
    double symbolinfo_ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    double symbolinfo_bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    static int count = 0;

    if(count == 0) {
        printf("iclose = %f", iclose);
        printf("symbolinfo_bid = %f", symbolinfo_bid);
        printf("symbolinfo_ask = %f", symbolinfo_ask);
        printf("spread = %f", sp);
        printf("ask - bid = %f", symbolinfo_ask - symbolinfo_bid);
        count++;
    }
    return(rates_total);
}


次の結果がエキスパートに表示されました。
(各行の先頭にある〇行目は説明の便宜上、後付けしました)

1行目  iclose = 0.855450
2行目  symbolinfo_bid = 0.855450
3行目  symbolinfo_ask = 0.855480
4行目  spread = 0.000000
5行目  ask - bid = 0.000030

1行目と2行目はBid価格です。
3行目はAsk価格です。
spreadはAsk価格とBid価格の差です。3行目までを見るとAsk価格とBid価格に差があるのですが・・・、4行目を見るとspreadは0です。

このことから、spread[0]の値は正しくないと思われます(ただし、上記コードで取得したAsk価格やBid価格が正しければ、の話ですが)。

そこで、spread[0]の代わりにSymbolInfoIntegerでspreadの値を取得してみました。
それが以下のコードです。

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[])
{
    ArraySetAsSeries(spread, true);

    double iclose  = iClose(NULL, PERIOD_M5, 0);
    double sp  = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) * _Point;
    double symbolinfo_ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    double symbolinfo_bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    static int count = 0;

    if(count == 0) {
        printf("iclose = %f", iclose);
        printf("symbolinfo_bid = %f", symbolinfo_bid);
        printf("symbolinfo_ask = %f", symbolinfo_ask);
        printf("spread = %f", sp);
        printf("ask - bid = %f", symbolinfo_ask - symbolinfo_bid);
        count++;
    }
    return(rates_total);
}


結果はこうなりました。

1行目  iclose = 0.855440
2行目  symbolinfo_bid = 0.855440
3行目  symbolinfo_ask = 0.855490
4行目  spread = 0.000050
5行目  ask - bid = 0.000050

今度はspreadの値が、Ask価格とBid価格の差になっています。
よって、このspreadの値は正しいと思われます。