MetaTrader 5ビルド3620:Webターミナルの改善、ONNXサポート、MQL5の高速行列乗算

ONNX(Open Neural Network Exchange)モデルを用いた操作に対応しました。 ONNXは、機械学習モデルのためのオープンソースフォーマットです。

10 3月 2023

ターミナル

  1. 取引レポートの合計利益計算を修正しました。
  2. 気配値表示ウィンドウから利用できる取引商品のファンダメンタルズデータを更新しました。
  3. LinuxシステムのWine7.0.1での取引プラットフォームの起動を修正しました。
  4. 検索バーから板情報に銘柄を追加できるように修正しました。説明で見つけた銘柄を、その行をクリックしてリストに追加することができませんでした。

MQL5

  1. ONNX(Open Neural Network Exchange)モデルを用いた操作に対応しました。

    ONNXは、機械学習モデルのためのオープンソースフォーマットです。このフォーマットは、ChainerCaffee2PyTorchを含む多くのプラットフォームでサポートされています。専用ツールを使ってONNXモデルを作成し、MQL5アプリケーションに統合して、取引の意思決定に利用することができます。

    サポートされるすべての関数は、ドキュメントに記載されています。テスト用ONNXモデルの例は、MetaEditorの公開プロジェクトで確認できます。ツールボックスで[公開プロジェクト]からONNX.Price.Predictionプロジェクトを探し、コンテキストメニューから[参加]を選択します。プロジェクトがコンピューターにダウンロードされ、ナビゲーターに表示されます。


    公開プロジェクトにおけるONNXモデルとの連携例


    プロジェクトをコンパイルし、EURUSDH1で実行し、結果を確認することができます。

    モデルとそれを実行するMQL5コードに加え、プロジェクトにはPricePredictionTraining.pyというPythonスクリプトも含まれています。これは、ONNXモデルを自分で作成する方法を紹介するものです。スクリプトを実行するには、Pythonをコンピュータにインストールして、次のようにコマンドプロンプトから必要なモジュールをインストールしてください。

    python.exe -m pip install --upgrade pip
    python -m pip install --upgrade tensorflow
    python -m pip install --upgrade pandas
    python -m pip install --upgrade scikit-learn
    python -m pip install --upgrade matplotlib
    python -m pip install --upgrade tqdm
    python -m pip install --upgrade metatrader5
    python -m pip install --upgrade onnx==1.12
    python -m pip install --upgrade tf2onnx
    ONNXの使用方法は、ドキュメントに記載されています。

  2. 一般行列乗算(GeMM)のサポートを追加しました。このアルゴリズムは、タスクの並列化とL1/L2/L3キャッシュの最適化された利用により、一部のプロセッサタイプでの計算を高速化します。計算速度は、KernelLibrary(MKL)(英語)やOpenBLASなどの一般的なパッケージと同程度です。詳細な比較テストはまもなく公開されます。

    新しいアルゴリズムは現在、matrix::GeMMメソッドでサポートされています。お使いのプロセッサがAVXおよびFMA(英語)命令をサポートしている場合(2013年以降にリリースされたほとんどのプロセッサがこれらの命令をサポートしています)、アルゴリズムは自動的に有効化されます。

  3. 行列とベクトルをDLLに転送する機能が追加されました。これにより、外部変数から、該当する型を利用する関数をインポートすることができます。

    行列とベクトルは、バッファへのポインタとしてDLLに渡されます。たとえば、float型の行列を渡すには、DLLからエクスポートされた関数の対応するパラメータが、float型のバッファポインタを受け取る必要があります。次は例です。

    MQL5
    #import "mmlib.dll"
    bool sgemm(uint flags,matrix<float> &C,const matrix<float> &A,const matrix<float> &B,ulong M,ulong N,ulong K,float alpha,float beta);
    #import
    C++
    extern "C" __declspec(dllexport) bool sgemm(UINT flags,float *C,const float *A,const float *B,UINT64 M,UINT64 N,UINT64 K,float alpha,float beta)
    バッファに加えて、正しく処理されるために行列とベクトルのサイズを渡す必要があります。

  4. 同期された時系列をMqlRatesから別の配列にコピーするための新しいCopySeries関数を追加しました。

    CopySeries関数を使用すると、1回の呼び出しで必要な時系列のみを別の指定された配列に取得できますが、時系列データはすべて同期されます。これは、特定のインデックスNで結果として得られる配列のすべての値が、指定された銘柄/時間枠のペアの同じバーに属することを意味します。したがって、プログラマーはバーの開始時間までに受信したすべての時系列の同期を確保する必要はありません。

    時系列の完全なセットをMqlRates配列として返すCopyRatesとは異なり、CopySeries関数を使用すると、特定の必要な時系列を個別の配列に取得できます。これは、時系列の種類を選択するためのフラグの組み合わせを指定することで実現できます。関数に渡される配列の順序は、MqlRates構造体のフィールドの順序と一致する必要があります。

    struct MqlRates
      {
       datetime time;         // period beginning time
       double   open;         // open price
       double   high;         // high price for the period
       double   low;          // low price for the period
       double   close;        // close price
       long     tick_volume;  // tick volume
       int      spread;       // spread
       long     real_volume;  // exchange volume
      }

    したがって、現在の銘柄/時間枠の最後の100バーの「time」、「close」、「real_volume」時系列の値を取得する必要がある場合は、次の呼び出しを使用します。

    datetime  time[];
    double    close[];
    long      volume[];
    CopySeries(NULL,0,0,100,COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_VOLUME_REAL,time,close,volume);
    

    time、close、volume配列の順序は、MqlRates構造体内のフィールドの順序と一致する必要があります。rates_maskの値の順序は無視されます。マスクは次のようになります。

    COPY_RATES_VOLUME_REAL|COPY_RATES_TIME|COPY_RATES_CLOSE


    //--- input parameters
    input datetime InpDateFrom=D'2022.01.01 00:00:00';
    input datetime InpDateTo  =D'2023.01.01 00:00:00';
    input uint     InpCount   =20;
    //+------------------------------------------------------------------+
    //| Script program start function                                    |
    //+------------------------------------------------------------------+
    void OnStart(void)
      {
    //--- arrays to get timeseries from the Rates structure
       double   open[];
       double   close[];
       float    closef[];
       datetime time1[], time2[];
    //---request close prices to a double array
       ResetLastError();
       int res1=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
                           COPY_RATES_TIME|COPY_RATES_CLOSE, time1, close);
       PrintFormat("1. CopySeries  returns %d values. Error code=%d", res1, GetLastError());
       ArrayPrint(close);
       
    
    //--- now also request open prices; use float array for close prices
       ResetLastError();
       int res2=CopySeries(NULL, PERIOD_CURRENT, 0, InpCount,
                           COPY_RATES_TIME|COPY_RATES_CLOSE|COPY_RATES_OPEN, time2, open, closef);
       PrintFormat("2. CopySeries  returns %d values. Error code=%d", res2, GetLastError());
       ArrayPrint(closef);
    //--- compare the received data
       if((res1==res2) && (time1[0]==time2[0]))
         {
          Print("  | Time             |    Open      | Close double | Close float |");
          for(int i=0; i<10; i++)
            {
             PrintFormat("%d | %s |   %.5f    |   %.5f    |   %.5f   |",
                         i, TimeToString(time1[i]), open[i], close[i], closef[i]);
            }
         }
    /*  Result
            1. CopySeries  returns 0 values. Error code=0
            [ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
            [10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
            2. CopySeries  returns 0 values. Error code=0
            [ 0] 1.06722 1.06733 1.06653 1.06520 1.06573 1.06649 1.06694 1.06675 1.06684 1.06604
            [10] 1.06514 1.06557 1.06456 1.06481 1.06414 1.06394 1.06364 1.06386 1.06239 1.06247
              | Time             |    Open      | Close double | Close float |
            0 | 2023.03.01 17:00 |   1.06660    |   1.06722    |   1.06722   |
            1 | 2023.03.01 18:00 |   1.06722    |   1.06733    |   1.06733   |
            2 | 2023.03.01 19:00 |   1.06734    |   1.06653    |   1.06653   |
            3 | 2023.03.01 20:00 |   1.06654    |   1.06520    |   1.06520   |
            4 | 2023.03.01 21:00 |   1.06520    |   1.06573    |   1.06573   |
            5 | 2023.03.01 22:00 |   1.06572    |   1.06649    |   1.06649   |
            6 | 2023.03.01 23:00 |   1.06649    |   1.06694    |   1.06694   |
            7 | 2023.03.02 00:00 |   1.06683    |   1.06675    |   1.06675   |
            8 | 2023.03.02 01:00 |   1.06675    |   1.06684    |   1.06684   |
            9 | 2023.03.02 02:00 |   1.06687    |   1.06604    |   1.06604   |
    */
      }
  5. OrderSend関数の動作を修正しました。同じ口座が複数のプラットフォームで同時に使用された場合、関数リクエストは間違った注文チケットを返す可能性がありました。
  6. EX5ライブラリのインポートを修正しました。インポートしたライブラリの名前と、インポート先のファイル名が一致しない場合はエラーとなります。

MetaEditor

  1. 共有プロジェクトメンバーへのプッシュ通知送信を追加しました。新しいオプションでは、プロジェクトの設定とファイルの変更についてユーザーに通知できます。通知を有効にするには、MQL5.communityプロファイルの[設定\セキュリティ]セクションにMetaQuotes IDを入力します。


    プロジェクトの更新をプッシュ通知でお知らせ


  2. ナビゲーターのファイルアイコンを更新しました。新しく、よりシンプルなメタファーで、より理解しやすくなっています。

テスター

  1. |」が含まれている場合に入力文字列パラメータが切り捨てられるエラーを修正しました。

MetaTrader 5 Webターミナルビルド3620

  1. Webターミナルインターフェイス用の既製のカラーテンプレートを追加しました。テンプレートは、チャートのバーと線の表示、気配値表示での価格と口座の資産報告に影響します。当社のデザインチームは、お客様の提案と伝統的な色の組み合わせに基づいて、カラーテンプレートプリセットを用意しました。


    新しいWebターミナルのカラーテンプレート


  2. 銘柄指定ウィンドウを再設計しました。取引商品データは、見やすいように論理ブロックに再編成されています。


    取引商品指定画面の更新


  3. Webターミナルを介したリアル口座の開設を修正しました。登録フォームに記入した後、サーバーがエラーを返すことがありました。
  4. 取引ダイアログのエラーを修正しました。ポジション変更ダイアログが開いているときにツールボックスウィンドウでXボタンを押してポジションを閉じた場合、ダイアログの内容がリセットされていませんでした。更新後、ダイアログは新しい発注モードに自動的にリセットされます。
  5. 口座管理ダイアログのサーバーフィールドの表示を修正しました。
  6. ツールバーの現在の時間枠の表示を修正しました。
  7. 取引ダイアログで、原資産単位での出来高の表示を修正しました。
  8. ストップロスとテイクプロフィットレベルの変更を修正しました。値の1つを変更すると、特定の条件下で2つ目の値がリセットされる可能性がありました。
  9. 投資リスク警告の表示を修正しました。