Rank instruments¶
A score ranks eligible instruments for a portfolio selection. Use comparable values and enough history for every member.
momentum_score(21) creates a score function based on a 21-bar log return. mean_reversion_score(21) reverses that preference. momentum_score returns an exclusion score when history is insufficient; the mean-reversion inversion needs an explicit missing-history guard, as explained below.
symbols = ["TCS", "INFY", "RELIANCE"]
def on_tick():
if should_rebalance("monthly"):
rebalance_top(symbols, momentum_score(21), n=2, gross=0.5)
This targets the top two with equal shares of 50% gross allocation. A custom score function takes a symbol and returns a number; float("-inf") excludes a member. Read scoring reference and orders for exact arguments.
Selection and money allocation are separate¶
With three eligible names, n=2 chooses at most the top two available scores. If both qualify, gross=0.5 divides a 50% gross allocation into 25% each. n is a count, lookback is a bar horizon, and gross is a fraction rather than a percent number.
Higher scores win in rebalance_top. A negative score is still eligible; float("-inf") is the explicit exclusion sentinel. If fewer than N names remain after exclusions, the available names share the gross allocation. The returned dictionary shows submitted target weights rather than guaranteed holdings.
Check score history before ranking¶
momentum_score(21) uses a 21-bar log return and therefore requires at least 22 closes. It returns the exclusion sentinel when history is insufficient. The current mean_reversion_score inverts that helper, including its sentinel; missing history can become positive infinity. Check history and finite score values explicitly before using it for selection.
For custom scores, return a numeric value for each requested symbol and -inf to exclude it. Keep units comparable: absolute price change can favour high-priced instruments, while return-based scores compare proportional changes.
Review one rebalance¶
Inspect the eligible list, scores, selected members and weights. rebalance_top issues a rebalance; top_n and bottom_n only return selected names from an existing score mapping. They do not create orders. If every score is excluded, rebalance_top returns an empty dictionary without issuing a rebalance; that is not an instruction to flatten the old book.