English Русский 中文 Español Deutsch Português
preview
どんな市場でも優位性を得る方法

どんな市場でも優位性を得る方法

MetaTrader 5 | 27 5月 2024, 10:49
629 0
Gamuchirai Zororo Ndawana
Gamuchirai Zororo Ndawana

内容

  1. 大要
  2. はじめに
  3. 戦略の概要オルタナティブデータソース
  4. 機械学習技法
  5. 戦略の構築
  6. 結論
  7. 推奨


大要

今日は、トレーダーが様々な市場において大幅な競争上の有利性を発揮するための、強固な取引戦略を構築します。従来の市場参加者が意思決定のために価格関連データ、テクニカル指標、公なニュース発表の組み合わせのみに依存するのに対し、私たちの戦略は、大多数がほとんど未開拓のままであるオルタナティブデータソースを活用することにより、先駆的なアプローチをとります。

私たちの戦略の前提は、オルタナティブデータの統合にあります。これは、主流の市場参加者によって見落とされがちなものなオプションです。このような未開拓のデータソースを活用し、機械学習技法を適用することで、私たちの戦略にしかない独自の洞察や視点を得ることができるかもしれません。

この調査では、セントルイス連邦準備銀行が提供するデータ、特にFREDとして知られる包括的なエコノメトリック時系列データベースを活用します。FREDは常に一般に公開されており、取引における十分な情報に基づいた意思決定に不可欠なデータを提供していることは間違いありません。さらに、セントルイス連邦準備銀行のような中央銀行から提供されるデータは、しばしば先行指標として機能し、エントリやエグジットのタイミングを効果的に計る能力を高めてくれます。

さらに、このデータは外部からの操作に影響されないため、取引戦略に組み込むには理想的な候補となります。

この記事は、PythonとMetaTrader 5を使用して最先端の取引戦略を簡単に構築できることを示す、実践的なガイドとなることを目的としています。読者が私たちのアプローチを容易に理解し、今日から始めることができるように、明瞭かつシンプルに説明することをモットーとします。


初めに:この記事の目的は、取引戦略にオルタナティブデータを簡単に適用する方法を示すことです。 

この記事を読み終える頃には、読者は以下の主要分野についての見識を深めていることでしょう。

  1. ノイズと不確実性の中で、オルタナティブデータはいかに意思決定を役立つか
  2. オルタナティブデータの信頼できる情報源をスクリーニングし、特定する技法
  3. 分析のためのオルタナティブデータの分析と前処理のベストプラクティス
  4. 意思決定プロセスを強化するための、オルタナティブデータソースを統合する強固な取引戦略の構築

オルタナティブデータの影響を示す一例として、衛星画像の戦略的利用があります。先進的なトレーダーは、衛星画像を活用して船舶の交通パターンを監視したり、石油タンカーの在庫レベルを観察したりします。これらのユニークなデータポイントによって、トレーダーは、他の方法では隠れてしまうかもしれない有益な取引機会を発見することができます。

衛星画像の利用は裕福なトレーダーの間では一般的かもしれませんが、この記事では、どんなトレーダーでも自由に利用できるオルタナティブデータを利用して市場を先取りする方法を紹介します。さらに、機械学習モデルを使用することで、複数のデータソースを同時に分析し、意思決定能力をさらに高めることができます。


取引戦略の概要オルタナティブデータソース

私たちの取引戦略は、簡単に理解できるように設計されています。MetaTrader 5端末からの従来の市場データとセントルイス連邦準備銀行からのオルタナティブデータを統合し、特にGBPUSDペアの将来の値動きの予測に焦点を当てます。

そのために、2つの主要な経済データセットをオルタナティブデータソースとして活用します。最初のデータセットは英ポンドに関する情報で、英ポンド市場における時間外銀行取引に課される金利の時系列データを提供します。こうした金利変動は、ポンドに対する機関投資家の需要水準を測るための代用指標として機能し、私たちの予測モデルに貴重な指標を提供します。

同様に、2つ目のデータセットには米ドルに関する情報が含まれており、連邦準備制度が管理するアメリカの銀行への翌日物融資に請求される金利の時系列で構成されています。連邦準備制度が金融政策の調整を通じて金利をコントロールすることで、米ドルに影響を与える可能性のある経済動向に関する別の洞察が得られます。

これらの経済時系列データを分析解釈して機械学習技法を採用することで、市場競争上の優位性をもたらす先行指標を発見するという目標を実現できるかもしれません。

私たちの戦略の有効性の礎は、信頼できるオルタナティブデータ源の確保にかかっています。信頼できるオルタナティブデータソースの有無は、取引する市場によって異なります。乱数発生器によって生成される合成市場には、実質的にオルタナティブデータソースがありません。合成市場は外界から独立しているからです。

  1. 信頼性:そもそも、オルタナティブデータの情報源はどうやってデータを入手しているのでしょうか。依存している情報チャンネルの信頼性を調べます。「どのように情報にアクセスしているのか」「情報ルートは信頼できるのか」といった質問は、信頼性を評価する上で極めて重要です。これらの点について疑問がある場合、より徹底的な評価の必要性が示唆されます。
  2. 更新頻度:私たちの焦点は、取引時間帯に合わせて毎日更新されるオルタナティブデータソースにあります。ただし、すべての情報源が毎日更新されているわけではないことに注意することが肝要です。中には、毎月または毎年更新されるものもあります。したがって、希望する取引頻度に沿った情報源を選択するようにします。
  3. 評判:信頼性だけでなく、信頼できる実績があり、正確性を維持することに関心のある情報源を優先します。評判の高いプロバイダーは、私たちのデータに信頼性を与えるだけでなく、説明責任を実証します。
  4. 透明なプレゼンテーション:透明性が高く、ユーザーフレンドリーな方法でデータを提示するプロバイダーを選択します。特に複雑なデータに伴う認知的負荷を考慮すると、効果的な意思決定をおこなうためには、データの提示における明確さとシンプルさが最も重要です。
  5. 価格体系:ニーズと予算の制約のバランスをとりながら、オルタナティブデータソースの価格モデルを評価します。無料の情報源もあれば、支払いが必要なものもあります。選択は、各ソースが提供する価値提案に沿ったものでなければなりません。
  6. 利用規約:オルタナティブデータソース(特に支払いを必要とするデータソース)に関連する条件を注意深く検討し、理解します。使用制限と限界を明確に理解することで、十分な情報に基づいた意思決定が可能になり、意図しないコンプライアンス上の問題を防ぐことができます。

概要すると、信頼性、更新頻度、評判、透明性、価格設定、取引条件に基づいてオルタナティブデータソースを厳密に評価することが、取引戦略においてデータを効果的に活用するためには不可欠です。

次に、セントルイス連邦準備銀行から入手したいくつかのオルタナティブデータを検証し始めます。セントルイス連銀からデータを取得するには2つの方法があります。

  1. プログラムでFRED Pythonライブラリを使用する
  2. FRED Webサイトで手動で取得する 

これらのデータセットを初めて使用するのであれば、まず手動でデータを収集することをお勧めします。FRED Webサイトには、各データセットの記録方法、データの意味、季節調整の有無、計測の単位やスケール、その他詳細に関する有用な注記や情報が掲載されているからです。データの性質に慣れたら、次はプログラムでデータを収集してもよいでしょう。最初のデモンストレーションでは、セントルイス連邦準備銀行のWebサイトからデータセットを手動でダウンロードしました。戦略構築の段階で、プログラム的アプローチに移行します。 

最初におこなうのは、MQL5スクリプトを使用してMetaTrader 5から市場データを収集することです。私はこの方法でデータを収集することを好みます。データに無制限にアクセスできるMQL5側で必要な前処理を実行できるからです。スクリプトはいたってシンプルです。

  • まず、テクニカル指標のハンドラを宣言します。4つの移動平均を使用します。
  • 次に、移動平均の読み取り値を格納するバッファを宣言します。この場合のバッファは動的配列です。
  • 次にファイル名が必要です。取引するペアの名前に「Market Data As Series」という文字列を続けたもので、CSV形式とします。
  • その後、どれだけのデータを収集したいかを宣言します。 
  • このスクリプトは、適用するチャートの現在の時間枠で動作します。
  • これでOnStart()イベントハンドラにたどり着きます。ここがスクリプトの心臓部です。
  • まず、4つのテクニカル指標をすべて初期化します。
  • 次に、指標の値を先ほど作成した配列にコピーします。
  • それが終わったら、ファイルを作成、書き込み、閉じるためのファイルハンドラを作成します。
  • 次に、単純なforループを使って配列を繰り返し処理し、CSVファイルに書き出します。ループの最初の反復では、列のヘッダーを書き、その後に実際の値を書き出します。
  • ループが完了したら、ファイルハンドラを使用してファイルを閉じ、MetaTrader 5端末からのデータとオルタナティブデータを結合する準備ができました。

#property copyright "Gamuchirai Zororo Ndawana"
#property link      "https://www.mql5.com"
#property version   "1.00"

//---Our handlers for our indicators
int ma_handle_5;
int ma_handle_15;
int ma_handle_30;
int ma_handle_150;

//---Data structures to store the readings from our indicators
double ma_reading_5[];
double ma_reading_15[];
double ma_reading_30[];
double ma_reading_150[];

//---File name
string file_name = _Symbol + " " + " Market Data As Series.csv";

//---Amount of data requested
int size = 1000000;
int size_fetch = size + 100;

void OnStart()
  {
      //---Setup our technical indicators
      ma_handle_5 = iMA(_Symbol,PERIOD_CURRENT,5,0,MODE_EMA,PRICE_CLOSE);
      ma_handle_15 = iMA(_Symbol,PERIOD_CURRENT,15,0,MODE_EMA,PRICE_CLOSE);
      ma_handle_30 = iMA(_Symbol,PERIOD_CURRENT,30,0,MODE_EMA,PRICE_CLOSE);
      ma_handle_150 = iMA(_Symbol,PERIOD_CURRENT,150,0,MODE_EMA,PRICE_CLOSE);
      
      //---Copy indicator values
      CopyBuffer(ma_handle_5,0,0,size_fetch,ma_reading_5);
      ArraySetAsSeries(ma_reading_5,true);
      CopyBuffer(ma_handle_15,0,0,size_fetch,ma_reading_15);
      ArraySetAsSeries(ma_reading_15,true);
      CopyBuffer(ma_handle_30,0,0,size_fetch,ma_reading_30);
      ArraySetAsSeries(ma_reading_30,true);
      CopyBuffer(ma_handle_150,0,0,size_fetch,ma_reading_150);
      ArraySetAsSeries(ma_reading_150,true);

      //---Write to file
       int file_handle=FileOpen(file_name,FILE_WRITE|FILE_ANSI|FILE_CSV,",");
       
    for(int i=-1;i<=size;i++){
      if(i == -1){
            FileWrite(file_handle,"Time","Open","High","Low","Close","MA 5","MA 15","MA 30","MA 150");
      }
      
      else{
            FileWrite(file_handle,iTime(_Symbol,PERIOD_CURRENT,i),
                                 iOpen(_Symbol,PERIOD_CURRENT,i),
                                 iHigh(_Symbol,PERIOD_CURRENT,i),
                                 iLow(_Symbol,PERIOD_CURRENT,i),
                                 iClose(_Symbol,PERIOD_CURRENT,i),
                                 ma_reading_5[i],
                                 ma_reading_15[i],
                                 ma_reading_30[i],
                                 ma_reading_150[i]
                                 );
      } 
    }
  }
//+------------------------------------------------------------------+

これで、市場データとともにオルタナティブデータの探索を開始する準備ができました。

いつものように、まず必要なパッケージをインポートすることから始めましょう。

import pandas as pd
import numpy as np 
import matplotlib.pyplot as plt
import seaborn as sns

次に、MQL5スクリプトからエクスポートしたデータを読み込みます。

GBPUSD = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\MetaQuotes\\Terminal\\NVUSDVJSNDU3483408FVKDL\\MQL5\\Files\\GBPUSD Market Data As Series.csv")

機械学習用に市場データを準備する際は、今日の価格が最後、最も古い価格が最初になるようにします。 

GBPUSD = GBPUSD[::-1]

それからインデックスをリセットする必要があります。

GBPUSD.reset_index(inplace=True)

どのくらい先のことを予測したいかを定義してみましょう。

look_ahead = 30
splits = 30

目標を準備する必要があります。 

GBPUSD["Target"] = GBPUSD["Close"].shift(-look_ahead)
GBPUSD.dropna(inplace=True)

これは、後で市場データとオルタナティブデータを簡単に整合させるのに役立ちます。

GBPUSD["Time"] = pd.to_datetime(GBPUSD["Time"])
GBPUSD.set_index("Time",inplace=True)

最初のオルタナティブデータは、日次のポンド翌日物平均金利(SOIA)です。これは、銀行が通常の営業時間外にポンドを借りる際の金利の平均です。

もしポンド債の平均金利が上昇し、一方でドルの平均金利が下落しているのであれば、それは機関投資家レベルではGBPが米ドルより強くなっていることを示唆している可能性があります。 

SOIA = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Downloads\\FED Data\\Daily Sterling Overnight Index Average\\IUDSOIA.csv")

オルタナティブデータをクリーンアップしましょう。まず、日付列を日付オブジェクトにします。

SOIA["DATE"] = pd.to_datetime(SOIA["DATE"])

データセットにはドットが含まれていますが、これは観測の欠測を表していると思われます。すべての点を0に置き換え、0を列の平均値に置き換えます。 

SOIA["IUDSOIA"] = SOIA["IUDSOIA"].replace(".","0")
SOIA["IUDSOIA"] = pd.to_numeric(SOIA["IUDSOIA"])
non_zero_mean = SOIA.loc[SOIA['IUDSOIA'] != 0, 'IUDSOIA'].mean()
SOIA['IUDSOIA'] = SOIA['IUDSOIA'].replace(0, non_zero_mean)

次に、日付をインデックスにします。

SOIA.set_index("DATE",inplace=True)

次のオルタナティブデータ源は、担保付翌日物調達金利(SOFR)です。これは担保付オーバーナイトローンのコストで、ニューヨーク連銀が毎日公表しています。 

SOFR = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Downloads\\FED Data\\Secured Overnight Financing Rate\\SOFR.csv")

SOFRデータセットに適用される前処理ステップは、SOIAデータセットに適用されるステップと同一であることに留意してください。したがって、最初から最後まで記事を読みやすくするために、これらのステップは省略します。 

それでは、3つのデータフレームを統合してみましょう。left_indexとright_indexをtrueに設定することで、両データセットのアライメントが、それぞれ完全な観測がある日にのみおこなわれるようにしています。例えば、GBPUSDデータセットには週末のレコードがないため、週末に観測されたすべてのオルタナティブデータポイントは、最終的に統合されたデータフレームには含まれません。 

merged_df = SOIA.merge(SOFR,left_index=True,right_index=True)
merged_df = merged_df.merge(GBPUSD,left_index=True,right_index=True)

次にインデックスをリセットする必要があります。

merged_df.reset_index(inplace=True)
merged_df.drop(columns=["index"],inplace=True)

予測因子を定義しましょう。

normal_predictors = ['Open', 'High', 'Low', 'Close', 'MA 5', 'MA 15','MA 30', 'MA 150']
alternative_predictors = ['IUDSOIA', 'SOFR']
all_predictors = normal_predictors + alternative_predictors

そして,予測変数の各組み合わせの誤差レベルを格納するデータフレームを作成します。

accuracy = pd.DataFrame(columns=["Normal","Alternative","All"],index=np.arange(0,splits))

これが現在のデータフレームです。

merged_df

統合データフレーム

図1:通常のデータとオルタナティブデータの両方を含むデータセット


最初の列はポンドの平均金利、2番目の列は米ドルの平均金利です。そこから以下の列はすでにお馴染みになっているはずです。目標は30日先の終値であることをお忘れなく。

最後に、後で使用するために、統合したデータフレームをcsvファイルにエクスポートします。

merged_df.to_csv('Alternative Data Target Look Ahead 30.csv')

データをスケールしてみましょう。

from sklearn.preprocessing import StandardScaler
scaled_data = merged_df.loc[:,all_predictors]
scaler = StandardScaler()
scaler.fit(scaled_data)
scaled_data = pd.DataFrame(scaler.transform(scaled_data),index=merged_df.index,columns=all_predictors)

では、モデルを訓練する準備をして、オルタナティブデータが役に立っているのか、それとも足かせになっているのかを確認しましょう。

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error 
from sklearn.model_selection import TimeSeriesSplit

訓練/テストの分割を準備しましょう。

tscv = TimeSeriesSplit(gap=look_ahead+10,n_splits=splits)

for i,(train,test) in enumerate(tscv.split(merged_df)):
    model = LinearRegression()
    model.fit(scaled_data.loc[train[0]:train[-1],all_predictors],merged_df.loc[train[0]:train[-1],"Target"])
    accuracy["All"][i] = mean_squared_error(merged_df.loc[test[0]:test[-1],"Target"],model.predict(scaled_data.loc[test[0]:test[-1],all_predictors]))


次に結果を箱ひげ図としてプロットします。

fig,axs = plt.subplots(1,3,sharex=True,sharey=True,figsize=(16,4))

for i,ax in enumerate(axs.flat):
    ax.boxplot(merged_df.iloc[:,i])
    ax.set_title(accuracy.columns[i])

予想子の組み合わせ

図2:通常データ(左)、オルタナティブデータ(中央)、すべての利用可能データ(右)を使用した場合の誤差値の分析

結果を解釈してみましょう。予測変数の通常の集合と予測変数の代替集合は、どちらもプロットの上部に達する長い尾を持っていることがよくわかります。しかし、最後のプロット(正規予測因子と代替予測因子の両方を持つプロット)は、つぶれた形をしています。このつぶれた形は、予測変数の両方のセットを一緒に使用すると誤差のばらつきが少なくなることを示す、望ましいものです。最後のプロットでは精度は安定していますが、最初の2つのプロットでは、通常データかオルタナティブデータに全面的に依存しているため、精度はそれほど安定していません。 

データに交互作用があるかどうかも確認できます。Y軸に目標、X軸にポンド金利の散布図を作成します。

sns.scatterplot(x=merged_df["IUDSOIA"],y=merged_df["Target"])

ポンド相互作用効果

図3:ポンド債に課される金利とGBPUSDペアの将来価値の関係を分析します。

このプロットを解釈する1つの方法は次のとおりです。プロットの上部から下部までの各線は、ポンド金利が固定された場合に目標がどのように変化するかを表します。ポンド金利が固定されているにもかかわらず目標値が変化しているという事実は、データに交互作用効果があることを示しています。これは、私たちが収集したオルタナティブデータ以外にも、目標に影響を与える強力な力が働いていることを示しているかもしれません。


機械学習技法 

適切な機械学習技法の選択は、データの性質に影響されます。次のことを考慮してください。

  • データセットのサイズ:行数が1万行以下、列数が30列以下の小さなデータセットでは、過剰適合のリスクを軽減するために、より単純なモデルを採用することが望ましいです。ディープニューラルネットワークのような複雑なモデルは、このような限られたデータでは効果的に学習するのが困難かもしれません。
  • データのノイズ:ノイズの多いデータセット(典型的にはデータポイントが欠落していたり、説明のつかないランダムな変動があるデータセットを意味する)にはより単純なモデルの方が適しています。複雑なモデルは分散が大きくなりがちで、ノイズの多いデータでは過剰適合しやすくなり、さらに、特にノイズの多い市場の日には、モデルがない方が良い場合さえあります。
  • データの次元性:データセットの列数が多い場合、前処理技術が有効です。高次元データの処理に有効なモデルを採用し、特徴選択と次元削減を適用します。
  • データサイズと計算能力:許容できるノイズレベルの大規模なデータセットがあり、その上、十分な計算リソースも利用できるのであれば、ディープニューラルネットワークのような高度なモデルを使用することが正当化されるかもしれません。これらのモデルは、十分な計算能力とクリーンなデータがあれば、データ内の複雑なパターンや関係を効果的に捉えることができます。

結論として、機械学習モデルの選択に完璧な解決策はありません。データのサイズ、ノイズ、次元、利用可能な計算能力などの性質は、最適なアプローチを決定する上で極めて重要な役割を果たします。堅牢で正確な予測結果を得るためには、データの特性に合わせてモデルを選択することが重要です。 
次に、どのようにデータに適したモデルを選択できるかを示します。


必要なライブラリをインポートすることから始めましょう。

import statistics as st

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

from sklearn.linear_model import Lasso,Ridge,LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import TimeSeriesSplit
from sklearn.metrics import mean_squared_error
from sklearn.svm import SVR
from sklearn.preprocessing import StandardScaler

from xgboost import XGBRegressor

次に、エクスポートしたcsvからデータを読み込みます。CSVには、私たちが統合したデータがすべて入っていました。

csv = pd.read_csv("C:\\Enter\\Your\\Path\\Here\\Alternative Data.csv")

データをスケールする準備をしましょう。

predictors = ['IUDSOIA', 'SOFR', 'Open', 'High', 'Low', 'Close']
target = 'Target'
scaled_data = csv.loc[:,predictors]
scaler = StandardScaler()
scaler.fit(scaled_data)
scaled_data = scaler.transform(scaled_data)

モデルを訓練しましょう。

splits = 10
gap = 30
models = ['Linear','Lasso','Ridge','Random Forest','Linear SVR','Sigmoid SVR','RBF SVR','2 Poly SVR','3 Poly SVR','XGB']

訓練とテストの分割を準備し、エラーメトリクスを格納するデータフレームを作成しましょう。

tscv = TimeSeriesSplit(n_splits=splits,gap=gap)
error_df = pd.DataFrame(index=np.arange(0,splits),columns=models)

ここで、モデルのエラーメトリクスを観察することができます。

for i,(train,test) in enumerate(tscv.split(csv)):
    model=XGBRegressor()
    model.fit(scaled_data.loc[train[0]:train[-1],predictors],csv.loc[train[0]:train[-1],target])
    error_df.iloc[i,9] =mean_squared_error(csv.loc[test[0]:test[-1],target],model.predict(scaled_data.loc[test[0]:test[-1],predictors]))

error_df

各モデルの誤差

図4:フィッティングした各モデルから得られた誤差の値


データの一部を箱ひげ図として可視化してみましょう。

fig , axs = plt.subplots(2,5,figsize=(20,20),sharex=True)

for i,ax in enumerate(axs.flat):
    ax.boxplot(error_df.iloc[:,i])
    ax.set_title(error_df.columns[i])


線形モデル

図5:使用したいくつかの線形モデルの誤差値


非線型モデル

図6:使用したいくつかの非線形モデルの誤差値


得られた概要統計の一部を表示します。

バリアンス(分散)      誤差 
線形分散:1.3365981802501968e-06 線形MSE:0.0022242681292296462
Lasso分散:3.0466413126186177e-05 LassoMSE:0.004995731270431843
Ridge分散:2.5678314939547713e-06 RidgeMSE:0.002467126140156681
ランダムフォレスト分散:2.607918492340197e-06 ランダムフォレストMSE:0.002632579355696408
線形SVR分散:3.825627012092798e-05 線形SVR MSE:0.004484702122899226
シグモイドSVR分散:27.654341711864102 シグモイドSVR MSE:1.6693947903605928
RBF SVR分散:4.1654658535332505e-05 RBF SVR MSE:0.004992333849448852
2ポリSVR分散:6.739873404310582e-05 2ポリSVR MSE:0.008163708245600027
3ポリSVR分散:0.0005393054392191576 3ポリSVR MSE:0.018431036676781344
XGB分散:7.053078880392137e-06 XGB MSE:0.003163819414983548


どのモデルも傑出したパフォーマンスを発揮していません。それらはすべて多かれ少なかれ同じパフォーマンス範囲内にあります。このような状況では、より単純なモデルの方が過剰適合の可能性が低いので、最適な選択かもしれません。したがって、この例では、取引戦略のモデルとして線形回帰を選択します。このモデルを選んだのは、その誤差レベルが他のどのモデルよりも優れており、さらにその分散が小さいからです。線形モデルは過剰適合の可能性が低く、長期にわたって安定する可能性が高いです。 


戦略の構築 

これで、Python用MetaTrader 5ライブラリを使用して、前のセクションで説明したすべてを堅牢な取引戦略に適用する準備が整いました。 

すべてのコードが簡単にたどれるように、すべてのステップで説明が与えられます。

まず、必要なパッケージをインポートします。

from fredapi import Fred
import MetaTrader5 as mt5
import pandas as pd
import numpy as np
import time
from datetime import datetime
import matplotlib.pyplot as plt

fredapiパッケージを使えば、FREDデータベースからプログラムでデータを引き出すことができます。ただし、ライブラリを使用する前にAPIキーを作成する必要があります。APIキーの作成は無料ですが、セントルイス連銀の無料ユーザーアカウントを作成した後でなければ取得できません。

次にグローバル変数を定義します。

LOGIN = ENTER_YOUR_LOGIN
PASSWORD = 'ENTER_YOUR_PASSWORD'
SERVER = 'ENTER_YOUR_SERVER'
SYMBOL = 'GBPUSD'
TIMEFRAME = mt5.TIMEFRAME_D1
DEVIATION = 1000
VOLUME = 0
LOT_MULTIPLE = 1
FRED = Fred(api_key='ENTER_YOUR_API_KEY')

では、取引口座にログインしてみましょう。

if mt5.initialize(login=LOGIN,password=PASSWORD,server=SERVER):
    print('Logged in successfully')
else:
    print('Failed To Log in')

ログイン成功です。

取引量を定義してみましょう。

for index,symbol in enumerate(mt5.symbols_get()):
    if symbol.name == SYMBOL:
        print(f"{symbol.name} has minimum volume: {symbol.volume_min}")
        VOLUME = symbol.volume_min * LOT_MULTIPLE

GBPUSDの出来高は最小:0.01


プログラム全体で使用する関数を定義しましょう。

まず、MetaTrader 5端末から現在の市場価格を取得する関数が必要です。

def get_prices():
    start = datetime(2024,3,20)
    end   = datetime.now()
    data  = pd.DataFrame(mt5.copy_rates_range(SYMBOL,TIMEFRAME,start,end))
    data['time'] = pd.to_datetime(data['time'],unit='s')
    data.set_index('time',inplace=True)
    return(data.iloc[-1,:])

次に、セントルイス連邦準備制度理事会にオルタナティブデータを要求する関数が必要です。

def get_alternative_data():
    SOFR = FRED.get_series_as_of_date('SOFR',datetime.now())
    SOFR = SOFR.iloc[-1,-1]
    SOIA = FRED.get_series_as_of_date('IUDSOIA',datetime.now())
    SOIA = SOIA.iloc[-1,-1]
    return(SOFR,SOIA)

次に、モデルの入力を準備する関数が必要です。

def get_model_inputs():
    LAST_OHLC = get_prices()
    SOFR , SOIA = get_alternative_data()
    MODEL_INPUT_DF = pd.DataFrame(index=np.arange(0,1),columns=predictors)
    MODEL_INPUT_DF['Open'] = LAST_OHLC['open']
    MODEL_INPUT_DF['High'] = LAST_OHLC['high']
    MODEL_INPUT_DF['Low'] =  LAST_OHLC['low']
    MODEL_INPUT_DF['Close'] = LAST_OHLC['close']
    MODEL_INPUT_DF['IUDSOIA'] = SOIA
    MODEL_INPUT_DF['SOFR'] = SOFR
    model_input_array = np.array([[MODEL_INPUT_DF.iloc[0,0],MODEL_INPUT_DF.iloc[0,1],MODEL_INPUT_DF.iloc[0,2],MODEL_INPUT_DF.iloc[0,3],MODEL_INPUT_DF.iloc[0,4],MODEL_INPUT_DF.iloc[0,5]]])
    return(model_input_array,MODEL_INPUT_DF.loc[0,'Close'])


そして、私たちのモデルを使って予測をおこなうための関数が必要です。

def ai_forecast():
    model_inputs,current_price = get_model_inputs()
    prediction = model.predict(model_inputs)
    return(prediction[0],current_price)

モデルを訓練しましょう。

training_data = pd.read_csv('C:\\Enter\\Your\\Path\\Here\\Alternative Data.csv')

モデルを設定します。

from sklearn.linear_model import LinearRegression
model = LinearRegression()

予測因子と目標を定義します。

predictors = ['Open','High','Low','Close','IUDSOIA','SOFR']
target     = 'Target'

モデルをフィッティングします。

model.fit(training_data.loc[:,predictors],training_data.loc[:,target])

取引アルゴリズムの核心に到達しました。

  • まず、無限ループを定義して、ストラテジーを稼働させ続けます。
  • 次に、現在の市場データを取得し、それを使用して予測をおこないます。
  • その後、モデルの期待値を表すブール値のフラグを持つことになります。モデルが価格の上昇を予想していれば、BUY_STATEはTrueとなり、そうでなければ、モデルが価格の下落を予想していれば、SELL_STATEはFalseとなります。
  • 未決済ポジションがない場合は、モデルの予測に従います。
  • 未決済ポジションがある場合は、モデルの予測が未決済ポジションに反しているかどうかを確認します。反していれば、ポジションをクローズします。反していなければ、ポジションを開けておくことができます。
  • 最後に、上記のすべてのステップを完了した後、アルゴリズムを1日スリープさせ、翌日に更新されたデータを取得します。

while True:
    #Get data on the current state of our terminal and our portfolio
    positions = mt5.positions_total()
    forecast , current_price = ai_forecast()
    BUY_STATE , SELL_STATE = False , False

    #Interpret the model's forecast
    if(current_price > forecast):
        SELL_STATE = True
        BUY_STATE  = False 

    elif(current_price > forecast):
        SELL_STATE = False
        BUY_STATE  = True

    print(f"Current price is {current_price} , our forecast is {forecast}")

    #If we have no open positions let's open them
    if(positions == 0):
        print(f"We have {positions} open trade(s)")
        if(SELL_STATE):
            print("Opening a sell position")
            mt5.Sell(SYMBOL,VOLUME)
        elif(BUY_STATE):
            print("Opening a buy position")
            mt5.Buy(SYMBOL,VOLUME)

    #If we have open positions let's manage them
    if(positions > 0):
        print(f"We have {positions} open trade(s)")
        for pos in mt5.positions_get():
            if(pos.type == 1):
                if(BUY_STATE):
                    print("Closing all sell positions")
                    mt5.Close(SYMBOL)
            if(pos.type == 0):
                if(SELL_STATE):
                    print("Closing all buy positions")
                    mt5.Close(SYMBOL)
    #If we have finished all checks then we can wait for one day before checking our positions again
    time.sleep(24 * 60 * 60)


最終結果

図7:初日の取引



2日目

図8:翌日の取引


結論 

オルタナティブデータは、金融市場の見方を変える大きな可能性を秘めています。適切なデータソースを注意深く選択することで、参加するほとんどの取引で正しい結果を得ることができる可能性があります。この戦略で最も重要なのは、信頼できるオルタナティブデータ源を持つことです。それ以外の場合は、通常のデータを使用しても問題ありません。時間をかけて自分で調べ、自分で結論を出し、自分の直感に従ってください。結局のところ、戦略構築は科学であると同時に芸術であることを忘れてはなりません。  したがって、どのオルタナティブデータソースが有用かを選択する際には、自分の推論スキルを慎重に適用し、さらに想像力を働かせて、ほとんどの人が思いつかないような斬新なアプリケーションやユースケースを見つけ出してください。 


推奨

今後の読者は、オルタナティブデータセットのより多くのソースを探し、オルタナティブデータの有用なソースを選択するために最適なサブセット選択などの機械学習技法を使用することが有益であると考えるかもしれません。さらに、デモで使用した線形モデルでは、データを生成したプロセスについて強い仮定を立てていることを忘れないでください。もしこれらの仮定が破られれば、モデルの精度は時間とともに悪化します。 

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

添付されたファイル |
Alternative_Data.zip (569.06 KB)
GMDH (The Group Method of Data Handling):MQL5で多層反復アルゴリズムを実装する GMDH (The Group Method of Data Handling):MQL5で多層反復アルゴリズムを実装する
この記事では、MQL5におけるGMDH (The Group Method of Data Handling)の多層反復アルゴリズム実装について説明します。
知っておくべきMQL5ウィザードのテクニック(第14回):STFによる多目的時系列予測 知っておくべきMQL5ウィザードのテクニック(第14回):STFによる多目的時系列予測
データのモデリングに「空間」と「時間」の両方の測定基準を使用する空間的時間的融合は、主にリモートセンシングや、私たちの周囲をよりよく理解するための他の多くの視覚ベースの活動で有用です。発表された論文のおかげで、トレーダーへの可能性を検証することで、その活用に斬新なアプローチを取ります。
ニュース取引が簡単に(第1回):データベースの作成 ニュース取引が簡単に(第1回):データベースの作成
ニュース取引は複雑で圧倒されるかもしれませんが、この記事ではニュースデータを入手する手順を説明し、さらに、MQL5経済指標カレンダーとその特徴についても学びます。
MetaTrader 5用のMQTTクライアントの開発:TDDアプローチ(最終回) MetaTrader 5用のMQTTクライアントの開発:TDDアプローチ(最終回)
この記事は、MQTT 5.0プロトコルのネイティブMQL5クライアントの開発ステップを説明する連載の最終回です。ライブラリはまだ製品化されていませんが、この部分では、他の証券会社から入手したティック(またはレート)でカスタム銘柄を更新するためにクライアントを使用します。ライブラリの現在の状況、MQTT 5.0プロトコルに完全に準拠するために足りないもの、可能なロードマップ、そしてその開発をフォローし貢献する方法についての詳細は、この記事の最後をご覧ください。