1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LLMの定期判定で「安全線」が値下がりと一緒に下がるバグ 〜承認済みの値を下限にし、到達確認はコードで先に行う〜

1
Posted at

みなさん、こんにちは!
「ALPHA FORGE 開発秘話」の第33話です。

含み損は-14.8%。それでもAIの判定は、毎日「保有継続」でした。
安全線より下には、まだ届いていないから。ただ、その安全線のほうが、値段と一緒に下へ動いていたんです🪜

日本株のデータ分析端末「ALPHA FORGE(アルファフォージ)」を、Claude Code と二人三脚で個人開発しています。今回は【事件簿】回。LLMに定期的な判定をさせている人に、毎回まっさらに考えるAIへ「前回の約束」をどう持たせたか、をお届けします。

【要約:この記事で伝えたいこと】

  1. 保有中の判定が、毎回その時点の値段と値動きの幅から安全線(シナリオ無効化水準)を引き直していた。前回の値も、人が承認した値も使われていなかった
  2. 保有継続・一部利確では承認済みの安全線を下限にし、値段がその線以下ならLLMを呼ばずに見直しを提案する形にした
  3. 持ち帰り:毎回考え直す仕組みには「前回の約束」を必ず渡す。守らせたい線はプロンプトでなくコードで守る

※本記事はnote連載[ALPHA FORGE 開発秘話 #33] の技術的な部分を、エンジニア向けに再構成したものです。

🧭 保有中の見直しは、毎回まっさら

ALPHA FORGEには、登録した保有状況をAIが定期的に見直す機能があります。判定は「保有継続(hold)」「一部利確(trim)」「買い増し(add)」「シナリオ無効化(stop_loss)」の4つです。

判定と一緒に、シナリオ無効化水準も出します。「ここまで下がったら、最初の見立ては崩れた」とみなす線で、この記事では「安全線」と呼びます。

AIが出すのは提案だけです。人が承認するまで何も起きませんし、このアプリは発注をしません。それでも安全線がちゃんと働かなければ、見直しの提案そのものが出てきません。

💥 「まだ届いていません」が続いた理由

見つけたのは2026年9月26日の夜です。人間が「大引け後レビュー」を頼み、AIが前日の判定をまとめました。

その中で、AIが「気になる点」として挙げた1行がありました。ある保有銘柄の安全線が、前日の判定から1日で約12%も下に動いている。そのあいだに含み損は-5.7%から-14.8%へ広がっていた、というものです。

人間が返したのは「この線の計算の仕方を調べてほしい」という短い一言。AIが調べた結果はこうでした。

  1. 保有中の判定は、毎回その時点の値段と値動きの幅(ATR)から安全線を計算し直していた
  2. 前回の安全線も、人が承認した安全線も、どこにも使われていなかった
  3. 安全線は、いつも今の値段より値動きの幅1本分以上、下に置かれていた

値段が下がれば安全線も下がる。仕組みの上では、値段が安全線に届く日が来ません🙈

02_wall.jpg
値段が下がると、安全線も一緒に下がる

ハマりどころ:新規の計算式を保有中にも使い回していた
新しく買う場面の判定なら、今の値段を基準に線を引くのは自然です。原因は、その計算を保有中の判定にもそのまま使い回していたことでした。「これから置く線」と「すでに約束した線」は別物です。

🛠️ 承認した線を「下限」にする

AIが出した直し方は2つです。

案 内容 評価
A サーバー側で、保有中の安全線を前回より下げない 推奨
B 前回の安全線と到達の有無をプロンプトに渡す AIの答え次第で守られない可能性がある

AIはAを勧めたうえで、人間に1つだけ判断を求めました。基準にする「前回の安全線」を、直近で承認された判定の値にするか、保有を登録したときの最初の値にするか。人間の返事は「1で進めて」。直近で承認された判定を基準にすることになりました。

03_fix.jpg
届いたかは先にルールで確かめ、AIには後で聞く

入った変更はこうです。

  1. 保有継続と一部利確では、承認済みの安全線より下げない(上にだけ動かす)
  2. AIが低い値を出したときは承認済みの値に戻し、判定理由に「AIの提案から補正した」と書き足す
  3. 値段が承認済みの安全線以下なら、AIを呼ばずに見直し(stop_loss)を提案して通知する
  4. 買い増しは線を置き直す判断なので対象外。買い直す前の古い判定も基準にしない

処理の順番を実装から示すとこうなります(コミット ee9ab7a の要点を抜き出して整理したもの。LLM呼び出し部分は _ask_llm に縮め、コメントは書き直しています)。

_NO_LOWER_STOP_ACTIONS = frozenset({"hold", "trim"})

async def evaluate_holding(holding):
    # 人が承認した最新判定(このロットの取得日以降)の安全線
    approved = await _approved_levels(holding)
    if approved is not None and holding.current_price <= approved[0]:
        # 到達はルールで確定させる。LLM は呼ばない
        return await _propose_stop_loss_on_breach(holding, holding.current_price, *approved)

    action, entry, stop, target, confidence, rationale = await _ask_llm(holding)

    if action in _NO_LOWER_STOP_ACTIONS and approved is not None and stop < approved[0]:
        rationale += "(安全線はLLM提案の値から、承認済みの値へ補正)"
        stop = approved[0]
    return await _record_signal(holding, action=action, stop=stop, ...)

基準にする判定は、DB側で「承認済み(approved / executed)」かつ「ロットの取得日以降」に絞っています。未承認や却下の判定は、人が合意していないので基準にしません。

SELECT * FROM portfolio_signals
WHERE symbol = :symbol
  AND status IN ('approved', 'executed')
  AND evaluated_at >= :since
ORDER BY evaluated_at DESC LIMIT 1

届いたかどうかは、AIに考えてもらうことではありません。「この値以下か」というルールなので、コードで先に確かめます。それでも出すのは承認待ちの提案までで、発注はしません。

fig_rules.jpg
下げない・書き残す・届いたら知らせる

⚖️ 戻さなかった線と、決めなかったこと

修正の報告で、AIは2つの注意点を先に書いていました。

  1. 下がってしまった線は元に戻らない:前日に承認された判定の時点で、安全線はもう下がっていた。その値が基準になるので、1日前の高い線には戻らない。戻すなら、線を指定し直す手段が別に要る
  2. 提案を却下したあとの扱いが決まっていない:届いたあとに保有を続けると決めても、基準の線は変わらない。5分ごとに同じ提案が出続ける(通知は同じ日・同じ銘柄・同じ判定で1回だけ)

どちらも、その場ではコードを足していません。線をどう引き直すかは、人が決めることだと考えたからです。

fig_open.jpg
下がった線は戻らない、却下後の扱いは未定

🧰 毎回まっさらなAIに、前回を渡す

LLMは毎回、渡された材料だけで考えます。前回の判定を覚えていてほしいなら、人間の側から渡すしかありません。今回の修正から、同じ種類の機能に使える依頼の型を組み立てるとこうなります。記事のために整理した例で、当時の人間の発言の引用ではありません。

定期的に判定をし直す処理を見直してください。
毎回、その場の値だけで計算し直している値があれば挙げてください。
人が承認した値を、次の判定でどう扱っているかを確かめてください。
「下げてはいけない値」「届いたら知らせる値」はコードで守り、AIの答えに任せないでください。
直したあと、すでに記録された値がどうなるかも報告してください。

「AIに守らせる」と「コードで守る」を分けておくと、どこを確かめればいいかがはっきりします✍️

🤝 誰が気づき、誰が決めたか

気づいたのはAIです。大引け後レビューの中で、安全線の下がり方を「気になる点」として挙げていました。

調べるよう指示したのは人間で、原因の特定と直し方の案、実装とテストの追加はAIです。テストは10件増え、すべて通ったと報告されています。基準をどの値にするか、コミットしてよいか、動いている処理を再起動してよいかは、人間が決めました。

AIは提案し、人間が承認する。保有の見直しでも、その順番は変えていません。

📌 保存用チェックリスト

fig_checklist.jpg
毎回考え直す仕組みの点検

  1. 毎回その場で引き直している値を洗い出す
  2. 人が承認した値を、次の判定が使っているか確かめる
  3. 下げてはいけない線は、AIでなくコードで守る
  4. 線に届いたら、誰に何を知らせるか決める
  5. 直したあと、すでに記録された値がどうなるか確かめる

☕ note.comで開発秘話と毎朝の検証ログを連載中

note.comでは、「ALPHA FORGE」の開発秘話と、毎朝のアルゴリズム検証ログを公開しています。

👉 元記事(note連載第33話):
https://note.com/featured_stocks/n/n3e0d47a145c7

同じ保有監視の話として、5分ごとのAI見直しに待ち時間を入れた第31話もどうぞ。

エンジニアでない方向けに「AIへの仕事の頼み方」をまとめた連載(メンバーシップ「AIとつくるラボ」)もやっています。第0話は無料で読めます。


免責事項
本記事は個人開発およびAIエージェントを活用したシステム開発の技術記録です。特定の銘柄の売買推奨や投資助言を行うものではありません。本記事は2026年9月26日の実装記録と会話ログを2026年10月24日に確認したものです。銘柄名と価格は掲載していません。シナリオ無効化水準は分析上の目安であり、投資の判断基準や損失の回避を保証するものではありません。本アプリは発注を行いません。

⚠️ 【システム検証記録に関する免責事項・注意事項】

  • 本記事は、独自開発アルゴリズム「ALPHA FORGE」の動作検証およびデータ分析過程を公開する技術・運用の個人的な記録ログです。
  • 掲載されているすべてのデータ(各スコア、基準観測値、統計的変動上限、シナリオ無効化水準など)は、過去の市場データに基づき数式(ATR等)により機械的に算出されたバックテスト・シミュレーション用のパラメータであり、特定の有価証券の売買勧誘、取引の推奨、投資助言・代理行為を目的としたものではありません。
  • また、将来の株価変動や運用成果を保証するものではありません。実際の投資判断および最終決定は、必ずご自身の責任と判断において行っていただけますようお願いいたします。
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?