Entries, deferrals and rejections posted to #trading-bot, but exits booked by the reconcile loop (bracket stop/take-profit legs that fill at Alpaca) were silent — the two Jun 9 stop-outs produced no message. Viktor asked for a Slack message on each position execution.
- move SlackNotifier to shared/ (now used by trade-executor AND api-gateway)
- add notify_close (ticker/qty/price/realized P&L/reason, win-loss emoji)
- reconcile loop notifies on each booked close, fail-soft; api-gateway config gains slack fields (channel defaults to trading-bot since the env carries only the bot token; chat:write.public covers posting)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>