English Русский 中文 Español Deutsch Português
preview
MQL5の圏論(第22回):移動平均の別の見方

MQL5の圏論(第22回):移動平均の別の見方

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

はじめに

圏論の金融への応用は、この連載の柱です。時系列予測については、ほとんどのトレーダーにとって重要で、彼らがこのプラットフォームのメンバーの大部分を占めているため、詳しく説明してきました。しかし、それ以外の用途としては、バリュエーション、リスク、ポートフォリオアロケーション、その他多くのものがあります。そして、バリュエーションの例をざっと挙げると、圏論が株式のバリュエーションを得るために適用されうる方法は無数にあります。例えば、主要な株価指標をそれぞれ圏内のオブジェクトとすると、これらの異なる指標(収益、負債など)にまたがってリンクする射(または)は、異なる評価クラス(A+、A、Bなど)に帰属させることができます。これによって、特定の銘柄の評価指標が得られれば、その銘柄がどの程度特定のクラスに属しているかを数値化することができます。これは簡略化されたアプローチであり、この範囲内で何ができるかのヒントになることを意図しているに過ぎません。

しかし、時系列にこだわると、移動平均は単純すぎるとして見過ごされることもありますが、テクニカル分析において非常に重要です。その理由は、その概念がボリンジャーバンドやMACDなど、他の多くの指標の基礎となっているからです。ボラティリティの低い値動きという見方もできます。市場にはノイズが多いので、「ボラティリティの低い」という見方は重要です。

今回は、前回紹介した自然変換のテーマを継続し、異なる次元の関連データセット間のギャップを埋める自然変換の能力を探ってみたいと思います。ここでの「次元」は、データセットの列数のことです。つまり、前回と同様、生価格の「単純な」系列と、移動平均価格の「複合的な」系列の2つの圏があります。ここでの目的は、たった3つの関手の範囲で、時系列予測への応用を示すことです。


背景

まず、ここで考えていることの基本的な定義を確認しておきましょう。関手は、2つの圏を写像する関数です。ここでは3つの関手を扱いますが、これらは下図のように構成されていると考えることができます。


始域圏には、設定された時間間隔の価格値を持つオブジェクトがあり、移動平均価格値の終域オブジェクトも同様の時間間隔です。A、B、Cという3つの関手を強調しています。最近の記事で圏をつなぐ関手を表現してきましたが、ここで新しいのは3つ目の関手の追加です。これは、自然変換を「垂直」配列で示すため、ここでの目的に役立ちます。図には「垂直」の設定が示されていますが、将来の曖昧さを避けるため、「垂直」とは、同じ始域と終域圏を共有する関手間の自然変換を指すのだと言及しておきます。つまり、もし圏が図式的に縦に配置されて私たちの自然変換が横方向を向いているように見えたとしても、自然変換は「縦」に配置されることになります。

移動平均線は通常、クロスオーバーポイントに注目することで、取引指標として使用されます。このようなクロスは、基調となる価格と交差する場所であり、上方へのクロスは抵抗障壁を示すため弱気であり、下方へのクロスは支持を示すため強気となります。しかし、多くの場合、これらのクロスオーバーポイントは、期間の異なる2つの移動平均の間にあります。つまり、通常、短い期間の平均が長い期間の平均を上回った場合、長い期間の移動平均がサポートされているため強気となり、逆に短い期間の平均が長い期間の平均を下回れば弱気となります。そのため、このモデルでは各関手が特定の平均化期間を表しています。つまり、関手Aは3つの中で最も短く、関手Bの周期はその中間となり、関手Cは最も長い平均周期を持つことになります。

私たちが考えている圏を見れば、なぜこの2つの時系列が圏の公理に合致するのか、概略を説明するのに役立つかもしれません。要約すると、順序論(英語) (時系列がより関連しやすい) が圏としてどのように解釈できるかについてはすでに説明しましたが、圏の公理はオブジェクト、射、恒等射、 アソシエーションです。始域圏と終域圏はともに価格時系列であるため、一方の描写は他方でも容易に推測できます。したがって、生価格の圏(始域)に注目すると、各価格ポイントは時間と価格の2つの要素からなるオブジェクトです。各価格ポイントは他の価格ポイントに続くので、射は価格ポイント間の順次写像です。各価格ポイントにおける恒等射は、周期が1の移動平均と考えることができ、これは価格系列と同じでありますが、周期が1のの平均が提供するのは同一性の関係です。最後に、L、M、Nの3つの連続した価格帯が与えられているため、関連性を持つ構成は容易に示唆されます。

L o (M o N) = (L o M) o N

MからNへの射の後、Lからの射に関連するときの価格は、LからMへの射の結果に関連するときのNでの価格と同じです。


圏と関手

すべての関手の始域圏となる圏1は、前述のように、関手がその平均値を写像する生の価格時系列を特徴とします。

したがって、この圏には全部で4つの関手が存在することになります。まず特筆すべきは、恒等関手です。なぜなら、圏と関手はオブジェクトと射のように振る舞うので、同一性が存在する必要があるからです。他の3つの関手は、前述のように異なる移動平均の実装を表し、それぞれの周期は、関手A、B、Cに対してそれぞれm_functor_a、m_functor_b、m_functor_cという整数の入力パラメータによって設定されます。

この3つの関手の終域を構成する2つ目の圏は、時系列の移動平均価格を持つ3つのオブジェクトをそれぞれ持つことになります。つまり、圏1の生の価格系列からの各関手は、圏2のそれ自身のオブジェクトに写像されます。

圏2には唯一の恒等関手が存在します。これらのオブジェクト間の射は、前回の記事で見た定義に従えば、自然変換に相当します。これはすべて、下の少し詳細な図に要約することができます。



この記事の関手写像では、最近の記事のように多層パーセプトロンやランダム分布フォレスト、線形判別分析といったサードパーティーのアルゴリズムは使用していません。むしろそれは移動平均アルゴリズムであり、検討中の2つの関手の終了値間の算術的差になるので、自然変換はさらに単純になります。


自然変換

金融の文脈で自然変換を定義することは、無人の地を踏みしめるようなものです。裏付けとなる資料や文献は多くありません。よく使われたり検討されたりするのは、ピアソン(英語)とスピアマンの2つの主要な実装がある相関のような他の方法です。比較に使える方法は他にもありますが、今回はシグナル生成アルゴリズムの一部としてスピアマンの相関を使うことにします。

つまり、2つの関手間の自然変換は、関手の対象オブジェクトの正味の差です。ここでの場合、3つの関手があり、それは3つの自然変換の可能性を意味します。ただし、2つの変換のみに焦点を当てます。関手Aと関手Bの間の変換(ABと呼ぶ)と関手B と関手Cの間の変換(BCと呼ぶ)です。これら2つの関手を使うにあたって、それぞれ2つのデータバッファを作ります。そこで、それぞれの移動平均の差を追跡し、それぞれの配列に記録することで、2つのデータバッファを作成します。これらのバッファを使っておこなうのは、相関係数の追跡です。この値を追跡することで、取引シグナルのテーゼを提示します。プラスの数値は市場がトレンドにあることを示し、マイナスの数値は綾押し/綾戻し相場を示します。

具体的には、移動平均のすべての増分変化の合計と、指示されたシグナルとが一致するようにシグナルを探します。この値がプラスであれば強気、逆にマイナスであれば弱気が示されます。各バーで必ず値を出すこのシグナルは、前述のように、2つの自然変換バッファ間の相関によってフィルタリングされます。別の言い方をすれば、私たちのシステムは、各移動平均ですでに確立されたトレンドがある以上、自然な変化を追跡することに補足的な利点があるかどうかを問います。


自然変形の垂直合成

圏論の中では、自然変換の「垂直合成」とその対義語である「水平合成」というフレーズは、文脈や著者の慣習によって、時として意味が入れ替わってしまうことがあります。始域と終域の圏を共有する関手間の自然変換を「水平合成」と呼ぶ文献があってもおかしくありません。これは私たちが使う定義ではありません。この記事とそれに続く記事ではっきりさせておきたいのは、垂直合成は始域と終域の圏を共有する関手間の自然変換を指すということです。

では、垂直合成の意義とは何でしょうか。私たちが採用してきた慣例からすると、この2つのうちシンプルな方です。これは、2つの比較的単純なデータセット(圏として推測される)を見て、より複雑な設定で複数の圏を扱うときに見過ごされがちな、データセット間の特別な関係を導き出す方法を提供します。

このことがよくわかるのが、この記事で選んだ価格系列データセットと移動平均データセットです。しかし、取引以外では、より洞察力のある例として料理の分野が挙げられます。料理の食材のリスト(始域圏)とメニューのコレクション(終域圏)を考えてみましょう。私たちの関手は、食材をそれぞれのメニューにペアリングするだけです。関手や射のような自然変換は、その起源の定義や構造を保持します。これは些細なことに思えるかもしれませんが、圏論の基礎となる概念です。つまり、オブジェクトの要素と構造(つまりメニューとそのアイテム)が設定されていれば、メニュー間の自然変換は、各料理の準備にかかる相対的な時間や各料理のコスト、シェフやレストランの焦点に応じた他の多くの関心領域の測定と評価に役立ちます。この情報を武器に、同型射(英語)を見て、さまざまなメニューから食材を導き出すことができます。これは他の手法やシステムでも可能ですが、圏論は構造を保持し、定量化可能なアプローチを提供します。


価格変動の予測

この垂直合成を活用し、2つの自然変換バッファの相関係数を記録分析することで、価格変動を予測します。これらの配列は初期化する必要があります。なぜなら、エキスパートアドバイザー(EA)が最初に実行を開始すると、相関を実行するのに十分なデータが読み込まれないからです。これは次のコードにあるように扱われます。

//+------------------------------------------------------------------+
//| Get Direction function from Natural Transformations.             |
//+------------------------------------------------------------------+
void CSignalCT::Init(void)
   {
      if(!m_init)
      {
         m_close.Refresh(-1);
         
         int _x=StartIndex();
         
         m_o_prices.Cardinality(m_functor_c+m_functor_c);
         for(int i=0;i<m_functor_c+m_functor_c;i++)
         {
            m_e_price.Let();m_e_price.Cardinality(1);m_e_price.Set(0,m_close.GetData(_x+i));m_o_prices.Set(i,m_e_price);
         }
         
         m_o_average_a.Cardinality(m_transformations+1);
         m_o_average_b.Cardinality(m_transformations+1);
         m_o_average_c.Cardinality(m_transformations+1);
         
         for(int i=0;i<m_transformations+1;i++)
         {
            double _a=0.0;
            for(int ii=i;ii<m_functor_a+i;ii++)
            {
               _a+=m_close.GetData(_x+ii);
            }
            _a/=m_functor_a;
            m_e_price.Let();m_e_price.Cardinality(1);m_e_price.Set(0,_a);m_o_average_a.Set(i,m_e_price);
            //
            double _b=0.0;
            for(int ii=i;ii<m_functor_b+i;ii++)
            {
               _b+=m_close.GetData(_x+ii);
            }
            _b/=m_functor_b;
            m_e_price.Let();m_e_price.Cardinality(1);m_e_price.Set(0,_b);m_o_average_b.Set(i,m_e_price);
            //
            double _c=0.0;
            for(int ii=i;ii<m_functor_c+i;ii++)
            {
               _c+=m_close.GetData(_x+ii);
            }
            _c/=m_functor_c;
            m_e_price.Let();m_e_price.Cardinality(1);m_e_price.Set(0,_c);m_o_average_c.Set(i,m_e_price);
         }
         //
         ArrayResize(m_natural_transformations_ab,m_transformations);ArrayInitialize(m_natural_transformations_ab,0.0);
         ArrayResize(m_natural_transformations_bc,m_transformations);ArrayInitialize(m_natural_transformations_bc,0.0);
         
         for(int i=m_transformations-1;i>=0;i--)
         {
            double _a=0.0;
            m_e_price.Let();m_e_price.Cardinality(1);m_o_average_a.Get(i,m_e_price);m_e_price.Get(0,_a);
            double _b=0.0;
            m_e_price.Let();m_e_price.Cardinality(1);m_o_average_b.Get(i,m_e_price);m_e_price.Get(0,_b);
            double _c=0.0;
            m_e_price.Let();m_e_price.Cardinality(1);m_o_average_c.Get(i,m_e_price);m_e_price.Get(0,_c);
            
            m_natural_transformations_ab[i]=_a-_b;
            m_natural_transformations_bc[i]=_b-_c;
         }
         
         m_init=true;
      }
   }

各関手に対して3つの移動平均ハンドルを宣言したので、それらの値を読み込む前に更新する必要があります。各移動平均の周期は入力パラメータであるため、m_functor_a、m_functor_b、m_functor_cに対して、それぞれハンドルm_ma_a、m_ma_b'm_ma_cがあります。また、各自然変換に対してm_natural_transformations_abとm_natural_transformations_bcという2つのバッファがあります。これらの配列のサイズは、入力パラメータm_transformationsによって設定されるので、最初に両方の配列のサイズをその値に合わせて変更する必要があります。すなわち、終域圏のオブジェクトであるm_o_average_a、m_o_average_b、m_o_average_cの各圏オブジェクトも、すべての変化増分を取得できるようにするために、この値に1を加えた値にサイズ変更する必要があります。

このシステムでは、自然変換バッファの相関がゼロより大きいときに移動平均の変化をマッチングして生成されたシグナルが予測能力に異なる移動平均周期の影響を評価します。これは、以下のような単純明快なGetDirection関数によって捕捉されます。

//+------------------------------------------------------------------+
//| Get Direction function from Natural Transformations.             |
//+------------------------------------------------------------------+
double CSignalCT::GetDirection()
   {
      double _r=0.0;
      
      Refresh();
      
      MathCorrelationSpearman(m_natural_transformations_ab,m_natural_transformations_bc,_r);
      
      return(_r);
   }

そして、CheckOpenLong関数とCheckOpenShort関数で「トレンド」を計算します。このトレンドがシグナルの方向性を決め、「方向性」が綾押し/綾戻し相場のフィルターとして機能します。その実装は次の通りです。

      m_ma_a.Refresh(-1);
      m_ma_b.Refresh(-1);
      m_ma_c.Refresh(-1);
      
      int _x=StartIndex();
      
      double _trend= (m_ma_a.GetData(0,_x)-m_ma_a.GetData(0,_x+1))+
                     (m_ma_b.GetData(0,_x)-m_ma_b.GetData(0,_x+1))+
                     (m_ma_c.GetData(0,_x)-m_ma_c.GetData(0,_x+1));


また、Init関数に非常によく似た、これらの値を更新する関数も必要です。完全なソースコードは本稿末尾に添付されています。

1999.01.01から2020.01.01までのFXペアUSDJPYを日足時間枠でバックテストしたところ、理想的な設定をいくつか含む以下のレポートが得られました。

r1


この設定で2020.01.01から2023.08.01までウォークフォワードすると、以下のようなレポートが得られます。

r2

肯定的なウォークが示されましたが、これはいつものようにシステムが機能していることを意味するものではなく、むしろ初期の発見を確認するために、より長い期間でテストできるものを手に入れたことを意味します。


取引システム開発のためのテストベッド

MQL5ウィザードのおかげで、このシグナルクラスを新規または既存の取引システムにシームレスに統合することができます。トレーダーがいつも使っているか、試してみたい他のシグナルの1つとして、このシグナルクラスを持つ新しいEAを組み立てるだけでよくなります。「Signal_XXX_Weight」(XXX はシグナルクラスの名前)の一般的な入力パラメータの値は通常0.0~1.0の範囲であり、すべてのシグナルにわたって最適化して、それぞれに適切な重みを決定できます

このような取引システムの評価は、トレーダーのニーズの是非によるべきです。通常は、成長か資本保全かの二者択一です。裏を返せば、成長にはAHPRが、安全にはリカバリーファクターが最適な指標ということでしょう。これはすべて大まかな推定であるため、読者や真剣なトレーダーは、自分にとって何が効果的かを導き出すために、もう少し精進する必要があるでしょう。

パフォーマンス評価システムが整えば、次に重要なのは、おそらく同様に、戦略の前提やウォークフォワードをおこなう能力を損なうことなく、戦略を段階的に改善する方法を持つことでしょう。この方法では、バックテストやウォークフォワードのパフォーマンスを、システムの反復や変更のたびに常に確認する代わりの単純な方法はありません。

また、いつものように、このモデルに基づいた後続クラスのインスタンスを持つ可能性もあります。いくつかの変更は必要ですが、全体的な要点は同じでしょう。まず、移動平均では、終値を適用価格として使用するのではなく、ボラティリティに傾いたものを使用します。これは、典型的な価格、またはおそらく中央価格である可能性があります。第2に、予測方向は2つの自然変換バッファ間の相関をまだ指し示すでしょうが、この場合「トレンド」として機能するようにバー範囲の現在の変化を追跡します。そのため、レンジの減少は正の相関(ゼロ以上の値)に裏打ちされる必要があります。ボラティリティが高まった場合も同様です。もし相関がゼロかマイナスであれば、このモデルは現在のボラティリティの変化は無視できることを示していることになります。この記事の最後には、この実装も添付されています。


結論

要約すると、垂直合成における自然変形のインパクトは、あまりにもアカデミックで古風な響きがあるため、多くの人の興味を引くことはありません。それでも、この記事の移動平均など、一般的な指標を使用した図を見ることでいくつかのパターンが明らかになり、そこから時系列を予測する際の確認シグナルを読み取ることができたので、これが洞察力に富んでいることは間違いありません。

これを利用して強固な取引システムを開発することは、常に本格的に始まるところであり、実現するためにはトレーダー側にもう少し手間がかかります。とはいえ、決意を固めたトレーダーがこれをやり遂げるには、オンライン上に十分なサポート資料があることは間違いありません。

読者がここで共有されていることにもっと納得できるように、時系列予測の枠を超え、バリュエーションやリスクといった取引やファイナンスの他の分野でも、これらの概念をさらに探求することを強くお勧めします。


参照文献

この記事の引用はほとんどウィキペディアからものもです。

この記事の圏論の概念を実践するためのリソースは以下に添付されています。圏論のクラスファイル「ct_22.mq5」とトレーリングファイル「TraillingCT_22_r1.mqh」です。クラスファイルはincludeフォルダに、トレイリングファイルはIncludeExpertTraillingフォルダに配置してください。MQL5ウィザードに不慣れな読者は、ウィザードでEAを組み立てる方法についてこちらの記事をご参照ください。このシグナルファイルはウィザードで組み立てることで使用することを意図しているからです。


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

添付されたファイル |
ct_22.mqh (29.34 KB)
TrailingCT_22.mqh (13.97 KB)
パターン検索への総当たり攻撃アプローチ(第VI部):循環最適化 パターン検索への総当たり攻撃アプローチ(第VI部):循環最適化
この記事では、MetaTrader 4および5の取引の自動化チェーン全体を完成するだけでなく、より興味深いことができるようになった改善の最初の部分を示します。今後、このソリューションにより、EAの作成と最適化の両方を完全に自動化し、効果的な取引構成を見つけるための人件費を最小限に抑えることができます。
MQL5の圏論(第21回):LDAによる自然変換 MQL5の圏論(第21回):LDAによる自然変換
連載21回目となるこの記事では、自然変換と、線形判別分析を使ったその実装方法について引き続き見ていきます。前回同様、シグナルクラス形式でその応用例を紹介します。
エキスパートアドバイザー(EA)に指標を追加するための既製のテンプレート(第1部):オシレーター エキスパートアドバイザー(EA)に指標を追加するための既製のテンプレート(第1部):オシレーター
この記事では、オシレーターカテゴリから標準的な指標を検討します。パラメータの宣言と設定、指標の初期化と初期化解除、EAの指標バッファからのデータとシグナルの受信など、EAですぐに使用できるテンプレートを作成します。
ニューラルネットワークが簡単に(第56回):核型ノルムを研究の推進力に ニューラルネットワークが簡単に(第56回):核型ノルムを研究の推進力に
強化学習における環境の研究は喫緊の課題です。いくつかのアプローチについてすでに見てきました。この記事では、核型ノルムの最大化に基づくもう一つの方法について見てみましょう。これにより、エージェントは新規性と多様性の高い環境状態を特定することができます。