Insights
What an insight represents
Section titled “What an insight represents”An insight is AQE’s unit of trading intent. It starts as a candidate trade and can move through submission, execution, fills, partial closes, and final closure while preserving a state history that AQS can inspect later.
Core fields include:
- symbol
- side
- confidence
- timeframe
- parent/child lineage
- quantity
- entry structure
- take-profit and stop-loss levels
- trailing stop gap
- fill and close prices
- state history
Core structure
Section titled “Core structure”pub struct Insight { pub insight_id: Uuid, pub parent_id: Option<Uuid>, pub state: InsightState, pub children: Vec<Insight>, pub order_id: Option<String>, pub side: OrderSide, pub symbol: String, pub quantity: Option<f64>, pub order_type: OrderType, pub order_class: OrderClass, pub limit_price: Option<f64>, pub stop_price: Option<f64>, pub take_profit_levels: Option<Vec<f64>>, pub stop_loss_levels: Option<Vec<f64>>, pub trailing_stop_price: Option<f64>, pub filled_price: Option<f64>, pub close_price: Option<f64>, pub partial_closes: Vec<PartialCloseResult>, pub state_history: Vec<(DateTime<Utc>, InsightState, Option<String>)>,}Lifecycle
Section titled “Lifecycle”AQE tracks insights through a state machine that includes:
NewExecutedFilledClosedCancelledRejected
Typical paths look like:
New -> Executed -> Filled -> ClosedNew -> RejectedExecuted -> CancelledFilled -> Closed
Expiry, pipe failures, broker rejections, and trade updates all feed into those transitions.
Creating an insight
Section titled “Creating an insight”The most common user-facing pattern is:
let mut insight = Insight::new( OrderSide::Buy, "AAPL".to_string(), StrategyType::Testing, ctx.timeframe().clone(), 80, None,);
insight .set_limit_price(Some(200.0)) .set_take_profit_levels(Some(vec![206.0])) .set_stop_loss(Some(197.5)) .set_period_unfilled(Some(5)) .set_period_till_tp(Some(12));
ctx.add_insight(insight);From there, the insight pipeline can add sizing, validations, or submission behaviour.
Child insights
Section titled “Child insights”AQE supports child insights directly on the core insight model. A parent insight can attach one or more child insights and preserve that relationship through the runtime and the snapshot data model.
pub fn add_child_insight( &mut self, mut child_insight: Insight, _ctx: &mut dyn StrategyContext,) -> &mut Self { child_insight.strategy_type = StrategyType::Custom(format!("{}-CHILD", self.strategy_type.to_string())); child_insight.parent_id = Some(self.insight_id); if child_insight.quantity.is_none() { child_insight.quantity = self.quantity; }
let child_id = child_insight.insight_id; self.children.push(child_insight);
self.update_state( self.state.clone(), Some(format!("Added child insight: {:?}", child_id)), ); self}That gives you two important capabilities:
- lineage:
child insights remain connected to the original parent through
parent_id - deferred submission: AQE can queue child insights and submit them at the right time in the runtime loop
Typical use cases include:
- staged entries
- follow-up signals derived from a parent fill
- multi-step trade plans that need a linked inspection trail
Time-to-live fields
Section titled “Time-to-live fields”AQE supports two important lifecycle controls:
period_unfilled- applies while the insight is still
NeworExecuted - expired insights are rejected or cancellation is requested, depending on state
- applies while the insight is still
period_till_tp- applies once the insight is
Filled - expiry can trigger a close request
- applies once the insight is
Those checks are enforced by the runtime, not by the UI.
State history
Section titled “State history”Every significant change can be recorded into state_history, including:
- state transitions
- submission
- broker acceptance
- fills
- partial closes
- cancellation requests
- rejections
- expiry handling
That history is what makes the shared inspector in AQS and Backtest Results useful for review.
Broker-managed legs
Section titled “Broker-managed legs”The insight stores the configuration you define, but the broker owns the actual execution legs:
- take profit legs
- stop loss legs
- trailing stop legs
For example, a trailing stop is defined on the insight as a float gap, while the broker creates and manages the actual trailing stop leg during execution.
Partial closes
Section titled “Partial closes”Insights can record partial close results over time. That matters for:
- scale-out strategies
- multi-target exits
- accurate inspection in AQS and backtest review
If a strategy uses more than one take-profit level, AQE can close part of the quantity while leaving the remaining position open.
Child insights and partial closes solve different problems:
- partial closes keep one insight open while reducing size over time
- child insights create separate linked insights with their own lifecycle
Related source
Section titled “Related source”aq-engine/src/core/insight/insight.rsaq-engine/src/core/insight/snapshot.rsaq-engine/src/core/strategy/mod.rs