【FX自動売買開発ログ #5】4時間足を試そうとしたら、先にバグが2つ出てきた話

前回のおさらい

前回、AIアンサンブル戦略の一見良さそうな結果が、実はトレード数がわずか2〜3件という「ほぼノイズ」の水準だったことが判明しました。原因を掘り下げると、「反転まで無制限保有」という設計上、判定がこまめに変わらない限りトレード自体が発生しにくい、という構造が見えてきました。

今回は、そこからの続きです。サンプル数を増やすために時間足を4時間足に切り替える案と、無制限保有の弱点を埋める損切りの実装、この2つのどちらを先にやるかを検討します。

まずは4時間足の見積もりを聞いてみた

サンプル数(トレード数)を増やす方法はいくつか考えられますが、今回は時間足を日足→4時間足に切り替える案を試すことにしました。同じstride/min_agree/confidence-thresholdの組み合わせで、まず4時間足でのAPI呼び出し回数を見積もってもらうところから始めます。

……のはずが、見積もりを出す前に、データそのものの問題が見つかりました。

バグその1:夏時間でタイムゾーンが混在していた

4時間足のCSVを調べたところ、タイムスタンプに+01:00と+00:00が混在していることが分かりました。夏時間(DST)の影響で、同じ「日足のインデックス」のはずが、時期によってオフセットがずれてしまっていたのです。これにより、CSVを再読込した際に日付フィルタ(--start/--end)が正しく機能しなくなるという、データ品質上のバグでした。

対処として、取得したイントラデイのデータをUTCに正規化してから保存するよう修正し、日付フィルタ側の比較ロジックも合わせて直してもらいました。データも再取得しましたが、これはYahoo Financeへの再取得なのでAPIコスト(Claude API)はかかっていません。

バグその2:キャッシュキーが「日付のみ」だった

タイムゾーンの修正のついでに、もう一つ見過ごせない不具合が見つかりました。理論判定のキャッシュキーが日付(.date())のみを使っていたのです。

日足データなら1日1本しかバーがないので問題になりませんが、4時間足・1時間足では同じ日に複数のバーが存在します。つまりこの実装のままだと、「7月15日の9時のバー」と「7月15日の21時のバー」が、キャッシュ上は同じキーとして扱われ、本来別々に判定すべき異なる相場状況に対して、誤って同じ判定結果を使い回してしまう状態でした。

これは地味に怖いバグです。動作は一見正常に見える(エラーも出ない、結果も返ってくる)のに、中身が静かに間違っている、というタイプの不具合だったので、日足だけで検証していた間は気づけませんでした。時刻情報を含めたキャッシュキーに直し、判定に使うローソク足のサマリー表示についても、日足以外では時刻を含めないと同日の複数バーを区別できないことが分かったため、合わせて修正しています。

修正後の4時間足見積もり

バグ修正後、あらためて4時間足での見積もりを計算してもらいました。同条件(stride=3, window=20, min_history=20, train_frac=0.5)での結果です。

項目値
対象期間の4hバー数1,635本
train評価ポイント266
test評価ポイント266
API呼び出し回数1,064回
概算コスト$5〜6程度

前回の日足・stride=3(152回、$0.35〜0.6程度)と比べると、約7倍の呼び出し回数です。4時間足は日足の約6倍の頻度でバーが存在するので、単純計算としては妥当な増え方ではあります。ただ、最小保有期間もstride=3本×4時間=12時間と、日足のときの3日から大きく短縮されるため、トレード数がどこまで増えるかは実際にやってみないと分からない、という回答でした。

損切りが先か、4時間足検証が先か

ここで、2つの選択肢のどちらを先にやるべきか意見を聞いてみました。返ってきたのは「損切りを先に実装すべき」という提案で、理由は次の3点でした。

  • 今の「反転まで無制限保有」という設計はドローダウンが制御されておらず、どのタイムフレームで検証しても結果の信頼性がそもそも低い
  • 損切りを入れれば挙動が大きく変わるため、先に4時間足で1,064回・$5〜6かけて検証しても、損切り導入後にもう一度やり直しになる可能性が高い(無駄打ちのリスク)
  • 損切り追加はバックテストエンジン側の純粋なロジック変更で、Claude APIコストはゼロ。既存のキャッシュ済み日足データだけで効果を検証できる

言われてみれば、根本の設計に不備があるまま検証範囲だけ広げても、出てくる数字の信頼性は変わりません。むしろ「お金のかからない改善」を先に済ませてから、「お金のかかる検証」に進む方が、今の開発の進め方(STEP5で予定していた「リスク管理はAIに判断させず固定ルールとしてハードコードする」という方針)にも合っています。

提案された順序は、①ATRベースの固定幅損切りをエンジンに追加 → ②既存の日足キャッシュデータで損切りあり/なしを比較 → ③その結果を踏まえて4時間足(または1時間足)への切り替えを検討、という流れです。

次回予告

次回は、このATRベースの損切りを実際にバックテストエンジンに組み込み、損切りあり/なしで結果がどう変わるかを、既にキャッシュ済みの日足データを使って(追加のAPIコストなしで)比較します。

※本シリーズは個人の技術検証・学習を目的とした開発記録であり、特定の投資手法や金融商品を推奨するものではありません。自動売買には元本割れのリスクがあり、掲載する内容を参考にした取引の結果について一切の責任を負いかねます。投資判断はご自身の責任で行ってください。

コメントを残す

メールアドレスが公開されることはありません。 ※ が付いている欄は必須項目です