複数シグナルをスコアで合議する設計 — 条件の積み上げに行き詰まったときの組み立て方
「A条件かつB条件かつC条件が揃ったらエントリー」という形でロジックを組んでいくと、条件を足すほどシグナルが出なくなり、かといって条件を外すとノイズが戻ってくる——という壁に当たります。本記事では、この行き詰まりをほどく選択肢として、検討を打ち切るかどうかを決める「ゲート条件」と、どれだけ条件が揃っているかを点数で表す「加点条件」の二層に分けるスコアリング設計を整理します。想定読者は、複数の指標をすでに組み合わせていて、条件の足し引きが手詰まりになっている方です。特定の重み付けが成果を保証するという話ではなく、判断構造の組み立て方を共有することが目的です。
ゲート条件の役割
ゲート条件は、満たしていなければその足での検討そのものを打ち切る足切りの層です。データが揃っていない起動直後、スプレッドが通常より大きく開いている時間帯、上位足の方向とまったく逆を向いている場面などが典型例で、トレンド相場とレンジ相場の区別のように前提そのものを問う条件もここに入ります。
ゲート条件が担うのは、そもそも成立しない場面を早い段階で捨てるという仕事です。他の材料がどれだけ良く見えても覆らない条件をここに置くことで、判定の下流に不健全な入力が流れ込むのを防げます。
一方で、ゲートは通すか通さないかの二値でしか答えを返しません。「わずかに足りない」と「大きく足りない」を区別できないため、閾値のすぐ近くで材料が揺れる場面ではシグナルの有無が細かく反転します。加えて、すべての条件をゲートとして直列に並べると、条件を1つ足すたびに通過率が掛け算で下がっていきます。条件を厳しくするほどシグナルが枯れるという冒頭の行き詰まりは、この構造から生まれています。
加点条件の役割
加点条件は、各判定に部分点を与え、その合計で候補の質を表す層です。ADXの基礎で扱うトレンドの強さ、RSIの基礎で扱うモメンタムの位置など、程度で語れる材料が向いています。
加点条件が担うのは、「どの程度揃っているか」を落とさずに保持するという仕事です。ある条件がわずかに届かなくても、他の材料が強ければ合計としては閾値を超えうる、という柔らかい判定になります。条件間の重要度の差も、重みという形で明示的に表現できます。さらに、判定の結果が「通った・落ちた」ではなく点数として残るため、後から候補を並べ直して検証しやすくなります。
限界もはっきりしています。合計してしまうと、同じ点数でも中身がまったく違うという事態が起こります。重要度の低い材料が数の力で押し切ってしまうこともあり、リスク管理上の禁止条件を加点に混ぜると、高得点によって静かに打ち消されてしまいます。重みの設定は自由度が高く、過去データに合わせて調整するほど当てはまりは良くなりますが、それは検証したというより過去に合わせただけかもしれない、という疑いが常に残ります。
なぜ二層に分けるのか
判定条件には性質の異なる2種類が混ざっています。ひとつは破ってはいけない条件、もうひとつは程度問題の条件です。二層構造の核心は、この2つを先に仕分けてから配置することにあります。
破ってはいけない条件を加点に混ぜると、他の材料の高得点で打ち消されます。逆に、程度問題の条件をゲートに置くと、閾値付近で判定が細かく反転し、挙動が不安定になります。どちらも、条件の性質と置き場所が噛み合っていないことが原因です。
この視点で見ると、ANDの積み上げはスコアリングの特殊な一形態にすぎません。すべての条件の重みが等しく、閾値が満点に設定された状態がANDです。閾値を満点から少し下げれば、1つの取りこぼしを許容する判定になります。つまり二層設計は、ANDを捨てる話ではなく、ANDを含んだより広い設計空間に出る話です。ゲート方式そのものを詰めていく設計はダマシを減らす二重確認の設計で扱っています。
ただし、スコア化しても情報量そのものが増えるわけではない点には注意が必要です。似た計算系統の指標を別々の項目として加点すると、同じ情報を二度数えることになり、合計点だけが不当に伸びます。加点項目は、互いに違う情報を見ているかどうかで選ぶ必要があります。
パラメータをどう考えるか
この設計で決めるのは、条件そのものより「条件の置き場所と重み」です。
- 仕分け: どの条件をゲートに置き、どれを加点に回すか。ここが設計の大半を占めます
- 重み: 出発点は全項目を等しくすることです。差をつけるのは、なぜその項目が重いのかを言葉で説明できるときに限ります
- 閾値: 満点に近いほどAND相当の厳しさになり、下げるほど候補の頻度が上がります。頻度と質のどちらに寄せるかを決める調整弁です
- 正規化: 単位の違う値をそのまま足さないようにします。各項目を0〜1へ写像するか、段階ごとの部分点に置き換えると、桁の大きい指標が合計を支配する事故を防げます
検証では、閾値を動かして結果を比べる前に、まずスコアの分布そのものを見ます。ほとんどの候補が同じ点数に固まっているなら、その加点項目は判定に寄与していないということです。手順そのものはバックテストの基礎にまとめていますが、重みは自由度が高い分だけ過去に合わせ込みやすく、良い数字が出たときほど疑ってかかる姿勢が必要になります。項目を増やすほど、検証に求められる期間と件数も増える点は意識しておきたいところです。
cBot化する際の考慮点
スコアリングの実装は分岐が浅くなる代わりに、材料の欠損と記録の設計が要点になります。
- 評価順序の固定: ゲート → 部分点 → 合計 → 閾値判定の順に固定します。ゲートで早期に打ち切れば、重い計算を回さずに済み計算負荷も下がります
- 部分点関数の分離: 各条件を「入力を受け取って0〜1を返す」小さな関数に切り出します。単体で確かめられる形になり、項目の差し替えも局所で済みます
- 欠損値の扱い: インジケーターが値を返せない区間では計算結果が
double.NaNになります。NaNを足した合計はNaNになり、閾値との比較は常に偽となるため、シグナルが出ない原因が見えないまま止まります。合計後にNaN検査を挟み、材料欠損はスコア不成立として明示的に扱います - 本数の確認:
Bars.Countが各指標の必要期間を満たしているかを確認してから計算に進みます - 確定値の使用: 判定は
Last(1)の確定値で行い、足の確定ごとに評価するOnBarベースにすると、検証と実運用の食い違いを避けやすくなります - 内訳の記録: 合計だけを残すと後から検証できません。項目ごとの点数を配列やログとして残しておきます
- 境界の扱い: 閾値をちょうど満たした場合に通すのか外すのか、
>=と>のどちらを使うかを最初に決めておきます
// OnBar内: ゲート → 加点 → 閾値判定 の順で評価する
if (!PassesGates()) return; // データ不足・時間帯・上位足の逆行など
double score = 0;
score += weightTrend * TrendScore(adx.Result.Last(1)); // 各関数は 0〜1 を返す
score += weightMomentum * MomentumScore(rsi.Result.Last(1));
score += weightVolatility * VolatilityScore(atr.Result.Last(1));
if (double.IsNaN(score)) return; // 材料欠損はスコア不成立として扱う
if (score >= entryThreshold)
{
// 内訳を記録したうえで、リスク幅の設定とエントリー処理へ
}
実装の流れ
処理の流れを上流から並べると、次のようになります。
- 材料の取得: 足の確定ごとに、各指標の確定値と上位足の状態を取り出します。
- ゲート評価: 前提が崩れている場面はここで打ち切り、以降の計算を行いません。
- 部分点の算出: 各条件を独立した関数で0〜1に写像し、重みを掛けます。
- 合計と閾値判定: 合計値の健全性を確認したうえで、閾値と比較して候補を絞ります。
- 記録: 合計と内訳、そして通過後の推移を残し、どの項目が効いているかを後から確かめられるようにします。
どう活用するか
「破ってはいけない条件はゲートへ、程度問題の条件は加点へ」という仕分けの骨格は、使う指標を入れ替えても崩れません。すでに移動平均・RSI・ATRの三層構成のような組み合わせを持っている方なら、既存の条件を仕分け直すところから試せます。判定を点数で表示する形が実際どう見えるかは、AI Setup Judgeの紹介記事も参考になります。
自分で組んでみたい方は、Claude Codeを併走させたcBot開発の設計メモとして本記事の構成を使ってみてください。作るより相談したいという方は、ai-programming.xyzで個別の開発相談を承っています。体系的に学びたい方に向けては、スクールでこうした判定構造の設計を、手を動かしながら学べるコースを用意しています。
本記事は一般的な情報提供を目的としています。投資助言ではありません。 取引判断はご自身の責任で行ってください。