Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/component/strategy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ TopkDropoutStrategy

- Generate the order list from the target amount

.. note::
`TopkDropoutStrategy` holds an **equal-weighted** portfolio: the available cash is split
evenly among the stocks bought on each rebalance. When its results are compared against a
capitalization-weighted benchmark such as the default ``SH000300``, the reported excess
return also contains the equal- versus cap-weighting spread of the universe, which is a
property of the weighting scheme rather than of the signal. Use a benchmark whose weighting
scheme matches the strategy if you want to isolate the contribution of the signal.

EnhancedIndexingStrategy
------------------------
`EnhancedIndexingStrategy` Enhanced indexing combines the arts of active management and passive management,
Expand Down
18 changes: 18 additions & 0 deletions qlib/contrib/strategy/signal_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,24 @@ def get_risk_degree(self, trade_step=None):


class TopkDropoutStrategy(BaseSignalStrategy):
"""
An equal-weighted top-k strategy with fixed daily turnover (the ``Topk-Drop`` algorithm).

.. note::
Positions are **equal-weighted**. On each rebalance the available cash is divided
evenly among the stocks to be bought (see :meth:`generate_trade_decision`), so the
realized portfolio approximates an equal-weighted portfolio of ``topk`` names.

This is worth keeping in mind when reading the excess return reported by
:class:`qlib.workflow.record_temp.PortAnaRecord`, which is a plain difference
against a single benchmark instrument. The default benchmark ``SH000300``
(CSI 300) is capitalization-weighted, so that difference also contains the return
spread between equal- and cap-weighting of the universe, which is a property of
the weighting scheme rather than of the signal. To isolate the contribution of the
signal, use a benchmark whose weighting scheme matches the strategy, e.g.
an equal-weighted portfolio of the same universe run through the same executor.
"""

# TODO:
# 1. Supporting leverage the get_range_limit result from the decision
# 2. Supporting alter_outer_trade_decision
Expand Down
14 changes: 14 additions & 0 deletions qlib/workflow/record_temp.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,20 @@ class PortAnaRecord(ACRecordTemp):

- The return report and detailed positions of the backtest, returned by `qlib/contrib/evaluate.py:backtest`
- port_analysis.pkl : The risk analysis of your portfolio, returned by `qlib/contrib/evaluate.py:risk_analysis`

.. note::
``excess_return_without_cost`` and ``excess_return_with_cost`` are computed as a
plain arithmetic difference between the portfolio return and the return of the
single instrument configured as ``config["backtest"]["benchmark"]``. No adjustment
is made for a difference in weighting scheme between the strategy and the benchmark.

The default configuration pairs an equal-weighted strategy
(:class:`~qlib.contrib.strategy.signal_strategy.TopkDropoutStrategy`) with a
capitalization-weighted benchmark (``SH000300``). Under that pairing the reported
excess return also contains the equal- versus cap-weighting spread of the universe,
so it should be read as performance relative to that specific index rather than as
the contribution of the signal alone. Choosing a benchmark whose weighting scheme
matches the strategy removes that component.
"""

artifact_path = "portfolio_analysis"
Expand Down