English Русский Español Português
preview
FX裁定取引:関係性評価パネル

FX裁定取引:関係性評価パネル

MetaTrader 5トレーディングシステム |
18 11
Yevgeniy Koshtenko
Yevgeniy Koshtenko

はじめに

アルゴリズムによるForex取引に取り組み始めてから、すでに長い年月が経ちました。試行錯誤を繰り返し、眠れない夜を過ごし、ときには大きな成果を得る。そんな時間の積み重ねでした。この間、私は単純なインジケーターから複雑な機械学習システムまで、実にさまざまな手法を試してきました。しかし、その中でもずっと頭から離れなかった考えがあります。「市場は本当に完全なのだろうか?」高速で明滅するレートの背後には、実は小さな歪みや裂け目が存在していて、そこから市場の本質を垣間見ることができるのではないか。そして、そこに利益機会も潜んでいるのではないか。こうして私は裁定取引分析へと辿り着きました。このアプローチは、私にとってほとんど“啓示”と言ってよいほどの発見となりました。

今回ご紹介するのは、MetaTrader 5用にMQL5で開発した、公正為替レート分析および裁定取引評価システムです。すべての始まりは、ある夜にふと思い浮かんだ単純な疑問でした。「市場が提示しているレートではなく、本来あるべき為替レートを計算できるとしたらどうだろう。」その好奇心から生まれたのが、本記事で紹介する分析パネルです。このパネルは、現在の価格が「理論上の適正値」からどの程度乖離しているかを可視化するだけでなく、三角裁定取引の経路、つまり、市場に一時的な非効率性が発生し、それを利用できる瞬間までも検出します。

理論を実際のコードへ落とし込む作業は、まさに冒険そのものでした。数え切れないほどの落とし穴、終わりの見えない試行錯誤、そしてすべてを投げ出したくなる瞬間も何度となくありました。本記事では、無機質な数式がどのようにして実用的なシステムへ変わっていったのか、市場がどのように私を試し続けたのか、そして結果を直感的に理解できる形で可視化する方法をどのように作り上げたのかをお話しします。また、実際のパネル動作例として、具体的な数値、シグナル、三角裁定も紹介します。さらに、その長所だけでなく弱点についても率直に分析し、単発トレードから複数通貨グリッド戦略に至るまで、さまざまな戦略へ適応させてきた経験についても共有したいと思います。特にマルチカレンシーグリッドは、私にとって格好の実験場となりました。

私の目的は、単にコードを披露したり、自分の成果を誇示したりすることではありません。皆さんに、実際に使える道具を提供したいのです。自由に持ち帰り、自分の用途に合わせて調整し、改良し、発展させることのできるものを。このパネルが、新しいアイデアへの刺激となるだけでなく、市場をこれまでとは異なる視点から見るきっかけになれば幸いです。市場は単なる混沌ではありません。解き明かすことのできる、一つのパズルなのです。



裁定取引をおこなうヘッジファンドとFX裁定取引の規模

外国為替市場における裁定取引を語るうえで、この分野の主要プレイヤー、すなわち、価格差の数学的分析を数十億ドル規模のビジネスへ発展させた専門ヘッジファンドに触れないわけにはいきません。彼らの経験と運用規模を知ることで、私たちの比較的小規模な裁定取引指標も、適切に活用されればどれほど大きな可能性を持ち得るのかが見えてきます。

通貨裁定取引の巨人たち

裁定取引をおこなうヘッジファンドの中でも、特に際立った存在がいくつかあります。たとえば、500億ドルを超える運用資産を持つMillennium Managementは、マルチストラテジー型の運用を採用しており、その中でも外国為替市場における統計的裁定取引は主要分野の一つとなっています。同社のクオンツ分析チームは、私たちが扱う「理論価格行列」と概念的には近いモデルを開発していますが、その背後には、はるかに高度な数学モデルと膨大な計算資源が存在しています。

また、Citadel Securities、Renaissance Technologies、そしてD. E. Shaw & Co.も、積極的に通貨裁定取引を活用している巨大プレイヤーです。彼らの優位性は、単なる資本力だけではありません。インターバンク市場への直接アクセス、 超低遅延サーバー(コロケーション)、主要取引所間を結ぶ専用通信回線といった技術基盤そのものが、大きな武器となっています。一部のファンドは、注文執行の遅延をマイクロ秒単位まで削減するために、数億ドル規模のインフラ投資をおこなっています。残念ながら、この領域においては、私たちのMetaTrader 5用インジケーターが真正面から競争することはできません。



理論的基盤:理論価格(フェアプライス)分析と裁定取引

理論価格分析という発想に私が強く惹かれたのは、「市場は時として間違えるのではないか?」と考えたことがきっかけでした。長年にわたりForexを取引してきた経験から、為替レートとは単なる画面上のランダムな数字ではないと私は感じています。市場とは、無数の通貨ペアが相互に影響し合う、巨大な相関ネットワークです。ある通貨ペアの動きは、まるで大きな織物を支える糸のように、他のペアを引っ張っていきます。そして、その織物のどこかに歪み、つまり価格の不一致が生じたなら、そこには利益を得るチャンスが存在するかもしれません。

理論価格とは、本質的には「市場が完全に合理的であった場合に成立しているはずの理想的な為替レート」です。たとえばEURUSDのような直接通貨ペアであれば、考え方は比較的単純です。Bid価格とAsk価格の中間値を取れば、それがおおよその基準価格になります。しかしForexの世界は、単純な直接通貨ペアだけでは成り立っていません。EURJPYのようなクロス通貨ペアは、主要通貨ペアを用いて計算できます。そこで私が思い出したのが、古典的でありながら今なお生き続けている概念、三角裁定取引でした。

EUR/USD * USD/JPY = EUR/JPY

もし実際のEURJPYレートがこの計算結果と一致しないのであれば、市場はどこかで何かを過小評価、あるいは過大評価していることになります。初めてこれを手動で確認した時のことを、今でも覚えています。私はデモ口座のレートを見ながら電卓を叩き、各通貨ペアを比較していました。差異はほんのわずかで、パーセントにすればごく小さなものでした。しかし、その「ズレ」が確かに存在するという事実に、私は強い興味を抱きました。それはまるで、誰も気づかない壁の小さな亀裂を見つけ、その隙間から内部を覗き込むような感覚でした。

そこから私はさらに深く掘り下げていきました。直接通貨ペアは、あくまで氷山の一角に過ぎません。価格の「妥当性」を本当に理解するには、すべての通貨関係を行列として構築する必要があります。たとえば、EUR、USD、GBP、JPYなど8種類の通貨があるとします。それぞれの通貨は、利用可能な通貨ペアを通じて、他のすべての通貨との関係を表現できます。たとえば、EURUSDとGBPUSDがあれば、EURGBPは次のように計算できます。

EURGBP = EURUSD / GBPUSD

さらに、USDJPYやJPYUSDのような逆通貨ペアも加えれば、さらに精度を高めることができます。特に私の興味を引いたのが、「動的補正(キャリブレーション)」という考え方でした。単一の通貨ペアだけに依存するのではなく、利用可能なすべてのレートを一つの整合的なシステムとして平均化できないだろうかと考えたのです。たとえばEURJPYを計算する場合でも、EURUSDとUSDJPYだけではありません。EURGBPとGBPJPY、あるいはCHFやAUDを経由するさらに長いルートまで利用できます。それはまるで、すべてのピースが完璧にはまるようにパズルを組み立てていく作業のようでした。 

では、同じ通貨を含む他のすべてのペアから、一つの通貨ペアをどのように算出するのでしょうか。EURUSDを例にとってみましょう。直接レートが1.10だとします。しかし、それはGBP経由(EURGBPとGBPUSD)、JPY経由(EURJPYとUSDJPY)、CHF経由など、さまざまなルートから検証できます。理論上、どの経路を辿っても同じ値に収束するはずです。もし一致しないのであれば、それ自体がシグナルになります。私は次第に、「8×8の為替レート行列を構築し、それを整合的な価格体系へ収束させることはできないだろうか」と考えるようになりました。それは、各通貨ペアを方程式として扱い、通貨レート全体を未知数とする連立方程式を解く作業に似ています。例は以下の通りです。 

EURUSD = 1. 10

USDJPY = 150

EURJPY = EURUSD * USDJPY = 165

しかし実際のEURJPYが166であれば、どこかに歪みが存在していることになります。こうした「方程式」は、市場全体には何十通りも存在します。すべての経路の平均値を取ることもできますし、中央値を採用することもできます。あるいは、線形方程式系を解く際の反復法のように、最も整合的な「最適価格」を探索することも可能です。 

そして、このパズルのもう一つの重要な要素が裁定取引でした。三角裁定取引とは、EURUSD → USDJPY → EURJPYのような3通貨ペアの循環を利用し、最終的に利益を得る取引です。しかし私はさらに考えました。三角形だけではなく、4通貨ペア、5通貨ペアといった、より長い経路まで探索したらどうなるのだろうか。理論上、経路が長くなるほどノイズは増えます。しかしその一方で、より興味深い歪みが見つかる可能性もあります。私は、あらゆるアイデアを実際の市場データで検証しました。ターミナルからデータを取得し、計算結果と現実の価格がどこで食い違うのかを確認し、その差異から学び続けました。 

私にとって、これは単なる数式の集合ではありません。これは単なる手法ではなく、市場観そのものです。市場とは、小さな誤差や歪みに満ちた生きた存在であり、そのズレを見抜けるようになれば、市場とより調和した形で向き合えるようになる。私はそう考えています。この考え方が、皆さんにとっても、より深く市場を探求し、新たな可能性を見つめ直すきっかけになれば幸いです。


裁定取引パネルの実装:アイデアからコードへ

理論をコードへ落とし込む作業は、常に挑戦の連続です。私は次のような形で、MQL5による裁定取引分析パネルを実装しました。

void CalculateFairValues() {
    GetCurrentMarketRates();
    InitializeCurrencyMatrix();
    FillCurrencyMatrixFromDirectRates();
    CalculateCrossRatesArbitrage();
    CalculateDiscrepancies();
    FindArbitrageOpportunities();
    GenerateSignals();
    UpdateDisplay();
}
この関数こそが、システムの中核です。現在の市場レートを取得し、理論レート行列を構築し、その中から裁定取引機会を探索します。私は特にCalculateCrossRatesArbitrageの実装に長い時間を費やしました。市場で常に直接通貨ペアが利用できるとは限らず、逆数変換を用いて補完しなければならなかったからです。
if(!g_market_rates[i].is_direct) {
    double temp_bid = 1.0 / g_market_rates[i].ask;
    double temp_ask = 1.0 / g_market_rates[i].bid;
    g_market_rates[i].bid = temp_bid;
    g_market_rates[i].ask = temp_ask;
}
また、裁定取引計算には専用ロジックを実装しました。
double CalculateArbitrageProfit(int pair1_idx, int pair2_idx, int pair3_idx, double amount) {
    double result = amount;
    // Calculation logic through Bid/Ask for a triangle
    return result;
}

このメソッドは、EURUSD → USDJPY → EURJPYのような循環取引における利益を算出します。しかし、最初の結果はかなり混沌としていました。スプレッドが利益の大半を打ち消してしまったのです。そのノイズを除去するために、私はInpArbitrageThresholdという閾値パラメータを追加せざるを得ませんでした。

次に重要となるのが、理論レート行列です。InitializeCurrencyMatrixでは対角要素に単位値(EUR/EUR = 1)を設定し、FillCurrencyMatrixFromDirectRatesで直接レートを埋め込みます。しかし、本当の「魔法」が起こるのはCalculateCrossRatesArbitrageの部分です。

void CalculateCrossRatesArbitrage() {
    for(int iterations = 0; iterations < 3; iterations++) {
        for(int i = 0; i < g_currencies_count; i++) {
            for(int j = 0; j < g_currencies_count; j++) {
                if(i == j) continue;
                for(int k = 0; k < g_currencies_count; k++) {
                    if(k == i || k == j) continue;
                    if(g_currency_matrix[i][k] != 0 && g_currency_matrix[k][j] != 0) {
                        double triangleRate = g_currency_matrix[i][k] * g_currency_matrix[k][j];
                        if(g_currency_matrix[i][j] == 0) g_currency_matrix[i][j] = triangleRate;
                        else g_currency_matrix[i][j] = (g_currency_matrix[i][j] * 0.7 + triangleRate * 0.3);
                        g_currency_matrix[j][i] = 1.0 / g_currency_matrix[i][j];
                    }
                }
            }
        }
    }
}

ここでは通貨間を三重ループで巡回しながら、三角関係を利用してクロスレートを補完しています。考え方自体はシンプルです。EURUSDとUSDJPYがあれば、EURJPYを算出できます。もし既にEURJPYの直接レートが存在している場合は、既存値を70%、新たに計算した値を30%の比率で加重平均します。反復回数を3回に設定したのは、精度と処理速度のバランスでした。私はEURJPYを用いてこのアルゴリズムをテストしていました。当初、価格差は0.1%程度ありましたが、3回の反復後には0.01%程度まで収束しました。しかし市場は待ってくれません。そこで私は、その時点で反復処理を終了することにしました。

では、ある通貨ペアを、他のすべての関連ペアからどのように算出するのでしょうか。たとえば、EURUSDの理論価格を求めたいとします。利用可能な経路としては、

  • EURGBPとGBPUSD:EURUSD = EURGBP * GBPUSD
  • EUR/JPYとUSD/JPY:EURUSD = EURJPY / USDJPY
  • EURCHFとUSDCHF:EURUSD = EURCHF / USDCHF

のようなものがあります。これらすべての経路を用いて平均値や中央値を求めることができます。あるいはさらに踏み込み、連立方程式を解く際のガウス=ザイデル法のような反復収束アルゴリズムを用いることも可能です。たとえば次のような実装です。

double CalculatePairFairValue(string base, string quote) {
    int baseIdx = GetCurrencyIndex(base);
    int quoteIdx = GetCurrencyIndex(quote);
    double sum = 0.0;
    int count = 0;
    for(int k = 0; k < g_currencies_count; k++) {
        if(k == baseIdx || k == quoteIdx) continue;
        if(g_currency_matrix[baseIdx][k] != 0 && g_currency_matrix[k][quoteIdx] != 0) {
            sum += g_currency_matrix[baseIdx][k] * g_currency_matrix[k][quoteIdx];
            count++;
        }
        if(g_currency_matrix[k][baseIdx] != 0 && g_currency_matrix[quoteIdx][k] != 0) {
            sum += g_currency_matrix[quoteIdx][k] / g_currency_matrix[k][baseIdx];
            count++;
        }
    }
    return (count > 0) ? sum / count : g_currency_matrix[baseIdx][quoteIdx];
}

コードの一行一行が、実運用上の課題との格闘でした。ですが、初めてシグナルと裁定取引トライアングルが画面上に現れた瞬間、私は確信しました。「これは、本当に機能している」と。


グラフィカルインターフェース:機能の可視化

どれほど優れたロジックを書いたとしても、分かりやすい可視化がなければ、それは単なる数字の集合に過ぎません。インターフェースには心血を注ぎました。

bool CreateGraphics() {
    ObjectCreate(0, "FVPanel_Main", OBJ_RECTANGLE_LABEL, 0, 0, 0);
    ObjectSetInteger(0, "FVPanel_Main", OBJPROP_XDISTANCE, 20);
    ObjectSetInteger(0, "FVPanel_Main", OBJPROP_YDISTANCE, 20);
    ObjectSetInteger(0, "FVPanel_Main", OBJPROP_XSIZE, 900);
    ObjectSetInteger(0, "FVPanel_Main", OBJPROP_YSIZE, 560);
    ObjectSetInteger(0, "FVPanel_Main", OBJPROP_BGCOLOR, InpBgColor);
    CreateText("FVPanel_Header", 220, 30, "ANALYSIS OF FAIR CURRENCY PRICES", InpHeaderTextColor, 12, true);
    CreateText("FVPanel_Signals", 60, 60, "SIGNALS OF DEVIATION FROM FAIR PRICE", InpBuySignalColor, 10, true);
    CreateText("FVPanel_Arbitrage", 460, 60, “ARBITRAGE OPPORTUNITIES", InpArbitrageColor, 10, true);
    return true;
}

パネルは、フェアプライスからの乖離シグナル、裁定取引経路、為替レート行列の大きく3つの領域に分かれています。「EURUSD: +0.04% — SELL」のようなシグナルは、緑や赤で強調表示されます。また、「EURUSD->USDJPY->EURJPY: +0.02%」のような三角裁定は、どの方向に取引をおこなうべきかを即座に示してくれます。

特に私が強いこだわりを持っていたのが、為替レート行列の表示部分です。8種類の通貨をテーブル形式で一覧表示し、理論価格からの乖離を色分けして視覚化します。フォントや余白の調整だけでも何時間も費やしました。すべてを見やすく、整然と表示したかったのです。

更新処理はタイマーによっておこなわれます。

void OnTimer() {
    g_timer_counter++;
    if(g_timer_counter >= InpUpdateInterval) {
        CalculateFairValues();
        g_timer_counter = 0;
    }
}

この仕組みによって、システムがリアルタイムに動作するようになります。市場データがリアルタイムで流れ込み、まるで市場の鼓動そのものを見ているかのように動き続けるのです。


動作結果と率直な評価

現時点では、このシステムをまだ実運用には投入していません。現在、この仕組みをベースにしたロボットを開発しているところであり、これでおそらく5回目か6回目となる「本当に機能する裁定取引EA」への挑戦になります。以下は、システムの動作動画です。



理論価格と行列についての考察

「行列から、どうやって理論価格を導き出すのか。」この問題は、いつしか私の中で一種の執着になっていました。8×8の通貨行列は、まるで市場全体の地図のようなものです。各セルには、ある通貨を別の通貨へ交換する際のレートが入っています。しかし実際のデータは非常にノイジーです。ブローカーはすべての通貨ペアを提供しているわけではありませんし、レートは絶えず変動し、さらにスプレッドが計算を乱します。私はさまざまなアプローチを試し始めました。

アプローチ1:複数経路の平均化

たとえばEURUSDを求める場合、私は以下のような複数のクロス経路を利用します。

  • EURGBP * GBPUSD
  • EURJPY / USDJPY
  • EURCHF / USDCHF

それぞれの経路から算出した値の平均を取るわけです。これは非常にシンプルな方法ですが、問題もあります。たとえばEURJPYはEURCHFより流動性が高い可能性がありますが、この方法ではそうした「重み」が考慮されません。

アプローチ2:反復収束法

これは、ガウス=ザイデル法のような考え方です。行列内の各セルを繰り返し更新し、変化量が十分小さくなるまで収束させていきます。先ほどのCalculateCrossRatesArbitrageは、その簡略版にあたります。しかし私はさらに考えました。もし、各通貨ペアの取引量を重みとして加えたらどうなるだろうか。あるいは、ボラティリティを考慮したらどうだろうか。

アプローチ3:誤差最小化

さらに私は、これを最適化問題として扱えないかと考えました。つまり、市場価格と行列内価格との差異の二乗和を最小化するという方法です。たとえば次のような実装です。

Error = Σ (MarketRate[i] - MatrixRate[i])^2

これを勾配降下法やSVD(特異値分解)のような手法で解くことができます。MQL5ではやや重すぎる処理になるかもしれませんが、Pythonであれば十分試す価値があると思っています。

アプローチ4:より長い経路

なぜ三角形だけに限定する必要があるのでしょうか。たとえば、EURGBP->GBPCHF->CHFUSDのようなチェーンを利用してEURUSDを導くこともできます。経路が増えるほど、より多くの情報を利用できるため、理論上は精度も向上します。しかしその一方で、ノイズも増加します。実際の市場では、長いチェーンはスプレッドや手数料の中に沈んでしまい、まるで沼に足を取られるように機能しなくなっていきます。

これらは、まだ理論段階の考察に過ぎません。 現実の市場は教科書通りには動きませんし、「理想価格」というものは、完全には到達できない理想なのかもしれません。それでも、その理想へ少しでも近づこうとすること自体が、すでに前進なのだと私は考えています。


結論

理論価格という発想から出発したとき、まさかここまでのシステムになるとは思っていませんでした。行列計算のバグに悩まされ、裁定機会の検出に失敗して落胆する。そんな試行錯誤の連続でした。しかし、その一歩一歩が、私に新しい発見をもたらしてくれました。

市場は単なるカオスではなく、複雑に組み合わさった精密な仕組みです。理論価格と裁定取引は、その内部構造を拡大して見せる虫眼鏡のような存在です。可視化によってデータは生きた情報となり、柔軟に適応できることで、システムは実運用向きになります。このパネルはまだ完璧ではありません。それでも、すでに私に大きな手応えを与えてくれています。

今後は機械学習の導入から実運用テストまで、多くの計画があります。Forex市場が止まることなく動き続けるように、私自身も立ち止まるつもりはありません。この記事が、皆さんにとって市場の舞台裏を覗き込み、自分自身の「歪み」や「非効率性」を見つけるきっかけになれば幸いです。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/17422

添付されたファイル |
最後のコメント | ディスカッションに移動 (11)
Vitaly Muzichenko
Vitaly Muzichenko | 18 3月 2025 において 21:09
Sergey Chalyshev #:

あなたはディーラーとブローカーを混同している。

ブローカーは調整できない。

ゲームのルールを学んでください。

注文とポジションはここでも混乱している。

Vladimir Gulakov
Vladimir Gulakov | 19 3月 2025 において 17:04
Sergey Chalyshev #:

あなたはディーラーとブローカーを混同している。

ブローカーは調整できない。

ゲームのルールを学んでください。

よし、ディーラーになろう。

pivomoe
pivomoe | 22 3月 2025 において 22:21
Yevgeniy Koshtenko #:

そして、標準偏差と比較すると、合成と実際の乖離はしばしば大きい......。

過去ログから大きな不一致の例を教えてもらえますか?

pivomoe
pivomoe | 23 3月 2025 において 11:36
Yevgeniy Koshtenko #:

それについては、次の記事を掲載する予定である。

2つ目の記事のコードを見た。最初の記事とはまったく関係がない。コードのどこにも、適正価格を下回ったり上回ったりしようとする試みすらない。運命の慈悲に注文のシートを投げるいつものネッターにすぎない。

Khai Nguyen
Khai Nguyen | 29 1月 2026 において 10:38
その結果、結果テーブルの特別な部分を含むスクリーンショットを意図的に撮らなかったと思います。
私はアイデアには従いますが、まだアイデアを現実的な取引に変えるのに苦労しています。

この添付された結果についてコメントし、効果的なシステムにする手助けをしてくれることを願っています。
CatBoost AIによるレンコ足の予測 CatBoost AIによるレンコ足の予測
AIを用いてレンコ足をどのように活用するのでしょうか。本記事では、最大59.27%の予測精度を実現したForex向けレンコ足トレーディングを題材に解説していきます。まず、レンコ足がどのように市場ノイズを除去するのか、その利点を見ていきます。さらに、なぜ価格パターンよりも出来高の方が重要なのかを学び、EURUSDに最適なレンコ足ブロックサイズの設定方法についても掘り下げます。また、CatBoost、Python、MetaTrader 5を組み合わせ、自分自身のレンコ足予測システムを構築する手順をステップごとに解説します。従来のテクニカル分析を超えるアプローチを求めるトレーダーに最適な内容です。
一次元特異スペクトル解析 一次元特異スペクトル解析
本記事では、特異スペクトル解析(SSA, Singular Spectrum Analysis)法の理論的および実践的側面について考察します。SSAは時系列解析の有効な手法の一つであり、時系列の複雑な構造を、トレンド、季節性(周期的)変動、ノイズなどの単純な成分へ分解して表現することを可能にします。
多通貨エキスパートアドバイザーの開発(第26回):取引商品の情報提供 多通貨エキスパートアドバイザーの開発(第26回):取引商品の情報提供
多通貨EAの開発へと進む前に、まずはこれまで構築してきたライブラリを用いて、新しいプロジェクトを作成する段階へ移行してみましょう。この例では、ソースコードの管理方法をどのように整理するのが最も適切か、そしてMetaQuotesの新しいコードリポジトリを活用することで、どのような利点が得られるのかを示していきます。
トレンドの基準:結論 トレンドの基準:結論
本記事では、実務におけるいくつかのトレンド判定基準の適用について検討します。また、それらの基準を基にしていくつかの新しい判定基準の開発も試みます。特に、市場データ解析および取引への適用効率に焦点を当てます。