見出し画像

為替取引のシミュレーター構築

この記事ではこれらのプラットフォームを使用した、為替情報の分析環境構築を紹介します。取引プラットフォームはMeta Trader 5(MT5)を使用し、MT5と通信してトレードを制御するアプリケーションを構築しました。

前回の記事でデータ分析とシミュレーションを統合するプラットフォームを紹介しました。プライベートで分析環境の縛りがない時に使用している環境です。オープンソースのデータバージョン管理システムであるDVCを参考に、自動制御のアルゴリズムをStrategyとして管理しています。StrategyはNotebookでの分析、シミュレーションでの評価、そして実際にアプリケーションとして稼働させる作業を全て統合します

為替取引用のStrategy構築に必要な作業は3つあります。1. Strategyの設計2. アカウント情報の再現3. Strategyとアカウント情報の統合です。これによりNotebook、シミュレーション、アプリケーションで共通する仕組みが構築できます。
さらにStrategyのシミュレーション環境を作成する4. シミュレーションでのMT5の再現を構築します。シミュレーションの用途や目的については過去の記事に詳しく紹介しています。Strategyを模索する段階で、データの背景をより深く理解するための手段として構築します。最後に為替取引で使用する5. 基本的な評価指標について紹介します。Strategyの内部データを使わない、トレード情報だけで完結した評価です。

以上の内容で為替取引の分析環境、シミュレーション、アプリケーションの実装を統合しています。

1. Strategyの設計

はじめに基本となるStrategyの構成を決めます。StrategyはDAG形式のスクリプト群で、実行する順番が決まっています。DAGはオープンソースのデータバージョン管理システムで使用している分析学習プロセスのパイプラインです。詳細については過去の記事で紹介しています。

為替取引ではLogicの役割をいくつかの明確なグループに分類できそうだったので、大きく5つに分けました。グループを実行する順番さえ守れば、同じ結果が得られるようにしています。

FIg.1 為替取引のStrategy

Fig.1 は5つのノードに分けたDAGです。一つのノードには1つ以上のLogicが順序不同で処理されます。
Filterは全体の計算に使うインジケーターをまとめて処理するグループです。例えば他のグループでBollingerBandsを使いたくなった場合、FilterにBollingerBands関連の計算を実行するLogicを追加します。Filter条件を満たさなければ以降の処理を実行せずEndまで飛ぶ処理も考えましたが、シミュレーション結果をデータ分析する際の都合で今の状態に落ち着いています。
Exitはポジションを持っているときに実行します。厳密にはEntryより先に実行されるので、もしかしたらこのDAG描写は少し修正が必要かもしれません。Exitはたいてい1つのLogicです。たまにpSARやトレーリングストップを加えたいときに2つ以上のLogicを使用します。持っているポジションのTPSL(Take Profit & Stop Loss)を更新したりもします。
EntryはBuyやSellのシグナルを決定します。ポジションをすでに持っているときも実行します。しかし別銘柄のポジションを単一口座で同時持ちすると証拠金維持率の管理が複雑になるため、基本的にはポジションを持っている時は何もしません。
ControllerはExitとEntryの結果を整理して最終決定を下します。複数のLogicがEntryやExitに存在する場合、どれか1つのLogicがポジションを操作する決定を下したときの判断です。
Money Management(M2s)はBuyやSellのシグナルが出た時に、購入するロット数を決定します。Strategyの目的によって購入方法は様々です。評価用の固定ロット、資産のx%、Entryパターンの勝率とPips幅を分析した期待値テーブルの使用などがあります。

Fig.2 現在使用する為替取引のStrategy

現在はFig.1に加えてSettingノードを入れています(FIg.2)。Settingはもしかしたら不要、もしくは別の場所で処理したほうが良いかもしれない暫定的なパラメータを計算しています。
例えばレバレッジ制限は資産状況によって変化するのですが、口座情報から制限ルールを自動取得できないのでここで計算しています。ほかにもブローカーの基準時からみた東京市場やニューヨーク市場などの時差を確認したりもします。サマータイムの切り替えは国によってばらばらで、厳密に知りたい場合に計算します。

StrategyにはDAG以外にもいくつかの設定が存在します。
例えばLogicのパラメータ情報です。シミュレーションでパラメータ評価する場合、Logicで意図的に読み取るよう設計します。Strategyでは事前にこのパラメータの設定が必要です。また、Strategyをビルドする際に最大窓サイズが決まります。ほかにも基準となる時間足と上位足の指定もStrategyが行います。

注目すべき点として、Strategyとアカウント情報は完全に独立しています。Strategyが口座の残高に基づいてロット数を決定する時も、残高の数値は次に紹介するAccountクラスが独立して管理しています。これは為替取引のデータ分析だけに限らず、関係のないデータを取り扱う場合も共通です。

2. MT5アカウント情報の再現

Strategyの実行にはMT5の状態管理が必要です。MT5の内部状態を再現するための仕組みとして、MT5アカウントと同じ様に稼働するAccountクラスを設計します。Accountクラスの設計はターゲットのプラットフォームによって大きく異なり、設計作業を通じて非常に深いデータへの理解が得られます。

Fig.3 MT5アカウント情報のイメージ図

まずは簡単に基本情報を紹介します。Fig.3では理解しやすいよう4つのグループに分けましたが、MT5のプログラミング言語であるMQLでは全く別の分類方法が使用されている点に注意が必要です。

Main Propertyは口座の設定情報です。ブローカーが提供するトレードサーバー名やデポジットの通貨、口座の種類などの設定があります。レバレッジ上限も含まれます。トレード結果に関わらず変化しない情報です。
Margin Propertyはポジションを持った時の設定情報です。SO SO(Stop Out)は証拠金維持率の下限で、欲をかいて証拠金維持率が下回ると強制的に決済が発生します。SO SC(Stop Call)はストップコールで、ブローカーが指定する証拠金維持率を下回ると色々制限が発生します。ここもトレード結果に関わらず変化しない情報です。
Accountは口座残高です。「残高」にはいくつか種類があります。口座へ入金するとその金額だけBalanceが増加します。所持するポジションの含み益か含み損とBalanceの合計値がEquityとなります。ブローカーが提供する様々なキャンペーンは、Creditとして加算されます。Creditは引き出せない仮想上の資産で、EquityとCreditの合計がMargin Freeとなります。証拠金維持率の計算はMargin Freeから算出されるため、Creditが多いとそれだけ少ない資産で多くのポジションを購入できます。
Positionは購入したポジション情報です。Marginは所持するポジションの金額で、Margin LevelはEquityとMarginから算出した証拠金維持率です。Profitは含み益と含み損です。

これらの情報のうちで、ポジション情報だけは少々特殊です。MT5のユーザーからすれば当たり前ですが、MT5は同じ口座に紐づいたポジションを異なる条件で取り扱えます。その条件とは、デバイス、Meta Trader端末、そして自動トレード(EA)です。そのため制御対象の口座には、Strategyと全く関係ない手段で購入したポジションが含まれる状況があります。また実際に運用する過程で自動トレードが予想外の振る舞いをし、Strategyの購入したポジションへ手を加える場合もあり得ます。
このようにポジション情報はシミュレーションでは問題なくとも、実際の稼働で予想外の挙動が発生する可能性があります。稼働中に予期せぬ不具合を防ぐため、Strategyの実行はMT5のポジション情報から独立させています。

Fig.4 Accountとポジションデータの関係図

TradeクラスはMT5とFirestoreのポジション情報を接続します。
Fig.4 はAccountクラスがトレード情報を取り扱うイメージです。StrategyとMT5は直接ポジションデータをやり取りせず、MT5から読み取った情報に差分があればFirestoreへ書き込みます。Strategyの実行にはFirestoreから読み込んだポジションデータのみ使用します。
このようにポジション操作はAccountクラスの中でも口座情報からある程度独立しており、Tradeクラスとして管理してます。ポジション購入ではMagic Number(MN)と呼ばれるパラメータが指定可能です。FirestoreにはMNでフィルタしたポジションのみ保存します。

ポジション情報の操作を除けば、口座情報の再現はポジションが資産へ与える影響の計算がコアになります。以降ではMT5アカウント情報をシミュレートするために必要な要素として、2.1. pip valueを使った損益計算2.2. 証拠金維持率の計算を紹介します。

2.1. Pip Valueを使った損益計算

Fig. 5 Pip Valueを使った損益計算

Pip Valueは損益を計算するための係数です。MT4やMT5のプログラミング言語であるMQLのフォーラムを見ていると、Pip Valueは自動トレードへ手を出した直後のトレーダーが最も躓きやすいポイントの一つのようです。Pip Valueを使用すると、Fig.5 のように通貨ペアの損益をBuyやSellに縛られず直感的に計算できるようになります。

Pip Valueの定義は「1ロットが1 Pips変化したときの損益」です。つまりPip Valueが$10、ポジションのロット数が15の時、18 Pips勝った時の利益は10 * 18 * 15=$2700となります(Fig.5)。この計算は、BuyとSellどちらも共通しています。Pip Valueは取引する通貨ペアと口座の通貨(デポジット通貨)の組み合わせで計算式が異なります。以降では導出方法を見ていきます。

Fig.6 通貨ペアの構成

Pip Valueは通貨ペアとデポジット通貨から決まります。デポジット通貨は口座に振り込んだ通貨です。通貨ペアの左右の通貨は業界ごとにいろんな名称があります。ここではFig.6の通り左をBase Currency、右をQuote Currencyと呼びます。
Base Currencyは購入した通貨に過ぎず、購入に使用した通貨であるQuote Currencyが損益計算の対象なります。ここではデポジット通貨がUSD、スタンダード口座、EURGBPを1.5ロット購入、勝ち幅が10 Pipsでの利益を計算してみます。

Fig.7 Pip Valueを使わない損益計算の例

Fig.7に具体的な計算例を示します。PipPointはPipsを価格へ変換する係数です。価格をPipsへ変換する場合は逆数をかけます。2段目はトレードする通貨ペアに対するロットサイズです。一般的に「スタンダード口座では1 pip当たり約$10の損益」といわれますが、このLotSizeとPip Pointを掛け合わせた値を示しています。3つ目の要素が重要で、Quote Currency(GBP)の損益をデポジット通貨(USD)へ変換しています。デポジット通貨はUSDなので、USDがQuote CurrencyとなるGBPUSDを掛け合わせます。
Pip Valueの定義は「1lotで1Pips当たりの損益」。つまり青色でハイライトした部分がPip Valueになります。Pip Valueを計算する際に考慮すべき点は2つあります。1つは取引している通貨ペアのQuote Currencyがデポジット通貨と一致するか、もう1つがQuote to Depoに該当する通貨ペアのQuote Currencyです。

Fig.8 通貨ペアとPip Valueの一覧

説明ではわかりづらいのでFig.8 で紹介します。GBPUSDはQuote CurrencyがUSD、つまりUSDUSDは(そのような銘柄は存在しませんが)常に1です。EURAUDはQuote CurrencyがAUD、AUDUSDはQuote CurrencyがUSDなので掛け合わせます。USDJPYとCHFJPYはQuote CurrencyがJPY、そしてUSDJPYはBase CurrencyがUSDなので割ります。
色付けした結果から明らかなように、Pip Valueは3通りの計算方法があります。GBPUSDに関してはUSDUSDと考えると、実質Quote to DepoのQuote CurrencyがDepoと一致するかどうかの2通りとの考え方もできます。

ここまで見ると、損益の計算式に少し疑問が出ると思います。それは、Quote to Depoはポジション購入時の価格を使うのか、それともポジション決済時の価格を使うのかです。考えてみれば当たり前ですが、EURを購入して稼いだAUDの利益をUSDへ両替するレートは常に変動しています。つまり、ポジション購入時のPip Valueと決済時のPip Valueが異なるのは当然だとわかります。

シミュレーションの損益計算は決済時のpip valueを使用します。そのため、取引する通貨ペアの価格データだけでなく、Quote Currencyとデポジット通貨から成る通貨ペアの価格データが口座情報の再現には必要になります。

2.2. 証拠金維持率の計算

証拠金維持率はトレードの健全性を管理する指標といえます。
証拠金維持率が基準値を下回るトレードは欲が暴走し正常なリスク管理ができていないです。逆に証拠金維持率が高すぎると、いくらトレードに勝てても資産全体から見ればほとんど利益が出ていません。これはリスクを取らなすぎる無駄の多いトレードです。
構築したStrategyの勝率や期待値から、自分なりに目標となる証拠金維持率を決めておくと良い目安となります。

Fig.9 通貨ペアとMarginの関係

この証拠金維持率はマージンから算出し、マージンはPip Valueと非常に似た方法で算出されます。Pip ValueはQuote Currencyに注目しましたが、マージンの計算にはBase Currencyへ注目します(Fig.9)。pip valueと同様にEURGBPの例で考えます。

Fig.10 Marginを算出する例

ロット数からマージンを算出する係数を、Pip Valueに倣って便宜上Margin Valueとしましょう。Margin ValueはFig.10のハイライトされた部分で算出できます。LotSizeはスタンダード口座では100,000で固定、レバレッジは200倍とします。一般的にレバレッジはEquityの大きさで変動するため、Equityの大きさと口座の契約内容から決定する要素が一段めです。2段目は購入したEURの価格をデポジット通貨へ変換する要素です。EURUSDはデポジット通貨であるUSDがQuote Currencyに存在するため、EURをUSDへ変換しています。三段目はロット数です。
Margin ValueはPip Valueと異なり、Pipsは関係ありません。Base通貨の価値をデポジット通貨へ変換するだけなので、Pip Valueと比べて非常に単純です。

Fig.11 通貨ペアとMargin Valueの一覧

Pip Valueと同じように、Margin Valueの算出パターンを確認してみましょう(Fig.11)。USDJPYはBase CurrencyがUSD、つまりUSDUSDは(そのような銘柄は存在しませんが)常に1です。CADCHFはBase CurrencyがCAD、USDCADはQuote CurrencyがCADなので逆数をかけます。GBPUSDはBase CurrencyがGBP、GBPUSDをそのまま掛け合わせます。EURAUDもBase CurrencyがEUR、EURUSDはQuote CurrencyがUSDなので掛け合わせます。
Pip Valueと同じく、Margin Valueは3通りの計算方法があります。USDJPYに関してはUSDUSDと考えると、実質Base to DepoのQuote CurrencyがDepoと一致するかどうかの2通りとの考え方ができます。この点においてもPip Valueと同様です。

Fig.12 証拠金維持率の計算例

Marginが算出できれば、証拠金維持率はすぐに算出できます。Margin Freeは所持するポジションの損益、ブローカーから提供されるボーナス(Credit)、そして既に所持しているマージンを加味した総資産です。Fig.12にポジションを持っていない状態と持っている状態で例を示します。例えばEquityが$200,000、新しいポジションのマージンが$100,000であれば、証拠金維持率は200%となります。既に持っているポジションのマージンが$150,000、Equityが$200,000、新しいポジションのマージンが$100,000であれば、証拠金維持率は50%です。

3. Strategyとアカウント情報の統合

StrategyはLogicを実行する機能はなく、単なるDAG情報に過ぎません。MT5のアカウント情報を活用し、価格データとともにStrategyを実行するRepositoryクラスが必要です。
AccountクラスはMT5以外のアカウントデータを再現すると構造が大きく変わります。一方Repositoryは取り扱うデータに関係なくほとんど同じ構造です。ここでは為替取引を実行する上で重要となる2点について紹介します。1つはLogicへの入力のビルド、もう1つが銘柄の設定情報です。

3.1. Logicへの入力のビルド

Fig.13 Logicの入出力をビルドする例

Fig.13はStrategyのグループを順番に実行する様子です。前のグループの結果に加え、価格、口座情報、Strategyの設定などの情報を使用しています。これらの情報から入力データをビルドします。Fig.13ではExitグループに2つのLogicが存在し、それぞれの実行結果を整理してExitグループ全体の結果を作成します。そして同様の手順で次のEntryの入力をビルドします。
このようにRepositoryは単純な仕組みです。Strategyの設定と口座情報から入力をビルドし、Logicの結果からグループの出力を決定します。

Fig.14 Logicへ入力する情報

Logicへの入力は大きく3つあります(Fig.14)。価格情報を含むData、環境情報としてContext、そして外部への入出力を管理するStoreです。以下に為替取引データでの中身を示します。

DataはMT5から取得した価格データです。Strategyの設定情報から、Logicの計算に必要な時間足とデータ量を取得します。Fig.14ではH1, H4, D1の時間足が直近7足取得しています。
ContextはMT5のプログラミング言語であるMQLで取得できるほとんどすべての環境情報を保持しています。アカウント情報であれば、既に紹介した口座の基本情報に加え、所持するポジション情報、そしてPip ValueとMargin Valueも含まれます。MT5の口座タイプやLogicを実行しているプラットフォームもわかります。
StoreはLogicからの「出力」に相当する機能をすべて保持しています。例えばFirestoreのドキュメントに関する機能です。本記事で紹介するシステムでは、Strategyを実行するユーザーへ事前にFirestoreの一部領域が割り当てられています。Storeを通して割り当てられたFirestoreへの読み書きが可能です。ほかにもCloudStorageに存在する学習済みモデルを事前にインストールし、Storeから使用しています。

以上の要素をStrategyの設定情報とAccountからビルドし、RepositoryクラスはLogicを実行します。Storeの設計に関してはまだまだ改良の余地があると思っていますが、現状はこのような状態で落ち着いています。

3.2. 銘柄の設定情報

MT5は為替取引と先物取引を同じモジュールで共有しています。この仕様は自動トレードやツールを作成する点で非常に便利ですが、為替取引に限定すれば明らかに不必要な大量の情報が存在します。そのためContextに記録する銘柄情報は、為替取引で使用頻度の多い情報のみMT5から取得しています

MQLはデータ型でプロパティが分類されています。例えば銘柄の最小ロット数はDouble型なのでSymbolInfoDouble()から、小数点とPipの関係を示すDigitはInteger型でSymbolInfoInteger()から取得できます。取得可能なすべての銘柄情報は以下のリンクで記述されています。これらの銘柄情報は、Repositoryクラスが準備するContextからLogicへ受け渡されます。以降ではContextへ記録している銘柄情報を簡単に紹介します。

symbolは銘柄の名前です。為替取引ではEURUSD等の通貨ペアに限定され、先物取引でMT5を使用する場合はCrude Oilなどが該当します。
pip, point, digitは小数点とPIPSの関係を示します。1.07316(EURUSD)であれば、pipは0.0001、pointは0.00001、digitは5となります。130.000(USDJPY)であれば、pipは0.01、pointは0.001、digitは3となります。
ask、bidは銘柄の現在の提示額です。それぞれの金額から算出したPip Value (Ask or Bid)とMargin Value (Ask or Bid)も取得できます。
symbol leverageは銘柄のレバレッジです。レバレッジはブローカーが決定しますが、具体的には銘柄とEquityから決定します。一般的にボラティリティが大きい銘柄(CHF、MXNなど)はレバレッジが小さく、運転資金であるEquityが少額なほどレバレッジが大きくなります。Symbol Leverageは最終的に決定したその銘柄のレバレッジです。
volume max、volume min、volume stepはロット数の設定です。文字通り、購入できるロット数の最大最小値と最小単位を示します。

シミュレーションで一部情報が使用不可能な点に注意が必要です。
例えばaskとbidはMT5に保存されない使い捨ての情報です。過去データが取得できないので、代わりに直近のcloseとspreadを使用する設計であればシミュレーションでも動作するでしょう。
またEquityとレバレッジのルールはMT5から提供されません。実際のEquityが1,000万円であるにも関わらず100万円の設定でシミュレーションした場合、自分で指定しなければ1000万円の小さいレバレッジで証拠金維持率を計算します。

4. シミュレーションを実行する仕組み

実際にアプリケーションを稼働させる場合は、3.で紹介したRepositoryがMT5とFirestoreから情報をやり取りします。シミュレーションではRepositoryの制御情報がMT5へ送信されたと仮定し、ProcessクラスがMT5とFirestoreを再現します。
Processクラスは構築作業を通じて、対象データの周辺環境を深く理解できます。例えばMT5の再現では、価格情報の仕組みと自動トレードを実行する時間外の処理への理解が深まります。ここで紹介するのは1. 価格情報の再現、そして2. トレード情報の取り扱いと時間外処理です。

4.1. 価格情報の準備

Fig.15 シミュレーションで準備する価格情報

まず前提として、シミュレーションは1つの銘柄に対してのみ実行します。そして最も短い時間足をメインタイムフレーム(Main TF)、Strategyが要求する上位足をサブタイムフレーム(Sub TF)、2.で紹介したPip ValueとMargin Valueを取得するために必要な価格情報をクロスレートとしています(Fig.15)。

EURGBPをトレードターゲットにしている場合、Main TfとSub TFは時間、OHLC、スプレッド、そしてTick VolumeをMT5から取得します。クロスレートはH1のEURUSDとGBPUSDです。これらは時間とCloseのみ取得します。
MT5から取得した価格情報は、ループ処理で繰り返しRepositoryへ入力します。時系列データの分割方法は過去の記事で紹介した通りです。

Fig.16 1分毎に取引が発生するローソク足の例

実際にMT5のデータを受け取るタイミングは、Main TFの時間足が決定した瞬間です。そのためStrategyを実行する時間と同じタイムスタンプのデータへアクセスするには遅れが発生します。Fig.16は説明のために1分毎に取引が発生する銘柄を仮定した、1時間足と4時間足のイメージ図です。12:00の価格データは1時間足では12:59に終値が決定し、4時間足では15:59に終値が決定します。
Fig.16左の1時間足を考えてみます。13:00のStrategy計算は、12:59にCloseが確定した12:00の1時間足が最新情報となります。しかし実際は13:00に取引数1、タイムスタンプ13:00、OHLCが同じ値の1時間足が形成されています。実際の稼働では13:00の計算は秒単位での遅れが想定され、ポジションを操作する場合13:00の始値に近い値で取引します。これらの理由から、13:00のStrategy計算でポジションを購入する場合、シミュレーションではこの13:00の取引で決定した始値を購入時の参考価格としています。このときStrategyが計算に利用できる最新データは12:59に決定した終値という点に注意が必要です。
複数足を利用するとこの影響が顕著になります。Fig.16右の4時間足では、Strategyの計算が4回(12:00, 13:00, 14:00, 15:00)発生します。この間Strategyの計算で利用できる4時間足の最新情報は8:00になります。しかしポジションの購入が発生した場合、Main TFである1時間足の始値が購入時の参考価格になります。

4.2. トレードの取り扱いと時間外処理

2.ではAccountクラスがStrategyへトレード情報を提供する仕組みを紹介しました。AccountクラスはMT5の口座情報を操作せずにRepositoryを実行できます。しかしシミュレーションではRepositoryの実行だけでなく、本来MT5が処理するはずだった口座情報の更新作業が必要です。ここではMT5がポジションに関する操作を受け取った場合の再現を紹介します。

ループ処理がRepositoryを実行すると、ポジションが変化する出力かチェックします。もし購入指示があればスプレッドを考慮しつつ記録し、決済指示があれば記録しておいたポジション情報へ決済時の価格情報を追記します。さらにRepository内に存在するAccountクラスの口座情報を更新します。更新内容で重要となるのは、損益や証拠金維持率、そしてループ間の決済処理です。

Fig.17 ストップコールの時間外処理

Fig.17では22:00のデータを使って23:00にBuyしています。このとき1時間足がMain TFで、具体例を示すために15分足の価格を一緒に描写しています。購入価格は23:00の始値、その後0:30に最安値を更新します。下は証拠金維持率のイメージです。この例ではストップアウトぎりぎりの運用をしています。
シミュレーションでは1時間足から証拠金維持率の最悪値を計算します。23:00から0:00では証拠金維持率がストップコールを上回っていますが、0:00から1:00の1時間足で最安値を記録するとストップコールを下回ります。この時0:00の最安値で強制決済された前提で、1:00のループ開始時に損失金額を口座へ反映します。つまり1:00のStrategyはポジションを持たない状態で実行されます。15分足で厳密にみると最安値より手前でストップアウトがかかっています。しかしMain TFでは詳細なストップアウト時の価格がわからないため、1時間足の最安値を決済価格としています。

ちなみにスワップ情報は少々特殊です。MT5ではスワップのレートは提供されず、履歴も存在しません。そのためスワップが与える口座への影響はシミュレーションを実行するユーザーが設計する必要があります。とはいえよほどのハイレバレッジでない限りトレードとは比較にならないほど影響が小さく、現実的な数値で計算すれば実際の口座金額と大きく乖離しないでしょう。Fig.17では0:00のループ開始時にスワップの損益を口座へ反映します。つまり0:00の証拠金維持率にスワップの影響が加味されています。

Fig.18 Stop Lossの時間外処理

時間外の処理も非常に重要になります。ポジション操作は大きく2種類存在します。1つはStrategyが直接操作する方法、もう1つは事前に設定したTPSL(Take Profit & Stop Loss)で決済する方法です。Fig.18はStop Lossで決済する例です。
22:00の1時間足からBuyを決定し、23:00の始値で購入しています。より詳細な15分足で見ると0:15に最安値がStop Lossを超えて自動決済されています。シミュレーションでは、1:00のループ開始時に0:00の最安値がStop Lossを超えているか確認します。この例ではStop Lossに引っ掛かっているので、1:00のStrategy計算は損失が発生しポジションを持っていない状態で始まります。ストップアウトとは異なり、決済価格はTPSLの指定した金額です。

5. 評価

シミュレーション結果はファイルに出力されます。出力するファイルは3種類あり、アカウント情報、トレード情報、そしてオブザーバー情報です。4.で実装したProcessクラスはループ毎にこれらの情報を記録し、ループ回数が設定値を超えるとバッチ処理でファイルへ出力します。

Fig.19 シミュレーションの出力と評価へ利用するイメージ

一般的に自動トレードの性能を測定する評価は、トレード情報のみ使用して評価可能です(Fig.19 緑色)。Fig.19の緑色はトレード情報を使用する基本評価、ピンク色はStrategyが意図的に出力したオブザーバー情報を使用するStrategy依存の評価です。
基本評価は評価手法がStrategyに関係ない勝率やトレード数が該当します。一方でオブザーバー情報は内部状態やインジケーター、学習済みモデルへの入力が該当します。基本評価はオブザーバー情報を用いた評価と異なり深い分析ができません、しかしStrategyの全体像を知るには十分で、評価するプログラムがStrategyに関係なく再利用できる利点があります。
ここでは自動トレードを評価する基本評価を簡単に紹介します。オブザーバーを用いた評価は文章のボリュームが多すぎるため省いています。

為替取引ではベースとなる評価が2種類あります。1つはPIPS評価、もう1つがアセット評価です。PIPS評価は勝率と期待値を、アセット評価はマネーマネジメント(M2s)を評価します。自動トレードを分析せず購入するだけであれば、これらの基本評価だけで十分統計的な評価がくだせます。しかしどちらの評価もStrategy全体に対する基本的な評価であり、パフォーマンス改善のための情報としては不十分である点に注意が必要です。

5.1. Pips評価

Pips評価はトレードの結果からロット数を除外した評価です。Strategyの性能を見るうえで最も基本的な情報がわかります。優れたStrategyであるには大量のPipsを稼ぐ必要は必ずしもなく、安定し再現性のあるトレードができれば十分です。以下にPips評価の一例を紹介します。

トレード数: 性能の善し悪しを見るには十分な量が必要です。性能の低いStrategyほど、トレード数が減るにつれてエッジが見えないままパフォーマンスが向上します。
プロフィットファクター(PF):  自動トレードの全体的な性能が見えます。十分なトレードとOoS(Out of Sample)の再現性があるPFは信憑性があります。
勝率: PFやStrategyの傾向で要求される水準が異なります。30%で十分な場合もあれば、早めにTake Profitするなら50%でも不足します。
リスクリワード: 勝ち幅と負け幅の比率を示し、Strategyの個性がわかります。高いほど伸びしろが増え、低いほど勝率が上がります。
Total PIPS: 勝率とPFが十分なStrategyであっても、OoSでPipsの合計値が不安定なら注意が必要です。たまたま大当たりしたトレードに極端に依存している可能性があります。
Maximum Draw Down(MDD): Pipsの最大累積値から現在の累積値を割った値です。Total Pipsで500Pipsまで到達した後に連敗で250Pipsまで低下した場合、MDDは50%になります。
Buy Ratio: 全トレードに占めるBuyの割合です。例えばシミュレーションでBuy(or Sell)が多い時だけ異常に性能が良い状態を発見できます。詳しく見た結果が「Sellに苦手なStrategyである」程度なら良いですが、再現性のない長期トレンドに便乗して性能が底上げされている危険が発見できます。
Zスコア: 連敗連勝の傾向がわかります。Strategy次第では容易に極端な数値へ振れます。0に近づけると統計的に扱いやすいですが、逆に性能が悪化する場合もあり必ずしも良い選択とは限りません。

以上の評価はすべて一覧としてテーブルで確認が可能です。これら以外にもテーブルで確認しづらい情報があります。曜日や時間帯とPipsの関係や、Pipsのランキングです。そのような評価は個別で関数を準備しています。

5.2. アセット評価

アセット評価はトレードの結果をEquityから評価します。Pips評価と異なりトレードの損益を見るので、ロット数の設定ルールであるMoney Management(M2s)の性能評価でもあります。
以下にアセット評価の基本的な情報を紹介します。Pips評価とまったく同じ指標は省いています。

総利益: シミュレーション期間内の最終的な利益です。単位は金額と%の2種類あります。
プロフィットファクター(PF): PipsのPFとは異なり、ロット数とPipsから損益として計算したPFです。PF(Pips)が十分なら、証拠金維持率を維持しつつ良いPF(アセット)を目指します。
Maximum Draw Down(MDD): PipsではなくEquityから見たMDDです。こちらも単位は金額と%の2種類があります。
Ret / MDD: 総利益とMDDの比率です。例えばロット数を増やし総利益が1割増えれば性能が上がったと感じます。しかし代償にMDDが許容できない程度まで悪化すれば、コストに見合った利益増加とは言えません。この指標はコストとリターンの目安となります。

以上の内容は一覧をテーブルで確認します。Pips評価と同じくテーブルで表現が面倒な内容は個別にグラフ化します。例えばEquityの時間変化やポジションを購入する時間帯と損益の関係です。

まとめ

この記事では、過去の記事で紹介した分析プラットフォームに基づいた為替取引のStrategyを構築しました。これによってNotebook上で作成したStrategyをシミュレーションで比較評価し、気に入ったStrategyを実際にアプリケーションとしてMT5で実行できるようになりました

過去の記事でも触れた通り、この分析プラットフォームはStrategyや評価指標を模索する際に使用します。MT5の内部構造を再現しシミュレーターを構築する作業を通じ、為替取引についての理解を深めます。そして既存の自動トレードアルゴリズムを分析しつつ自分なりのStrategyを固めます。

もし満足のいくStrategyを発見しパフォーマンスを評価する指標が決まったなら、Pythonサーバーにプッシュすれば十分稼働します。複数のStrategyと同時に運用する場合、次のボトルネックはシミュレーションの計算速度と組み合わせ評価です。ここまで来ればStrategy設計に大きな変更が加えられる状況はあり得ません。Pythonではなくベンダー依存の言語(MQL5)やC言語へ安心して実装できます。分析すべき要素も熟知できているはずなので、評価で使用した数値をモニタリングするだけで良いでしょう。


この記事が気に入ったらサポートをしてみませんか?