ワールドカップが開幕したばかりだというのに、市場は早速、私たちに小さな衝撃的な教訓を与えてくれました。強豪チームがまさか負けることはない、というわけではありません。ただ、その負け方の姿勢は往々にして私たちの想像以上に独創的だったりするのです。
例えば、スペイン 0-0 カーボベルデ。試合前に実力、ランキング、選手層の厚さだけを見れば、ほとんどの人は素朴に考えるでしょう。「スペインが勝つだろう」と。しかし、サッカーが最も面白く、そしてトレーダーを最も苛立たせるのは、まさにこの点です。あなたは「強豪チームの勝利」を買っているつもりでも、実際には90分間の運命の連続ドラマ全体を買っているのです。最初の15分でゴールがなければ、オッズが動きます。30分経っても0-0なら、市場は眉をひそめ始めます。70分になっても動きがなければ、当初は堅そうに見えた強豪チームの勝利も、突然不安定になります。
ここで、古典的なジレンマに直面します。アービトラージは素晴らしいが、予測は難しい、というものです。
真のアービトラージは、理論上は無リスクです。例えば、互いに排他的かつ網羅的な契約のセットを見つけ、何が起ころうともその組み合わせで決済でき、かつ購入コストが決済額を下回る場合などです。聞こえは素晴らしく、トレーダー版の昼寝のようなものです。しかし、問題はここにあります。そのような機会は非常に稀であり、現れてもすぐに消え去り、容量も十分でないことが多いのです。
一方、予測は別物です。あなたは強豪チームが高確率で勝つと判断し、陣容、調子、日程、怪我人を分析し、オッズから暗に示される確率を見ることもできます。しかし、試合は私たちが真剣に分析したからといって、それに合わせて進行してくれるわけではありません。特にサッカーではそれが顕著です。早い段階でのレッドカード、ポストへのシュート、とんでもないVAR判定など、どれも素晴らしいロジックを、試合後の振り返りでの沈黙に変えてしまう可能性があります。
そこで問題です。純粋なアービトラージは希少すぎるし、純粋な予測はランダムすぎる。ならば、その両方の中間地点に立つことはできないでしょうか? 市場そのものがすでにいくつかの事前確率を与えてくれています。例えば、強豪チームの勝利の価格、0-0の価格、0-1の価格などです。これらの価格は、何もないところから生まれたわけではなく、市場が様々な経路に対して集合的に付けた価格を反映しています。では、これらの事前確率を利用し、さらに独自の数学モデルを少し加えることで、完璧ではないがより保護された組み合わせを構築し、「経路収束」の窓をこじ開けることはできないでしょうか?
これが、このアイデアの出発点です。
これは従来の無リスクアービトラージでもなければ、単なる当てずっぽうの予測でもありません。どちらかというと、妥協案のようなものです。まず市場が示す主確率には参考価値があると認め、次に低確率の経路を使って主判断の最も脆弱な部分を保護し、同時に簡易モデルで価格がまだ許容範囲かどうかをチェックする、というものです。
ある試合で、ブラジルがハイチより明らかに強いとします。市場が示すブラジル勝ちの価格は0.89で、ブラジルが勝つことが強い主経路であることを示しています。しかし、私たちはブラジル勝ちだけを直接購入するのではなく、同時に二つの保護経路、すなわち0-0と0-1にも目を向けます。なぜなら、強豪チーム勝利の判断にとって、最も辛い初期のシナリオは、すべての結果がそうであるわけではなく、試合がなかなか動かないか、弱豪チームが1点を先取する場合だからです。
そこで、初期の組み合わせは次のようになります。
text
ブラジル勝ち Yes
0-0 Yes
0-1 Yes
価格は次のように仮定します。
text
ブラジル勝ち = 0.89
0-0 = 0.016
0-1 = 0.011
3本の足の合計コストは次の通りです。
text
C = 0.89 + 0.016 + 0.011 = 0.917
このセットは、完全な事象を網羅していません。1-1、0-2、2-2、その他あらゆる奇妙なシナリオをカバーしていません。ですから、このまま試合終了までホールドすれば、もちろん損失が出る可能性があり、しかも直接的に損失が出る可能性があります。しかし、これには非常に重要な特徴があります。市場がすでに示している3つの確率を組み合わせて、主勝ちを中心とした経路のバスケットを形成しているのです。
もし最終的にブラジルが勝てば、組み合わせは1を決済します。もし最終的に0-0または0-1になれば、それも1を決済します。つまり、私たちが購入しているのは、
text
ブラジル勝ち ∪ 0-0 ∪ 0-1
ということです。これらの経路のいずれかが発生すれば、満期時の決済は1です。コストは0.917で、カバー経路内には0.083の余裕があります。しかし、本当の鍵は試合終了時ではなく、途中経過にあります。
もしブラジルが早い段階でゴールを決め、スコアが1-0になれば、0-0と0-1という2本の保護脚はほぼ無価値になりますが、ブラジル勝ちの価格は上昇します。この時点で、ブラジル勝ちの売り可能価格が初期総コストを上回り、さらに目標利益を加えたものであれば、主勝ちを手仕舞いして、この組み合わせを早期に収束させることができます。
計算式は簡単です。
text
利確条件 = ブラジル勝ちの売り気配値 >= 初期総コスト C + 目標利益
例えば、目標利益を0.02とします。
text
トリガー価格 = 0.917 + 0.02 = 0.937
もし1-0の後にブラジル勝ちの売り気配値が0.95になった場合、
text
確定利益 = 0.95 - 0.917 = 0.033
この場合、私たちは最終結果の当たり外れで儲けているのではなく、試合の経路が有利な分岐に入ったことで、組み合わせを早期に売却しているのです。このプロセスは、市場があなたに小さな窓を開けてくれたようなものです。あなたはその窓辺で詩を書いたりせずに、まず窓をくぐり抜けるべきです。
しかし、ここでさらに問題があります。3本の足が安く見えたとしても、それだけで購入する価値があるとは限りません。市場価格はあくまでも一次情報です。たとえそれが素朴なものであっても、私たち自身の基準尺が必要です。
そこで、私は最も基本的なポアソンゴールモデルを使いました。
サッカーのスコアは、大まかに言えば、2つのチームが90分間でそれぞれゴールを決めるランダムなプロセスと見なすことができます。ホームチームの90分間の期待ゴール数を λ_home、アウェイチームの期待ゴール数を λ_away とすると、ホームチームが i ゴール、アウェイチームが j ゴールを決める確率は次のように書けます。
text
P(i, j) = Pois(i; λ_home) × Pois(j; λ_away)
ここで、
text
Pois(k; λ) = e^(-λ) × λ^k / k!
もちろん、これは非常に粗いモデルです。サッカーは2つの独立した抽選機ではなく、ゴール後に戦術が変わり、レッドカードが出れば変わり、心理状態も変わります。しかし、このモデルの利点は、シンプルで透明であり、少なくとも直感だけで判断することを防いでくれる点にあります。
試合前には、ポアソンモデルがまず初期の参考値を提供します。私たちは手動で λ_home と λ_away を設定することもできますし、プログラムに市場の正確なスコアのオッズから逆算させることもできます。例えば、0-0、0-1、1-0、1-1、2-0、2-1、3-0 といったスコアのオッズは、それぞれ市場が示す確率点に相当します。プログラムは、ポアソンモデルが計算するスコア確率が、これらの市場価格にできるだけ近づくような λ_home と λ_away の組を探す必要があります。
言い換えれば、市場は「これらのスコアはだいたいこの値段だと思う」と言っています。ポアソンモデルは横で小声で「では、それを当てはめてみて、この価格セットの背後にどのようなゴール強度が隠れているか見てみよう」と言っているのです。
戦略では、次のように設定できます。
python
CALIBRATE_LAMBDA_FROM_MARKET = True
MODEL_SCORE_SAMPLES = "0-0,0-1,1-0,1-1,2-0,2-1,3-0"
これらのスコアはモデリングにのみ使用され、注文には関与しません。実際に取引される足は、依然として次の通りです。
text
対象チーム勝ち
0-0
0-1
コードでは、グリッドサーチを用いてλをフィッティングします。これは複雑ではありませんが、非常に直感的です。
python
def fit_lambdas_from_score_markets(quotes, model_score_legs, event_state=None):
samples = []
live_score = event_state.get("score_tuple") if event_state else None
minute = event_state.get("elapsed") if event_state else None
is_live = bool(live_score and minute not in [None, ""])
for leg in model_score_legs:
q = quotes.get(leg["name"])
p_market = quote_probability(q)
if p_market is None:
continue
target_h, target_a = parse_score_text(leg["score"])
if is_live:
current_h, current_a = live_score
if current_h > target_h or current_a > target_a:
continue
samples.append((target_h - current_h, target_a - current_a, p_market, leg["score"]))
else:
samples.append((target_h, target_a, p_market, leg["score"]))
if len(samples) < 2:
return None
best = None
for ih in range(5, 501, 5):
lh = ih / 100.0
for ia in range(5, 501, 5):
la = ia / 100.0
err = 0.0
for add_h, add_a, p_market, _score in samples:
p_model = poisson_pmf(add_h, lh) * poisson_pmf(add_a, la)
err += (p_model - p_market) ** 2
if best is None or err < best["err"]:
best = {"lambda_home": lh, "lambda_away": la, "err": err, "samples": samples}
if is_live:
ratio = max(0.01, max(0.0, 90.0 - float(minute)) / 90.0)
best["lambda_home"] = best["lambda_home"] / ratio
best["lambda_away"] = best["lambda_away"] / ratio
best["source"] = "live_score_markets"
else:
best["source"] = "pre_match_score_markets"
return best
試合前、この λ は単なる初期較正である。試合がまだ始まっていないため、リアルタイムの経路を更新できず、スコアはデフォルトで 0:0、残り時間は 90 分である。この段階では、これをエントリーフィルターとして使用する:
text
モデルカバー確率 = P(対象チーム勝利) + P(0:0) + P(0:1)
そして、以下の条件が必要である:
text
モデルカバー確率 - 市場コスト >= 安全マージン
市場価格が十分に安く、かつモデルがこのバスケットにわずかなアドバンテージがあると判断した場合にのみ、ポジションのオープンを許可する。
本当に面白くなるのは試合が始まってからである。
試合が始まると、ポアソンモデルはもはや静的ではない。例えば、試合が 30 分経過し、現在のスコアがまだ 0:0 だとすると、残り時間は 60 分となり、今後の得点強度は残り時間に比例して縮小する:
text
λ_home_remaining = λ_home × (90 - t) / 90
λ_away_remaining = λ_away × (90 - t) / 90
もし現在のスコアがすでに 1:0 であれば、0:0 や 0:1 はもはや起こり得ない。この場合、モデルは現在のスコアを起点とし、残り時間に何点追加で入るかだけを計算する。最終スコア 2:0、2:1、3:0、1:1 など、依然として起こり得るスコアのみが新しい推定の対象となる。
これがリアルタイムポアソン更新の鍵である。つまり、毎分機械的に試合前の λ を縮小するのではなく、現在のスコア、残り時間、そしてまだ発生し得る正確なスコアのオッズを組み合わせて、その後の試合の展開を再推定するのである。
最終的な戦略は 3 層の判断となる。
第 1 層は市場コスト:
text
win_ask + 0:0_ask + 0:1_ask <= 最大許容コスト
第 2 層はポアソンフィルター:
text
モデルカバー確率 - 市場コスト >= 安全マージン
第 3 層は経路収束:
text
現在の組み合わせの bid 価値 >= 初期コスト + 目標利益
第 1 層と第 2 層の両方が満たされた場合にのみ、エントリーを検討する。エントリー後は、モデルで終盤を想像するのではなく、実際のマーケットの bid でポジションをクローズできるか判断する。モデルはエントリーの質を高め、マーケットの bid が実現可能性を決定する。
契約の検索もできるだけシンプルに行う。Polymarket のワールドカップ市場の slug は非常に規則的である。例えば、ある試合の event slug は次のようになる:
python
EVENT_SLUG = "fifwc-aut-jor-2026-06-17"
Jordan 勝利を守る場合、対応する勝利契約のサフィックスは:
python
WIN_SUFFIX = "jor"
すると、取引に必要な 3 つの契約は直接組み立てられる:
python
def yes_symbol(slug):
return slug + "_USDC.Yes"
def build_legs():
legs = [
{
"name": "win",
"slug": EVENT_SLUG + "-" + WIN_SUFFIX,
"symbol": yes_symbol(EVENT_SLUG + "-" + WIN_SUFFIX),
"kind": "win",
}
]
for score in parse_scores(PROTECT_SCORES):
legs.append(
{
"name": "score_" + score.replace("-", "_"),
"slug": EVENT_SLUG + "-exact-score-" + score,
"symbol": yes_symbol(EVENT_SLUG + "-exact-score-" + score),
"kind": "score",
"score": score,
}
)
return legs
ここでは、チーム名を使った曖昧検索はできるだけ避ける。例えば Jordan で検索すると、Michael B. Jordan、Jordan Pickford、Jordan Spieth が簡単にヒットし、最終的にサッカー戦略が始まる前に、エンターテイメント、イングランドのゴールキーパー、ゴルフが同じテーブルに座ることになる。event slug で契約を組み立てれば、すっきりする。
試合中にはリアルタイムのスコアも必要である。最初のバージョンでは、Polymarket Gamma の event から直接取得できる:
python
def get_event_state():
data = get_json(GAMMA_BASE + "/events", slug=EVENT_SLUG)
e = data[0]
return {
"title": e.get("title"),
"score": e.get("score"),
"score_tuple": parse_score(e.get("score")),
"elapsed": e.get("elapsed"),
"period": e.get("period"),
"live": bool(e.get("live")),
"ended": bool(e.get("ended")),
"start_time": e.get("startTime"),
}
現在の売却可能価値は実際の板の bid を使用:
python
def basket_bid_value(legs, quotes):
total = 0.0
for leg in legs:
pos = positions.get(leg["name"], {})
amount = float(pos.get("amount", 0))
if amount <= 0:
continue
q = quotes.get(leg["name"])
if not q or q["bid"] is None:
continue
total += amount * q["bid"]
return total
利確判断:
python
cost = current_position_cost()
value = basket_bid_value(legs, quotes)
target = cost + TARGET_PROFIT * SHARES
if value >= target:
close_all()
これが最小バージョンです。サッカー予測を解決したと偽ることも、安定したアービトラージを宣言することもありません。単に「アービトラージ」と「予測」の間のグレーゾーンを調べてみようという試みです。
アービトラージの美しさは確実性にありますが、確実性は希少です。予測の魅力は自由度が大きいことですが、ランダム性も大きいです。この戦略が行っているのは、市場が提示する予測価格を材料として、高確率のメイン判断に2つの低確率の保護パスを組み合わせ、さらにポアソンモデルで粗いフィルターをかけ、試合中に早期収束するウィンドウを構築しようとすることです。
リスクは明確に説明しなければなりません。この組み合わせは完全な事象をカバーしておらず、無リスクアービトラージではありません。これは、強弱の差が大きく、メインパスが十分に明確で、保護パスの価格が十分に低い試合に適しています。試合自体が五分五分である場合や、保護レッグがすでに高額である場合、無理に行う意味はありません。さらに厄介なのは、すべての不利なパスをカバーしているわけではないことです。例えば1:1、0:2、2:2などの結果では、この組み合わせが明らかな損失を生む可能性があります。そのため、ポジション上限、最大損失、ストップロスのルールを設定する必要があり、「アービトラージに見えるから」といってアービトラージとして扱ってはいけません。
ポアソンモデルも魔法ではありません。それは非常に素朴な数学的基盤にすぎず、「この価格はいいな」という感覚から、「少なくとも透明なモデルでこの価格をチェックした」という一歩前に進むためのものです。モデルは間違えますし、市場も間違えますし、私たち自身もさらに間違えます。取引において最も誠実な部分は、おそらくこれらすべてが間違うことを認め、間違いが一気にテーブルをひっくり返さないようにすることでしょう。
今回の試みは非常に浅いものです。それはむしろ、次のような問いかけに近いです:純粋なアービトラージの機会が減り、純粋な予測が難しくなっている今、市場がすでに与えている確率を活用して、より構造化された取引を構築できないだろうか?リスクを消し去る幻想ではなく、リスクを分解し、それがどのルートから来るのかを明確に見極めることです。
おそらくこれが答えではありませんが、掘り続ける価値のある小さな穴です。予測はどのメインルートがより広いかを教え、アービトラージの考え方は方向だけでなく組み合わせ構造も見るよう促します。この両者の間には、まだ多くの探求の余地があるかもしれません。
戦略ソースコード: Polymarket サッカーパス収束戦略
- 1




