Designing an AI Trading System Without Letting the Model Control Everything
This article discusses software architecture and system safety patterns. It does NOT constitute financial advice, trading signals, or investment recommendations.
1. The Problem with Direct Model Execution
When integrating machine learning into automated systems, a dangerous anti-pattern is connecting model inference outputs directly to execution endpoints. Promoters of "AI-driven trading" often imagine an end-to-end model that reads ticks, predicts price direction, and submits live broker orders autonomously.
In production software engineering, this design is unacceptably fragile. Machine learning models are probabilistic function approximators. They suffer from distribution drift, high-confidence invalid predictions during market shocks, and zero internal awareness of account drawdown limits or market session boundaries.
2. Deterministic Safety Architecture
The AITOS architecture establishes a strict boundary separating statistical AI prediction from execution authority:
flowchart TD
subgraph PROBABILISTIC_AI["AI Signal Scoring (Probabilistic)"]
A[Market Feed V3] --> B[Data Validation Engine
Outliers & Stale Ticks]
B --> C[Feature Engineering Pipeline
Technical Indicators]
C --> D[PyTorch / ONNX Model
Candidate Signal Scoring]
end
subgraph DETERMINISTIC_SAFETY["DETERMINISTIC SAFETY BOUNDARY"]
D -->|Candidate Proposal Score| E[Risk Engine Gate]
E -->|Check 1| F{Emergency Kill Switch?}
F -->|Active| G[HALT & LOG REJECTION]
F -->|Inactive| H{Daily Drawdown Breached?}
H -->|Yes| G
H -->|No| I{Market Hours 09:15-15:25 IST?}
I -->|No| G
I -->|Valid| J[Approved Order Payload]
end
subgraph EXECUTION_GATEWAY["Execution Gateway"]
J --> K[Paper Trading Sandbox
Simulated 0.05% Slippage]
J --> L[Broker API Gateway
Upstox V3 Order API]
end
Diagram 1: Stage-gated execution pipeline enforcing a hard boundary between AI signal proposal scoring and deterministic risk checks.
3. Risk Engine Implementation
The risk engine evaluates every model recommendation against hard rules. If any check fails, the trade proposal is dropped and logged:
# services/trading_execution/safety_risk_engine.py
class SystemKillSwitchException(Exception):
pass
class SafetyRiskEngine:
def __init__(self, daily_pnl_limit: float, max_order_val: float):
self.daily_pnl_limit = daily_pnl_limit
self.max_order_val = max_order_val
self.kill_switch_active = False
def validate_proposal(self, proposal: TradeProposal, current_pnl: float) -> bool:
if self.kill_switch_active:
raise SystemKillSwitchException("Trading halted: Emergency Kill Switch is ACTIVE")
if current_pnl <= -self.daily_pnl_limit:
logger.error(f"Proposal rejected: Daily PnL {current_pnl} breached limit {-self.daily_pnl_limit}")
return False
now_ist = datetime.now(pytz.timezone("Asia/Kolkata")).time()
if not (time(9, 15) <= now_ist <= time(15, 25)):
logger.warning(f"Proposal rejected: Inactive market hours ({now_ist})")
return False
if proposal.estimated_cost > self.max_order_val:
logger.warning("Proposal rejected: Order value exceeds capital threshold")
return False
return True
4. Engineering Decisions & Tradeoffs
| Decision | Rationale | Tradeoff |
|---|---|---|
| Deterministic Safety Boundary | Prevents probabilistic AI models from executing orders during market volatility shocks. | Strict risk filters may drop candidate trades during rapid market breakouts. |
| Paper Trading Parity | Evaluates signals under simulated 0.05% slippage and brokerage charges before live routing. | Requires real-time position state tracking synchronization in memory and DB. |
| Single Exit Authority | Centralized exit execution handler preventing concurrent duplicate order placement. | Creates a single thread lock bottleneck requiring careful mutex scope management. |
Related Engineering Articles
- From PyTorch to ONNX: Designing a Low-Latency Model Inference Pipeline
- Designing a Real-Time Market Data Pipeline for Algorithmic Trading