Skip to content

Live Runtime

The live runtime is organised around a small set of observable surfaces:

  • insights
  • strategy_accounts
  • strategy_equity_points
  • strategy_live_metrics
  • strategy_events
  • strategy_actions

The pipeline runs inside the strategy runtime, not in the UI. This is where state-specific logic, expiry handling, and rejection paths are enforced.

aq-engine/src/core/strategy/mod.rs
fn run_insight_pipeline(&mut self) {
// For each insight:
// - skip terminal rows
// - reject or cancel expired insights
// - run state-specific pipes
// - reject the insight if a pipe fails or does not pass
// - clear first_on_fill after filled-state pipes complete
}

The paper broker protects the runtime account model by rejecting unaffordable orders before they can create invalid buying-power state.

aq-engine/src/core/broker/paper_broker.rs
async fn submit_order(&self, insight: Insight) -> Result<Order, BrokerError> {
// ...
if let Some(estimated_price) = order.limit_price.or(order.stop_price) {
if let Some(reason) = self.insufficient_funds_reason(order.qty, estimated_price) {
let mut rejected_order = order.clone();
rejected_order.status = TradeUpdateEvent::Rejected;
rejected_order.rejection_reason = Some(reason);
self.emit_trade_event(&rejected_order, TradeUpdateEvent::Rejected);
return Ok(rejected_order);
}
}
}

Live state should be scoped by:

  • strategy_id
  • live_session_id

This allows AQS to observe only the currently running strategy session without mixing rows from older sessions or other users.

  • insight updates should be persisted as state changes happen
  • account and equity should update on fills and closes
  • live metrics should reflect current runtime state
  • reconnects should replay bounded pending sync operations where possible
  • aq-engine/src/core/strategy/mod.rs
  • aq-engine/src/core/broker/paper_broker.rs
  • aq-engine/src/core/strategy/aqs_sync.rs