feat(kevin): reconcile Alpaca bracket auto-closes + order status
Bracket stop-loss/take-profit legs fill at Alpaca without passing through the executor, so those closes (and their P&L) were invisible locally. - broker: add get_order(nested) + list_orders to BaseBroker/AlpacaBroker (+ SimulatedBroker); BrokerOrder carries child legs - Trade gains broker_order_id (migration f6a7b8c9d0e1); executor stamps the entry order id - new api_gateway trade-reconcile loop: books a closing SELL + realized P&L when a bracket leg fills (idempotent on the leg order id), syncs PENDING->terminal status, logs drift; runs alongside portfolio_sync [ci skip] Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
52b3c76482
commit
82dc622544
13 changed files with 1049 additions and 8 deletions
|
|
@ -80,6 +80,18 @@ class OrderResult(BaseModel):
|
|||
model_config = {"from_attributes": True}
|
||||
|
||||
|
||||
class BrokerOrder(OrderResult):
|
||||
"""An order plus its bracket child legs.
|
||||
|
||||
Returned by ``BaseBroker.get_order`` so reconciliation can inspect a
|
||||
bracket's stop-loss / take-profit legs (each an ``OrderResult``) to learn
|
||||
which leg filled and at what price. Simple orders carry an empty
|
||||
``legs`` list.
|
||||
"""
|
||||
|
||||
legs: list[OrderResult] = Field(default_factory=list)
|
||||
|
||||
|
||||
class PositionInfo(BaseModel):
|
||||
"""Current position state — used in API responses and portfolio views."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue