English Deutsch
preview
Pythonを使用したEA用ディープラーニングONNXモデルの季節性フィルタと期間

Pythonを使用したEA用ディープラーニングONNXモデルの季節性フィルタと期間

MetaTrader 5エキスパートアドバイザー | 23 5月 2024, 09:37
203 0
Javier Santiago Gaston De Iriarte Cabrera
Javier Santiago Gaston De Iriarte Cabrera

はじめに

外国為替市場の季節性から利益を得る」稿を読んだとき、これを興味深い記事にしようと考えました。季節性のあるEAと季節性のないEAを比較し、EAが恩恵を受けるかどうかを確認することができます。 

市場が季節要因に影響されることはすでに知っていました。マーク・ザッカーバーグが投資家からの資金でFacebookの資金を手に入れたことを知ったとき、このことは明らかでした。 この投資家は以前、カリブ海で予想されるハリケーンによる上昇を予測して、バー・ミツバからの資金を石油株に投資していました。彼はまず気候を調査し、ある期間に悪天候が続くと予測しました。

たとえ市場と季節性が良い関係にあることはわかっていても、結果が良くならなかったとしても、私はこの記事を書くことに非常に誇りを持っており、興味を持っています。これを実現する良い方法は、両方のEAを1つに統合することですが、それについてはすでに記事があるので、ここにリンクを貼っておきます  (「MQL5でONNXモデルをアンサンブルする方法の例」)。

まず、EAを使用してフィルタありとなしのモデルを比較し、データのフィルタがどのような影響を与えるかを確認します。その後、グラフを使用して季節性について議論し、最終的に2024年 2月を実際に季節性ありとなしで研究します。記事の最後の部分では(非常に興味深いと思います)、「MQL5でONNXモデルを使用する方法」稿ですでに得たEAに対する他のアプローチについて説明し、EAとONNXモデルを微調整することで利益を得られるかどうかを見てみます(答えは「得られる」です)。

これを実現するために、まずこの「Download all data from a symbol」スクリプトでデータ(すべてのティック)をダウンロードします(このスクリプトを購入してこの記事をサポートしてください)。このスクリプトを調べたい銘柄・チャートに追加するだけで、しばらく(1時間以内)すれば、その銘柄の過去のティックがすべてFilesフォルダにダウンロードされます。

すべてのティックをダウンロードしたら、そのcsvを操作して、必要な、あるいは欲しいデータ(この場合は2015年1月から2月までの期間から2023年までの期間)だけを抽出します。


季節性

取引における季節性とは、年間を通じて予測可能な資産価格の定期的な変動と変動を見極めることです。ある銘柄が他の銘柄よりも特定の時期に良い結果を出す傾向があることを認識するようなものです。この考えを少し紐解いてみましょう。

取引における季節性を理解します。

  • 定義:季節性とは、価格が時期によって繰り返し変動する傾向にあることに気づくことです。これは、実際の季節(夏や冬など)、商業シーズン(休日の雑踏など)、あるいは特定の月と関連付けることもできます。
  • 例:賢明な投資家が注意するパターンの例をいくつか挙げます。
    • 天候に左右される季節性:天候が農繁期に影響を与えるように、天候は商品価格や関連銘柄などにも影響を与えます。例えば、ビーチ用品を販売する会社では、夏場は売上が伸びるが、寒くなると落ち込み、株価に影響を与えるかもしれません。
    • 祝日の季節性:小売株は、祝日商戦の熱狂の中でしばしば上昇します。ギフトショップのような祝日商戦に強い企業は、この時期に輝きを増す傾向があります。
    • 四半期業績の季節性:上場企業は四半期ごとに決算を発表しており、株価はこの時期に予想通りの反応を示します。
    • 税務の季節性:税務関連の出来事は、特に金融に関連するセクターにとっては市場を揺るがす可能性があります。
    • 自然のサイクル:観光業やエネルギー産業には、夏のバカンスや冬の暖房需要など、季節ごとの需要パターンがあります。

季節性に基づく取引戦略:

  • トレーダーはいくつかの方法で季節性を活用することができます。
    • 季節のパターンを見極める:過去のデータを調べ、特定の時期に繰り返される傾向を見つけます。
    • 取引タイミング:こうした季節的なトレンドに基づいて、ポジションを建てたり決済したりします。
    • リスク管理:不安定な時期にどの程度のリスクを取るかを調整します。
    • セクターローテーション:1年のうち、時期によってパフォーマンスが良くなる傾向のあるセクター間で投資を切り替えます。


データのフィルタ

ここではローパスフィルタを使用します。次はウィキペディアからの引用です。

ローパスフィルタは、遮断周波数より低い周波数の成分はほとんど減衰させず、遮断周波数より高い周波数の成分を逓減させるフィルタである。フィルタの正確な周波数特性は、フィルタ設計に依存する。このフィルタは、オーディオ用途ではハイカットフィルタやトレブルカットフィルタと呼ばれることもある。ローパスフィルタはハイパスフィルタと対称の関係にある。

なぜアルゴリズム取引ではハイパスフィルタではなくローパスフィルタを選択するのでしょうか。アルゴリズム取引においてローパスフィルタが好まれるのは、いくつかの重要な利点に由来します。
  1. シグナルの平滑化:ローパスフィルタはノイズの多い値動きを効果的に平滑化し、短期的な変動よりも長期的なトレンドを強調します。
  2. 高周波ノイズの低減:ローパスフィルタは、取引戦略にとって意味のある情報を提供しない可能性のある高周波ノイズを減衰させるのに役立ちます。
  3. 取引コストの削減:より長期的なトレンドに注目することで、ローパスフィルタはより少ない戦略的な取引につながり、取引費用を削減できる可能性があります。
  4. より優れたリスク管理:ローパスフィルタは、短期的な市場変動の影響を軽減し、より安定した予測可能な取引戦略に貢献します。
  5. 投資ホライズンとの整合性:ローパスフィルタは、長期的な視野に立った投資戦略に適しており、長期間にわたるトレンドを効果的に捉えることができます。

個人的には、高周波をフィルタするためにローパスフィルタを使用しています。ここでハイパスフィルタを使用するのはあまり意味がありません。

これを使用します(注:結局、記事の最後の部分で、パラメータのcutoff_frequencyを0.1、cutoffとorderを1に変更しました。それの方が結果が良かったからです。また、フィルタするための正しい.pyは、記事の最後の部分のものです(そこでは、より良いパラメータを使用しただけでなく、フィットとインバースにminmaxscalerも使用しました))。

# Low-pass filter parameters
cutoff_frequency = 0.01  # Cutoff frequency as a proportion of the Nyquist frequency
order = 4

# Apply the low-pass filter
def butter_lowpass_filter(data, cutoff, fs, order):
    nyquist = 0.5 * fs
    normal_cutoff = cutoff / nyquist
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    print("Filter coefficients - b:", b)
    print("Filter coefficients - a:", a)
    y = lfilter(b, a, data)
    return y

filtered_data_low = butter_lowpass_filter(df2['close'], cutoff_frequency, fs=1, order=order)

ここでは onnx_LSTM_simple_filtered.pyとonnx_LSTM_simple_not_filtered.pyを使用してONNXモデルを作り、比較します。

注:ローパスフィルタのパラメータが異なるモデルv1とモデルv2を使用しました。

これがその結果です。

EAには同じ入力を使用します。

入力

入力2

研究期間は2月1日から3月1日までです。

フィルタなしモデルの場合:

RMSE         : 0.0010798043714784716
MSE          : 1.165977480664017e-06
R2 score     : 0.8799146678247277

フィルタなし


フィルタ付きV1

# Parámetros del filtro pasa bajo

cutoff_frequency = 0.01  # Frecuencia de corte en proporción a la frecuencia de Nyquist

order = 4


RMSE         : 0.0010228999869332884
MSE          : 1.0463243832681218e-06
R2 score     : 0.8922378749062259


フィルタ付きv1


フィルタ付きV2

cutoff_frequency = 0.1  # Frecuencia de corte en proporción a la frecuencia de Nyquist

order = 2

RMSE         : 0.0010899163515744447
MSE          : 1.1879176534293484e-06
R2 score     : 0.8775550550819025

フィルタ付きV2


フィルタの結論

正しいパラメータを使用した場合のみ、より良い結果が得られます。

よって、フィルタの使用は便利です。

使用コードとモデル

ONNX.eurusd.H1.120.Prediction_FILTERED.mq5

ONNX.eurusd.H1.120.Prediction_FILTERED_v2.mq5 ONNX.eurusd.H1.120.Prediction_NOT_FILTERED.mq5のダウンロード

onnx_LSTM_simple_EURUSD_filtered.py

onnx_LSTM_simple_EURUSD_not_filtered.py

銘柄からすべてのデータをダウンロードする: EURUSD_LSTM_120_1h_not_filtered.onnx EURUSD_LSTM_120_1h_filtered_v1.onnx EURUSD_LSTM_120_1h_filtered_v2.onnx


銘柄には季節性があるのか?

この部分では、まずこれをグラフで見ます。2015年から2023年までの2月のデータを取得し、その週前後の動きを見るためにデータを追加します。

これがその期間から見えるものです。

2月の合計

結論

いくつかの傾向があることがわかります。少なくとも黒(合計線)は水平でありません。各行の間にはギャップがありますが、これは銘柄が年間を通じて取引され、価格が変動するためです。このため、この記事の次の部分では、2月のすべての銘柄を年ごとに連結します。また、このため、たとえば、2022年の最後の日付から2023年2月1日までの高頻度を通過させないため、フィルタを使用する必要があります。AIがたとえば金曜日のクローズと月曜日のオープンを学習した場合、これらの変化を学習せず、より平滑化されたデータを求めます。

スクリプトと使用データ

銘柄から全てのデータをダウンロードする Download_seasonalities_1h_v2.py data febs.zip draw_with_sum.py


この銘柄データは相関関係があるのか?

自己相関は、連続する時間間隔の値間の類似性の程度を示すデータの特性です。

1に近い値は、大きな正の相関があることを示します。

これはautocorrelation.pyで得られた結果です。

[1.         0.99736147 0.99472432 0.99206626 0.98937664 0.98671649
 0.98405706 0.98144222 0.9787753  0.97615525 0.97356318 0.97099777
 0.96848029 0.96602671 0.96360361 0.96113539 0.95865344 0.95615626
 0.95362417 0.95108177 0.94854957 0.94599045 0.94346076 0.94091564
 0.93837742 0.93583734 0.9332909  0.93074655 0.92826504 0.92579028
 0.92330505 0.92084645 0.91834403 0.91581296 0.91328091 0.91076099
 0.90826447]


2月シーズン用のONNXモデルの作成

このタスクでは、すべてのデータを1つのcsvに連結し、それを使用してモデルを作るだけです。

create concatseasonal.pyを使用して1つのCSVを作成し、zip seasonal_feb_contacに追加します。onnx_LSTM_..._seasonals.pyで訓練し、モデルを作成します。

使用したスクリプトとデータ


seasonal_feb_concat.zip
create_concat_seasonal_data.py

onnx_LSTM_simple_EURUSD_concat_seasonals.py


季節モデルのテスト結果と120日(1H)フィルタ付きモデルとの比較

季節モデル

RMSE         : 0.013137568368684325
MSE          : 0.00017259570264185493
R2 score     : 0.7166764010650979

これは驚くような結果ではありませんが、全体的には良好な結果です(マイナスのシャープの結果はあまりない)。

シャープ

シャープ2

季節最適化


フィルタ付きモデルと比較すると、このようになります。

シャープフィルタ付き

シャープフィルタ2D

フィルタ付き最適化


私が不思議に思ったのは、フィルタモデルの最適化ではシャープ値のマイナスの数が表の半分を占めているのに対し、季節性モデルではマイナスの数が表の5分の1程度を占めていることです。これは注目すべきことで、たとえr2が低くても、利益をもたらす頑健なモデルであるように思われるからです。

SLとTPを使わずにEAをテストすることもできましたが、EAでは常にSLとTPを使用する方が良いです。


使用したコードとONNXモデル

ONNX.eurusd.H1.120.Prediction_seasonal.mq5 EURUSD_LSTM_270_1h_filtered_seasonal0.72.onnx onnx_LSTM_simple_EURUSD_concat_seasonals.py



どの時期に使用するのか?

この記事では、EURUSDでより良い結果が得られるようにフィルタを微調整しました。

cutoff_frequency = 0.1  # Frecuencia de corte en proporción a la frecuencia de Nyquist
order = 1

フィルタも修正しました。

from sklearn.preprocessing import MinMaxScaler
from scipy.signal import butter, lfilter

# Parámetros del filtro pasa bajo
cutoff_frequency = 0.1  # Frecuencia de corte en proporción a la frecuencia de Nyquist
order = 1

# Aplicar filtro pasa bajo
def butter_lowpass_filter(data, cutoff, fs, order):
    nyquist = 0.5 * fs
    normal_cutoff = cutoff / nyquist
    b, a = butter(order, normal_cutoff, btype='low', analog=False)
    print("Coeficientes del filtro - b:", b)
    print("Coeficientes del filtro - a:", a)
    y = lfilter(b, a, data)
    return y

scaled = MinMaxScaler(feature_range=(0,1))

valores_df1 = df.filter(['close']).values
valores_df1 = pd.DataFrame(valores_df1)
x_features1 = valores_df1[[0]]
valores_df2 = x_features1.values


data_escalada = scaled.fit_transform(valores_df2)

print(data_escalada)

filtered_data_low = butter_lowpass_filter(data_escalada, cutoff_frequency, fs=1, order=order)
print("filtered_data_low",filtered_data_low)

filtered_data_low_unscaled = scaled.inverse_transform(filtered_data_low)

注文は整数の価格に四捨五入する必要があります。

この戦略は、1 時間間隔では1ヶ月にわたって、具体的には2024年2月にテストされます。30分間隔では、2月1日から2月15日までテストされます。

15分間隔では、フィルタを使用した場合と使用しなかった場合のテストをおこない、その結果、微調整したフィルタを使用した方が(少なくとも全体的には)良い結果が得られるという結論に達しました。

フィルタ付き15分(シャープ)

フィルタ付き15分テスト


テスター 2D 15分

1フィルタ付き15分テスト


LTSM_simple_15m_filtrado.py LSTM.15m.EURUSD.120.0.98.onnx ONNX.eurusd.H1.120.15m_eurusd.mq5


フィルタなし15分

フィルタなし15分テスト

2d 15分フィルタなし

フィルタ付き15分テスト

LTSM_simple_15m_filtrado_sin.py LSTM.15m.EURUSD.120.0.98.onnx ONNX.eurusd.H1.120.15m_eurusd.mq5


フィルタ付き30分(以後は常にフィルタを使用)

テスター 30分

テスター 30分 2D

30分テスト


LSTM.30m.EURUSD.120.0.94.onnx
LTSM_simple_30m_filtrado.py ONNX.eurusd.H1.120.30m_eurusd.mq5


1時間

1時間テスト

1時間テストヒートマップ

1時間テスト


1 hour files.zip (815.64 KB)


2時間

2日間の期間を使用することができないので、1日間の期間を使用しました(EAのNextDay値)。

テスター 2時間

ヒートマップ 2時間

テスト 2時間

グラフ 2時間

バックテスト2時間


2h.zip

32以上のファイルは読み込めないので、次のファイルはすべてフォルダにアップロードされます。


結論

この戦略では、期間が長くなるにつれて、すべてのTPとSLの結果がより強固になるようです。


NextDay変数

ONNXモデルをmql5で使用する方法」稿の戦略を使用していますが、2時間戦略で良い結果を得ているので、1日足を使用しています。他のNextDay変数値を検討します。

   if(TimeCurrent()>=ExtNextDay)
     {
      GetMinMax();
      //--- set next day time
      ExtNextDay=TimeCurrent();
      ExtNextDay-=ExtNextDay%PeriodSeconds(PERIOD_D1);
      ExtNextDay+=PeriodSeconds(PERIOD_D1);
     }
void GetMinMax(void)
  {
   vectorf close;
   close.CopyRates(_Symbol,PERIOD_D1,COPY_RATES_CLOSE,0,SAMPLE_SIZE);
   ExtMin=close.Min();
   ExtMax=close.Max();
  }

ここでは、期間30分のEURUSDをフィルタ付きデータで、異なるNextDay期間(1日、12時間、6時間を使用)で研究し、結果を議論します。

30分(NextDayは1日)

1D30分

1Dヒートマップ30分

1Dテスト


30分(NextDayは12時間)

12H30分テスト

12Hヒートマップ

12Hテスト 30分


30分(NextDayは6時間)

6H30分

6Hヒートマップ 30分足

6H 30分テスト


NextDay変数値を微調整すると、結果は良くなるようです。NextDayが短い期間でどのように変化するか見てみましょう。

30分(NextDayは4時間)

4時間

4時間ヒートマップ

テスト4時間


30分(NextDayは2時間)

30分2H

30分NextDay2Hヒートマップ

2Hテスト


30分(NextDayは1時間)

1H 30分

1Hヒートマップ30分

テスト1H 30分


少なくとも30分間では、30分間に8バーから12バー程度が良い結果をもたらすようです。


この「ゲーム」はより多くのお金を獲得することであり、そのための1つの方法は、より多くの勝ちトレードと堅実な戦略を持つことです。この戦略を使用して5分間の期間で勝つことができるかどうかを見てみましょう。NextDay変数を1時間と30分にして試してみます。

入力

5分(NextDayは1時間)

テスター1H(5分間)

ヒートマップ1H(5分間)

結果テスト1H(5分)



5分(NextDayは30分)

テスター 30分(5分)

ヒートマップ 30分(5分)

テスト 30分(5分)

使用ファイル:   Last files.zip

他の期間はより信頼性が高いようですが、別のEAが必要な場合は、より多くのEAを使用する必要があります。


例えば、時間やバーの制限を設けるなどして、より良い結果やより堅実な結果を得ることができます。例えば、1時間の期間で、NextDayを12時間とすると、一度注文を出したら、12時間以内に決済しなければならないことにできます。

   if(ExtPredictedClass>=0)
     {
      if(PositionSelect(_Symbol))
         CheckForClose();
      else
        {
         CheckForOpen();
         started_time1 = rates[0].time;
         string started_time1_str = TimeToString(started_time1);
int total = PositionsTotal();
   if(total>0)
     {
      datetime started_time2 = rates[0].time;
      string started_time2_str = TimeToString(started_time2);
      int segundos = started_time2 - started_time1;
      Print("Tiempo 1: ", started_time1_str);
      Print("Tiempo 2: ", started_time2_str);
      Print("Diferencia en segundos: ", segundos);
      if((segundos >= days*PeriodSeconds(PERIOD_H12)) && segundos != 0)
        {
         Print("closing position----------------");
         ExtTrade.PositionClose(_Symbol,3);

        }
     }

テスター

ヒートマップ

テスト

グラフ


ONNX.eurusd.120.1h_H12_eurusd.v3.mq5
 (9.23 KB)


結論

季節性、フィルタ、モデルやEAの比較、EAのパラメータを見てきました。私がこの記事を作るのを楽しんだように、読者がこの記事を読むのを楽しんでくれたら幸いです。 


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

MQL5入門(第6部):MQL5における配列関数の入門ガイド MQL5入門(第6部):MQL5における配列関数の入門ガイド
MQL5の旅の次の段階を始めましょう。この洞察に満ちて初心者に優しい記事では、残りの配列関数について調べ、複雑な概念を解明し、効率的な取引戦略を作成できるようにします。ArrayPrint、ArrayInsert、ArraySize、ArrayRange、ArrarRemove、ArraySwap、ArrayReverse、ArraySortについて説明します。アルゴリズム取引の専門知識を、これらの必要不可欠な配列関数で高めてください。一緒にMQL5マスターへの道を歩みましょう。
知っておくべきMQL5ウィザードのテクニック(第13回):ExpertSignalクラスのためのDBSCAN 知っておくべきMQL5ウィザードのテクニック(第13回):ExpertSignalクラスのためのDBSCAN
DBSCAN (Density-Based Spatial Clustering of Applications with Noise)は、データをグループ化する教師なし形式であり、入力パラメータをほとんど必要としません。入力パラメータは2つだけであり、K平均法などの他のアプローチと比較すると利点が得られます。ウィザードで組み立てたEAを使用してテストし、最終的に取引するために、これがどのように建設的であり得るかを掘り下げます。
制約付きCustom Maxを実装するための一般的な最適化定式化(GOF) 制約付きCustom Maxを実装するための一般的な最適化定式化(GOF)
この記事では、MetaTrader 5端末の設定タブでCustom Maxを選択する際に、複数の目的と制約条件を持つ最適化問題を実装する方法を紹介します。最適化問題の例は、ドローダウンが10%未満、連敗回数が5回未満、1週間の取引回数が5回以上となるように、プロフィットファクター、ネットプロフィット、リカバリーファクターを最大化するといったものです。
MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第7回):オーサムオシレーターシグナルを持つジグザグ MQL5を使ったシンプルな多通貨エキスパートアドバイザーの作り方(第7回):オーサムオシレーターシグナルを持つジグザグ
この記事の多通貨エキスパートアドバイザー(EA)は、オーサムオシレーター(AO、Awesome Oscillator)でフィルタされたジグザグ(ZigZag)指標を使用するまたは互いのシグナルをフィルタするEA(自動売買)です。