//! # Broker Connection Example //! //! Demonstrates how to connect to different brokers using the data module. //! This example shows connection setup for Interactive Brokers. #![allow(unused_crate_dependencies)] use common::{Order, OrderSide, OrderType, Price, Quantity, Symbol, TimeInForce}; use data::brokers::interactive_brokers::{IBConfig, InteractiveBrokersAdapter}; use data::brokers::BrokerClient; use tokio::time::{timeout, Duration}; use tracing::{error, info, warn}; // use trading_engine::prelude::*; // REMOVED - prelude does not exist #[tokio::main] async fn main() -> anyhow::Result<()> { // Initialize logging tracing_subscriber::fmt::init(); info!("Starting broker connection example"); // Example 1: Interactive Brokers Connection if let Err(e) = interactive_brokers_example().await { warn!("Interactive Brokers example failed: {}", e); } // Example 2: Data Manager with multiple providers // Note: DataManager and DataConfig not yet implemented // if let Err(e) = data_manager_example().await { // warn!("Data manager example failed: {}", e); // } info!("Broker connection examples completed"); Ok(()) } /// Example of connecting to Interactive Brokers TWS async fn interactive_brokers_example() -> anyhow::Result<()> { info!("=== Interactive Brokers Connection Example ==="); // Create IB configuration let config = IBConfig { host: "127.0.0.1".to_string(), port: 7497, // Paper trading port client_id: 1, account_id: "DU123456".to_string(), // Demo account connection_timeout: 30, max_reconnect_attempts: 3, heartbeat_interval: 60, request_timeout: 10, }; // Create adapter let mut adapter = InteractiveBrokersAdapter::new(config); info!("Created Interactive Brokers adapter"); // Attempt connection with timeout match timeout(Duration::from_secs(10), adapter.connect()).await { Ok(Ok(())) => { info!("✓ Successfully connected to Interactive Brokers TWS"); // Test basic functionality info!("Connection status: {}", adapter.is_connected()); // info!("Adapter name: {}", adapter.name()); // DISABLED: name() method removed // Subscribe to market data for a test symbol // DISABLED: Methods removed from adapter /* let symbol = Symbol::from("AAPL"); match adapter.subscribe_market_data(symbol.clone()).await { Ok(()) => { info!("✓ Successfully subscribed to market data for {}", symbol); // Wait for some data tokio::time::sleep(Duration::from_secs(5)).await; // Unsubscribe if let Err(e) = adapter.unsubscribe_market_data(symbol).await { warn!("Failed to unsubscribe from market data: {}", e); } }, Err(e) => warn!("Failed to subscribe to market data: {}", e), } */ // Disconnect info!("Disconnecting from Interactive Brokers..."); if let Err(e) = adapter.disconnect().await { warn!("Error during disconnect: {}", e); } else { info!("✓ Successfully disconnected"); } }, Ok(Err(e)) => { warn!("Failed to connect to Interactive Brokers: {}", e); warn!("Make sure TWS or IB Gateway is running on port 7497"); return Err(e.into()); }, Err(_) => { warn!("Connection to Interactive Brokers timed out"); warn!("Make sure TWS or IB Gateway is running and accepting connections"); return Err(anyhow::anyhow!("Connection timeout")); }, } Ok(()) } /// Example of using the DataManager for coordinated broker and provider access #[allow(dead_code)] #[allow(dead_code)] async fn data_manager_example() -> anyhow::Result<()> { // NOTE: DataManager and DataConfig not implemented yet // This example is commented out until those types are available println!("DataManager example not available - component not implemented"); Ok(()) } /// Example of order submission (commented out for safety) #[allow(dead_code)] async fn order_submission_example(adapter: &mut InteractiveBrokersAdapter) -> anyhow::Result<()> { info!("=== Order Submission Example (DEMO ONLY) ==="); warn!("This example is for demonstration only - no actual orders will be submitted"); // Create a demo order (will not be submitted) use rust_decimal_macros::dec; let mut order = Order::new( Symbol::from("AAPL"), OrderSide::Buy, Quantity::try_from(1.0)?, Some(Price::from_decimal(dec!(100.0))), // Low price to avoid accidental fills OrderType::Limit, ); order.time_in_force = TimeInForce::Day; info!("Demo order created:"); info!(" Symbol: {}", order.symbol); info!(" Side: {:?}", order.side); info!(" Quantity: {}", order.quantity); info!(" Type: {:?}", order.order_type); info!(" Price: {:?}", order.price); // In a real application, you would submit the order like this: // let result = adapter.submit_order(order).await; // But for safety, we're just demonstrating the order structure info!("Order submission example completed (no actual order submitted)"); Ok(()) } /// Helper function to check if TWS is running async fn check_tws_status() -> bool { match tokio::net::TcpStream::connect("127.0.0.1:7497").await { Ok(_) => { info!("✓ TWS/IB Gateway appears to be running on port 7497"); true }, Err(_) => { warn!("✗ Cannot connect to port 7497 - TWS/IB Gateway may not be running"); warn!("To run this example successfully:"); warn!("1. Install and start TWS or IB Gateway"); warn!("2. Enable API connections in the configuration"); warn!("3. Set the socket port to 7497 (paper trading)"); false }, } } /// Configuration helper fn print_setup_instructions() { info!("=== Setup Instructions ==="); info!("To run broker connection examples:"); info!(""); info!("Interactive Brokers:"); info!("1. Download and install TWS or IB Gateway"); info!("2. Start the application and log in"); info!("3. Go to Configure -> API -> Settings"); info!("4. Enable 'Enable ActiveX and Socket Clients'"); info!("5. Set Socket port to 7497 for paper trading"); info!("6. Add 127.0.0.1 to trusted IP addresses"); info!(""); info!("Environment Variables (optional):"); info!("- POLYGON_API_KEY: Your Polygon.io API key"); info!("- IB_TWS_HOST: TWS host (default: 127.0.0.1)"); info!("- IB_TWS_PORT: TWS port (default: 7497)"); info!(""); }