use num_traits::FromPrimitive;
use crate::core::common::TagValue;
use crate::core::order::{AuctionStrategy, Order, OrderComboLeg};
use crate::core::order_condition::{
create_condition, ConditionType, ExecutionCondition, MarginCondition, PercentChangeCondition,
PriceCondition, TimeCondition, VolumeCondition,
};
pub fn at_auction(action: &str, quantity: f64, price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.tif = "AUC".to_string();
order.order_type = "MTL".to_string();
order.total_quantity = quantity;
order.lmt_price = price;
order
}
pub fn discretionary(action: &str, quantity: f64, price: f64, discretionary_amount: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = price;
order.discretionary_amt = discretionary_amount;
order
}
pub fn market_order(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MKT".to_string();
order.total_quantity = quantity;
order
}
pub fn market_if_touched(action: &str, quantity: f64, price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MIT".to_string();
order.total_quantity = quantity;
order.aux_price = price;
order
}
pub fn market_on_close(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MOC".to_string();
order.total_quantity = quantity;
order
}
pub fn market_on_open(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MKT".to_string();
order.total_quantity = quantity;
order.tif = "OPG".to_string();
order
}
pub fn midpoint_match(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MKT".to_string();
order.total_quantity = quantity;
order
}
pub fn midprice(action: &str, quantity: f64, price_cap: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MIDPRICE".to_string();
order.total_quantity = quantity;
order.lmt_price = price_cap; order
}
pub fn pegged_to_market(action: &str, quantity: f64, market_offset: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "PEG MKT".to_string();
order.total_quantity = quantity;
order.aux_price = market_offset; order
}
pub fn pegged_to_stock(
action: &str,
quantity: f64,
delta: f64,
stock_reference_price: f64,
starting_price: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "PEG STK".to_string();
order.total_quantity = quantity;
order.delta = delta;
order.stock_ref_price = stock_reference_price;
order.starting_price = starting_price;
order
}
pub fn relative_pegged_to_primary(
action: &str,
quantity: f64,
price_cap: f64,
offset_amount: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "REL".to_string();
order.total_quantity = quantity;
order.lmt_price = price_cap;
order.aux_price = offset_amount;
order
}
pub fn sweep_to_fill(action: &str, quantity: f64, price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = price;
order.sweep_to_fill = true;
order
}
pub fn auction_limit(
action: &str,
quantity: f64,
price: f64,
auction_strategy: AuctionStrategy,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = price;
order.auction_strategy = auction_strategy;
order
}
pub fn auction_pegged_to_stock(
action: &str,
quantity: f64,
starting_price: f64,
delta: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "PEG STK".to_string();
order.total_quantity = quantity;
order.delta = delta;
order.starting_price = starting_price;
order
}
pub fn auction_relative(action: &str, quantity: f64, offset: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "REL".to_string();
order.total_quantity = quantity;
order.aux_price = offset;
order
}
pub fn block(action: &str, quantity: f64, price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity; order.lmt_price = price;
order.block_order = true;
order
}
pub fn box_top(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "BOX TOP".to_string();
order.total_quantity = quantity;
order
}
pub fn limit_order(action: &str, quantity: f64, limit_price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
order.transmit = true;
order
}
pub fn limit_order_with_cash_qty(
action: &str,
quantity: f64,
limit_price: f64,
cash_qty: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
order.cash_qty = cash_qty;
order
}
pub fn limit_if_touched(
action: &str,
quantity: f64,
limit_price: f64,
trigger_price: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LIT".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
order.aux_price = trigger_price;
order
}
pub fn limit_on_close(action: &str, quantity: f64, limit_price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LOC".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
order
}
pub fn limit_on_open(action: &str, quantity: f64, limit_price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.tif = "OPG".to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
order
}
pub fn passive_relative(action: &str, quantity: f64, offset: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "PASSV REL".to_string();
order.total_quantity = quantity;
order.aux_price = offset;
order
}
pub fn pegged_to_midpoint(action: &str, quantity: f64, offset: f64, limit_price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "PEG MID".to_string();
order.total_quantity = quantity;
order.aux_price = offset;
order.lmt_price = limit_price;
order
}
pub fn bracket_order(
parent_order_id: i32,
action: &str,
quantity: f64,
limit_price: f64,
take_profit_limit_price: f64,
stop_loss_price: f64,
) -> (Order, Order, Order) {
let mut parent = Order::default();
parent.order_id = parent_order_id;
parent.action = action.to_string();
parent.order_type = "LMT".to_string();
parent.total_quantity = quantity;
parent.lmt_price = limit_price;
parent.transmit = false;
let mut take_profit = Order::default();
take_profit.order_id = parent.order_id + 1;
take_profit.action = (if action == "BUY" { "SELL" } else { "BUY" }).to_string();
take_profit.order_type = "LMT".to_string();
take_profit.total_quantity = quantity;
take_profit.lmt_price = take_profit_limit_price;
take_profit.parent_id = parent_order_id;
take_profit.transmit = false;
let mut stop_loss = Order::default();
stop_loss.order_id = parent.order_id + 2;
stop_loss.action = (if action == "BUY" { "SELL" } else { "BUY" }).to_string();
stop_loss.order_type = "STP".to_string();
stop_loss.aux_price = stop_loss_price;
stop_loss.total_quantity = quantity;
stop_loss.parent_id = parent_order_id;
stop_loss.transmit = true;
(parent, take_profit, stop_loss)
}
pub fn market_to_limit(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MTL".to_string();
order.total_quantity = quantity;
order
}
pub fn market_with_protection(action: &str, quantity: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MKT PRT".to_string();
order.total_quantity = quantity;
order
}
pub fn stop(action: &str, quantity: f64, stop_price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "STP".to_string();
order.aux_price = stop_price;
order.total_quantity = quantity;
order
}
pub fn stop_limit(action: &str, quantity: f64, limit_price: f64, stop_price: f64) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "STP LMT".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
order.aux_price = stop_price;
order
}
pub fn stop_with_protection(action: &str, quantity: f64, stop_price: f64) -> Order {
let mut order = Order::default();
order.total_quantity = quantity;
order.action = action.to_string();
order.order_type = "STP PRT".to_string();
order.aux_price = stop_price;
order
}
pub fn trailing_stop(
action: &str,
quantity: f64,
trailing_percent: f64,
trail_stop_price: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "TRAIL".to_string();
order.total_quantity = quantity;
order.trailing_percent = trailing_percent;
order.trail_stop_price = trail_stop_price;
order
}
pub fn trailing_stop_limit(
action: &str,
quantity: f64,
lmt_price_offset: f64,
trailing_amount: f64,
trail_stop_price: f64,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "TRAIL LIMIT".to_string();
order.total_quantity = quantity;
order.trail_stop_price = trail_stop_price;
order.lmt_price_offset = lmt_price_offset;
order.aux_price = trailing_amount;
order
}
pub fn combo_limit_order(
action: &str,
quantity: f64,
limit_price: f64,
non_guaranteed: bool,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.tif = "GTC".to_string();
order.total_quantity = quantity;
order.lmt_price = limit_price;
if non_guaranteed {
order
.smart_combo_routing_params
.push(TagValue::new("NonGuaranteed".to_string(), "1".to_string()));
}
order
}
pub fn combo_market_order(action: &str, quantity: f64, non_guaranteed: bool) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "MKT".to_string();
order.total_quantity = quantity;
if non_guaranteed {
order
.smart_combo_routing_params
.push(TagValue::new("NonGuaranteed".to_string(), "1".to_string()));
}
order
}
pub fn limit_order_for_combo_with_leg_prices(
action: &str,
quantity: f64,
leg_prices: Vec<f64>,
non_guaranteed: bool,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "LMT".to_string();
order.total_quantity = quantity;
for price in leg_prices {
let mut combo_leg = OrderComboLeg::default();
combo_leg.price = price;
order.order_combo_legs.push(combo_leg)
}
if non_guaranteed {
order
.smart_combo_routing_params
.push(TagValue::new("NonGuaranteed".to_string(), "1".to_string()));
}
order
}
pub fn relative_limit_combo(
action: &str,
quantity: f64,
limit_price: f64,
non_guaranteed: bool,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.total_quantity = quantity;
order.order_type = "REL + LMT".to_string();
order.lmt_price = limit_price;
if non_guaranteed {
order
.smart_combo_routing_params
.push(TagValue::new("NonGuaranteed".to_string(), "1".to_string()));
}
order
}
pub fn relative_market_combo(action: &str, quantity: f64, non_guaranteed: bool) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.total_quantity = quantity;
order.order_type = "REL + MKT".to_string();
if non_guaranteed {
order
.smart_combo_routing_params
.push(TagValue::new("NonGuaranteed".to_string(), "1".to_string()));
}
order
}
pub fn one_cancels_all(oca_group: &str, oca_orders: Vec<Order>, oca_type: i32) {
for mut order in oca_orders {
order.oca_group = oca_group.to_string();
order.oca_type = oca_type;
}
}
pub fn volatility(
action: &str,
quantity: f64,
volatility_percent: f64,
volatility_type: i32,
) -> Order {
let mut order = Order::default();
order.action = action.to_string();
order.order_type = "VOL".to_string();
order.total_quantity = quantity;
order.volatility = volatility_percent; order.volatility_type = volatility_type; order
}
pub fn market_fhedge(parent_order_id: i32, action: &str) -> Order {
let mut order = market_order(action, 0.0);
order.parent_id = parent_order_id;
order.hedge_type = "F".to_string();
order
}
pub fn pegged_to_benchmark(
action: &str,
quantity: f64,
starting_price: f64,
pegged_change_amount_decrease: bool,
pegged_change_amount: f64,
reference_change_amount: f64,
reference_con_id: i32,
reference_exchange: &str,
stock_reference_price: f64,
reference_contract_lower_range: f64,
reference_contract_upper_range: f64,
) -> Order {
let mut order = Order::default();
order.order_type = "PEG BENCH".to_string();
order.action = action.to_string();
order.total_quantity = quantity;
order.starting_price = starting_price;
order.is_pegged_change_amount_decrease = pegged_change_amount_decrease;
order.pegged_change_amount = pegged_change_amount;
order.reference_change_amount = reference_change_amount;
order.reference_contract_id = reference_con_id;
order.reference_exchange_id = reference_exchange.parse().unwrap();
order.stock_ref_price = stock_reference_price;
order.stock_range_lower = reference_contract_lower_range;
order.stock_range_upper = reference_contract_upper_range;
order
}
pub fn attach_adjustable_to_stop(
parent: Order,
attached_order_stop_price: f64,
trigger_price: f64,
adjust_stop_price: f64,
) -> Order {
let mut order = stop(
(if parent.action == "BUY" {
"SELL"
} else {
"BUY"
})
.as_ref(),
parent.total_quantity,
attached_order_stop_price,
);
order.parent_id = parent.order_id;
order.trigger_price = trigger_price;
order.adjusted_order_type = "STP".to_string();
order.adjusted_stop_price = adjust_stop_price;
order
}
pub fn attach_adjustable_to_stop_limit(
parent: Order,
attached_order_stop_price: f64,
trigger_price: f64,
adjusted_stop_price: f64,
adjusted_stop_limit_price: f64,
) -> Order {
let mut order = stop(
(if parent.action == "BUY" {
"SELL"
} else {
"BUY"
})
.as_ref(),
parent.total_quantity,
attached_order_stop_price,
);
order.parent_id = parent.order_id;
order.trigger_price = trigger_price;
order.adjusted_order_type = "STP LMT".to_string();
order.adjusted_stop_price = adjusted_stop_price;
order.adjusted_stop_limit_price = adjusted_stop_limit_price;
order
}
pub fn attach_adjustable_to_trail(
parent: Order,
attached_order_stop_price: f64,
trigger_price: f64,
adjusted_stop_price: f64,
adjusted_trail_amount: f64,
trail_unit: i32,
) -> Order {
let mut order = stop(
(if parent.action == "BUY" {
"SELL"
} else {
"BUY"
})
.as_ref(),
parent.total_quantity,
attached_order_stop_price,
);
order.parent_id = parent.order_id;
order.trigger_price = trigger_price;
order.adjusted_order_type = "TRAIL".to_string();
order.adjusted_stop_price = adjusted_stop_price;
order.adjustable_trailing_unit = trail_unit;
order.adjusted_trailing_amount = adjusted_trail_amount;
order
}
pub fn price_condition(
trigger_method: i32,
con_id: i32,
exchange: &str,
price: f64,
is_more: bool,
is_conjunction: bool,
) -> PriceCondition {
let mut price_condition: PriceCondition = create_condition(ConditionType::Price).into();
price_condition.contract_condition.con_id = con_id;
price_condition.contract_condition.exchange = exchange.to_string();
price_condition
.contract_condition
.operator_condition
.is_more = is_more;
price_condition.trigger_method = FromPrimitive::from_i32(trigger_method).unwrap();
price_condition.price = price;
price_condition
.contract_condition
.operator_condition
.order_condition
.is_conjunction_connection = is_conjunction;
price_condition
}
pub fn execution_condition(
symbol: &str,
sec_type: &str,
exchange: &str,
is_conjunction: bool,
) -> ExecutionCondition {
let mut exec_condition: ExecutionCondition = create_condition(ConditionType::Execution).into();
exec_condition.symbol = symbol.to_string();
exec_condition.exchange = exchange.to_string();
exec_condition.sec_type = sec_type.to_string();
exec_condition.order_condition.is_conjunction_connection = is_conjunction;
exec_condition.order_condition.cond_type = ConditionType::Execution;
exec_condition
}
pub fn margin_condition(percent: f64, is_more: bool, is_conjunction: bool) -> MarginCondition {
let mut margin_condition: MarginCondition = create_condition(ConditionType::Margin).into();
margin_condition.operator_condition.is_more = is_more;
margin_condition.percent = percent;
margin_condition
.operator_condition
.order_condition
.is_conjunction_connection = is_conjunction;
margin_condition
.operator_condition
.order_condition
.cond_type = ConditionType::Margin;
margin_condition
}
pub fn percentage_change_condition(
pct_change: f64,
con_id: i32,
exchange: &str,
is_more: bool,
is_conjunction: bool,
) -> PercentChangeCondition {
let mut pct_change_condition: PercentChangeCondition =
create_condition(ConditionType::Execution).into();
pct_change_condition
.contract_condition
.operator_condition
.is_more = is_more;
pct_change_condition.change_percent = pct_change;
pct_change_condition.contract_condition.con_id = con_id;
pct_change_condition.contract_condition.exchange = exchange.to_string();
pct_change_condition
.contract_condition
.operator_condition
.order_condition
.is_conjunction_connection = is_conjunction;
pct_change_condition
.contract_condition
.operator_condition
.order_condition
.cond_type = ConditionType::PercentChange;
pct_change_condition
}
pub fn time_condition(time: &str, is_more: bool, is_conjunction: bool) -> TimeCondition {
let mut time_condition: TimeCondition = create_condition(ConditionType::Time).into();
time_condition.operator_condition.is_more = is_more;
time_condition.time = time.to_string();
time_condition
.operator_condition
.order_condition
.is_conjunction_connection = is_conjunction;
time_condition.operator_condition.order_condition.cond_type = ConditionType::Time;
time_condition
}
pub fn volume_condition(
con_id: i32,
exchange: &str,
is_more: bool,
volume: i32,
is_conjunction: bool,
) -> VolumeCondition {
let mut vol_cond: VolumeCondition = create_condition(ConditionType::Volume).into();
vol_cond.contract_condition.con_id = con_id;
vol_cond.contract_condition.exchange = exchange.to_string();
vol_cond.contract_condition.operator_condition.is_more = is_more;
vol_cond.volume = volume;
vol_cond
.contract_condition
.operator_condition
.order_condition
.is_conjunction_connection = is_conjunction;
vol_cond
.contract_condition
.operator_condition
.order_condition
.cond_type = ConditionType::Volume;
vol_cond
}
pub fn what_if_limit_order(action: &str, quantity: f64, limit_price: f64) -> Order {
let mut order = limit_order(action, quantity, limit_price);
order.what_if = true;
order
}