English Русский Deutsch
preview
初心者のためのMetaTrader 5とRによるアルゴリズム取引

初心者のためのMetaTrader 5とRによるアルゴリズム取引

MetaTrader 5トレーディング | 25 4月 2024, 10:25
164 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

はじめに

MetaTraderは、取引プラットフォームの分野で最高峰に位置づけられており、世界的に高く評価されています業界最高水準の品質で有名なこのソフトウェアは、無料で提供されており、幅広いユーザーが利用できます。その結果、MetaTraderコミュニティは年々着実に成長しています。このコミュニティは、その歴史上かつてないほど多様化し、さまざまな文化的背景を持ち、さまざまなプログラミング言語の熟練度を持つ個人で構成されています。言及すべきは、MetaQuotes Language 5(プラットフォームの公式言語)と並んで、PythonがMetaTraderプラットフォーム内で完全にサポートされている唯一のプログラミング言語であるという事実です。

MetaQuotesコミュニティは、アカデミアや科学計算のバックグラウンドに関係なく、Rから移行するコミュニティのメンバーを歓迎しています。Pythonの進歩、そしてMetaTrader端末内で唯一完全にサポートされている言語としてPythonが排他的に統合されていることによって、Rに熟達した個人が自分のプログラミングスキルを時代遅れと認識する必要はありません。この記事では、創造性とちょっとした工夫を凝らすことで、RとMetaTrader 5を使用した包括的なアルゴリズム取引アドバイザーを構築することが完全に可能であることを説明することで、陳腐化を示唆する考え方に挑戦します。

筆者の経験に基づくと、この記事で取り上げたパッケージは、MetaTrader 5端末内で個別に使用した場合、不完全な相互作用を示すので、言及しておくべきです。各パッケージには独特の制限があります。ただし、一体となって使用されると、これらのパッケージは互いの欠点を効果的に補い、RとMetaTraderを使用した取引アルゴリズムの開発に役立つ堅牢なフレームワークを形成します。

ご注意ください。

1. オペレーティングシステムの検討

このデモは、Windows 11 OS Build 22621.1848を搭載したWindowsマシンで実施しました。これらの手順は、他のオペレーティングシステムではテストされていません。

2. Rバージョンの互換性

このデモはRバージョン4.3.2を使用しています。同じバージョンのRを使用することが必須です。本プレゼンテーションで取り上げるパッケージの中には、以前のバージョンのR言語をサポートしていないものがあるからです。

3. RStudioとの統合

このデモは、Rコードを書くために設計された、洗練された統合開発環境であるRStudioと統合されています。このデモのコースを通して最適なコーディング体験を得るために、RStudioを活用することをお勧めします。


環境の設定

まずは環境を整えましょう。

初めに、コンピュータにRのバージョン4.3.2があることを確認してください。不明な場合やRをインストールしていない場合は、ステップをお見せします。

Rがインストールされているかどうかを確認するには、デスクトップ上のRアイコンを探してください。インストールされていれば、R端末が表示されているはずです。Rのインストールが必要な場合や古いバージョンをお持ちの場合は、Rの公式リポジトリ(The Comprehensive R Archive Network)からセットアップを入手できます。このリンクは常にRの最新バージョンを表示し、現時点ではバージョン4.3.2です。セットアップファイルをダウンロードしたら、表示される指示に従って、まず言語を選択します。 

Rがインストールできたので、今使用しているバージョンを確認しましょう。R端末を開くと、新しいセッションを開始するたびに、挨拶メッセージの一番上にバージョンが表示されます。より詳細な情報が必要な場合は、端末でいつでも[version]コマンドを使用することができます。

Rバージョンの確認

図1:Rバージョンの確認

次に、RStudioをセットアップしましょう。RStudioがインストールされていない場合は、RStudio Desktop - Positからダウンロードできます。先に説明したRのセットアップ手順と同様に、画面に表示されるプロンプトに従うだけです。

インストールが完了したら、インストールしたRStudioが指すRのバージョンを検証してみましょう。

まず、RStudioを開きます。

次に、[tools]、[global options]の順に選択します。

グローバルオプション

図2:RStudioで実行中のRのバージョンを確認する

そこから、実行しているRのバージョンがわかります。

マシンに2つ以上のバージョンのR(一緒に今インストールしたバージョン4.3.2と、以前からあったバージョン)がインストールされている場合、[change]をクリックします。

オプションメニュー

図3:RStudioで実行中のRのバージョンを確認する

そこから、[choose a specific version of R]を選択し、バージョン4.3.2を選択して[OK]をクリックし、変更を有効にするためにRStudioを再起動します。 

Rのバージョンを選択

図4:異なるバージョンのRを選択する

RStudioを再起動したら、いくつかの依存関係をインストールする必要があります。 

#Algorithmic Trading With RStudio And MetaTrader 5
#Gamuchirai Zororo Ndawana
#This script will help you get your environment setup and test that everything is working fine
#Sunday 17 December 2023

#Installing Dependencies
install.packages("stringi")             #This package is a dependency for devtools
install.packages("devtools")            #We will use this package to install R packages hosted on github
install.packages("xts")                 #We will use this package to plot data fetched from the MetaTrader 5 Terminal
install.packages("quantmod")            #We will use this package to plot data fetched from the MetaTrader 5 Terminal
install.packages("ttr")                 #We will use this package to calculate technical indicator values 
install.packages("reticulate")          #We will use this package to call Python libraries in R 
devtools::install_github("Kinzel/mt5R") #We will use this open source package to interact with the MetaTrader 5 Terminal

まずは最初のライブラリ、reticulateをインポートしてみましょう。 このライブラリを使用すると、R内でPythonコードを実行することができます。ここでは、reticulateを使用して、仮想環境にMT5Pythonライブラリをインストールします。MT5ライブラリがインストールされると、RStudioセッションとPython仮想環境の間の橋渡しとしてreticulateを使用することができます。この仲介接続により、MetaTrader 5端末にコマンドを送信することができ、取引の実行が容易になります。

まず、reticulateライブラリを読み込みます。

#Libraries
#Importing reticulate
library(reticulate)
次に、reticulateライブラリ内のvirtualenv_create()関数を使用して仮想環境を作成します。この関数は、仮想環境の名前を表す文字列パラメータを受け取ります。プログラミングにおいて、仮想環境は個々のプロジェクトのために孤立した自己完結型の空間を構築する方法を提供します。仮想環境を採用する基本的な理由は、依存関係を効果的に管理し、コンフリクトを緩和し、プロジェクトの再現性を維持することです。これは、複数のプロジェクトやパッケージが共通の依存関係を持ちながら、同じ依存関係の異なるバージョンを必要とする場合に、特に重要になります。 
#Create a virtual environment
virtualenv_create("rstudio-metatrader5")

仮想環境が構築されたら、次のステップはそれを活性化して活用することです。これはreticulateライブラリ内のuse_virtualenv()関数を使用することで実現できます。仮想環境をアクティブにすることで、その後のPython操作はこの環境の分離されたコンテキスト内で実行されるようになり、プロジェクト固有の依存関係や設定を管理できるようになります。 

#Use the virtual environemnt 
use_virtualenv("rstudio-metatrader5")

reticulateライブラリ内のpy_install()関数を使用して、MetaTrader 5 Pythonライブラリをインストールします。この関数に、インストールするライブラリの名前を提供します。この例では、MetaTrader 5です。

#Install metatrader5 python library
py_install("MetaTrader5")

ライブラリをインストールした後、MetaTrader 5ライブラリをインポートし、MT5という変数に格納します。これは、reticulateライブラリのimport()関数を使うことで実現できます。変数MT5は、以降のステップでMetaTrader 5ライブラリとやり取りするためのインターフェイスとして機能します。

#Import MetaTrader 5
MT5 <- import("MetaTrader5")

先に進む前に、MetaTrader 5端末が現在実行されていないことを確認してください。実行中の場合は、終了してください。

それでは、RStudioセッションからMetaTrader 5端末を直接起動してみましょう。これは、MetaTrader 5 Pythonライブラリからinitialize関数を呼び出すことで実現できます。初期化に成功すると、関数はTRUEを返し、MetaTrader 5端末が正常に起動したことを示します。

#Initialize the MetaTrader 5 Terminal
MT5$initialize()

[1] TRUE

口座情報、端末の詳細、銘柄の明細にアクセスする機能はありますが、最初の制限事項があります。プログラムで別の口座にログインできないことです。端末の初期化中にアクティブになった口座は、ユーザーが手動で変更しない限り、アクセス可能な唯一の口座となります。MetaTrader 5ライブラリを使用して別の口座にログインするPythonスクリプトを作成し、reticulateを使用してRからそれを実行することは可能ですが、この記事では、読者がMQL5プログラミングの基本的な理解とともにRプログラミングの知識しか持っていないことを前提としています。


続く制限は、 reticulateを使用して過去の価格情報を要求できないことです。この制約は、オブジェクトがRとPythonの間を行き来する際に、reticulateが裏で自動的にデータ型を変換していることに起因しているのかもしれません。その結果、端末に過去の価格データを要求する際に返されるオブジェクトの扱いが難しいようです。そこで、 reticulateの欠点を補うために2つ目のパッケージを利用します。

#Get account information
account_info <- MT5$account_info()

#Print account information
account_info$company
account_info$balance
account_info$name

#Get terminal information
terminal_info <- MT5$terminal_info()

terminal_info$build
terminal_info$company
terminal_info$name

[1]"Deriv.comLimited"

[1]868.51

[1]"Gamuchirai Ndawana"

[1]4094

[1]"MetaQuotes Software Corp."

[1]"MetaTrader 5"

#Requesting price data
price_data <- MT5$copy_rates_from_pos("Boom 1000 Index",MT5$TIMEFRAME_M1,0,10)

Error in py_call_impl(callable, call_args$unnamed, call_args$named) :

SystemError: <built-in function copy_rates_from_pos> returned a result with an exception set

Run `reticulate::py_last_error()` for details.

MT5Rを使用してこれらの問題に対処していきます。その前に、MT5Rが内部でどのように動作しているかを理解しましょう。

MT5Rパッケージは、RStudioとMetaTrader 5端末間にWebSocket接続を確立し、全二重通信チャネルを作成します。全二重システムでは、データは同時に送受信できます。このチャネルを有効にするには、MetaTrader 5端末が特定のポートをリッスンしている必要があります。さらに、同じポートでRStudioセッションと通信する必要があります。幸いなことに、MT5RにはMetaQuotes Language 5で書かれたエキスパートアドバイザー(EA)が搭載されており、私たちのコマンドをリッスンしてくれます。このEAはオープンソースであり、必要に応じて追加機能を組み込む柔軟性を提供します。 さらに、ソースコードが必要であれば、こちらからダウンロードできます。記事にはEAのカスタマイズされたバージョンが添付されています。カスタマイズ版には、トレーリングストップロスやテイクプロフィットを自動的におこなう機能が追加されています。

MT5R

図5:MT5Rの図

EAをダウンロードしたら、他のEAと同じファイルに配置する必要があります。MetaTrader 5端末を開き、[ファイル]、[データフォルダを開く]の順に選択してください。

データフォルダを開く

図6:データフォルダを探す

次に、「.\MQL5\experts\」に移動し、EAをexpertsフォルダに配置します。完了したら、取引したい銘柄を開き、MT5R EAをチャート上に配置します。お使いのコンピュータで、MetaTrader 5がネットワーク操作を使用できるように許可を与えるかどうかを尋ねるプロンプトが表示される場合があります。許可を与えてください。これが完了したら、RStudioに戻り、取引アルゴリズムの構築を続ける準備ができています。 

RStudioを開き、MT5R、xts、quantmodライブラリをインポートします。

#Import the MT5R Library
library(mt5R)
#Import xts to help us plot
library(xts)
#Import quantmod to help us plot
library(quantmod)

次に、MT5RパッケージのPing()関数を使用して、端末への接続が確立されているかどうかを確認します。この関数は、EAと通信できた場合にTRUEを返します。

#Check if our connection is established
MT5.Ping()
#Global variables
MARKET_SYMBOL <- "Volatility 75 Index"

[1] TRUE

MT5Rは、先に説明したログインの問題には対応していませんが、価格データのリクエストの問題には対応しています。

MetaTrader 5端末から価格データを要求するには、MT5RライブラリからGetSymbol関数を呼び出します。この関数に、銘柄名、分単位の時間枠(日足は1440)、そして行数を提供します。データが返され、一番古いデータが一番上に、現在の価格が一番下になります。 

xtsパラメータはtrueに設定しています。これによって、データフレームをRの時系列オブジェクトに変換し、プロットの日付を裏で自動的に形式します。また、テクニカル指標の値をデータフレームに簡単に追加することもできます。

#Request historical price data
price_data <- MT5.GetSymbol(MARKET_SYMBOL, iTF = 1, iRows=5000,xts = TRUE)
quantmodのlineChart()関数を使用して、価格データを簡単にプロットすることができます。

#Plotting a line chart
lineChart(price_data, name = MARKET_SYMBOL)


ラインプロット

図7:RStudioでの価格データのプロット

quantmodのaddIndicator関数を使用して、プロットにテクニカル指標を追加することもできます。たとえば、60期間の相対強度指数をプロットに追加します。 

#We can also add technical indicators to the plot
addRSI(n=60)

テクニカル指標の追加

図8:プロットにテクニカル指標を追加する


データの処理

RSIとAroon指標を追加したときは、それらをプロットに追加しただけでした。テクニカル指標の値をデータフレームに追加するには、quantmodパッケージから指標を呼び出し、計算に必要な対応する列を渡す必要があります。この例では、20周期の単純移動平均、20周期の相対力指標、20周期の平均トゥルーレンジ指標をデータフレームに追加します。

#Add moving average
price_data$SMA_20 <- SMA(price_data$Close,n = 20)
#Add RSI to the dataframe
price_data$RSI_20 <- RSI(price_data$Close,n=20)
#Add ATR to the dataframe
price_data$ATR_20 <- ATR(price_data[,c("High","Low","Close")], n=20)

これが終わったら、欠損値のある行をすべて削除します。

#Drop missing values
price_data <- na.omit(price_data)

次の終値を含む「next close」という機能を追加します。次の終値が終値より大きければ、ターゲットは1になり、そうでなければ0になります。これは、Rのifelse関数を使用しておこないます。

#Next close price
price_data$Next_Close <- lag(price_data$Close,-1)

#Setting up our target
price_data$Target <- ifelse( ( (price_data$Next_Close) > price_data$Close) , 1 , 0)

その後、訓練・テストの分割をおこなう準備が整います。最初の4000行を訓練に使い、残りをテストに使用します。時系列データを扱う場合、データ漏洩(モデルが意図せず未来の情報から学習して過去を予測してしまうこと)を避けるため、ランダムな分割は避けます。その代わり、データの自然な時間順序を維持することを優先します。実際的には、最初の4000行を時系列で選択し、残りの行も同様に選択します。このアプローチは、モデルが過去のデータから学習して将来を予測することを保証し、時系列分析のベストプラクティスを支持します。

#Train test split
train_set <- price_data[1:4000,]
train_y <- price_data[1:4000,c("Target")]

test_set <- price_data[4001:4980,]
test_y <- price_data[4001:4980,c("Target")]

さて、データを訓練セットとテストセットに分けたので、次のステップは選択したモデルを訓練することです。この例では、二次判別分析(QDA)を選択します。QDAは、2つのクラス間の区別を最大化し、より効果的なデータ分類を促進することを目的としています。これは、2つのクラスの平均間の分離を最大化し、各クラス内の平均からの広がりを最小化することによって達成されます。QDAを実装するために、QDAモデルを格納するMASSライブラリを利用します。そこで、MASSライブラリをインポートしてQDAモデルにアクセスし、分析に採用します。

#Fitting models
library(MASS)
#Quadratic Discriminant Analysis
#Using OHLC Data
qda  <- qda(Target ~ Open+High+Low+Close,data = train_set)
qda

以下のように呼び出します。

qda(Target ~ Open + High + Low + Close, data = train_set)

以下は、グループの事前確率です。

      0       1 

0.49925 0.50075 

グループとは

      Open     High      Low    Close

0 365424.6 365677.8 365159.9 365420.5

1 365125.4 365384.0 364866.6 365131.4

混同行列から、モデルが市場の下降よりも上昇を予測していることがわかります。

#Evaluating model performance
#Custom Quadratic Discriminant Analysis
qda_predictionts <- predict(qda,test_set)
qda_predictionts <- qda_predictionts$class

#Confusion matrix
table(qda_predictionts,test_y)

混同行列

図9:混同行列


取引ロジックの実装

取引アルゴリズムの基本的な本質に到達しました。まず不可欠なのは、last_tradeとして指定された変数の確立です。この変数は、直近に開始された取引を監視するという極めて重要な機能を果たすため、重要な意味を持ちます。その重要性は、モデルが市場全体のエクスポージャーを損なう可能性のある不利な市場の動きを予測した場合に、容易にポジションをタイムリーに決済できるようにすることにあります。単純なエンコードシステムを思い出しましょう。1の値は買い(BUY)、0の値は売り(SELL)を意味します。

#Keeping track of the last trade
last_trade <- -1

私たちのアルゴリズムを運用するには、無限ループを開始することが不可欠です。取引ロジックはその中で複雑に入れ子になっています。この永久ループは、タイムアウト関数を組み込むことによって達成され、それによって反復の頻度が調整されます。新しいローソク足の生成に合わせた、同期的な反復サイクルを目指します。Sys.sleep関数を統合することで、取引行動が市場の分刻みの変化のリズムに沿うようになります。

最初のステップは、現在の市場情報を取得することです。

そして、そのデータをモデルに渡し、予測を得ます。

モデルが予測をおこなったら、reticulateと一緒にインストールしたMT5パッケージを使用して、未決ポジションがあるかどうかを確認します。未決ポジションがなければ、市場予測の方向にポジションを建て、last_trade変数を更新します。

未決ポジションがある場合は、モデルがそのポジションに対して敵対的な動きを予測しているかどうかを確認し、予測していればポジションを閉じます。

そして最後に、タイムアウトを追加して、アルゴリズムが1バーに1回ポジションを確認するようにする必要があります。

while(TRUE){
  #Fetching current market data
  print("Fetching market information")
  data <- MT5.GetSymbol(MARKET_SYMBOL,iTF=1, iRows = 2)
  data <- data[1,]
  
  #Forecasting market move
  qda_forecast <- predict(qda,data)
  qda_forecast <- qda_forecast$class
  print("Model forecast: ")
  print(qda_forecast)
  #Checking if we have no open positions
  current_positions <- MT5$positions_total()
  
  #If we have no open positions, open a position following the model forecast
  if(current_positions == 0){
    print("We have no open positions. Opening a new position")
    
    #A Forecast of 1 means buy
    if(qda_forecast == 1){
      print("Opening Buy Position")
      MT5$Buy(MARKET_SYMBOL,symbol_info$volume_min)
      last_trade <- 1
    }
    #A Forecast of 0 means sell
    if (qda_forecast == 0){
      print("Opening Sell Position")
      MT5$Sell(MARKET_SYMBOL,symbol_info$volume_min)
      last_trade <- 0
    }
  }
  
  else{
      #Are we anticipating a move against our open position?
      if(last_trade != qda_forecast){
        #If we are, let's close our position
        print("Closing open position")
        MT5$Close(MARKET_SYMBOL)
        #Reset last trade
        last_trade <- -1
      }
    
    else{
      #Otherwise everything is expected to be fine
      print("The current position is aligned with the market")
      info <- MT5$account_info()
      print("Current Profit")
      print(info$profit)
    }
    
  }
  #Wait for a new candle to form 
  Sys.sleep(60)
}


すべてをまとめる

図10:Rの二次判別分析モデルを使用したMetaTrader 5でのリアルタイム取引


結論

RとMetaTrader 5を使用したリアルタイム取引アルゴリズムの開発で課題にぶつかったにもかかわらず、この記事は、このタスクが当初思われたよりもアプローチしやすいものであることを示しています。Rの初級者でも、大きな進歩を遂げることができます。個々のパッケージの限界は補完的なパッケージによって効果的に緩和され、特に、採用されたアプローチでは依存関係を最小限に抑えています。全体として、Rのユーザーであれば誰でもアクセス可能な、実行可能で堅牢なフレームワークを提示しています。

さらに、ここに添付するMT5Rエキスパートアドバイザーのカスタマイズバージョンは、ストップロスとテイクプロフィットを自律的に組み込むように設計されており、取引管理を支援します。ユーザーは必要に応じて機能を拡張することが推奨されます。またお会いできる日まで、平和と繁栄、そして有益な取引をお祈りします。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/13941

添付されたファイル |
mt5R_v0_1_5.mq5 (151.33 KB)
float16およびfloat8形式のONNXモデルを扱う float16およびfloat8形式のONNXモデルを扱う
機械学習モデルの表現に使用されるデータ形式は、その有効性に決定的な役割を果たします。近年、深層学習モデルを扱うために特別に設計された新しい型のデータがいくつか登場しています。この記事では、現代のモデルで広く採用されるようになった2つの新しいデータ形式に焦点を当てます。
時系列マイニングのためのデータラベル(第6回):ONNXを使用したEAへの応用とテスト 時系列マイニングのためのデータラベル(第6回):ONNXを使用したEAへの応用とテスト
この連載では、ほとんどの人工知能モデルに適合するデータを作成できる、時系列のラベル付け方法をいくつかご紹介します。ニーズに応じて的を絞ったデータのラベル付けをおこなうことで、訓練済みの人工知能モデルをより期待通りの設計に近づけ、モデルの精度を向上させ、さらにはモデルの質的飛躍を助けることができます。
MQL5における拡張ディッキー–フラー検定の実装 MQL5における拡張ディッキー–フラー検定の実装
本稿では、拡張ディッキー–フラー検定の実装を示し、Engle-Granger法を用いた共和分検定に適用します。
データサイエンスと機械学習(第18回):市場複雑性を極める戦い - 打ち切りSVD v.s. NMF データサイエンスと機械学習(第18回):市場複雑性を極める戦い - 打ち切りSVD v.s. NMF
打ち切り特異値分解(Truncated SVD)と非負行列因子分解(NMF)は次元削減技法です。両者とも、データ主導の取引戦略を形成する上で重要な役割を果たしています。次元削減、洞察の解明、定量分析の最適化など、複雑な金融市場をナビゲートするための情報満載のアプローチをご覧ください。