Expand description
Broker-resident profit-target close order for open option spreads.
Schwab’s live order API rejects a stop trigger on a multi-leg complex option order
(confirmed via orders preview: complexOrderStrategyType: VERTICAL/IRON_CONDOR +
orderType: STOP_LIMIT + stopPrice -> HTTP 400 “Stop price must be populated only for
stop orders” — the identical shape works fine on a single-leg option). A plain GTC complex
NET_DEBIT limit order to close at the profit target, however, is accepted structurally.
So only the profit-target side of exit protection can live on Schwab’s servers; stop-loss
and DTE-close remain dependent on the agent’s own tick loop (see docs/OPTIONS_RULES.md).
Structs§
Functions§
- build_
profit_ target_ close_ order - Build a resting GTC complex
NET_DEBITorder that closesentry_order’s legs at the profit-target debit, by inverting each leg’s opening instruction (BUY_TO_OPEN->SELL_TO_CLOSE,SELL_TO_OPEN->BUY_TO_CLOSE) rather than re-deriving strikes/symbols. - cancel_
protective_ order - Cancel a resting protective order (e.g. before the mechanical tick loop closes the position early on a stop/DTE/thesis exit, to avoid a duplicate-close race).
- place_
profit_ target_ order_ with_ retry - Place the profit-target close order with retry. Failure here does NOT block the entry
(the position is still opened without broker-side protection) — callers should record the
failure on
TrackedPosition::protective_order_attemptsand let the reconcile pass retry. - profit_
target_ debit - Debit (per share) at which
profit_target_pctis captured, given the entry credit. Mirrors theprofit_pctformula inagent::exits:((entry - debit) / entry) * 100. - reconcile_
protective_ orders - Retry placing the profit-target close order for any open position missing one.
Runs every tick (called from
reconcile_open_positions’s caller intick_once) so a placement failure right after entry — or a position that predates this feature and has noentry_paramsto rebuild from — keeps getting retried rather than staying naked indefinitely. Positions with no storedentry_paramscannot be rebuilt and are counted as unprotected but not retried (nothing to retry with).