- execution.py: dual-write SIP_NO_FILL and SIP_PARTIAL to engine_event
so the strategy summary can surface them to users
- execution.py: emit SIP_NO_FILL event (with cash/required amounts) on
the paper path instead of silently returning when funds are insufficient
- strategy_service.py: improve insufficient_funds message to show exact
shortfall and reassure user that next SIP will auto-execute when funded
- strategy_service.py: clear SIP_NO_FILL warning after a successful
SIP_TRIGGERED so it does not persist after funds are added
- runner.py: always write PRICE_FETCH_ERROR and HISTORY_LOAD_ERROR to
engine_event regardless of ENGINE_DEBUG flag
- db.py (backend + engine): raise default pool sizes to 20/50 max
connections to handle 100 concurrent users without pool exhaustion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- start_strategy filters running check by mode so starting LIVE
won't clash with an active PAPER run and vice versa
- stop_strategy and resume_strategy accept optional mode param
so each tab stops/resumes only its own run
- paper_broker_service scopes all run lookups to mode=PAPER
- paper_mtm scopes run lookup to mode=PAPER
- routers/strategy exposes ?mode= query param on /stop and /resume
- run_service get_active_run_id and get_running_run_id already
support mode filtering (added in previous session)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When start_strategy is called with a new strategy on an active run,
update strategy_config in DB before building engine config so the
new strategy is used both now and on future resumes/restarts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When restarting an existing run with a different strategy, the saved
DB config was winning over the user's selection. req.strategy_name
now takes priority so switching strategies works correctly.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>