2019年1月5日土曜日

[MQL4] OnTick() 内で Bid, Ask を更新する方法

EA の `OnTick()` 処理中に Bid, Ask が更新されたとしても `Bid`, `Ask` 変数にこれらの値は反映されません。

注文の実行時など、最新の値を使用したい時は [RefreshRates()](https://docs.mql4.com/series/refreshrates) を使用すると `Bid`, `Ask` 変数等を更新する事が出来ます。



### 動作確認
以下のような EA を作成して実行してみました。

```mq4
void OnTick()
{
    RefreshRates();
    printf("A  Ask: %s, Bid: %s, Volume: %d",
           DoubleToStr(Ask, Digits),
           DoubleToStr(Bid, Digits),
           Volume[0]);
           
    Sleep(10000);
    
    printf("B  Ask: %s, Bid: %s, Volume: %d",
           DoubleToStr(Ask, Digits),
           DoubleToStr(Bid, Digits),
           Volume[0]);

    RefreshRates();

    printf("C  Ask: %s, Bid: %s, Volume: %d",
           DoubleToStr(Ask, Digits),
           DoubleToStr(Bid, Digits),
           Volume[0]);
}
```

結果は以下です。
```
A  Ask: 109.119, Bid: 109.111, Volume: 2
// 10 秒待機
B  Ask: 109.119, Bid: 109.111, Volume: 2
// RefreshRates() 実行
C  Ask: 109.120, Bid: 109.112, Volume: 11
```

B では10秒前の情報が保持されています。`RefreshRates()` を実行すると最新の情報に更新されました。

### 戻り値について
`RefreshRates()` の戻り値はエラーではなく、更新できたかどうかです。
例えば、以下のように `OnTick()` の最初で `RefreshRate()` を呼んでも、ほぼ間違いなく `false` になります100% ではない。

```mq4
void OnTick()
{
    bool refreshed = RefreshRates();
    Print(refreshed);
}
```

### 注意点
`RefreshRates()` は他スレッドとの排他が発生しているはずです。
そのため、あまり頻繁に呼ぶと動作が遅くなる可能性があります。

ただ、私の手元では目立った遅延は確認できませんでした。
それなりのスペックを持ったマシンであれば、ほとんど気にする必要は無いと思いますが、念の為。