Chapter 78: LLM Trade Execution
Chapter 78: LLM Trade Execution
Overview
LLM Trade Execution represents a cutting-edge approach to optimizing order execution using Large Language Models. Traditional algorithmic execution strategies (TWAP, VWAP, implementation shortfall) follow pre-defined rules, while LLM-based execution can dynamically adapt to market conditions, interpret real-time information, and make intelligent decisions to minimize market impact and execution costs.
This chapter explores how to leverage LLMs for intelligent trade execution in both traditional equity markets and cryptocurrency trading on platforms like Bybit.
Table of Contents
- Introduction
- Theoretical Foundation
- Execution Cost Components
- Traditional Execution Algorithms
- LLM-Based Execution Architecture
- Market Impact Modeling
- Real-Time Decision Making
- Cryptocurrency Execution on Bybit
- Implementation Strategy
- Risk Management
- Performance Metrics
- References
Introduction
What is Trade Execution Optimization?
Trade execution is the process of converting trading decisions into actual market transactions. The challenge lies in executing large orders without significantly moving the market against you:
┌─────────────────────────────────────────────────────────────────────────┐│ The Execution Challenge │├─────────────────────────────────────────────────────────────────────────┤│ ││ You want to BUY 10,000 shares of AAPL ││ ││ Option A: Execute All at Once ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ Current Price: $150.00 │ ││ │ Your massive order hits the market │ ││ │ Price jumps to: $152.50 (market impact!) │ ││ │ Average execution price: $151.25 │ ││ │ Extra cost: $12,500 (1.25 * 10,000) │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ Option B: Smart Execution (LLM-Optimized) ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ LLM analyzes: liquidity, order book, news, optimal timing │ ││ │ Splits into 50 orders across 2 hours │ ││ │ Average execution price: $150.15 │ ││ │ Extra cost: $1,500 (0.15 * 10,000) │ ││ │ Savings: $11,000! │ ││ └──────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────┘Why LLMs for Trade Execution?
| Aspect | Traditional Algorithms | LLM-Based Execution |
|---|---|---|
| Adaptability | Fixed rules | Dynamic adjustment |
| Information processing | Numeric data only | Multi-modal (news, sentiment) |
| Market regime detection | Predefined thresholds | Contextual understanding |
| Decision explanation | Limited | Natural language reasoning |
| Learning capability | Requires retraining | Continuous adaptation |
| Novel situations | May fail | Can reason through |
Theoretical Foundation
Optimal Execution Theory
The seminal work by Almgren and Chriss (2001) formulates optimal execution as a trade-off between market impact and timing risk:
$$\min_{x_t} E\left[\sum_{t=1}^{T} \left( g(v_t) + h(x_t) \right) \right] + \lambda \cdot \text{Var}\left[\sum_{t=1}^{T} P_t x_t \right]$$
Where:
- $x_t$ is the quantity executed at time $t$
- $g(v_t)$ is the temporary market impact (function of trading rate)
- $h(x_t)$ is the permanent market impact
- $\lambda$ is the risk aversion parameter
- $P_t$ is the price at time $t$
LLM as Execution Agent
LLMs can be viewed as policy functions that map market state to execution actions:
$$\pi_{LLM}: \text{Market State} \times \text{Order State} \rightarrow \text{Execution Action}$$
The key advantage is that LLMs can incorporate:
┌─────────────────────────────────────────────────────────────────────────┐│ LLM Information Fusion │├─────────────────────────────────────────────────────────────────────────┤│ ││ TRADITIONAL ALGO INPUTS: LLM ADDITIONAL INPUTS: ││ ┌──────────────────────┐ ┌──────────────────────┐ ││ │ • Price data │ │ • News sentiment │ ││ │ • Volume │ │ • Social media │ ││ │ • Spread │ │ • Earnings calls │ ││ │ • Order book depth │ │ • Macro events │ ││ │ • Historical patterns │ │ • Sector trends │ ││ │ • Volatility │ │ • Cross-asset signals │ ││ └──────────────────────┘ │ • Regulatory news │ ││ │ • Technical patterns │ ││ │ • Analyst opinions │ ││ └──────────────────────┘ ││ ││ Combined → Holistic Execution Decisions ││ │└─────────────────────────────────────────────────────────────────────────┘Execution Quality Metrics
A good execution should minimize total cost:
┌─────────────────────────────────────────────────────────────────────────┐│ Execution Cost Decomposition │├─────────────────────────────────────────────────────────────────────────┤│ ││ Total Execution Cost = Market Impact + Timing Cost + Opportunity Cost ││ ││ 1. Market Impact ││ ┌──────────────────────────────────────────────────────┐ ││ │ • Temporary: Price moves during your trade │ ││ │ • Permanent: Price shift that remains after trade │ ││ │ • Typically: 0.1-0.5% for liquid stocks │ ││ │ 1-5% for illiquid crypto │ ││ └──────────────────────────────────────────────────────┘ ││ ││ 2. Timing Cost ││ ┌──────────────────────────────────────────────────────┐ ││ │ • Risk of adverse price movement while waiting │ ││ │ • Larger for volatile assets │ ││ │ • Crypto: High due to 24/7 trading │ ││ └──────────────────────────────────────────────────────┘ ││ ││ 3. Opportunity Cost ││ ┌──────────────────────────────────────────────────────┐ ││ │ • Cost of not executing immediately │ ││ │ • Missed alpha if signal decays quickly │ ││ │ • Balance: Fast execution vs low impact │ ││ └──────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────┘Execution Cost Components
Implementation Shortfall
Implementation Shortfall (IS) measures the total cost of execution relative to a benchmark price:
$$IS = \frac{P_{exec} - P_{decision}}{P_{decision}} \times \text{sign}(\text{side})$$
Where:
- $P_{exec}$ is the volume-weighted average execution price
- $P_{decision}$ is the price when the trading decision was made
- $\text{side}$ is +1 for buy, -1 for sell
Market Impact Model
The Almgren-Chriss market impact model:
Temporary Impact: η(v) = η · v^β (typically β ≈ 0.5-1.0)Permanent Impact: g(v) = γ · v (linear in trade size)
Where:- v is the trading rate (shares per unit time)- η is the temporary impact coefficient- γ is the permanent impact coefficient
Total Cost = Σ [η(vₜ) + g(vₜ)] × xₜLLM Market Impact Estimation
/// LLM-enhanced market impact estimation#[derive(Debug, Clone)]pub struct LlmMarketImpactEstimator { /// Base Almgren-Chriss model pub base_model: AlmgrenChrissModel,
/// LLM client for contextual adjustments pub llm_client: LlmClient,
/// Historical impact data pub impact_history: Vec<ImpactObservation>,
/// Current market regime pub market_regime: MarketRegime,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct MarketImpactEstimate { /// Base model estimate pub base_impact_bps: f64,
/// LLM adjustment factor (0.5 to 2.0) pub llm_adjustment: f64,
/// Final impact estimate pub estimated_impact_bps: f64,
/// Confidence interval pub confidence_low: f64, pub confidence_high: f64,
/// LLM reasoning pub reasoning: String,}
impl LlmMarketImpactEstimator { /// Estimate market impact with LLM enhancement pub async fn estimate_impact( &self, order: &OrderSpec, market_state: &MarketState, context: &ExecutionContext, ) -> Result<MarketImpactEstimate, EstimationError> { // 1. Get base model estimate let base_impact = self.base_model.estimate(order, market_state)?;
// 2. Gather contextual information let context_info = self.gather_context(market_state, context).await?;
// 3. Ask LLM for adjustment let prompt = self.build_impact_prompt( order, market_state, base_impact, &context_info, );
let llm_response = self.llm_client.query(&prompt).await?; let adjustment = self.parse_adjustment(&llm_response)?;
// 4. Combine estimates Ok(MarketImpactEstimate { base_impact_bps: base_impact, llm_adjustment: adjustment.factor, estimated_impact_bps: base_impact * adjustment.factor, confidence_low: base_impact * adjustment.low_factor, confidence_high: base_impact * adjustment.high_factor, reasoning: adjustment.reasoning, }) }}Traditional Execution Algorithms
TWAP (Time-Weighted Average Price)
┌─────────────────────────────────────────────────────────────────────────┐│ TWAP Execution Strategy │├─────────────────────────────────────────────────────────────────────────┤│ ││ Goal: Execute evenly over time period ││ ││ Quantity per interval = Total Quantity / Number of Intervals ││ ││ Example: Buy 10,000 shares over 2 hours (8 intervals of 15 min) ││ ││ Time | Target | Price | Executed | Cumulative ││ --------|--------|--------|----------|------------ ││ 09:30 | 1,250 | $100.0 | 1,250 | 1,250 ││ 09:45 | 1,250 | $100.1 | 1,250 | 2,500 ││ 10:00 | 1,250 | $100.2 | 1,250 | 3,750 ││ 10:15 | 1,250 | $99.9 | 1,250 | 5,000 ││ 10:30 | 1,250 | $100.3 | 1,250 | 6,250 ││ 10:45 | 1,250 | $100.1 | 1,250 | 7,500 ││ 11:00 | 1,250 | $100.0 | 1,250 | 8,750 ││ 11:15 | 1,250 | $100.2 | 1,250 | 10,000 ││ ││ Pros: Simple, predictable ││ Cons: Ignores market conditions, easily detected ││ │└─────────────────────────────────────────────────────────────────────────┘VWAP (Volume-Weighted Average Price)
┌─────────────────────────────────────────────────────────────────────────┐│ VWAP Execution Strategy │├─────────────────────────────────────────────────────────────────────────┤│ ││ Goal: Execute in proportion to expected volume ││ ││ Quantity_t = Total_Quantity × (Expected_Volume_t / Total_Volume) ││ ││ Example: Historical volume distribution ││ ││ Volume Profile (typical U-shape): ││ ▓▓▓▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▓▓▓▓ ││ |------|--------|--------|--------|--------|------| ││ 9:30 10:00 11:00 12:00 13:00 14:00 16:00 ││ High Low Low Lunch Low Low High ││ ││ Execution follows this profile: ││ Time | Vol% | Target | Price | Executed ││ --------|--------|--------|--------|---------- ││ 09:30 | 15% | 1,500 | $100.0 | 1,500 ││ 10:00 | 8% | 800 | $100.1 | 800 ││ 11:00 | 7% | 700 | $100.2 | 700 ││ ... | ... | ... | ... | ... ││ ││ Pros: Blends with market, lower impact ││ Cons: Requires volume prediction, still predictable ││ │└─────────────────────────────────────────────────────────────────────────┘Implementation Shortfall
┌─────────────────────────────────────────────────────────────────────────┐│ Implementation Shortfall Strategy │├─────────────────────────────────────────────────────────────────────────┤│ ││ Goal: Minimize cost relative to decision price ││ ││ Trade-off: Urgency vs Market Impact ││ ││ ┌────────────────────────────────────────────┐ ││ │ Risk-Impact Trade-off │ ││ │ │ ││ │ Cost │ ││ │ ↑ │ ││ │ │ ╲ Market │ ││ │ │ ╲ Impact │ ││ │ │ ╲ ↗ │ ││ │ │ ╲ ↗ │ ││ │ │ ╲ ★ ↗ │ ││ │ │ ╲ ↗ │ ││ │ │ Timing╲ ↗ │ ││ │ │ Risk ↗ │ ││ │ │ ↗ ╲ │ ││ │ └──────────────────────────→ Time │ ││ │ Fast Slow │ ││ │ │ ││ │ ★ = Optimal execution rate │ ││ └────────────────────────────────────────────┘ ││ ││ Almgren-Chriss optimal trajectory: ││ x(t) = X₀ × sinh(κ(T-t)) / sinh(κT) ││ ││ Where κ = √(λσ²/η), λ = risk aversion ││ │└─────────────────────────────────────────────────────────────────────────┘LLM-Based Execution Architecture
System Overview
┌─────────────────────────────────────────────────────────────────────────┐│ LLM Execution System Architecture │├─────────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────────────────┐ ││ │ PARENT ORDER │ ││ │ Buy 10,000 BTC over 4 hours │ ││ └─────────────────┬───────────────────┘ ││ │ ││ ↓ ││ ┌───────────────────────────────────────────────────────────────────┐ ││ │ LLM EXECUTION ENGINE │ ││ │ │ ││ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ ││ │ │ State Observer │ │ Decision Engine │ │ Risk Manager │ │ ││ │ │ • Order book │→ │ • Strategy │→ │ • Position │ │ ││ │ │ • Trades │ │ selection │ │ limits │ │ ││ │ │ • News/Social │ │ • Timing │ │ • Impact │ │ ││ │ │ • Market regime │ │ • Sizing │ │ thresholds │ │ ││ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ ││ │ │ │ │ │ ││ │ └────────────────────┴────────────────────┘ │ ││ │ │ │ ││ │ ↓ │ ││ │ ┌─────────────────────┐ │ ││ │ │ LLM Reasoning │ │ ││ │ │ Layer │ │ ││ │ │ • Context fusion │ │ ││ │ │ • Strategy adapt │ │ ││ │ │ • Explain decisions │ │ ││ │ └──────────┬──────────┘ │ ││ └───────────────────────────────┼───────────────────────────────────┘ ││ │ ││ ↓ ││ ┌───────────────────────────────────────────────────────────────────┐ ││ │ CHILD ORDER GENERATION │ ││ │ │ ││ │ Time | Action | Quantity | Price Type | Reasoning │ ││ │ ---------|--------|----------|------------|-------------------- │ ││ │ 00:00 | Buy | 500 BTC | Limit | "Low volatility, │ ││ │ | | | | patient execution" │ ││ │ 00:15 | Buy | 800 BTC | Market | "News catalyst, │ ││ │ | | | | accelerate buying" │ ││ │ 00:30 | Wait | - | - | "Spread widened, │ ││ │ | | | | wait for liquidity" │ ││ │ ... | ... | ... | ... | ... │ ││ └───────────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────┘Core Components
/// LLM-based execution system#[derive(Debug, Clone)]pub struct LlmExecutionSystem { /// LLM client for decision making pub llm_client: LlmClient,
/// Market data stream pub market_data: MarketDataStream,
/// Order management system pub oms: OrderManagementSystem,
/// Execution strategies available pub strategies: Vec<ExecutionStrategy>,
/// Risk management pub risk_manager: RiskManager,
/// Performance tracker pub tracker: ExecutionTracker,
/// Configuration pub config: ExecutionConfig,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct ExecutionConfig { /// Maximum participation rate (% of volume) pub max_participation: f64,
/// Maximum spread to cross pub max_spread_bps: f64,
/// Urgency parameter (0 = patient, 1 = urgent) pub urgency: f64,
/// Enable LLM-based adaptation pub llm_adaptation_enabled: bool,
/// LLM query frequency (seconds) pub llm_query_interval_secs: u64,
/// Minimum order size pub min_order_size: f64,
/// Use dark pools when available pub use_dark_pools: bool,}
impl Default for ExecutionConfig { fn default() -> Self { Self { max_participation: 0.10, max_spread_bps: 10.0, urgency: 0.5, llm_adaptation_enabled: true, llm_query_interval_secs: 60, min_order_size: 0.01, use_dark_pools: true, } }}
/// Parent order specification#[derive(Debug, Clone, Serialize, Deserialize)]pub struct ParentOrder { /// Unique order ID pub id: uuid::Uuid,
/// Symbol to trade pub symbol: String,
/// Buy or Sell pub side: Side,
/// Total quantity to execute pub total_quantity: f64,
/// Execution deadline pub deadline: chrono::DateTime<chrono::Utc>,
/// Benchmark price (for IS calculation) pub decision_price: f64,
/// Execution constraints pub constraints: ExecutionConstraints,
/// Current status pub status: OrderStatus,
/// Executed quantity so far pub executed_quantity: f64,
/// Volume-weighted average execution price pub vwap: Option<f64>,}
/// Child order generated by execution system#[derive(Debug, Clone, Serialize, Deserialize)]pub struct ChildOrder { /// Reference to parent order pub parent_id: uuid::Uuid,
/// Child order ID pub child_id: uuid::Uuid,
/// Quantity for this slice pub quantity: f64,
/// Order type pub order_type: OrderType,
/// Limit price (if applicable) pub limit_price: Option<f64>,
/// Time-in-force pub time_in_force: TimeInForce,
/// LLM reasoning for this order pub reasoning: String,
/// Venue/route pub venue: String,}Prompt Engineering for Execution
┌─────────────────────────────────────────────────────────────────────────┐│ Execution Decision Prompt Template │├─────────────────────────────────────────────────────────────────────────┤│ ││ SYSTEM PROMPT: ││ """ ││ You are an expert algorithmic execution trader. Your task is to ││ determine the optimal execution strategy for the current market ││ conditions. You must minimize market impact while managing timing ││ risk. ││ ││ You have access to: ││ - Order book data (bids, asks, depth) ││ - Recent trades and volume ││ - Market volatility metrics ││ - News and social sentiment ││ - Historical execution data ││ ││ Available actions: ││ - AGGRESSIVE: Cross spread, take liquidity ││ - PASSIVE: Post limit orders, provide liquidity ││ - WAIT: Pause execution, reassess later ││ - ACCELERATE: Increase execution rate ││ - DECELERATE: Slow down execution rate ││ ││ Always explain your reasoning clearly. ││ """ ││ ││ USER PROMPT: ││ """ ││ PARENT ORDER: ││ {order_details} ││ ││ CURRENT MARKET STATE: ││ {market_state} ││ ││ EXECUTION PROGRESS: ││ {progress} ││ ││ RECENT NEWS/EVENTS: ││ {news_context} ││ ││ What should be the next execution action? Provide: ││ 1. Recommended action (AGGRESSIVE/PASSIVE/WAIT/etc) ││ 2. Suggested quantity for next slice ││ 3. Order type (MARKET/LIMIT) and price if limit ││ 4. Detailed reasoning ││ 5. Risk assessment ││ """ ││ │└─────────────────────────────────────────────────────────────────────────┘Market Impact Modeling
LLM-Enhanced Impact Prediction
┌─────────────────────────────────────────────────────────────────────────┐│ Market Impact Prediction Pipeline │├─────────────────────────────────────────────────────────────────────────┤│ ││ STEP 1: Gather Market Microstructure Data ││ ───────────────────────────────────────────────────────────────────── ││ • Order book depth at multiple levels ││ • Recent trade flow and direction ││ • Spread dynamics ││ • Volume profile and patterns ││ ││ STEP 2: Compute Base Impact Estimate ││ ───────────────────────────────────────────────────────────────────── ││ Using Almgren-Chriss or Kyle lambda: ││ ││ impact_base = η × (order_size / ADV)^0.5 × σ ││ ││ Where: ││ - η: impact coefficient (calibrated historically) ││ - ADV: average daily volume ││ - σ: volatility ││ ││ STEP 3: LLM Contextual Adjustment ││ ───────────────────────────────────────────────────────────────────── ││ LLM considers: ││ • Is there unusual order flow suggesting informed trading? ││ • Are there pending news events that could affect liquidity? ││ • Is the market in a regime of high/low liquidity? ││ • Are there correlated assets providing signals? ││ ││ Output: adjustment_factor ∈ [0.5, 2.0] ││ ││ STEP 4: Final Estimate ││ ───────────────────────────────────────────────────────────────────── ││ impact_final = impact_base × adjustment_factor ││ ││ Example: ││ • Base estimate: 15 bps ││ • LLM reasoning: "Earnings call tomorrow, expect lower liquidity" ││ • Adjustment: 1.4x ││ • Final estimate: 21 bps ││ │└─────────────────────────────────────────────────────────────────────────┘Implementation
/// Market impact model types#[derive(Debug, Clone)]pub enum ImpactModel { /// Linear permanent impact (Kyle model) Kyle { lambda: f64 },
/// Square-root temporary impact (Almgren-Chriss) AlmgrenChriss { eta: f64, gamma: f64 },
/// Power-law impact PowerLaw { alpha: f64, beta: f64 },
/// LLM-enhanced hybrid model LlmEnhanced { base_model: Box<ImpactModel>, llm_weight: f64, },}
impl ImpactModel { /// Estimate temporary impact pub fn temporary_impact(&self, trade_rate: f64, context: &MarketContext) -> f64 { match self { Self::Kyle { lambda } => *lambda * trade_rate,
Self::AlmgrenChriss { eta, .. } => { eta * trade_rate.sqrt() * context.volatility }
Self::PowerLaw { alpha, beta } => { alpha * trade_rate.powf(*beta) }
Self::LlmEnhanced { base_model, llm_weight } => { let base = base_model.temporary_impact(trade_rate, context); let llm_adjustment = context.llm_impact_adjustment.unwrap_or(1.0); base * (1.0 - llm_weight + llm_weight * llm_adjustment) } } }
/// Estimate permanent impact pub fn permanent_impact(&self, total_quantity: f64, adv: f64) -> f64 { match self { Self::Kyle { lambda } => *lambda * total_quantity / adv,
Self::AlmgrenChriss { gamma, .. } => { gamma * (total_quantity / adv).sqrt() }
Self::PowerLaw { alpha, beta } => { alpha * (total_quantity / adv).powf(*beta) }
Self::LlmEnhanced { base_model, .. } => { base_model.permanent_impact(total_quantity, adv) } } }}
/// Real-time impact estimationpub struct RealtimeImpactEstimator { model: ImpactModel, rolling_window: VecDeque<ImpactObservation>, calibration_interval: Duration, last_calibration: chrono::DateTime<chrono::Utc>,}
impl RealtimeImpactEstimator { /// Update with observed impact pub fn observe_impact(&mut self, observation: ImpactObservation) { self.rolling_window.push_back(observation);
// Keep only recent observations while self.rolling_window.len() > 1000 { self.rolling_window.pop_front(); }
// Recalibrate if needed if chrono::Utc::now() - self.last_calibration > self.calibration_interval { self.recalibrate(); } }
/// Recalibrate model parameters fn recalibrate(&mut self) { // Use recent observations to update model parameters // This could use regression or more sophisticated methods // ... }}Real-Time Decision Making
Execution State Machine
┌─────────────────────────────────────────────────────────────────────────┐│ LLM Execution State Machine │├─────────────────────────────────────────────────────────────────────────┤│ ││ ┌──────────────┐ ││ │ INITIALIZED │ ││ └──────┬───────┘ ││ │ ││ ↓ ││ ┌──────────────┐ ││ ┌────→│ ACTIVE │←────┐ ││ │ └──────┬───────┘ │ ││ │ │ │ ││ Resume │ ┌──────┴──────┐ │ Continue ││ │ │ │ │ ││ │ ↓ ↓ │ ││ ┌─────┴─────┐ ┌───────────┴┐ ││ │ PAUSED │ │ EXECUTING │ ││ │ │ │ │ ││ │ LLM says: │ │ Placing │ ││ │ "Wait for │ │ child │ ││ │ liquidity"│ │ orders │ ││ └─────┬─────┘ └───────┬────┘ ││ │ │ ││ │ ↓ ││ │ ┌───────────┐ ││ │ │ FILLED │ ││ │ │ (partial) │ ││ │ └─────┬─────┘ ││ │ │ ││ │ ┌──────────┴──────────┐ ││ │ │ │ ││ │ ↓ ↓ ││ │ ┌───────────┐ ┌───────────┐ ││ │ │ COMPLETE │ │ ADJUSTING │ ││ │ │ │ │ │ ││ │ │ All qty │ │ LLM says: │ ││ │ │ executed │ │ "Change │ ││ │ │ │ │ strategy" │ ││ │ └───────────┘ └─────┬─────┘ ││ │ │ ││ └──────────────────────────────┘ ││ ││ Key Transitions: ││ • ACTIVE → PAUSED: Low liquidity or adverse conditions ││ • ACTIVE → EXECUTING: Ready to place order ││ • EXECUTING → FILLED: Order executed (partial or full) ││ • FILLED → ADJUSTING: LLM recommends strategy change ││ • ADJUSTING → ACTIVE: New parameters applied ││ │└─────────────────────────────────────────────────────────────────────────┘Real-Time LLM Query Logic
/// Real-time execution decision enginepub struct ExecutionDecisionEngine { /// Parent order being executed parent_order: ParentOrder,
/// Current execution state state: ExecutionState,
/// LLM client llm_client: LlmClient,
/// Market data stream market_stream: MarketDataStream,
/// Execution strategy in use current_strategy: ExecutionStrategy,
/// Decision history decision_history: Vec<ExecutionDecision>,
/// Performance metrics metrics: ExecutionMetrics,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct ExecutionDecision { /// Timestamp pub timestamp: chrono::DateTime<chrono::Utc>,
/// Recommended action pub action: ExecutionAction,
/// Order slice details pub order_slice: Option<OrderSlice>,
/// LLM reasoning pub reasoning: String,
/// Confidence score (0-1) pub confidence: f64,
/// Market context at decision time pub market_snapshot: MarketSnapshot,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub enum ExecutionAction { /// Place aggressive market order Aggressive { quantity: f64 },
/// Place passive limit order Passive { quantity: f64, limit_price: f64 },
/// Wait for better conditions Wait { duration_secs: u64, reason: String },
/// Accelerate execution rate Accelerate { new_rate: f64 },
/// Slow down execution Decelerate { new_rate: f64 },
/// Cancel remaining and stop Cancel { reason: String },}
impl ExecutionDecisionEngine { /// Get next execution decision from LLM pub async fn get_decision(&self) -> Result<ExecutionDecision, ExecutionError> { // 1. Gather current market state let market_snapshot = self.market_stream.snapshot().await?;
// 2. Calculate execution progress let progress = self.calculate_progress();
// 3. Build prompt with full context let prompt = self.build_decision_prompt(&market_snapshot, &progress);
// 4. Query LLM let response = self.llm_client.query(&prompt).await?;
// 5. Parse LLM response let decision = self.parse_decision(&response, &market_snapshot)?;
// 6. Validate decision against risk limits self.validate_decision(&decision)?;
Ok(decision) }
/// Build comprehensive decision prompt fn build_decision_prompt( &self, market: &MarketSnapshot, progress: &ExecutionProgress, ) -> String { format!( r#"EXECUTION DECISION REQUEST
PARENT ORDER:- Symbol: {}- Side: {:?}- Total Quantity: {}- Remaining: {}- Deadline: {}- Decision Price: {}
EXECUTION PROGRESS:- Executed: {:.2}%- VWAP: {}- Implementation Shortfall: {:.2} bps- Time Elapsed: {:.1}%
CURRENT MARKET STATE:- Mid Price: {}- Spread: {:.2} bps- Best Bid: {} @ {}- Best Ask: {} @ {}- Bid Depth (5 levels): {}- Ask Depth (5 levels): {}- Last 10 trades: {}- 1-min volume: {}- Volatility (1hr): {:.2}%
RECENT CONTEXT:{}
PREVIOUS DECISIONS:{}
Based on this information, what should be the next execution action?Provide: action type, quantity, price (if limit), and detailed reasoning. "#, self.parent_order.symbol, self.parent_order.side, self.parent_order.total_quantity, self.parent_order.total_quantity - self.parent_order.executed_quantity, self.parent_order.deadline, self.parent_order.decision_price, progress.percent_complete, progress.vwap.map_or("N/A".to_string(), |v| format!("{:.2}", v)), progress.implementation_shortfall_bps, progress.time_elapsed_percent, market.mid_price, market.spread_bps, market.best_bid_qty, market.best_bid, market.best_ask_qty, market.best_ask, market.bid_depth.iter().map(|l| format!("{}@{}", l.qty, l.price)).collect::<Vec<_>>().join(", "), market.ask_depth.iter().map(|l| format!("{}@{}", l.qty, l.price)).collect::<Vec<_>>().join(", "), market.recent_trades.iter().map(|t| format!("{}{:.0}@{}", if t.is_buy { "B" } else { "S" }, t.qty, t.price)).collect::<Vec<_>>().join(", "), market.volume_1min, market.volatility_1hr * 100.0, self.get_recent_context(), self.format_recent_decisions(), ) }}Cryptocurrency Execution on Bybit
Bybit-Specific Execution Considerations
┌─────────────────────────────────────────────────────────────────────────┐│ Crypto Execution Challenges (Bybit) │├─────────────────────────────────────────────────────────────────────────┤│ ││ 1. 24/7 Markets ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ • No market close - continuous execution possible │ ││ │ • Liquidity varies by hour (US/Europe/Asia sessions) │ ││ │ • Weekend volatility can be extreme │ ││ │ • LLM must understand time-of-day patterns │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 2. Fragmented Liquidity ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ • Liquidity split across spot, perpetual, and options │ ││ │ • Multiple exchanges (Bybit, Binance, OKX, etc.) │ ││ │ • Cross-venue execution can reduce impact │ ││ │ • LLM can route orders to optimal venues │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 3. High Volatility ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ • BTC volatility: 50-100% annualized (vs 15-20% for stocks) │ ││ │ • Flash crashes and pumps common │ ││ │ • Execution timing much more critical │ ││ │ • LLM must detect regime changes quickly │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 4. Funding Rate Dynamics ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ • Perpetual futures have 8-hour funding │ ││ │ • Extreme funding can cause price impact │ ││ │ • Time execution around funding to benefit │ ││ │ • LLM can anticipate funding-driven moves │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 5. Liquidation Cascades ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ • Leverage can cause forced liquidations │ ││ │ • Liquidations create temporary liquidity │ ││ │ • Can be opportunity or risk depending on side │ ││ │ • LLM monitors liquidation levels │ ││ └──────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────┘Bybit Integration
/// Bybit execution clientpub struct BybitExecutionClient { /// API client api: BybitApi,
/// WebSocket for real-time data ws: BybitWebSocket,
/// Order book manager orderbook: OrderBookManager,
/// Position tracker positions: PositionTracker,
/// Execution configuration config: BybitExecutionConfig,}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct BybitExecutionConfig { /// API credentials pub api_key: String, pub api_secret: String,
/// Use testnet for paper trading pub testnet: bool,
/// Account type (spot, linear, inverse) pub account_type: AccountType,
/// Default leverage pub default_leverage: u32,
/// Maximum order size in USD pub max_order_size_usd: f64,
/// Minimum order interval (milliseconds) pub min_order_interval_ms: u64,}
impl BybitExecutionClient { /// Create new client pub async fn new(config: BybitExecutionConfig) -> Result<Self, BybitError> { let base_url = if config.testnet { "https://api-testnet.bybit.com" } else { "https://api.bybit.com" };
let api = BybitApi::new(&config.api_key, &config.api_secret, base_url)?; let ws = BybitWebSocket::connect(config.testnet).await?;
Ok(Self { api, ws, orderbook: OrderBookManager::new(), positions: PositionTracker::new(), config, }) }
/// Execute child order pub async fn execute_order(&self, order: &ChildOrder) -> Result<OrderResult, ExecutionError> { // Validate order against limits self.validate_order(order)?;
// Build Bybit order request let request = match order.order_type { OrderType::Market => self.build_market_order(order), OrderType::Limit => self.build_limit_order(order), OrderType::PostOnly => self.build_post_only_order(order), }?;
// Submit order let response = self.api.place_order(request).await?;
// Track execution let result = self.track_execution(&response).await?;
Ok(result) }
/// Get real-time order book pub async fn get_orderbook(&self, symbol: &str) -> Result<OrderBook, BybitError> { self.orderbook.get(symbol).await }
/// Get current funding rate pub async fn get_funding_rate(&self, symbol: &str) -> Result<FundingRate, BybitError> { self.api.get_funding_rate(symbol).await }
/// Stream market data updates pub fn subscribe_market_data(&mut self, symbol: &str) -> impl Stream<Item = MarketUpdate> { self.ws.subscribe_orderbook(symbol) .merge(self.ws.subscribe_trades(symbol)) .merge(self.ws.subscribe_ticker(symbol)) }}
/// Crypto-specific execution strategiespub enum CryptoExecutionStrategy { /// Standard TWAP adapted for 24/7 Twap24h { slices: usize, randomize: bool, },
/// Volume-following with session awareness VwapSessions { volume_curve: VolumeCurve, session_weights: SessionWeights, },
/// Funding rate aware execution FundingAware { base_strategy: Box<CryptoExecutionStrategy>, funding_threshold: f64, },
/// Liquidation hunter LiquidationHunter { liquidation_levels: Vec<PriceLevel>, aggressiveness: f64, },
/// LLM-adaptive execution LlmAdaptive { base_strategy: Box<CryptoExecutionStrategy>, adaptation_interval: Duration, },}Crypto-Specific Factors for Execution
┌─────────────────────────────────────────────────────────────────────────┐│ Crypto Execution Signals │├─────────────────────────────────────────────────────────────────────────┤│ ││ 1. Funding Rate Signal ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ IF funding_rate > 0.05% (high positive): │ ││ │ → Many longs paying shorts │ ││ │ → Potential for long squeeze │ ││ │ → If SELLING: accelerate before funding snapshot │ ││ │ → If BUYING: wait until post-funding pullback │ ││ │ │ ││ │ IF funding_rate < -0.03% (negative): │ ││ │ → Shorts paying longs │ ││ │ → If BUYING: accelerate before funding │ ││ │ → If SELLING: wait for potential bounce │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 2. Open Interest Changes ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ OI increasing + Price increasing: │ ││ │ → New longs entering, trend continuation │ ││ │ → If BUYING: execute steadily │ ││ │ │ ││ │ OI increasing + Price decreasing: │ ││ │ → New shorts entering, trend continuation │ ││ │ → If SELLING: execute steadily │ ││ │ │ ││ │ OI decreasing + Price moving: │ ││ │ → Positions closing, potential reversal │ ││ │ → Be cautious, reduce aggression │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 3. Liquidation Proximity ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ Large liquidation cluster nearby: │ ││ │ → If price moving toward cluster: wait for cascade │ ││ │ → Cascade provides temporary liquidity │ ││ │ → Execute aggressively into liquidation flow │ ││ │ │ ││ │ Example: $65,000 BTC with $500M longs liquidating at $64k │ ││ │ → If SELLING: accelerate to $64k, then normal pace │ ││ │ → If BUYING: wait for cascade, buy the dip │ ││ └──────────────────────────────────────────────────────────────┘ ││ ││ 4. Exchange Flow ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ Large inflows to exchanges: │ ││ │ → Potential selling pressure coming │ ││ │ → If SELLING: front-run with aggressive execution │ ││ │ │ ││ │ Large outflows from exchanges: │ ││ │ → Supply being removed (bullish) │ ││ │ → If BUYING: accelerate before supply squeeze │ ││ └──────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────┘Implementation Strategy
Module Architecture
78_llm_trade_execution/├── Cargo.toml├── README.md├── README.ru.md├── readme.simple.md├── readme.simple.ru.md├── python/│ ├── __init__.py│ ├── execution/│ │ ├── __init__.py│ │ ├── llm_executor.py # Main LLM execution engine│ │ ├── strategies.py # Traditional + LLM strategies│ │ ├── impact_model.py # Market impact estimation│ │ └── decision_engine.py # Real-time decision making│ ├── data/│ │ ├── __init__.py│ │ ├── bybit_client.py # Bybit API integration│ │ ├── market_data.py # Market data handling│ │ └── orderbook.py # Order book management│ ├── evaluation/│ │ ├── __init__.py│ │ ├── metrics.py # Execution metrics│ │ └── backtest.py # Execution backtesting│ └── notebooks/│ ├── 01_basic_execution.ipynb│ ├── 02_llm_adaptation.ipynb│ └── 03_crypto_execution.ipynb├── src/│ ├── lib.rs # Library root│ ├── execution/│ │ ├── mod.rs # Execution module│ │ ├── engine.rs # Main execution engine│ │ ├── strategies.rs # Execution strategies│ │ ├── llm_adapter.rs # LLM integration│ │ └── state_machine.rs # Execution state│ ├── impact/│ │ ├── mod.rs # Impact module│ │ ├── models.rs # Impact models│ │ ├── estimator.rs # Real-time estimation│ │ └── calibration.rs # Model calibration│ ├── data/│ │ ├── mod.rs # Data module│ │ ├── bybit.rs # Bybit client│ │ ├── orderbook.rs # Order book│ │ └── types.rs # Data types│ ├── strategy/│ │ ├── mod.rs # Strategy module│ │ ├── twap.rs # TWAP strategy│ │ ├── vwap.rs # VWAP strategy│ │ ├── is.rs # Implementation shortfall│ │ └── adaptive.rs # LLM-adaptive strategy│ └── utils/│ ├── mod.rs # Utilities│ └── config.rs # Configuration├── examples/│ ├── basic_execution.rs # Basic execution demo│ ├── llm_execution.rs # LLM-enhanced execution│ ├── bybit_execution.rs # Bybit integration demo│ └── backtest_execution.rs # Execution backtesting├── experiments/│ └── test_impact_model.rs # Impact model testing└── tests/ └── integration.rs # Integration testsKey Design Principles
- Modular Strategy System: Easy switching between TWAP, VWAP, IS, and LLM-adaptive
- Real-Time LLM Integration: Efficient querying without blocking execution
- Risk-First Approach: All decisions validated against risk limits
- Explainability: Every execution decision logged with reasoning
- Graceful Degradation: Falls back to traditional algo if LLM unavailable
Risk Management
Execution-Specific Risks
┌────────────────────────────────────────────────────────────────────────┐│ Execution Risk Management │├────────────────────────────────────────────────────────────────────────┤│ ││ 1. LLM Latency Risk ││ ├── LLM queries take 1-5 seconds ││ ├── Market can move significantly during query ││ └── Mitigation: ││ → Async LLM queries (don't block execution) ││ → Use cached decisions when LLM slow ││ → Fallback to traditional algo if LLM unavailable ││ ││ 2. LLM Hallucination Risk ││ ├── LLM may recommend impossible actions ││ ├── May miscalculate quantities or prices ││ └── Mitigation: ││ → Strict validation of all LLM outputs ││ → Sanity checks on quantities and prices ││ → Never trust LLM blindly - always verify ││ ││ 3. Over-trading Risk ││ ├── LLM might be overly aggressive ││ ├── Could cause excessive market impact ││ └── Mitigation: ││ → Hard limits on participation rate ││ → Maximum order size caps ││ → Minimum time between orders ││ ││ 4. Model Risk ││ ├── Impact models may be miscalibrated ││ ├── Market regime changes invalidate assumptions ││ └── Mitigation: ││ → Continuous model recalibration ││ → Conservative impact estimates ││ → Monitor predicted vs actual impact ││ ││ 5. Technical Risk (Crypto) ││ ├── Exchange API failures ││ ├── Network latency ││ ├── Blockchain congestion ││ └── Mitigation: ││ → Retry logic with exponential backoff ││ → Multiple exchange connections ││ → Local order tracking independent of API ││ │└────────────────────────────────────────────────────────────────────────┘Safety Limits
/// Execution safety limits#[derive(Debug, Clone, Serialize, Deserialize)]pub struct SafetyLimits { /// Maximum participation rate (fraction of volume) pub max_participation: f64,
/// Maximum single order size (in quote currency) pub max_order_size: f64,
/// Minimum time between orders (seconds) pub min_order_interval_secs: f64,
/// Maximum spread to cross (bps) pub max_spread_bps: f64,
/// Maximum deviation from benchmark price (bps) pub max_price_deviation_bps: f64,
/// Maximum implementation shortfall before alert (bps) pub max_is_threshold_bps: f64,
/// Stop execution if volatility exceeds (%) pub max_volatility_threshold: f64,
/// LLM query timeout (seconds) pub llm_timeout_secs: u64,
/// Maximum orders per minute pub max_orders_per_minute: u32,}
impl Default for SafetyLimits { fn default() -> Self { Self { max_participation: 0.10, // 10% of volume max_order_size: 100_000.0, // $100K per order min_order_interval_secs: 5.0, // 5 seconds max_spread_bps: 20.0, // 20 bps max_price_deviation_bps: 100.0, // 1% max_is_threshold_bps: 50.0, // 50 bps max_volatility_threshold: 5.0, // 5% hourly llm_timeout_secs: 10, // 10 seconds max_orders_per_minute: 20, // 20 orders } }}
/// Validate execution decision against safety limitspub fn validate_decision( decision: &ExecutionDecision, limits: &SafetyLimits, market_state: &MarketState,) -> Result<(), ValidationError> { // Check order size if let Some(slice) = &decision.order_slice { let order_value = slice.quantity * market_state.mid_price; if order_value > limits.max_order_size { return Err(ValidationError::OrderSizeTooLarge { requested: order_value, limit: limits.max_order_size, }); } }
// Check participation rate let expected_volume = market_state.avg_volume_1min * 60.0; // hourly if let Some(slice) = &decision.order_slice { let participation = slice.quantity / expected_volume; if participation > limits.max_participation { return Err(ValidationError::ParticipationTooHigh { rate: participation, limit: limits.max_participation, }); } }
// Check spread if market_state.spread_bps > limits.max_spread_bps { match &decision.action { ExecutionAction::Aggressive { .. } => { return Err(ValidationError::SpreadTooWide { spread: market_state.spread_bps, limit: limits.max_spread_bps, }); } _ => {} // Passive/wait is OK } }
// Check volatility if market_state.volatility_1hr > limits.max_volatility_threshold { return Err(ValidationError::VolatilityTooHigh { volatility: market_state.volatility_1hr, limit: limits.max_volatility_threshold, }); }
Ok(())}Performance Metrics
Execution Quality Metrics
| Metric | Description | Target |
|---|---|---|
| Implementation Shortfall | Cost vs decision price | < 10 bps |
| VWAP Slippage | Execution VWAP vs market VWAP | < 5 bps |
| Arrival Price Slippage | Execution vs arrival price | < 15 bps |
| Participation Rate | % of market volume | 5-15% |
| Fill Rate | % of order executed | > 95% |
| Completion Time | Time to complete execution | Within deadline |
| Spread Captured | For limit orders | > 30% of spread |
| LLM Value-Add | Improvement over baseline algo | > 3 bps |
LLM Execution Metrics
| Metric | Description | Target |
|---|---|---|
| Decision Latency | Time from query to decision | < 5 seconds |
| Decision Quality | Correct action rate | > 80% |
| Adaptation Frequency | Strategy changes per execution | 2-5 |
| Reasoning Quality | Coherent explanations | > 90% |
| Fallback Rate | Times falling back to baseline | < 10% |
| Cost Savings | IS improvement vs TWAP | > 20% |
Monitoring Dashboard
┌────────────────────────────────────────────────────────────────────────┐│ EXECUTION MONITORING DASHBOARD │├────────────────────────────────────────────────────────────────────────┤│ ││ PARENT ORDER: BUY 10.5 BTC Status: ACTIVE ││ ──────────────────────────────────────────────────────────────────── ││ ││ PROGRESS │ PERFORMANCE ││ ┌──────────────────────────────┐ │ ┌──────────────────────────────┐││ │ ████████████░░░░░░░░ 60% │ │ │ Decision Price: $64,250 │││ │ Executed: 6.3 BTC │ │ │ Current VWAP: $64,312 │││ │ Remaining: 4.2 BTC │ │ │ Impl Shortfall: +9.7 bps │││ │ Time Left: 45 min │ │ │ vs TWAP Baseline: -5.2 bps │││ └──────────────────────────────┘ │ └──────────────────────────────┘││ │ ││ MARKET STATE │ LLM STATUS ││ ┌──────────────────────────────┐ │ ┌──────────────────────────────┐││ │ Price: $64,350 │ │ │ Last Query: 30s ago │││ │ Spread: 4.2 bps │ │ │ Action: PASSIVE │││ │ Volume (1hr): 450 BTC │ │ │ Confidence: 0.82 │││ │ Volatility: 1.2% │ │ │ │││ │ Funding: +0.012% │ │ │ Reasoning: "Spread narrow, │││ └──────────────────────────────┘ │ │ posting limits to capture" │││ │ └──────────────────────────────┘││ RECENT ORDERS ││ ┌────────────────────────────────────────────────────────────────────┐││ │ Time │ Type │ Qty │ Price │ Status │ Impact │ Reasoning │││ │ 14:23:15│ LIMIT │ 0.5 │ 64,340 │ FILLED │ 2 bps │ Passive │││ │ 14:21:02│ LIMIT │ 0.8 │ 64,335 │ FILLED │ 1 bps │ Passive │││ │ 14:18:45│ MARKET│ 1.2 │ 64,360 │ FILLED │ 8 bps │ Aggressive │││ │ 14:15:00│ WAIT │ - │ - │ - │ - │ High spread│││ └────────────────────────────────────────────────────────────────────┘││ │└────────────────────────────────────────────────────────────────────────┘References
-
LLM-Based Agents for Algorithmic Trading: A Survey
- URL: https://arxiv.org/abs/2408.06361
- Year: 2024
-
Optimal Execution of Portfolio Transactions
- Almgren, R., & Chriss, N. (2001)
- Journal of Risk
-
Optimal Trading Strategy and Supply/Demand Dynamics
- Obizhaeva, A., & Wang, J. (2013)
- Journal of Financial Markets
-
The Market Microstructure of Cryptocurrency Markets
- Makarov, I., & Schoar, A. (2020)
- Journal of Financial Economics
-
Machine Learning for Market Microstructure and High Frequency Trading
- Sirignano, J., & Cont, R. (2019)
- SSRN Working Paper
-
Deep Reinforcement Learning for Optimal Execution
- Ning, B., Lin, F., & Jaimungal, S. (2021)
- Machine Learning for Asset Management
-
Language Models for Trading: A Survey
- URL: https://arxiv.org/abs/2503.21422
- Year: 2025
-
Execution Quality with Algorithmic Trading
- Hendershott, T., Jones, C., & Menkveld, A. (2011)
- Journal of Finance
Next Steps
- View Simple Explanation - Beginner-friendly version
- Russian Version - Русская версия
- Run Examples - Working Rust code
- Python Notebooks - Interactive tutorials
Chapter 78 of Machine Learning for Trading