HeyTraders Documentation

Cross-Sectional Ranking Strategies

Runtime contract: LIVE/PAPER, candle evaluation (for example 1h), with the strategy's current balances and positions supplied. These fixed-notional basket examples use portfolio_value(), which requires that live state. Historical backtests should express a target gross weight directly through rebalance_to(...); they do not provide live balances to this calculation.

Momentum Top-Bottom Basket

Tags: cross_sectional, ranking, momentum, top_n, bottom_n, basket, long_short, rebalance, cross_mode Functions: get_data, drop_nan, top_n, bottom_n, portfolio_value, long_short_equal_weight, cap_weights, rebalance_to Description: Ranks a fixed tradable universe by trailing momentum, allocates a fixed basket budget, goes long the strongest assets and short the weakest assets, then rebalances in cross mode. Code:

scores = {}
for ticker in context['tickers']:
    data = get_data(ticker)
    ret = data.close / data.close.shift(20) - 1
    last_ret = ret[-1]
    if last_ret is None:
        continue
    scores[ticker] = last_ret

scores = drop_nan(scores)
longs = top_n(scores, 2)
shorts = bottom_n(scores, 2)

target_basket_notional = 1000.0
equity = portfolio_value()
target_gross = min(target_basket_notional / equity, 1.0) if equity else 0.0

weights = long_short_equal_weight(longs, shorts, gross=target_gross)
weights = cap_weights(weights, 0.25)
rebalance_to(weights, min_change=0.0)

RSI Mean-Reversion Basket

Tags: cross_sectional, ranking, rsi, mean_reversion, basket, cross_mode Functions: get_data, rsi, drop_nan, bottom_n, portfolio_value, equal_weight, rebalance_to Description: Ranks a fixed universe by latest RSI and rotates a fixed basket budget into the most oversold assets. Code:

scores = {}
for ticker in context['tickers']:
    data = get_data(ticker)
    rsi_value = rsi(data.close, 14)[-1]
    if rsi_value is None:
        continue
    scores[ticker] = rsi_value

scores = drop_nan(scores)
longs = bottom_n(scores, 2)

target_basket_notional = 1000.0
equity = portfolio_value()
target_gross = min(target_basket_notional / equity, 1.0) if equity else 0.0

weights = equal_weight(longs, gross=target_gross)
rebalance_to(weights, min_change=0.0)