PR

【機械学習】AIを取り入れた新しいトレード方法

MQL5記事

金融市場でAIと機械学習が注目される中、MQL5を使う人にとって便利なツールが登場しました。それが、ONNX(Open Neural Network Exchange)です。ONNXを使うと、高度なAIモデルをMQL5で簡単に使えるようになります。

この記事では、ONNXとMQL5の組み合わせについて以下の点を説明します:

  • ONNXの基本的な考え方と主な部品
  • PythonでモデルをONNX形式に変換し、MQL5で使う方法
  • MQL5でONNXを使うことの良い点
  • 実際に使うための手順とコツ

AIを使った取引の仕組みに興味がある人、市場でより良い結果を出したい人にとって、ONNXは役立つツールになるでしょう。この記事を読んで、新しい取引の技術を学び、あなたの取引方法を改善しましょう。

WAN
WAN

MT5というトレードに最適なプラットフォームでAIが使えるようになって

MQL5は大きく発展しましたね!

はじめに

AIと機械学習の時代

AIと機械学習は今、社会の様々な分野、特に金融市場で広く使われるようになっています。これらの技術は、市場を分析したり取引の方法を改善したりするのに役立っています。

複雑なAIモデルを使うのは難しいと思われてきましたが、最近は誰でも比較的簡単にAIモデルを作って使えるようになりました。これは、無料で使えるツールが増えたり、インターネット上のサービスが充実したりしたからです。

そのおかげで、多くの人がAIの良いところを取り入れられるようになってきています。

ONNXとは

ONNXは、機械学習や深層学習のモデルを表現するための形式です。この形式を使うと、異なるAIのツール間でモデルを共有したり、様々な環境でモデルを使ったりすることが簡単になります。

ONNXの主な特徴は以下の通りです:

  • 互換性:TensorFlow、PyTorch、scikit-learnなど、異なるAIのツール間でモデルを変換して共有できます。
  • 柔軟性:単純なニューラルネットワークから複雑なものまで、幅広い種類のAIモデルを扱えます。
  • 効率性:ONNXモデルは、様々な機器や環境で効率よく動作するように調整できます。
  • 豊富なツール:ONNXは多くのソフトウェアで使えるようになっており、モデルの変換、改善、実行のための道具がたくさん用意されています。

MQL5を使う人にとって、ONNXはとても便利なツールです。PythonなどのよくAIで使われる言語でモデルを作るのは比較的簡単ですが、MQL5で同じことをするのは難しいです。ONNXを使えば、Pythonなどで作ったAIモデルをMQL5で使えるようになります。

つまり、MQL5を使う人も、高度なAIを自分の取引の仕組みに取り入れられるようになるのです。

WAN
WAN

PythonでAIを作るのは簡単!

さくっと覚えちゃおう!

ONNXの基本的な考え方

ONNXモデルとは

ONNXモデルは、機械学習モデルを表現したものです。これは基本的に、計算の手順を表す図のようなものです。この図では、丸(ノード)が計算を表し、線がデータの流れを表します。このような表現方法を使うことで、モデルの構造と動きを明確に定義し、異なる環境でも同じように解釈できるようになります。

ONNXモデルの主な特徴:

  • 環境に依存しない:ONNXモデルは、特定のAIのツールや機器に縛られない形式で保存されます。
  • 読みやすさ:ONNXモデルは人間が読める形式で保存され、必要に応じて手動で確認や修正ができます。
  • 拡張性:新しい計算方法やデータの種類を追加することで、ONNXの形式を拡張できます。
  • バージョン管理:ONNXは厳密にバージョン管理されており、古いバージョンとの互換性を保ちながら新しい機能を追加しています。

ノード、テンソル、演算子の解説

ノード

ノードはONNXの図の中の基本的な計算の単位です。各ノードは特定の計算を表し、1つ以上の入力を受け取り、0個以上の出力を生み出します。ノードの例としては、畳み込み層、活性化関数、プーリング層などがあります。

ノードの主な特徴:

  • 固有の名前を持つ
  • 特定の計算の種類(例:Conv、ReLU、MaxPool)を持つ
  • 入力と出力のテンソルを指定する
  • 必要に応じて追加の情報を持つ(例:フィルターの大きさ、ステップ幅)
WAN
WAN

ノードは人間でいう脳細胞の一つになるよ

テンソル

テンソルは、ONNXモデル内でデータを表現する多次元の配列です。これらは、ノード間を流れる入力、出力、または中間のデータを表します。

テンソルの主な特性:

  • 次元:テンソルの形を定義(例:[バッチの大きさ, チャンネル, 高さ, 幅])
  • データの種類:テンソル内のデータの型(例:float32, int64)
  • 名前:テンソルを識別するための一意の文字列
WAN
WAN

テンソルは人間でいう五感から得る情報かな?

演算子

演算子は、ONNXのテンソルに適用される関数です。各演算子は、行列の掛け算や要素ごとの足し算などの特定の計算を表します。

ONNXの主な演算子の種類:

  • 計算の演算子:Add, Sub, Mul, Div など
  • 論理の演算子:And, Or, Not など
  • 比較の演算子:Equal, Greater, Less など
  • ニューラルネットワーク特有の演算子:Conv, Pool, BatchNormalization など
  • 活性化関数:ReLU, Sigmoid, Tanh など
  • データを縮める演算子:ReduceSum, ReduceMean など
  • テンソルを操作する演算子:Reshape, Transpose, Concat など

これらの基本的な要素を組み合わせることで、ONNXは複雑な機械学習モデルを表現し、異なる環境間で共有することができます。MQL5を使う人にとって、これらの考え方を理解することは、ONNXモデルをMQL5で効果的に使い、高度な機械学習の機能を取引の仕組みに組み込む上で重要です。

WAN
WAN

視覚、聴覚、嗅覚、味覚、触角それぞれ学習方法は違うよね

嗅覚の情報なのに、視覚的な学習方法を選択しても意味がないように

情報によって適切な演算子、学習方法があるんだよ

PythonでモデルをONNX形式に変換し、MQL5で使う方法

データ収集

データを集めることは、機械学習モデルを作る上で最も大切な段階の一つです。MQL5でデータを集める場合、通常はMT5(またはMT4)を通じて行います。以下に、MQL5でデータを集める方法の概要を示します:

  1. 時系列データを取得する: MQL5では、CopyRates()という関数を使って、価格の始値、高値、安値、終値(OHLC)データを取得します。
  2. 指標のデータを集める: テクニカル指標の値も重要なデータの源になります。CopyBuffer()という関数を使って指標の値を取得できます。
  3. 経済指標のデータ: SymbolInfoDouble()やSymbolInfoInteger()という関数を使って、スプレッドやスワップなどの経済指標データを取得できます。
  4. データの正規化: 集めたデータは、機械学習モデルに適した形に整える必要があります。これには、スケーリングや標準化などの方法が含まれます。
matrixf GetLiveData(uint start, uint total)
 {
   matrixf return_matrix(total, 3);
   
   
    OPEN.CopyRates(Symbol(), PERIOD_CURRENT,COPY_RATES_OPEN, start, total);
    HIGH.CopyRates(Symbol(), PERIOD_CURRENT,COPY_RATES_HIGH, start, total);
    LOW.CopyRates(Symbol(), PERIOD_CURRENT,COPY_RATES_LOW, start, total);
        
    return_matrix.Col(OPEN, 0);
    return_matrix.Col(HIGH, 1);
    return_matrix.Col(LOW, 2);
          
      
   return return_matrix;
 }

WAN
WAN

機械学習ではmatrixやvectorという新しい型が存在するよ

簡単に言うとmatrixはエクセルのような行と列の2次元配列

vectorは列だけの1次元配列さ

きちんと理解するにはクラスやメソッドを知ろう

MQL5側のデータ正規化

データを整えることは、機械学習モデルの性能を最大限に引き出すために欠かせない作業です。MQL5でデータを整える方法には以下のようなものがあります:

  1. 最小-最大スケーリング: データを0から1の範囲に収めます。
  2. 標準化: データの平均を0、標準偏差を1にします。
  3. 対数変換: データの分布を正規分布に近づけるために使います。
switch(NORM)
   {
    case  NORM_MEAN_NORM:
      
       //--- saving the mean
       
       norm_params.Assign(norm_x.mean_norm_scaler.mean);
       WriteCsv(normparams_folder+csv_name_+".mean_norm_scaler.mean.csv",norm_params,x_vars);
       
       //--- saving the min
       
       norm_params.Assign(norm_x.mean_norm_scaler.min);
       WriteCsv(normparams_folder+csv_name_+".mean_norm_scaler.min.csv",norm_params,x_vars);
       
       //--- saving the max
       
       norm_params.Assign(norm_x.mean_norm_scaler.max);
       WriteCsv(normparams_folder+csv_name_+".mean_norm_scaler.max.csv",norm_params,x_vars);
           
      break;
      
    // ... (他のケースは省略)
   }

正規化されたデータは、CSVファイルなどの形式で保存し、Python環境で使用できるようにします。

WAN
WAN

本記事のようにMQL5で正規化してCSVにしてもいいけど、PythonでCSVを

読み込んでから前処理として正規化してもいいよ

やりやすい方法で大丈夫!

Pythonでのモデル構築

Pythonでの機械学習モデル構築は、通常以下のステップで行います:

  1. 必要なライブラリのインポート
  2. データの読み込みと前処理
  3. モデルの定義
  4. モデルのコンパイルと訓練
# 多層パーセプトロンニューラルネットワーク(MLP)の構築
class NeuralNetworkClass():
    def __init__(self, csv_name, target_column, batch_size=32):
        # データの読み込みと前処理
        self.data = pd.read_csv(dataset_path+"\\"+csv_name)
        if self.data.empty:
            print(f"No such dataset or Empty dataset csv = {csv_name}")
            quit()
        
        print(self.data.head())
        
        self.target_column = target_column
        X = self.data.drop(columns=self.target_column).to_numpy()
        Y = self.data[self.target_column].to_numpy()
        
        self.train_x, self.test_x, self.train_y, self.test_y = train_test_split(X, Y, test_size=0.3, random_state=42)
        
        print(f"train x shape {self.train_x.shape}\ntest x shape {self.test_x.shape}")
        
        self.input_size = self.train_x.shape[-1]
        self.output_size = 1
        self.batch_size = batch_size
        self.model = None
        
        self.plots_directory = "Plots"
        self.models_directory = "Models"

    def BuildNeuralNetwork(self, activation_function='relu', neurons = 10):
        self.model = keras.Sequential([
            keras.layers.Input(shape=(self.input_size,)),
            keras.layers.Dense(units=neurons, activation=activation_function, activity_regularizer=l2(0.01), kernel_initializer="he_uniform"),
            keras.layers.Dense(units=self.output_size, activation='linear', activity_regularizer=l2(0.01), kernel_initializer="he_uniform")  
        ])
        self.model.summary()

    # ... (train_network と test_network メソッドは省略)

ONNXモデルの保存

訓練されたモデルをONNX形式で保存するには、tf2onnxライブラリを使用します。

def saveONNXModel(self, folder="ONNX Models"):
    
    path = data_path + "\\MQL5\\Files\\" + folder 
    
    if not os.path.exists(path): # create this path if it doesn't exist
        os.makedirs(path)
    
    onnx_model_name = f"MLP.REG.{self.target_column}.{self.data.shape[0]}.onnx"
    path +=  "\\" + onnx_model_name
    
    
    loaded_keras_model = load_model(f"Models\\MLP.REG.{self.target_column}.{self.data.shape[0]}.h5") 
    
    onnx_model, _ = tf2onnx.convert.from_keras(loaded_keras_model, output_path=path)

    onnx.save(onnx_model, path )
    
    print(f'Saved model to {path}')
WAN
WAN

出力されたONNXの再学習はできないので、追加で学習する必要がある場合は

学習ライブラリ独自の保存形式でチェックポイントとして保存するのもあり!

MQL5でのONNXモデル取得

MQL5でONNXモデルを使用するには、まずモデルをMQL5環境にインポートする必要があります。これは通常、以下のように行います:

  1. ONNXモデルファイルをMetaTrader 5のデータフォルダに配置します。
  2. MQL5コード内でモデルをリソースとして宣言します。
  3. ONNXハンドルを作成します。
#resource "\\Files\\ONNX Models\\MLP.REG.CLOSE.10000.onnx" as uchar RNNModel[]

long mlp_onnxhandle;

#include <MALE5\preprocessing.mqh>
CPreprocessing<vectorf, matrixf> *norm_x;

int inputs[], outputs[];

vectorf OPEN,
       HIGH, 
       LOW;
       
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
  if (!LoadNormParams()) //Load the normalization parameters we saved once
    {
      Print("Normalization parameters csv files couldn't be found \nEnsure you are collecting data and Normalizing them using [ONNX get data.ex5] Script \nTrain the Python model again if necessary");
      return INIT_FAILED;
    }
   
//--- ONNX SETTINGS
 
  mlp_onnxhandle = OnnxCreateFromBuffer(RNNModel, MQLInfoInteger(MQL_DEBUG) ? ONNX_DEBUG_LOGS : ONNX_DEFAULT); //creating onnx handle buffer | rUN DEGUG MODE during debug mode
  
  if (mlp_onnxhandle == INVALID_HANDLE)
    {
       Print("OnnxCreateFromBuffer Error = ",GetLastError());
       return INIT_FAILED;
    }

//--- since not all sizes defined in the input tensor we must set them explicitly
//--- first index - batch size, second index - series size, third index - number of series (only Close)
   
   OnnxTypeInfo type_info; //Getting onnx information for Reference In case you forgot what the loaded ONNX is all about

   long input_count=OnnxGetInputCount(mlp_onnxhandle);
   Print("model has ",input_count," input(s)");
   for(long i=0; i<input_count; i++)
     {
      string input_name=OnnxGetInputName(mlp_onnxhandle,i);
      Print(i," input name is ",input_name);
      if(OnnxGetInputTypeInfo(mlp_onnxhandle,i,type_info))
        {
          PrintTypeInfo(i,"input",type_info);
          ArrayCopy(inputs, type_info.tensor.dimensions);
        }
     }

   long output_count=OnnxGetOutputCount(mlp_onnxhandle);
   Print("model has ",output_count," output(s)");
   for(long i=0; i<output_count; i++)
     {
      string output_name=OnnxGetOutputName(mlp_onnxhandle,i);
      Print(i," output name is ",output_name);
      if(OnnxGetOutputTypeInfo(mlp_onnxhandle,i,type_info))
       {
         PrintTypeInfo(i,"output",type_info);
         ArrayCopy(outputs, type_info.tensor.dimensions);
       }
     }
   
//---

   if (MQLInfoInteger(MQL_DEBUG))
    {
      Print("Inputs & Outputs");
      ArrayPrint(inputs);
      ArrayPrint(outputs);
    }
   
   const long input_shape[] = {batch_size, 3};
   
   if (!OnnxSetInputShape(mlp_onnxhandle, 0, input_shape)) //Giving the Onnx handle the input shape
     {
       printf("Failed to set the input shape Err=%d",GetLastError());
       return INIT_FAILED;
     }
   
   const long output_shape[] = {batch_size, 1};
   
   if (!OnnxSetOutputShape(mlp_onnxhandle, 0, output_shape)) //giving the onnx handle the output shape
     {
       printf("Failed to set the input shape Err=%d",GetLastError());
       return INIT_FAILED;
     }
   
//---

   return(INIT_SUCCEEDED);
  }

モデルのリアルタイム実行

ONNXモデルをMQL5で実行するには、入力データを準備し、OnnxRun関数を使用して予測を行います。

void OnTick()
  {
   matrixf input_data = GetLiveData(0,1);
   vectorf output_data(1);
   
   
   if (!OnnxRun(mlp_onnxhandle, ONNX_NO_CONVERSION, input_data, output_data))
     {
       Print("Failed to Get the Predictions Err=",GetLastError());
       ExpertRemove();
       return;
     }
   
   Comment("inputs_data\n",input_data,"\npredictions\n",output_data);
}

この方法を使えば、Pythonで作った機械学習モデルをMQL5の環境で効果的に活用できます。取引を行う人は高度なAIモデルの力を自動取引の仕組みに組み込むことができ、より洗練された取引方法を実現できます。

MQL5でONNXを使用する利点

相互運用性と柔軟性

ONNXの最大の利点の1つは、異なる機械学習のツール間で互換性があることです。これにより、MQL5を使う人は、TensorFlow、PyTorch、scikit-learnなどの強力なPythonのライブラリで作られたモデルを直接使うことができます。この互換性は、以下の点で大きな利点をもたらします:

  1. 様々なモデルを使える:深層学習、機械学習、統計モデルなど、様々な種類のモデルをMQL5で使えます。
  2. 専門家の知識を活かせる:データの専門家やAIの専門家が他の言語で開発したモデルを、MQL5を使う人が直接利用できます。
  3. 開発時間を短縮できる:既にあるモデルを再利用することで、新しいモデルを一から作る必要がなくなり、開発時間を大幅に短縮できます。
  4. 継続的に改善できる:Pythonなどで開発されたモデルを継続的に改善し、その最新版を簡単にMQL5で使えます。

柔軟性の面では、ONNXは様々な種類の機械学習モデルを扱えます。これには、単純な線形回帰から複雑な深層学習まで含まれます。この柔軟性により、取引を行う人は市場の状況や取引の方法に最適なモデルを選んで使うことができます。

効率とコミュニティサポート

ONNXモデルは、効率的に動作するように最適化されています。これは、リアルタイムの取引環境では特に重要です。ONNXのプログラムは、モデルの計算を高速化し、コンピューターのリソースの使用を最小限に抑えるように設計されています。これにより、MQL5を使う人は、複雑なAIモデルを使いながらも、取引の仕組みの反応の速さを保つことができます。

効率性の主な利点:

  • 反応が速い:最適化されたONNXのプログラムにより、高速な予測ができます。
  • リソースを効率的に使う:ONNXモデルは、メモリと計算能力を効率的に使うように最適化されています。
  • 規模に応じて調整できる:小さなモデルから大きな深層学習モデルまで、様々な規模のモデルを効率的に動かせます。
  • 機器に合わせて最適化:ONNXのプログラムは、CPUやGPUなど、様々な機器に対して最適化されています。

コミュニティのサポートの面では、ONNXは大きくて活発なコミュニティに支えられています。これにより、以下のような利点があります:

  • 豊富な情報源:ONNXの使い方、良い使い方、問題解決の方法に関する多くの情報が利用できます。
  • 継続的な改善:コミュニティからの意見により、ONNXは常に進化し、新しい機能や改善が加えられています。
  • 幅広いツールのサポート:多くの機械学習のツールやフレームワークがONNXを使えるようになっており、関連するツールが豊富にあります。
  • 問題解決が速い:コミュニティの掲示板や質問サイトを通じて、問題解決のサポートを受けられます。

異なる環境での互換性

ONNXの重要な特徴の一つは、異なる環境でも使えることです。これは、MQL5を使う人にとって特に重要な利点をもたらします:

  • 開発環境の自由度:モデルの開発をPythonなどの環境で行い、実行をMQL5環境で行うことができます。
  • 異なる取引ソフトへの移植性:ONNXモデルは、MetaTrader 5以外の取引ソフトでも使える可能性があります。
  • テストと実際の取引での一貫性:同じONNXモデルをテスト環境と実際の取引環境の両方で使えるため、結果の一貫性が高まります。
  • クラウドでの使用が簡単:ONNXモデルは、クラウド環境にも簡単に導入でき、大規模な取引システムの構築が可能になります。
  • 異なる機器での実行:デスクトップパソコン、ノートパソコン、さらにはスマートフォンなど、様々な機器でONNXモデルを動かせます。
WAN
WAN

ONNXが無かったらMQL言語の限られたライブラリで、かつCPUで学習しないといけないから

スキル的にも時間的にも非常に厳しくなる。

かといってPythonに予測をさせているとバックテストが遅くなる。

これを解決できたONNXは画期的!

まとめ

ONNXの利点

ONNXは、MQL5を使う人が高度な機械学習モデルを取引の方法に取り入れるための強力なツールです。その主な利点をまとめると:

  • 互換性:異なる機械学習のツールで作られたモデルをMQL5で使えます。
  • 柔軟性:様々な種類と複雑さのモデルを扱えます。
  • 効率性:最適化されたプログラムにより、速くて効率の良い実行が可能です。
  • コミュニティのサポート:活発なコミュニティによる継続的な改善と支援があります。
  • 異なる環境での互換性:開発、テスト、実際の使用の柔軟性が高まります。

ONNXの重要性と将来性

将来的には、ONNXの重要性はさらに増すと予想されます:

  • AIモデルの進化:より複雑で高度なAIモデルが開発されるにつれ、ONNXのような共通の形式の需要が高まります。
  • リアルタイム取引の高度化:市場がより複雑になる中、高度なAIモデルをリアルタイムで活用する必要性が高まります。
  • 規則への対応:金融業界の規則が厳しくなる中、モデルの透明性と説明のしやすさが求められ、ONNXのような共通の形式が重要になります。
  • 機器での計算:取引の反応速度を上げるために、個々の機器でAIモデルを動かすことが重要になり、ONNXの軽さと効率の良さが注目されます。
  • クラウドとの連携:クラウドを使った取引システムとの連携が進み、ONNXの異なる環境での使いやすさがより重要になります。

ONNXは、MQL5を使う人がより高度で効果的な自動取引システムを作るための重要なツールとなります。その互換性、効率性、柔軟性により、取引を行う人は最新のAI技術を活用し、市場での競争力を高めることができます。ONNXの使い方を学ぶことで、MQL5を使う人は自動取引の新しい可能性を探り、より洗練された取引方法を実現できるでしょう。

オンラインコミュニティ

こちらのコミュニティで、AIや機械学習をトレードに活かすために日々探求しています。
興味のある方は覗いてみてください。

参考記事

ONNXをマスターする:MQL5トレーダーにとってのゲームチェンジャー
機械学習モデルを交換するための強力なオープン標準形式であるONNXの世界に飛び込んでみましょう。ONNXを活用することでMQL5のアルゴリズム取引にどのような変革がもたらされ、トレーダーが最先端のAIモデルをシームレスに統合し、戦略を新たな...
タイトルとURLをコピーしました