TopkDropoutStrategy ignores get_risk_degree() for position sizing
メンテナーはふだん 3 日以内に返信
@zhaow-de がすでに取り組んでいます。
2026年6月21日 から。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 78/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 静か
- 技術スタック
- python
調査の方向性
qlib/contrib/strategy/signal_strategy.py を読み、特に 266 行目付近の TopkDropoutStrategy.generate_trade_decision と、69 行目付近の get_risk_degree() のドキュメントを確認してください。その sizing の経路を 365 行目付近の WeightStrategyBase と比較し、その後、オーバーライドされた getter が買い付けの sizing に影響する一方で、既存の戦略の動作は変わらないことを検証してください。
索引モデルが issue の本文から書いたものです。
説明
🐛 Bug Description
get_risk_degree() is documented as the dynamic market-timing hook ("Dynamically risk_degree will result in Market timing.", qlib/contrib/strategy/signal_strategy.py:69). But TopkDropoutStrategy.generate_trade_decision sizes new buys with the raw attribute self.risk_degree, not the getter:
# qlib/contrib/strategy/signal_strategy.py:266
value = cash * self.risk_degree / len(buy) if len(buy) > 0 else 0
It is the only use of risk_degree in TopkDropoutStrategy, and it bypasses get_risk_degree(). So a subclass that overrides get_risk_degree() to return a time-varying multiplier (the documented way to implement market timing) has zero effect on a TopkDropout book — the override is never called. (By contrast, WeightStrategyBase at line 365 and its subclass EnhancedIndexingStrategy at line 482 do call self.get_risk_degree(...), so the inconsistency is within the same module.)
To Reproduce
- Subclass
TopkDropoutStrategyand overrideget_risk_degree()to return, say,0.0on some dates (a regime gate to cash) andself.risk_degreeotherwise. - Backtest it vs. the un-subclassed
TopkDropoutStrategyon the same signal. - The two produce identical trades/returns — the overridden
get_risk_degree()is never consulted for buy sizing.
Expected Behavior
TopkDropoutStrategy should size buys with self.get_risk_degree(trade_step) (as WeightStrategyBase does), so that overriding get_risk_degree() actually enables market timing as documented:
value = cash * self.get_risk_degree(trade_step) / len(buy) if len(buy) > 0 else 0
Environment
- Qlib version: 0.9.7 (
qlib/contrib/strategy/signal_strategy.py(TopkDropoutStrategy.generate_trade_decision, line ~266) - Python version: 3.12
Additional context
Discovered while building a BTC-trend regime overlay (RegimeGatedTopkStrategy(TopkDropoutStrategy)) that gates gross exposure via get_risk_degree(). The overlay had no effect on backtests until we worked around it by pushing the gated value onto self.risk_degree per step before delegating to super().generate_trade_decision(). A two-line fix in TopkDropoutStrategy (use the getter) would remove the need for the workaround.
- 主要言語
- Python
- スター
- 49.5k
- フォーク
- 7.8k
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートあり
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/qlib のほかの issue
-
StructuredCovEstimator crashes for one factor and uses inconsistent residual variance対応中かも @Divyansh151005 が 1 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
microsoft/qlib#2377 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
-
collect_info.py does not start: pkg_resources is gone from setuptools 82対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
microsoft/qlib#2354 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
-
IdxMax and IdxMin return the position of NaN instead of the extreme value対応中かも @bozarnr が 26 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
microsoft/qlib#2352 · コメント 4 件 ·
メンテナーはふだん 3 日以内に返信
-
Bug: Rsquare(N=0) expanding path leaks inf/garbage on near-constant windows (rolling path is guarded)対応中かも @DogInfantry が 102 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
microsoft/qlib#2297 · コメント 4 件 ·
メンテナーはふだん 3 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
microsoft/qlib#2198 · コメント 1 件 ·
メンテナーはふだん 3 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
google-ai-edge/litert-torch#1346 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
geneontology/gocam-py#272 ·
-
pushed_authorization_request sends list authorization_details as a Python repr対応中かも @RaphaelFakhri が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
auth0/auth0-python#903 ·
メンテナーはふだん 1 日以内に返信