Let the strategy own the whole account; drop the unmanaged list
Every position is the strategy's: names it does not select, including ones outside the index such as AAOI, are sold at the next rebalance, and sizing uses the full NAV less the cash buffer. A position that is not a USD stock cannot be traded as a SMART/USD order, so rebalance refuses to run while one exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -148,16 +148,18 @@ 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 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)
|
||||
# The strategy owns the whole account: every position it does not select is sold.
|
||||
# Orders go out as SMART/USD stocks, so any other kind of position stops the run.
|
||||
if foreign := [h.symbol for h in state.holdings if (h.sec_type, h.currency) != ("STK", "USD")]:
|
||||
raise SystemExit(f"positions that are not USD stocks: {foreign}; close them before rebalancing")
|
||||
investable = state.nav_usd * (1 - ex.cash_buffer)
|
||||
weights = select_with_buffer(score, {h.symbol for h in state.holdings}, st.top_n, st.buffer)
|
||||
# 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.
|
||||
# outside 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},
|
||||
{h.symbol: h.market_price for h in managed} | opens.iloc[-1].dropna().to_dict(),
|
||||
{h.symbol: h.quantity for h in state.holdings},
|
||||
{h.symbol: h.market_price for h in state.holdings} | 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