開発:MQL開発8/ローソク足の始値 と 発注タイミングを合わせる | シストレの現実

シストレの現実

インフラ構築のプロが、シストレをゼロから始める記録です。
リーン・スタートアップの考えを取り込み、Expert Adviser を作っていきます。

教えるような大したものではなく、ユースケースの一つになれば幸いです。

前回から惹き潰え、 MetaEditor のデバッガを使ってみようかなぁと思ってたんですけど、
どーーーーーも上手く動かない。
カスタム関数使いまくってるせいか、キチンとブレイクポイントで止まってくれないんです。
原因が分かれば使い易いかもしれないんですが、、、

今回のところはPrintデバッグで間に合ってるので保留。


さて、今日は以前に発掘したEA開発における課題に挑みます。


課題: 始値と約定価格がけっこうズレてる

ズレ01


そこで、「始値に成行注文しているのがうまくいってない」という仮定を潰すことにしました。

先日、たまたま Excelで集計して調べてみた通り、
Volume配列に格納されるTick数の値が全然アテにならないことが分かったので、
今回修正してみよう!一石二鳥だ!!というわけで、こういう感じに直してみました。


まず変更した箇所。もうサンプルEAのソースコードそのまま。
bool isPossibleOrder(int MarketTrend, double StopLossPrice, double ExitPrice) {

(略)

    //--- 前提条件の確認

    if (Volume[0] > 1)      return(false); // 最初のティック時のみ許可

    if (MarketTrend <= 0)   return(false); // 市場トレンドが明確なこと

(略)


これをガッツリ差し替えてみました。参考にしたのは下記のサイト。

MT4のバーの始値でのみエントリーするプログラム法 : こんなFXの日記

bool isPossibleOrder(int MarketTrend, double StopLossPrice, double ExitPrice) {

(略)

    //--- 前提条件の確認(その1)

    // バーの始値での取引かを判定

    static int BarBefore = 0;

    int BarNow = Bars;

    if( (BarNow - BarBefore) != 1) {

        BarBefore = BarNow;

        return(false);

    }

    BarBefore = BarNow;



    //--- 前提条件の確認(その2)

    if (MarketTrend <= 0)   return(false); // 市場トレンドが明確なこと

(略)

ソースコード上は少し長くなりましたが、Volume配列よりも、Barsの値を信用することにしました。
※ちなみに、以前のPrintデバッグの方法でBarsの値を集計してみると、Barsの値は揃っていて信用できそうです。


修正後の結果はこちら!

ズレ02


んーーーー、なんだかズレが一定な気がします。。。。。あ!


スプレッドのことをすっかり忘れてた!!


というわけで、注文時点の 始値、約定価格(Ask/Bid)、スプレッド の3つを表示してみます。
下記のソースコードを注文の箇所に追記してバックテストをしてみます。

買い注文の場合
Print(Hour(),":",Minute(),":",Seconds()," OrderSend/BUY Ask=",Ask," Open=",Open[0]," Spread=",MarketInfo(Symbol(),MODE_SPREAD));

売り注文の場合
Print(Hour(),":",Minute(),":",Seconds()," OrderSend/BUY Bid=",Bid," Open=",Open[0]," Spread=",MarketInfo(Symbol(),MODE_SPREAD));


そうすると...

ズレ03


たしかに、Ask と 約定価格がぴったり一致
加えて、約定価格=Ask=Open - Spread ということでピッタリ数が合いました。
これでズレの原因がはっきりしましたね!

このズレは「正しいズレ」であって、修正する必要の無いズレ ですね。
ただ、このズレ=スプレッドは考慮できていませんでしたから、そこを考慮して修正しないといけませんね。

課題追加: スプレッドを考慮した指値&逆指値