#![cfg(feature = "sync")]
use ibapi::client::blocking::Client;
use ibapi::contracts::Contract;
use ibapi::orders::conditions::*;
use ibapi::orders::{order_builder, Action, OrderCondition};
use std::thread;
use std::time::Duration;
#[test]
#[ignore] fn test_conditional_orders() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
println!("=== Testing Conditional Orders (Issue #325) ===\n");
println!("Connecting to TWS Paper Trading on 127.0.0.1:7497...");
let client = Client::connect("127.0.0.1:7497", 100)?;
println!("✓ Connected to TWS\n");
let mut order_id = client.next_valid_order_id()?;
println!("Starting order ID: {}\n", order_id);
println!("=== Test 1: Price Condition ===");
test_price_condition(&client, order_id)?;
order_id += 1;
thread::sleep(Duration::from_secs(2));
println!("\n=== Test 2: Time Condition ===");
test_time_condition(&client, order_id)?;
order_id += 1;
thread::sleep(Duration::from_secs(2));
println!("\n=== Test 3: Margin Condition ===");
test_margin_condition(&client, order_id)?;
order_id += 1;
thread::sleep(Duration::from_secs(2));
println!("\n=== Test 4: Execution Condition ===");
test_execution_condition(&client, order_id)?;
order_id += 1;
thread::sleep(Duration::from_secs(2));
println!("\n=== Test 5: Volume Condition ===");
test_volume_condition(&client, order_id)?;
order_id += 1;
thread::sleep(Duration::from_secs(2));
println!("\n=== Test 6: Percent Change Condition ===");
test_percent_change_condition(&client, order_id)?;
order_id += 1;
thread::sleep(Duration::from_secs(2));
println!("\n=== Test 7: Multiple Conditions with AND Logic ===");
test_multiple_conditions(&client, order_id)?;
println!("\n=== ALL TESTS COMPLETED ===");
println!("Check TWS for the submitted conditional orders.");
println!("All 6 condition types were successfully created and submitted!");
Ok(())
}
fn test_price_condition(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Price Condition:");
println!(" Trigger when AAPL price > $200");
let condition = PriceCondition::builder(265598, "SMART")
.greater_than(200.0)
.trigger_method(TriggerMethod::Default) .build();
let contract = Contract::stock("MSFT").build();
let mut order = order_builder::market_order(Action::Buy, 10.0);
order.conditions = vec![OrderCondition::Price(condition)];
order.conditions_ignore_rth = false;
order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted the price condition encoding.");
Ok(())
}
fn test_time_condition(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Time Condition:");
println!(" Trigger after 14:30:00 today");
use time::OffsetDateTime;
let now = OffsetDateTime::now_utc();
let time_str = format!("{:04}{:02}{:02} 14:30:00", now.year(), now.month() as u8, now.day());
let condition = TimeCondition::builder().greater_than(time_str).build();
let contract = Contract::stock("AAPL").build();
let mut order = order_builder::market_order(Action::Buy, 10.0);
order.conditions = vec![OrderCondition::Time(condition)];
order.conditions_ignore_rth = true;
order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted the time condition encoding.");
Ok(())
}
fn test_margin_condition(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Margin Condition:");
println!(" Trigger when margin cushion < 30%");
let condition = MarginCondition::builder().less_than(30).build();
let contract = Contract::stock("TSLA").build();
let mut order = order_builder::market_order(Action::Sell, 5.0);
order.conditions = vec![OrderCondition::Margin(condition)];
order.conditions_cancel_order = true; order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted the margin condition encoding.");
Ok(())
}
fn test_execution_condition(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Execution Condition:");
println!(" Trigger when MSFT trade executes");
let condition = ExecutionCondition::builder("MSFT", "STK", "SMART").build();
let contract = Contract::stock("AAPL").build();
let mut order = order_builder::market_order(Action::Buy, 10.0);
order.conditions = vec![OrderCondition::Execution(condition)];
order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted the execution condition encoding.");
Ok(())
}
fn test_volume_condition(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Volume Condition:");
println!(" Trigger when TSLA volume > 50M shares");
let condition = VolumeCondition::builder(76792991, "SMART").greater_than(50_000_000).build();
let contract = Contract::stock("TSLA").build();
let mut order = order_builder::market_order(Action::Buy, 10.0);
order.conditions = vec![OrderCondition::Volume(condition)];
order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted the volume condition encoding.");
Ok(())
}
fn test_percent_change_condition(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Percent Change Condition:");
println!(" Trigger when SPY changes > 2%");
let condition = PercentChangeCondition::builder(756733, "SMART").greater_than(2.0).build();
let contract = Contract::stock("SPY").build();
let mut order = order_builder::market_order(Action::Sell, 10.0);
order.conditions = vec![OrderCondition::PercentChange(condition)];
order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted the percent change condition encoding.");
Ok(())
}
fn test_multiple_conditions(client: &Client, order_id: i32) -> Result<(), Box<dyn std::error::Error>> {
println!("Creating order with Multiple Conditions (AND logic):");
println!(" 1. Trigger when price > $180");
println!(" 2. AND after 15:00:00 today");
let price_condition = PriceCondition::builder(265598, "SMART")
.greater_than(180.0)
.conjunction(true) .build();
use time::OffsetDateTime;
let now = OffsetDateTime::now_utc();
let time_str = format!("{:04}{:02}{:02} 15:00:00", now.year(), now.month() as u8, now.day());
let time_condition = TimeCondition::builder()
.greater_than(time_str)
.conjunction(true) .build();
let contract = Contract::stock("AAPL").build();
let mut order = order_builder::market_order(Action::Buy, 10.0);
order.conditions = vec![OrderCondition::Price(price_condition), OrderCondition::Time(time_condition)];
order.conditions_ignore_rth = false;
order.transmit = false;
println!(" Submitting order ID {}...", order_id);
client.submit_order(order_id, &contract, &order)?;
println!(" ✓ Order submitted successfully!");
println!(" TWS accepted multiple conditions with AND logic.");
Ok(())
}