#![allow(clippy::uninlined_format_args)]
use ibapi::contracts::{Contract, Currency, Exchange, SecurityType, Symbol};
use ibapi::orders::{order_builder, Action, OrderUpdate};
use ibapi::Client;
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
let client = Client::connect("127.0.0.1:4002", 100).await?;
println!("Connected to server version {}", client.server_version());
let mut order_stream = client.order_update_stream().await?;
println!("Created order update stream");
let monitor_handle = tokio::spawn(async move {
println!("Starting order update monitor...");
while let Some(update) = order_stream.next().await {
match update {
Ok(OrderUpdate::OrderStatus(status)) => {
println!("Order Status Update:");
println!(" Order ID: {}", status.order_id);
println!(" Status: {}", status.status);
println!(" Filled: {}", status.filled);
println!(" Remaining: {}", status.remaining);
println!(" Avg Fill Price: {}", status.average_fill_price);
}
Ok(OrderUpdate::OpenOrder(order_data)) => {
println!("Open Order Update:");
println!(" Order ID: {}", order_data.order_id);
println!(" Symbol: {}", order_data.contract.symbol);
println!(" Action: {:?}", order_data.order.action);
println!(" Quantity: {}", order_data.order.total_quantity);
println!(" Order Type: {}", order_data.order.order_type);
println!(" Status: {}", order_data.order_state.status);
}
Ok(OrderUpdate::ExecutionData(exec_data)) => {
println!("Execution:");
println!(" Order ID: {}", exec_data.execution.order_id);
println!(" Symbol: {}", exec_data.contract.symbol);
println!(" Side: {}", exec_data.execution.side);
println!(" Shares: {}", exec_data.execution.shares);
println!(" Price: {}", exec_data.execution.price);
println!(" Time: {}", exec_data.execution.time);
}
Ok(OrderUpdate::CommissionReport(report)) => {
println!("Commission Report:");
println!(" Execution ID: {}", report.execution_id);
println!(" Commission: {} {}", report.commission, report.currency);
}
Ok(OrderUpdate::Message(notice)) => {
println!("Order Message: {} - {}", notice.code, notice.message);
}
Err(e) => {
eprintln!("Error in order stream: {e:?}");
break;
}
}
println!("---");
}
println!("Order update monitor stopped");
});
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
let contract = Contract {
symbol: Symbol::from("AAPL"),
security_type: SecurityType::Stock,
exchange: Exchange::from("SMART"),
currency: Currency::from("USD"),
..Default::default()
};
let order = order_builder::limit_order(Action::Buy, 100.0, 150.0);
let order_id = client.next_order_id();
println!(
"\nSubmitting order {} for {} {} @ {}",
order_id,
order.total_quantity,
contract.symbol,
order.limit_price.unwrap()
);
client.submit_order(order_id, &contract, &order).await?;
println!("Order submitted successfully");
println!("\nWaiting for order updates...");
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
let order_id2 = client.next_order_id();
let order2 = order_builder::limit_order(Action::Sell, 50.0, 160.0);
println!(
"\nSubmitting order {} for {} {} @ {}",
order_id2,
order2.total_quantity,
contract.symbol,
order2.limit_price.unwrap()
);
client.submit_order(order_id2, &contract, &order2).await?;
println!("Order submitted successfully");
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
monitor_handle.abort();
println!("\nExample complete");
Ok(())
}