推奨銘柄システムの改善記録 — 「毎回同じ顔ぶれ」問題をどう解いたか
はじめに
毎朝動いている日本株推奨スキルに、ずっと気になっていた問題があった。ランキングの顔ぶれがほとんど変わらないのだ。ソフトバンクグループ、トヨタ、ソニーグループ。確かに優良企業だが、これでは「今日おすすめの銘柄」ではなく「いつでも大丈夫な大型株リスト」になってしまう。今回はこの問題を起点に、スコア構造の根本から見直した記録をまとめる。
問題の解剖:なぜ毎回同じ銘柄が出るのか
まず原因を特定するために、推奨スコアの計算式を掘り下げた。
recommend_score = composite_signal × 0.5 + analyst_score × 0.3 + upside_score × 0.2
composite_signal = value_score × 0.4 + alpha_score × 0.3 + pullback_score × 0.3
一見バランスが取れているように見えるが、実態は2つの構造的な問題を抱えていた。
問題1:alpha_score が全銘柄で 50 固定
AlphaScreener(フリーキャッシュフロー・アクルーアルズ・粗利益率を分析するスクリーナー)は実装済みだったが、スコア計算には接続されておらず、全銘柄が一律 50 点のデフォルト値を使っていた。つまり「利益の質」がスコアに一切反映されていなかった。
問題2:アナリストカバレッジが多い銘柄ほど有利
アナリストデータが存在しない場合は 50 点(中立)として扱われる設計だった。大型株はアナリストが 15〜23 名いるため strong_buy 評価(analyst_score ≈ 87.5 点)を得やすいのに対し、小中型株はデータがなければ常に 50 点スタート。この構造的なハンデが、大型株を上位に固定する要因になっていた。
7日以内に調査済みの銘柄をスキップする「7日フィルタ」と、全銘柄スキップ時に発動する「簡略モード」も重なり、キャッシュした古いデータでランキングを出すという状況になっていた。
改善1:毎回全銘柄を新規取得する
まず7日フィルタと簡略モードを廃止した。「今日のおすすめ」を出すためには、今日のデータで評価するのが前提だからだ。過去データとの比較は CompanyStore の format_comparison が担うため、毎回保存・毎回比較という設計に切り替えた。
改善2:先行スコア調整(Forward-Looking Boost)
「変わり映えのない推奨」をもう一段解消するために、「まだ動いていないが動く手前にある銘柄」を浮上させる先行シグナル調整層を追加した。
| シグナル | 加減点 | 狙い |
|---|---|---|
| 決算発表まで7日以内 | +15pt | 株価は発表前に動く |
| 決算発表まで14日以内 | +10pt | 仕込みのタイミング |
| 相対力指数(RSI)30〜40 | +15pt | 底打ち直後・まだ上昇しきっていない |
| RSI 40〜50 | +8pt | 回復途上 |
| RSI 70超 | -20pt | 過熱圏・新規エントリー不適 |
| 52週高値の95%以上 | +12pt | ブレイクアウト直前 |
| 52週高値の90〜95% | +6pt | 高値に接近中 |
| 前回トップ5に入っていた銘柄 | -15pt | ローテーション確保 |
これらは価格が動いた後ではなく、動く前に観測できる変数だ。決算前に機関投資家が仕込む、RSIが底打ちから回復する途中に乗る、という先読みの発想をスコアに落とし込んだ。
改善3:AlphaScreener の実データをスコアに接続する
最も効果が大きかったのはこの変更だった。recommendation_engine.py の1箇所を修正し、AlphaScreener._calc_alpha_score(info) を実際に呼び出すようにした。
# 変更前
alpha_score = 50 # デフォルト固定
# 変更後
alpha_result = self.alpha_screener._calc_alpha_score(info)
alpha_score = alpha_result["total"]
実データで計算すると、銘柄間の差は歴然だった。
| 銘柄 | alpha_score | FCFマージン | アクルーアルズ比率 |
|---|---|---|---|
| アドバンテスト | 100.0 | 24.3% | -0.158(低いほど良い) |
| 東京エレクトロン | 93.3 | 12.1% | -0.190 |
| 中外製薬 | 79.0 | 20.9% | 0.110 |
| ソフトバンクグループ | 25.0 | -0.7% | 1.018(要注意水準) |
| キーエンス | 0.0 | N/A | N/A |
この変更による推奨ランキングへの影響は下記の通りだ。
大きく上昇した銘柄(利益の質が実際に高い)
- アドバンテスト:composite +15.0pt、4位 → 1位
- 東京エレクトロン:composite +13.0pt、8位 → 4位
- 中外製薬:composite +8.7pt、6位 → 3位
下落した銘柄(FCFがマイナス・アクルーアルズ不良)
- ソフトバンクグループ:composite -7.5pt、1位 → 5位
- エムスリー:composite -7.5pt、5位 → 8位
ソフトバンクグループが1位から5位に下がったのは、FCFがマイナス(-0.7%)でアクルーアルズ比率が1.018という実態を正しく反映した結果だ。「有名だから上位」ではなく「稼ぐ力で評価する」スコアに近づいた。
残課題
キーエンスとファナックは yfinance からFCFデータが取得できず、alpha_score がゼロになってしまう。日本株の財務データはyfinanceのカバレッジが薄い銘柄があり、この問題は構造的に残る。アナリストカバレッジの薄い小中型株が依然として不利な構造も完全には解消していない。
一方で、AlphaScreenerが機能しない銘柄については「データが取れない=評価できない」として正直に扱うほうが、50点というダミー値で誤魔化すより誠実だという判断でもある。
おわりに
今回の改善は「コードを書き直す」よりも「既存の仕組みを正しく接続する」という作業が中心だった。AlphaScreenerはすでに存在していたし、先行シグナルも既存の取得データから計算できる。問題は「あるのに使われていなかった」ことで、繋ぎ方を変えるだけで結果が大きく変わった。
分析システムはデータ取得や可視化に目が向きがちだが、スコアの設計とデータの接続を定期的に見直すことで、出力の質が変わる。そういう地道な改善が積み重なっていく。
本記事はAIが自動生成した分析システムの改善記録です。投資は自己責任でお願いします。