weex_rust_sdk 0.6.1

Professional Rust SDK for WEEX Exchange - AI Wars ready with full API coverage, AI Log upload, Futures trading
Documentation
use crate::traits::Exchange;
use crate::strategy::{Strategy, Context};
use crate::ws::handler::{MarketEvent, AccountEvent, EventHandler};
use crate::risk::{PositionSizer, RiskConfig};
use crate::types::{Side, OrderType};
use tokio::sync::broadcast;
use std::sync::Arc;
use tokio::sync::RwLock;

/// Trading signal generated by a strategy
#[derive(Debug, Clone)]
pub enum Signal {
    Buy { symbol: String, size: String, price: Option<String> },
    Sell { symbol: String, size: String, price: Option<String> },
    Close { symbol: String },
    Hold,
}

/// Engine state
#[derive(Debug, Clone, Default)]
pub struct EngineState {
    pub running: bool,
    pub total_trades: u64,
    pub winning_trades: u64,
    pub total_pnl: f64,
}

/// Strategy execution engine
pub struct Engine<E: Exchange + Clone + Send + Sync + 'static> {
    exchange: E,
    position_sizer: PositionSizer,
    state: Arc<RwLock<EngineState>>,
}

impl<E: Exchange + Clone + Send + Sync + 'static> Engine<E> {
    pub fn new(exchange: E, risk_config: RiskConfig) -> Self {
        Engine {
            exchange,
            position_sizer: PositionSizer::new(risk_config),
            state: Arc::new(RwLock::new(EngineState::default())),
        }
    }

    /// Run the engine with a strategy and event streams
    pub async fn run<S: Strategy + Send + Sync + 'static>(
        &self,
        strategy: S,
        mut market_rx: broadcast::Receiver<MarketEvent>,
        mut account_rx: broadcast::Receiver<AccountEvent>,
    ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        // Mark as running
        {
            let mut state = self.state.write().await;
            state.running = true;
        }

        loop {
            tokio::select! {
                // Handle market events
                Ok(event) = market_rx.recv() => {
                    match event {
                        MarketEvent::Ticker { symbol, price } => {
                            // Build context
                            let context = Context {
                                exchange_name: "weex".to_string(),
                                symbol: symbol.clone(),
                                price,
                                balance: 0.0, // Would fetch from account
                                position: 0.0,
                            };
                            
                            // Get signal from strategy
                            // Note: Strategy trait would need to be extended
                            // For now, just log
                            tracing::debug!("Ticker: {} @ {}", symbol, price);
                        }
                        _ => {}
                    }
                }
                
                // Handle account events
                Ok(event) = account_rx.recv() => {
                    match event {
                        AccountEvent::OrderUpdate { order_id, status, filled_size } => {
                            tracing::info!("Order {} -> {} (filled: {})", order_id, status, filled_size);
                            
                            if status == "filled" {
                                let mut state = self.state.write().await;
                                state.total_trades += 1;
                            }
                        }
                        AccountEvent::PositionUpdate { symbol, size, pnl, .. } => {
                            tracing::info!("Position {} size={} pnl={}", symbol, size, pnl);
                        }
                        _ => {}
                    }
                }
            }
        }
    }

    /// Execute a trading signal
    pub async fn execute_signal(&self, signal: Signal) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
        match signal {
            Signal::Buy { symbol, size, price } => {
                tracing::info!("Executing BUY {} size={}", symbol, size);
                // Would call exchange.place_futures_order(...)
            }
            Signal::Sell { symbol, size, price } => {
                tracing::info!("Executing SELL {} size={}", symbol, size);
            }
            Signal::Close { symbol } => {
                tracing::info!("Closing position {}", symbol);
            }
            Signal::Hold => {}
        }
        Ok(())
    }

    /// Get current engine state
    pub async fn get_state(&self) -> EngineState {
        self.state.read().await.clone()
    }
}