English Русский 中文 Español Deutsch Português
preview
MQL5の圏論(第21回):LDAによる自然変換

MQL5の圏論(第21回):LDAによる自然変換

MetaTrader 5トレーディングシステム | 23 1月 2024, 12:46
184 0
Stephen Njuki
Stephen Njuki

はじめに

これまで、、学問的な場以外でも応用可能なトピックを数多く取り上げてきました。集合と射、コミュテーション、オントロジーログ、積、共積、極限、コリミット、モノイド、群、グラフ、次数、関手、そして今回の自然変換です。圏論は、ここで検討したものよりもはるかに広い範囲をカバーするものであり、これらのトピックは、数学に関連する他の学問分野への適用や利用が容易であることから選ばれたものです。このテーマについてより徹底的なレビューに興味があるなら、これらの問題について聖書とみなす人もいる「圏論の基礎」が興味深いはずです。

自然変換についての考察を続けるにあたり、この記事では時系列予測への応用についてさらに考察します。自然な変換は、関連性のあるデータセットから推測できることが多いです。

そこで問題です。ある新興企業が、顧客の購入履歴を長期的に管理するためにデータベースを作成し、最初には主キー、製品名列、支払金額列の3列があるとします。時間が経つにつれて、この企業は製品列に多くの繰り返しがあることに気づきます。つまり、特定の製品が多く購入されているということです。そこで、顧客の嗜好をよりよく識別し、ポートフォリオに欠けている可能性のある製品の開発を検討するために、製品に関するより多くの情報を記録し始めることが決定されました。この目的のために、製品列はバージョン、サブスクリプションモード、ビルド名の3列に分割されます。 あるいは、支払い情報により多くの色を必要とし、支払い列を3つに分割し、例えば支払いモード、通貨(またはロケール)、支払い金額の列を設けることにするかもしれません。将来の段階では、顧客の購入状況や好みによって、さらに多くの分割が必要になるかもしれないからです。

新しく作成された各列は、古い製品列に写像されます。また、例えば、古い単一製品列と支払金額列、あるいはデータベース内のテーブルの他の列との間に、いくつかの重要な相関関係を確立していた場合、新しいテーブル構造でこれらの相関関係を再確立するのは面倒な作業となります。この問題に対処する手段はたくさんあるでしょうが、自然変換はシームレスな代替案を提供します。

これを理解するために、まず2つの圏に分けて考えてみましょう。始域圏には、企業データベースのテーブルリストがあり、コード始域圏には、2つのバージョンの顧客情報テーブルがあります。簡潔化のために、リストを始域内の1つのオブジェクトとし、各テーブルを終域内の別々のオブジェクトとすると、リストから各テーブルへの2つの関手が、2つのテーブル間の自然変換を意味します。つまり、1つの関手は古いテーブル(ここでの場合は単純な3列テーブル)に対応し、2つ目の関手はテーブル構造のリビジョンに対応することになります。これがリビジョン1の場合、2番目の関手は5列のテーブルに写像されます。

自然変換の意味は、一次方程式、二次方程式、多層パーセプトロン、ランダム分布フォレスト、線形判別分析などのアルゴリズムによる写像関数によって、これら2つのテーブル間の違いを定量化できることを意味するだけでなく、これらの重みを使って、古いテーブルとの事前相関を再確立し、作成された列に対して新しい相関を開発できることを意味します。


背景

つまり、簡単にまとめると、自然変換とは、2つの関手のターゲットオブジェクトの違いです。この違いの使い方は、本連載でこれらの関手の終域範疇のオブジェクトの可換合成である自然性の四角形で強調されてきました。第18回ではこれを紹介し、第19回では自然性の四角形の帰納法を使ったさらなる例を見ました。

多くのトレーダーは、価格チャートやMetaTraderターミナルに内蔵されている指標に精通しているだけでなく、独自のカスタム指標をコーディングしたり、エキスパートアドバイザー(EA)を開発したりしているので、時系列データの概念はほとんどのトレーダーにとって異質なものではありません。そのため、これらまたはこれらのようなテーマについては、ほとんどの人がある程度の下調べをしています。それにもかかわらず、チャートで見る外国為替ペアの価格は各期間で明確な価格を持っていることを考えると離散時間です。週の大半である市場が開いているときは常に変化しており、実際には連続した時間系列であるという事実にもかかわらずです。そのため、離散時間系列ビューが分析の助けになります。

従って、分析をおこなう能力は、特定の時点における特定の証券の「コンセンサス」価格を持つことに根ざしています。そして、ほとんどの予測の目的である予測をおこなおうとする場合、異なるタイムエポックにおける異なる系列の研究が重要になります。だからこそ、タイムラグのあるデータを見比べることは、正確な結果を得る上でより建設的といえます。

したがって、この記事では2つのデータセットを見ていくことにします。「はじめに」でほのめかしたように、2つのデータセットは似ており、一方は他方より単に精巧なだけです。この2つのセットを使って、遅延付きの自然変換をおこない、予想に役立てます。この2つのデータセットはテーブルとして表すことができ、非常にシンプルです。1つ目は移動平均値、2つ目はその平均値を構成する価格が表示されます。


データセットの説明

シンプルなテーブルには2つの列があるだけです。タイムスタンプ列と移動平均列です。このテーブルと複合テーブルの行数は、ユーザーが入力パラメータm_dataで設定します。この単純なテーブルは、使用される移動平均の期間の大きさによって、複合テーブルよりも時間をずらして表示されます。つまり、移動平均の期間が5であれば、このテーブルの値は複合テーブルの5回分の棒グラフになります。

後発の複合テーブルは、タイムスタンプの列と、それぞれ異なる時点の価格を示す列を持ちます。タイムスタンプを超えるこれらの追加列の数は移動平均期間によって設定されるため、ここでも移動平均が5価格バーを超えている場合、このテーブルには1つのタイムスタンプ列と5つの価格列が含まれることになります。

自然変換写像を持つこれら2つのデータセットは、「はじめに」ですでに挙げたように、多くの方法で定義することができます。この記事では、本連載でまだ検討したことのない方法、線形判別分析(LDA)を使用します。MQL5ウィザードとAlglibライブラリをどのように使うかは、この記事で紹介しましたが、ここで復習しておくと役に立つかもしれません。

より具体的な定義は、こちら(英語)にありますが、大まかに言えばLDAは分類器です。典型的な訓練データセットを見ると、常に独立変数(最終結果に影響を与えると仮定される値)と、「最終結果」として機能する分類器変数(複数可)があります。LDAでは、この最終結果を最大nクラス(nは自然数)に分類することができます。Ronald Fisher卿(英語)によって開発されたこのアルゴリズムは、各分類の主要な重心を定義するのに役立つ重みのベクトルを出力し、未知の重心(新しいまたは未知のデータポイント)の位置を推定することもできます。この情報があれば、未知の重心と既知の重心の位置を単純に比較し、どちらに近いかを知ることができます。これを説明するために、「重みのベクトル」は、2つの分類子だけを持つ点を区切る線の方程式と考えることができます。分類子が3つなら、それは平面の方程式です。もし1つなら、数直線上の座標です。どちらのシナリオでも、各データポイントに座標セットを与えることで、訓練データセットの区別をつけることができます。


時系列予測のための自然変換

従って、以前に第18回と第19回で述べたように、自然性の正方形を見る場合、通常は終域のオブジェクトがすべてであり、この記事のために、価格ポイントと移動平均の2つの異なるデータセットがどのように自然変換を共有できるかを示すにあたり、関手のソース圏やオブジェクト(複数可)については何も述べていません。これらは重要ではありません。しかし、ソース圏に複数のオブジェクトがある場合、単純データセットと複合データセットの両方に複数の比例インスタンスが存在することになります。このことは、第19回の自然性の正方形の帰納法を見たときに浮き彫りになりました。

図の写像の観点からすれば、ここでの自然変換は過度に複雑なものではないはずです。データセットのタイムスタンプ列はリンクされ、複合データセットのすべての価格列は単純データセットの移動平均列に写像されます。これは通常、説明とロジックのためにMQL5コードで表現され、そのために単純データセットと複合データセットのインスタンスがそれぞれm_o_sとm_o_cとして宣言されています。これらのクラスインスタンスは、「始域」という用語が、射にリンクされたオブジェクトの1つに対するプロパティであり、それ自体は必ずしも名詞ではないという認識のもと、「始域」ではなく「オブジェクト」という名前になりました(意味が通じるかどうかわかりませんが)。以前の記事の大半で「始域」と呼んでいたものは、より一般的には「オブジェクト」と呼ばれます。MQL5の内蔵クラスとの混同を避けるため、「オブジェクト」の使用は控えていました。この方法では、価格データを直接写像関数にコピーするような直接的な方法よりも、ロジックの間違いが起こりにくくなります。このようなバグは、EAをテストしても、正常にコンパイルされるため表示されません。したがって、ここでは何が可能であるかを示すためにそれを実証しているだけです。

LDAを用いて自然変換をおこない、遅行価格ポイントから将来の移動平均価格値への重要な写像をおこないます。タイムスタンプの列は利用されませんが、読者がどのようにデータが構成されているかを理解できるように、念のため記載しておきます。上記のタイムラグは移動平均期間の長さに相当します。訓練の際には、移動平均の期間の長さをnとしたとき、開始インデックスからn本さかのぼった価格を使用することになります。つまり、予測をおこなう際には当然ながら最新の価格を使用するが、予測はn本先までとなります。直近の移動平均線ではありません。


予測のための自然変換の適用

そのため、このコードは主にシグナルクラス内の2つの関数で処理されることになります。というのも、前述のように、一般的に圏のアウトラインとなるクラス構造全体、つまり射や関手を使ってコーディングするのではなく、オブジェクトクラスと要素クラスだけを使って、終域圏にあるものを写像するからです。最終的な結果は同じになるはずですが、ここで選ばれたアプローチは、コンピュータのリソースに対してより効率的であり、したがってストラテジーテスターでのテストも容易になります。しかしこの場合、圏とその関手のロジックのミスを避けるため、コンパイルやストラテジーテストの実行時にミスが表示されないよう、より注意を払う必要があります。つまり、更新関数は以下のようになります。

//+------------------------------------------------------------------+
//| Refresh function to update objects.                              |
//+------------------------------------------------------------------+
void CSignalCT::Refresh(int DataPoints=1)
   {
      m_time.Refresh(-1);
      m_close.Refresh(-1);
      
      for(int v=0;v<DataPoints;v++)
      {
         m_e_s.Let(); m_e_s.Cardinality(2);
         m_e_c.Let(); m_e_c.Cardinality(m_independent+1);
         
         m_e_s.Set(0,TimeToString(m_time.GetData(v)));
         m_e_c.Set(0,TimeToString(m_time.GetData(v)));
      
         double _s_unit=0.0;
         //set independent variables..
         for(int vv=0;vv<m_independent;vv++)
         {
            double _c_unit=m_close.GetData(StartIndex()+v+vv+m_independent);
            
            m_e_c.Set(vv+1,DoubleToString(_c_unit));
         }
         
         m_o_c.Set(0,m_e_c);
         
         //get dependent variable, the MA..
         for(int vv=v;vv<v+m_independent;vv++)
         {
            _s_unit+=m_close.GetData(StartIndex()+vv);
         }
         
         _s_unit/=m_independent;
         
         m_e_s.Set(1,DoubleToString(_s_unit));
         
         m_o_s.Set(0,m_e_s);
      }
   }


この更新関数は、下記のGetDirection関数によって呼び出されます。

//+------------------------------------------------------------------+
//| Get Direction function from implied naturality square.           |
//+------------------------------------------------------------------+
double CSignalCT::GetDirection()
   {
      double _da=0.0;
      
      int _info=0;
      CMatrixDouble _w,_xy,_z;
      _xy.Resize(m_data,m_independent+1);
      
      double _point=0.00001;
      if(StringFind(m_symbol.Name(),"JPY")>=0){ _point=0.001; }
      
      for(int v=0;v<m_data;v++)
      {
         Refresh(v+1);
         
         ...
         
         //training classification
         _xy.Set(v,m_independent,(fabs(_ma-_lag_ma)<=m_regularizer*_point?1:(_ma-_lag_ma>0.0?2:0)));
      }
      
      m_lda.FisherLDAN(_xy,m_data,m_independent,__CLASSES,_info,_w);
      
      if(_info>0)
      {
         double _centroids[__CLASSES],_unknown_centroid=0.0; ArrayInitialize(_centroids,0.0);
         
         _z.Resize(1,m_independent+1);
         
         m_o_c.Get(0,m_e_c);
         
         for(int vv=0;vv<m_independent;vv++)
         {
            string _c="";
            m_e_c.Get(vv+1,_c);
            
            double _c_value=StringToDouble(_c);
            _z.Set(0,vv,_c_value);
         }
         
         for(int v=0;v<m_data;v++)
         {
            for(int vv=0;vv<m_independent;vv++)
            {
               _centroids[int(_xy[v][m_independent])]+= (_w[0][vv]*_xy[v][vv]);
            }
         }
         
         // best vector is the first 
         for(int vv=0;vv<m_independent;vv++){ _unknown_centroid+= (_w[0][vv]*_z[0][vv]); }
         
         
... 
      }
      else
      {
         
... 
      }
      
      return(_da);
   }

予測するのは将来の移動平均価格の変化であるため、マイナスの変化は弱気、プラスの変化は強気を示し、「変化なし」は市場の横ばいを意味します。「変化なし」を定量化するために、レギュライザーパラメータ「m_regulizer」があります。これは、弱気または強気の変化とみなされるための最小の予測規模を設定します。銘柄のポイントサイズと掛け合わせることで数値化される整数です。

というわけで、これが変換を実装するコードのようやくです。重要な変数の宣言は、いつものようにクラスマニフェストでおこないます。シグナルクラスの典型的な宣言に加え、特別なクラスとして、単純要素のインスタンス、複合要素のインスタンス、単純要素、複合要素、線形判別クラスのインスタンスの宣言を追加します。

新しいバーができるたびに、更新関数を使ってこれらの要素、ひいてはそのオブジェクトの値を更新します。これには、独立変数を割り当て、単純に入力移動平均期間の長さに等しい数の価格を割り当てます。これらの価格を複合要素とオブジェクトに渡します。LDAには3つの分類子を使用し、2つは強気、1つは綾押し/綾戻し相場、0は弱気相場を表します。つまり、各訓練データポイントは、現在の移動平均(訓練セットのインデックスに基づく)と遅行移動平均との差に基づいて分類を割り当てられます。両平均は、すでに述べた入力と等しい長さで取られ、遅延もこの長さに等しくなります。

分類子の割り当ては、このAlglibによる線形判別分析の実装のもとでの訓練に相当します。どのシグナルを無視するか、つまり何がホワイトノイズなのかを単純に決定する正則化レジームについても言及する価値があるでしょう。2つの移動平均の差のうち、入力パラメータm_regularizerよりも小さいものを、銘柄のポイントサイズと掛け合わせて、価格移動平均のスプレッドと同等にします。

これでフィッシャー関数を実行し、係数(または重み)の行列'w'を出力します。これは、説明したように、分類器間の定義平面に対する方程式を形成します。

次の予測のための現在の価格ポイントを表すZ行列は、最新の価格配列で埋められ、その後、w行列で定義されたセントロイド値を得るために、フィッシャー関数からw行列とのドット積が与えられます。この値が未知のセントロイドです。

同様に、3つの分類器のセントロイド値も、この行列と独立変数の行列とのドット積で埋められます。

3つの分類器のセントロイド値と未知数のセントロイド値が得られたので、この未知数と3つの分類器を比較し、未知数がどの分類器に最も近いかを確認します。


実世界での応用

ケーススタディとして、今年の初めから6月1日までGBPUSDでテストをおこないました。その結果、以下のような報告がなされました。

r1


8月までのウォークでは、以下のレポートにあるような否定的な結果が得られます。

r2


ウォークフォワードレポートに基づく予測精度には疑問があるようですが、これは最適化の実行が不完全であったこと(最初の3世代のみ実行)、あるいはテストウィンドウが小さすぎたことが原因かもしれません。ソースコードが添付されているので、読者が対処できるでしょう。しかし、ここで示されているのは、本連載のすべての記事と同様、取引システムを発展させる可能性です。


結論

日常生活において、データベースのテーブルやデータ保存形式は、単にサイズが大きくなるだけでなく、複雑になることがよくあります。この最後のポイントは、データ列が追加されるにつれて複雑になっていくデータセットを見て実証しました。予測を行うために時間差のあるデータセットを考慮することで、これを目的に活用しようと考えました。最適化の結果は、わずか3世代の実行で可能性を示しましたが、これらの実行はウォークフォワードすることができませんでした。これは、このシグナルクラスを他のシグナルクラスと組み合わせることで改善できるかもしれないし、より長時間の広範なテストが実施されるかもしれません。

自然変換は、ビジネスや分析のニーズによってデータセットが変化する場合だけでなく、比較が必要な場合、デフォルトでは両方のデータセットのディメンション(列数)が同じでない場合など、さまざまなデータ構造を扱うのに適しています。これは、いくつかの分野で重宝されるに違いない機能です。


参照文献

参考文献はいつものようにほとんどウィキペディアです。記事内のリンクをご覧ください。

一般的な注意事項として、添付のシグナルファイルはMQL5ウィザードでアセンブルする必要があります。この記事は、ウィザードクラスについてよく知らない人のためのオリエンテーションとして役立つでしょう。


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

添付されたファイル |
ct_21.mqh (31.39 KB)
SignalCT_21_r2.mqh (11.52 KB)
MQL5の圏論(第22回):移動平均の別の見方 MQL5の圏論(第22回):移動平均の別の見方
この記事では、最も一般的で、おそらく最も理解しやすい指標を1つだけ取り上げて、連載で扱った概念の説明の簡略化を試みます。移動平均です。そうすることで、垂直的自然変換の意義と可能な応用について考えます。
ニューラルネットワークが簡単に(第56回):核型ノルムを研究の推進力に ニューラルネットワークが簡単に(第56回):核型ノルムを研究の推進力に
強化学習における環境の研究は喫緊の課題です。いくつかのアプローチについてすでに見てきました。この記事では、核型ノルムの最大化に基づくもう一つの方法について見てみましょう。これにより、エージェントは新規性と多様性の高い環境状態を特定することができます。
パターン検索への総当たり攻撃アプローチ(第VI部):循環最適化 パターン検索への総当たり攻撃アプローチ(第VI部):循環最適化
この記事では、MetaTrader 4および5の取引の自動化チェーン全体を完成するだけでなく、より興味深いことができるようになった改善の最初の部分を示します。今後、このソリューションにより、EAの作成と最適化の両方を完全に自動化し、効果的な取引構成を見つけるための人件費を最小限に抑えることができます。
ニューラルネットワークが簡単に(第55回):対照的内発制御(Contrastive intrinsic control、CIC) ニューラルネットワークが簡単に(第55回):対照的内発制御(Contrastive intrinsic control、CIC)
対照訓練は、教師なしで表現を訓練する方法です。その目標は、データセットの類似点と相違点を強調するためにモデルを訓練することです。この記事では、対照訓練アプローチを使用してさまざまなActorスキルを探究する方法について説明します。