【AI投資システム構築】7.MT4/MT5と学習モデルの連携システム構成

:::note info
:coffee: **CoffeeBreak**
開始早々コーヒーブレイク。
昨今のアメリカの相互関税で市場は大荒れ模様ですが、私のAI予測＋ファンダメンタル分析はコツコツと利益を出しています。
逆にビビりすぎて、相互関税発動前に予測を無視して早々に利確をしてしまい、大変大きな機会損失が発生しました。もったいない…。
:::

# MT4/MT5 + 他アプリ連動のシステム構築

MT4/MT5は個人向けのFXの自動トレードツールですが、
MT4/MT5だけではAI連動など複雑なアプリは作れません。

::: note info
:coffee::coffee: **CoffeeBreak**
またまたコーヒーブレイク。昔はなかった（はず）ですが、
最近のMT4/MT5では、Pythonと連動できるようになったようです。
興味ある方は、"Python-EA"でWeb検索してみてください。
勉強不足ですいません。
私がこれから記載する内容は、Pythonだけではなく、BatファイルやWindowsアプリと連動させる方法です。
少し古い内容かもしれませんが、汎用的な内容となります。
:::

MT4/MT5 は常駐アプリのようなものです。
一定時間毎、もしくは通貨の変動がある度（Tick情報が更新される度）に、特定の処理を実行する常駐アプリです。
エキスパートアドバイザー(EA)のプログラムを任意の時間軸に設定することで稼働します。

詳しくは下記サイト等をご参照ください。

https://www.mql5.com/ja

プログラム上では、下記のいずれかのコールバック関数内に処理を記述します。

~~~C:
void OnTick(void)
{
    // EAを取り付けた通貨の変動がある度（Tick情報が更新される度）に実行する処理を記載
}

void OnTimer(void)
{
    // 一定の時間間隔で実行する処理を記載
}
~~~
通常のEAでテクニカルチャート分析によるトレードを行うと下記のようなフローになると思います。

1. テクニカルチャートの値を取得
1. テクニカルチャート分析を実施
1. 分析結果より、トレード実施

このフローに、学習モデルによる予測の処理(Pythonによる学習モデル呼び出しと実行の処理）を組み込みます。
簡単に言うと、インプットとアウトプットをCSVファイルにして、
Pythonを実行するバッチファイルを起動するだけです。
フローチャートに表すとこんな感じです。

![フローチャート.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992567/0b1c46fc-301a-4579-b35b-f575dfd0ce7a.png)

MT4/MT5側の(EA側の)処理フローは下記のようになります。

1. テクニカルチャートの値を取得
1. 取得した値をCSVファイル出力
1. 予測バッチ処理を実行する
1. 待機(終了ファイル検索)
1. 終了ファイル削除
1. 予測結果CSVファイル読み込み
1. 予測に基づいてトレード実行
1. 予測結果CSVファイル削除

上記2.～4.までのサンプルプログラムはこんな感じです。

~~~c:他バッチ処理実行
#import "shell32.dll"
int ShellExecuteW(int handle, string IpOperation, string IpFile, string IpParameters, string IpDirectory, int nShowCmd);
#import
void OnTick(void)
{
    string input_filename = "Inputs\\input.csv";  // 入力ファイル名
    string finish_filename = "Outputs\\finish.csv";  // 終了ファイル名
    string output_filename = "Outputs\\output.csv";  // 出力ファイル名

    // 入力ファイルオープン
    int input_file = FileOpen(input_filename, FILE_CSV|FILE_WRITE, ",");

    // 予測用パラメータ出力
    FileWrite(input_file, "任意のパラメータ");

    // 入力ファイルクローズ
    FileClose(input_file);

    // 引数設定
    string setParams = "h1 h2 h3"; // 引数が複数ある場合は半角スペースで分ける
    
    // 予測バッチ（BAT_FILE_PATH）を非同期起動
    if (ShellExecuteW(0, "", BAT_FILE_PATH, setParams, "", 0) <= 32) {
        Print("Error:バッチの起動に失敗しました。");
        return -1;
    }

    // 待機(終了ファイル検索)
    while(1)
    {
        if (FileIsExist(finish_filename) == true)
        {
            break;
        }
        // 500msサイクル
        Sleep(500);
    }
}
~~~

Pythonバッチ側の処理フローは下記のとおりです
1. テクニカルチャートCSVファイル読み込み
（MT4/MT5側でデータの標準化を行っていない場合は、ここで行う）
1. 学習モデル読み込み（複数ある場合はすべて）
1. 予測実行（複数ある場合はすべて実行し、平均をとる）
1. 予測結果CSVファイル出力
1. 処理終了フラグファイル出力

上記2.～3.までのサンプルプログラムはこんな感じです。

~~~python:予測処理実行
    models = []
    for try_cnt in range(1,OUTPUT_NUM+1):
        # 予測モデル読み込み
        model = tf.keras.models.load_model(f".\\models\\model_try{try_cnt}.h5")
        # 予測モデルのパラメータ読み込み
        model.load_weights(f".\\model\\param_try{try_cnt}.hdf5")
        models.append(model)

    # 予測実行
    preds = []
    for model in models:
        # 予測実行
        pred = model.predict(X)
        preds.append(pred)

    # 予測結果の平均をとる
    preds_array = np.array(preds)
    preds_mean = np.mean(preds_array, axis=0)
~~~

以上です。簡単ですね。
ただし下記２点ご注意ください。

予測を行いたい時刻ピッタリ(例8:00ぴったり)に実行すると、他の通貨ペアが更新されていないのか、
8:00のデータが集まらない可能性があります。
「同じ時刻のデータ」の条件に当てはまらないため、このデータで予測を行うと、
誤った予測になってしまいます。
8:05まで待ってから、8:00の情報を集めるなど、即時性は弱まってしまいますが、少し待ちましょう。

またこれも他通貨を集めた影響なのか、MT4やMT5ツールの性質なのか、FX会社のサーバーの影響なのか（原因は私もよくわかりません）
FX会社によっては、初回の取得は失敗する（時間的な欠損が生じている）場合があります。
同じプログラムでも、いつも成功するFX会社と頻繁に失敗するFX会社があります。
そのため、私は取得が成功するまで（取得した通貨ペアの時刻がすべて合うまで）、トライすることにしています。大抵は2回目で成功します。

# まとめ
MT4/MT5と学習モデルの連携システム構成案について記載しました。
実はこの外部連携方法を用いると、予測バッチのみならず、様々なことが行えます。
月間の結果を自動出力してExcelにまとめてしまうとか、トレード管理アプリと連携するとかですね。

私の場合、通貨毎のトレード判定へ、人によるファンダメンタル分析結果を即時反映させるため、
下記の図のようなWindowsデスクトップアプリをつくり、
ワンクリックでトレードの方向性を変更できるようにしています。
「AIさん、AUDJPYの通貨ペアは"SELL"予測の時だけトレードするようにしてください」のような使い道のツールです。

![ファンダメンタルズツール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3992567/9e9edb3b-0a6a-4df9-af68-f5aedb514ac3.png)

これも上述した外部連携方法を用いています。

上述した連携システムも構築してから数年たっているため、
もしかしたら今はもっと簡単な連携方法があるかもしれません。
古い情報かもしれませんが、少しでも参考にしていただけますと幸いです。

次はシミュレーション方法について（注意点について）投稿するつもりです。
よろしくお願いいたします。