執行専用EAの作成

執行専用EAはFXシステム(Python)から送られたシグナルに基づいて売買する。

メタエディターの設定

メタエディターを初めて使うときのみ、実行する。

①MT4のメニューバーで「ツール」をクリックする。

②「メタエディター」をクリックする。

メタエディターが起動する。

③メタエディターのメニューバーで「Tools」をクリックする。

④「Options...」をクリックする。

⑤「Options」で「Font」タブをクリックする。

⑥「Font:」で「Takao ゴシック」を選択する。

これは単なる好みである。

⑦「Script」:で「日本語」を選択する。

⑧「OK」ボタンをクリックする。

サンプルプログラムの作成

①メタエディターのツールバーで「New」ボタンをクリックする。

②「MQL Wizard」で「Expert Advisor (template)」が選択されているのを確認する。

③「次へ」ボタンをクリックする。

④「Name:」を「Experts\ExecutionOnly」で上書きする。

⑤「Author:」を消去する。

⑥「Link:」も消去する。

⑦「次へ」ボタンをクリックする。

⑧続けて「次へ」ボタンをクリックする。

⑨「完了」ボタンをクリックする。

⑩メタエディターで以下のプログラムをコピー&ペーストして「ExecutionOnly.mq4」ファイルを上書きする。

// ファイル名は必ず31文字以内にすること。
extern string Filename = "sample_strategy";
extern double Lot = 0.1;
extern int MaxPos = 5;

void OnTick() {
    // 変数を宣言する。
    bool check;
    int file_handle;
    int i;
    int signal;
    int total;
    int pos;
    int ticket;
    string comment = Filename;

    // シグナルをファイルから確認する。
    file_handle = FileOpen(Filename + ".csv", FILE_READ | FILE_CSV);
    if (file_handle != INVALID_HANDLE) {
        // シグナルには2が加えられているので2を減じて元に戻す。
        signal = FileReadNumber(file_handle) - 2;
        FileClose(file_handle);
    }

    // ポジション総数(このEA以外のものも含む)を確認する。
    total = OrdersTotal();

    // このEAのポジションを確認する。
    pos = 0;
    for (i = 0; i < OrdersTotal(); i++) {
        if (OrderSelect(i, SELECT_BY_POS) == TRUE) {
            if (OrderComment() == comment) {
                if (OrderType() == OP_BUY) {
                    pos = 1;
                }
                else if (OrderType() == OP_SELL) {
                    pos = -1;
                }
            }
        }
    }

    // ポジション総数が最大ポジション数以下である前提で、
    // ポジションが「なし」、かつ、
    if (total <= MaxPos && pos == 0) {
        RefreshRates();
        // シグナルが「買い」なら、新規買い注文を送信する。
        if (signal == 1) {
            ticket = OrderSend(Symbol(), OP_BUY, Lot, Ask, 3, 0, 0, comment);
        }
        // シグナルが「売り」なら、新規売り注文を送信する
        else if (signal == -1) {
            ticket = OrderSend(Symbol(), OP_SELL, Lot, Bid, 3, 0, 0, comment);
        }
    }
    // ポジションが「買い」、かつ、シグナルが「なし」、または「売り」なら、
    // 決済売り注文を送信する。
    else if (pos == 1 && (signal == 0 || signal == -1)) {
        for (i = OrdersTotal() - 1; i >= 0; i--) {
            if(OrderSelect(i, SELECT_BY_POS) == TRUE) {
                if (OrderComment() == comment && OrderType() == OP_BUY) {
                    check = OrderClose(OrderTicket(), OrderLots(), Bid, 3);
                }
            }
        }
    }
    // ポジションが「売り」、かつ、シグナルが「なし」、または「買い」なら、
    // 決済買い注文を送信する。
    else if (pos == -1 && (signal == 0 || signal == 1)) {
        for (i = OrdersTotal() - 1; i >= 0; i--) {
            if(OrderSelect(i, SELECT_BY_POS) == TRUE) {
                if (OrderComment() == comment && OrderType() == OP_SELL) {
                    check = OrderClose(OrderTicket(), OrderLots(), Ask, 3);
                }
            }
        }
    }

    // ポジション総数、ポジション、シグナルを出力する。
    Print("total = ", total);
    Print("pos = ", pos);
    Print("signal = ", signal);
}

サンプルプログラムの第1行にcsvファイルの名前を設定する(例として「sample_strategy」としてある)。

警告:csvファイルの名前は半角で必ず31文字以内にする。そうしないとOrderComment()関数に正しく読み込まれない。ファイル名でEAのポジションを識別するようにしているので、正しく読み込まれないと大変なことになる。例えば他のEAのポジションを自分のものと勘違いして決済し、本来の保有者であるEAはポジションが突然決済されてしまったので、再びポジションを持つ。すると、執行専用EAは決済したはずなのにまたポジションが出来てしまったので再び決済する。こうして新規注文、決済注文が繰り返されるが、コンピューターは非常に高速にこれを実行するので、その都度払うスプレッドだけで退場させられるだろう。

⑪ツールバーの「Compile」ボタンをクリックする。

「Toolbox」の「Description」に「0 error(s), 0 warning(s)」と表示されればOK。

空のcsvファイルの作成

シグナルのやり取りはcsvファイルを通じて行う。そこで、あらかじめ空のcsvファイルを作っておく。

上のサンプルプログラムに合わせて、「sample_strategy.csv」ファイルを作成する場合を例とする。また、MT4のインストール先は「~/.wine/drive_c/Program Files (x86)/OANDA - MetaTrader」であるとする。半角スペースのあるフォルダー名は「""」で囲む点に注意。

○端末に以下のコマンドをコピー&ペーストして「Enter」キーを押す。

touch ~/.wine/drive_c/"Program Files (x86)"/"OANDA - MetaTrader"/mql4/Files/sample_strategy.csv
(2017/01/08更新)