Manage every USD stock position except an explicit unmanaged list
rebalance treated only today's S&P 500 members as the strategy's, so a held name that left the index (or was renamed on Wikipedia) was never sold and its value shrank the investable amount, unlike quant-trading's engine, which sells non-members at the next rebalance. Now every USD stock/ETF position is managed except execution.unmanaged (AAOI); a holding without bars is priced from the account for its exit. On the paper account the managed set is unchanged (the 10 current members). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -148,15 +148,16 @@ async def rebalance(cfg: Config, submit: bool) -> None:
|
||||
|
||||
async with Broker(cfg.ib) as broker:
|
||||
state = await broker.account_state()
|
||||
managed = [h for h in state.holdings if h.sec_type == "STK" and h.currency == "USD" and h.symbol in universe]
|
||||
managed = [h for h in state.holdings if h.sec_type == "STK" and h.currency == "USD" and h.symbol not in ex.unmanaged]
|
||||
unmanaged_value = sum(h.market_value_usd for h in state.holdings if h not in managed)
|
||||
investable = state.nav_usd * (1 - ex.cash_buffer) - unmanaged_value
|
||||
weights = select_with_buffer(score, {h.symbol for h in managed}, st.top_n, st.buffer)
|
||||
# Sized at today's open, the latest price in the bars; filled at the close.
|
||||
# Sized at today's open, the latest price in the bars; filled at the close. A holding
|
||||
# that left the index has no bars and takes the account's price; its exit size does not use it.
|
||||
orders = plan_orders(
|
||||
weights,
|
||||
{h.symbol: h.quantity for h in managed},
|
||||
opens.iloc[-1].dropna().to_dict(),
|
||||
{h.symbol: h.market_price for h in managed} | opens.iloc[-1].dropna().to_dict(),
|
||||
investable,
|
||||
max(ex.min_trade_value, ex.min_trade_fraction * state.nav_usd),
|
||||
ex.resize_band,
|
||||
|
||||
Reference in New Issue
Block a user