Skip to content

Commit

Permalink
Implements exercise options (#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
wboayue authored Oct 28, 2024
1 parent 52e65d4 commit 8a0676e
Show file tree
Hide file tree
Showing 20 changed files with 478 additions and 420 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ exclude = [
byteorder = "1.4.3"
crossbeam = "0.8.2"
log = "0.4.17"
time = {version = "0.3.17", features = ["formatting", "macros", "local-offset", "parsing"]}
time = {version = "0.3.17", features = ["formatting", "macros", "local-offset", "parsing", "serde"]}
time-tz = "1.0.2"
serde = {version = "1.0.213" , features = ["derive"]}

[dev-dependencies]
anyhow = "1.0.66"
Expand Down
4 changes: 2 additions & 2 deletions examples/breakout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::VecDeque;

use ibapi::contracts::Contract;
use ibapi::market_data::realtime::{Bar, BarSize, WhatToShow};
use ibapi::orders::{order_builder, Action, OrderNotification};
use ibapi::orders::{order_builder, Action, PlaceOrder};
use ibapi::Client;

fn main() {
Expand Down Expand Up @@ -38,7 +38,7 @@ fn main() {

let notices = client.place_order(order_id, &contract, &order).unwrap();
for notice in notices {
if let OrderNotification::ExecutionData(data) = notice {
if let PlaceOrder::ExecutionData(data) = notice {
println!("{} {} shares of {}", data.execution.side, data.execution.shares, data.contract.symbol);
} else {
println!("{:?}", notice);
Expand Down
4 changes: 2 additions & 2 deletions examples/executions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ fn main() -> anyhow::Result<()> {

let client = Client::connect("127.0.0.1:4002", 100)?;

let executions = client.executions(filter)?;
for execution in executions {
let subscription = client.executions(filter)?;
for execution in &subscription {
println!("{execution:?}")
}

Expand Down
39 changes: 39 additions & 0 deletions examples/options_exercise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use ibapi::{
contracts::{Contract, SecurityType},
orders::ExerciseAction,
Client,
};

fn main() {
env_logger::init();

let client = Client::connect("127.0.0.1:4002", 100).expect("connection failed");

let contract = create_option_contract("AAPL", 180.0, "C", "20250221");

let accounts = client.managed_accounts().expect("could not get managed accounts");
let account = &accounts[0];
let manual_order_time = None;

let subscription = client
.exercise_options(&contract, ExerciseAction::Exercise, 100, account, true, manual_order_time)
.expect("exercise options request failed!");

for status in &subscription {
println!("{status:?}")
}
}

fn create_option_contract(symbol: &str, strike: f64, right: &str, last_trade_date_or_contract_month: &str) -> Contract {
Contract {
symbol: symbol.to_owned(),
security_type: SecurityType::Option,
exchange: "SMART".to_owned(),
currency: "USD".to_owned(),
last_trade_date_or_contract_month: last_trade_date_or_contract_month.to_owned(),
strike,
right: right.to_owned(),
multiplier: "100".to_owned(),
..Default::default()
}
}
54 changes: 54 additions & 0 deletions examples/options_purchase.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use ibapi::{
contracts::{Contract, SecurityType},
orders::{self, order_builder, PlaceOrder},
Client,
};

fn main() {
env_logger::init();

let client = Client::connect("127.0.0.1:4002", 100).expect("connection failed");

let contract = create_option_contract("AAPL", 180.0, "C", "20250221");

let order_id = client.next_valid_order_id().expect("could not get next valid order id");
// let order_id = client.next_order_id();
println!("next order id: {order_id}");

let order = order_builder::market_order(orders::Action::Buy, 5.0);
println!("contract: {contract:?}, order: {order:?}");

let subscription = client.place_order(order_id, &contract, &order).expect("could not place order");
for status in subscription {
println!("{status:?}")
}
let order_id = client.next_order_id();
println!("next order id: {order_id}");

let order = order_builder::market_order(orders::Action::Buy, 5.0);
println!("contract: {contract:?}, order: {order:?}");

let subscription = client.place_order(order_id, &contract, &order).expect("could not place order");
for status in subscription {
println!("{status:?}");
if let PlaceOrder::OrderStatus(order_status) = status {
if order_status.remaining == 0.0 {
break;
}
}
}
}

fn create_option_contract(symbol: &str, strike: f64, right: &str, last_trade_date_or_contract_month: &str) -> Contract {
Contract {
symbol: symbol.to_owned(),
security_type: SecurityType::Option,
exchange: "SMART".to_owned(),
currency: "USD".to_owned(),
last_trade_date_or_contract_month: last_trade_date_or_contract_month.to_owned(),
strike,
right: right.to_owned(),
multiplier: "100".to_owned(),
..Default::default()
}
}
7 changes: 4 additions & 3 deletions examples/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use anyhow::Ok;
use clap::builder::PossibleValue;
use clap::{arg, Command};

use ibapi::orders::OrderDataResult;
use ibapi::client::Subscription;
use ibapi::orders::Orders;
use ibapi::Client;

fn main() -> anyhow::Result<()> {
Expand Down Expand Up @@ -53,8 +54,8 @@ fn main() -> anyhow::Result<()> {
Ok(())
}

fn print_orders(orders: impl Iterator<Item = OrderDataResult>) {
for order in orders {
fn print_orders(orders: Subscription<Orders>) {
for order in &orders {
println!("order: {order:?}")
}
}
16 changes: 8 additions & 8 deletions examples/place_order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clap::{arg, ArgMatches, Command};
use log::{debug, info};

use ibapi::contracts::Contract;
use ibapi::orders::{self, order_builder, OrderNotification};
use ibapi::orders::{self, order_builder, PlaceOrder};
use ibapi::Client;

fn main() {
Expand Down Expand Up @@ -41,17 +41,17 @@ fn main() {

println!("contract: {contract:?}, order: {order:?}");

let results = client.place_order(order_id, &contract, &order).expect("could not place order");
let subscription = client.place_order(order_id, &contract, &order).expect("could not place order");

for status in results {
for status in subscription {
match status {
OrderNotification::OrderStatus(order_status) => {
PlaceOrder::OrderStatus(order_status) => {
println!("order status: {order_status:?}")
}
OrderNotification::OpenOrder(open_order) => println!("open order: {open_order:?}"),
OrderNotification::ExecutionData(execution) => println!("execution: {execution:?}"),
OrderNotification::CommissionReport(report) => println!("commission report: {report:?}"),
OrderNotification::Message(message) => println!("notice: {message}"),
PlaceOrder::OpenOrder(open_order) => println!("open order: {open_order:?}"),
PlaceOrder::ExecutionData(execution) => println!("execution: {execution:?}"),
PlaceOrder::CommissionReport(report) => println!("commission report: {report:?}"),
PlaceOrder::Message(message) => println!("notice: {message}"),
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions examples/readme_place_order.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use ibapi::contracts::Contract;
use ibapi::orders::{order_builder, Action, OrderNotification};
use ibapi::orders::{order_builder, Action, PlaceOrder};
use ibapi::Client;

pub fn main() {
Expand All @@ -16,11 +16,11 @@ pub fn main() {

let subscription = client.place_order(order_id, &contract, &order).expect("place order request failed!");

for notice in subscription {
if let OrderNotification::ExecutionData(data) = notice {
for event in &subscription {
if let PlaceOrder::ExecutionData(data) = event {
println!("{} {} shares of {}", data.execution.side, data.execution.shares, data.contract.symbol);
} else {
println!("{:?}", notice);
println!("{:?}", event);
}
}
}
7 changes: 4 additions & 3 deletions examples/readme_realtime_data_2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ fn main() {
.realtime_bars(&contract_nvda, BarSize::Sec5, WhatToShow::Trades, false)
.expect("realtime bars request failed!");

while let (Some(bar_nvda), Some(bar_aapl)) = (subscription_nvda.next(), subscription_aapl.next()) {
for (bar_aapl, bar_nvda) in subscription_aapl.iter().zip(subscription_nvda.iter()) {
// Process each bar here (e.g., print or use in calculations)
println!("NVDA {}, AAPL {}", bar_nvda.close, bar_aapl.close);
println!("AAPL {}, NVDA {}", bar_nvda.close, bar_aapl.close);

// when your algorithm is done, cancel subscription
// You can simply break the or explicitly cancel the subscription.
// Subscriptions are automatically canceled when they go out of scope.
subscription_aapl.cancel();
subscription_nvda.cancel();
}
Expand Down
Loading

0 comments on commit 8a0676e

Please sign in to comment.