Skip to content

Commit

Permalink
Handle market closing orders on changing sides.
Browse files Browse the repository at this point in the history
  • Loading branch information
golden-lucky-monkey committed Apr 14, 2022
1 parent f52fd75 commit b236491
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 24 deletions.
12 changes: 10 additions & 2 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub(crate) fn convert_increment_to_precision(increment: rust_decimal::Decimal) -
incr *= rust_decimal::Decimal::from(10);
precision += 1;
}
return precision
return precision;
}

/// Lead setting file from JSON
Expand All @@ -113,5 +113,13 @@ pub(crate) fn read_settings(filepath: &str) -> SettingsFile {
let settings: SettingsFile =
serde_json::from_reader(reader).expect("Error when reading config json");

return settings
return settings;
}

/// Invert side i.e. buy -> sell, sell -> buy
pub(crate) fn invert_side(side: ftx::rest::Side) -> ftx::rest::Side {
return match side {
ftx::rest::Side::Buy => ftx::rest::Side::Sell,
ftx::rest::Side::Sell => ftx::rest::Side::Buy
};
}
34 changes: 24 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ async fn main() {
}
Ok(o) => {
(o.bid.unwrap(), o.ask.unwrap())
},
}
};

// Create local variables to handle side
Expand Down Expand Up @@ -190,6 +190,18 @@ async fn main() {
positions_count += 1;

if settings.live {
// Check if position is currently open and close it
let open_position = futures::executor::block_on(
order_handler::get_open_position(&api, &settings.market_name));

if open_position {
log::info!("Closing existing position...");
futures::executor::block_on(
order_handler::market_close_order(&api, &settings.market_name));
futures::executor::block_on(
order_handler::cancel_all_trigger_orders(&api, &settings.market_name));
}

// TODO: Use Kelly criterion for order sizing
// Place order on FTX
let order_placed = futures::executor::block_on(
Expand Down Expand Up @@ -221,14 +233,16 @@ async fn main() {
// TODO: Market close position in event of failure
if !triggers_placed {
log::warn!("Cancelling all orders...");
let cancel_orders = futures::executor::block_on(
order_handler::cancel_all_orders(&api, &settings.market_name));
match cancel_orders {
Ok(_o) => continue,
Err(e) => {
log::error!("Unable to cancel orders Err: {:?}, panicking!", e);
panic!()
}
let order_closed = futures::executor::block_on(
order_handler::market_close_order(&api, &settings.market_name));
let triggers_cancelled = futures::executor::block_on(
order_handler::cancel_all_trigger_orders(&api, &settings.market_name));

if order_closed && triggers_cancelled {
continue;
} else {
log::error!("Unable to close order, panicking!");
panic!()
}
}
}
Expand All @@ -240,7 +254,7 @@ async fn main() {
price,
order_size,
&current_side,
positions_count
positions_count,
).expect("Unable to write positions to file.");
}
}
Expand Down
78 changes: 66 additions & 12 deletions src/order_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//! trigger orders and canceling orders


/// Create a market order on FTX
pub(crate) async fn place_market_order(
api: &ftx::rest::Rest,
Expand Down Expand Up @@ -39,15 +38,73 @@ pub(crate) async fn place_market_order(

}

/// Check if position is open on a market
pub(crate) async fn get_open_position(api: &ftx::rest::Rest, market_name: &str) -> bool {
let positions = api.request(ftx::rest::GetPositions {}).await.unwrap();

for position in positions {
if position.future == market_name {
return true
}
}
return false
}


/// Close postion at market
pub(crate) async fn market_close_order(api: &ftx::rest::Rest, market_name: &str) -> bool {
let positions = api.request(ftx::rest::GetPositions {}).await.unwrap();

for position in positions {
if position.future == market_name {
let order_closed = api.request( ftx::rest::PlaceOrder {
market: String::from(market_name),
side: crate::helpers::invert_side(position.side),
price: None,
r#type: ftx::rest::OrderType::Market,
size: position.size,
reduce_only: false,
ioc: false,
post_only: false,
client_id: None,
reject_on_price_band: false
}).await;

return match order_closed {
Err(e) => {
log::error!("Unable to close order or no order open, Err: {:?}", e);
false
}
Ok(o) => {
log::info!("Closed order successfully: {:?}", o);
true
}
};
}
}
log::warn!("No order open, cannot close");
return false
}

/// Cancel all open orders and trigger orders on FTX
pub(crate) async fn cancel_all_orders(api: &ftx::rest::Rest, market_name: &str) -> ftx::rest::Result<String> {
return api.request(ftx::rest::CancelAllOrder {
pub(crate) async fn cancel_all_trigger_orders(api: &ftx::rest::Rest, market_name: &str) -> bool {
let triggers_cancelled = api.request(ftx::rest::CancelAllOrder {
market: Option::from(String::from(market_name)),
side: None,
conditional_orders_only: Option::from(false),
limit_orders_only: Option::from(false),
}).await;

return match triggers_cancelled {
Ok(o) => {
log::info!("Cancelled all trigger orders: {:?}", o);
true
},
Err(e) => {
log::error!("Unable to cancel orders Err: {:?}, panicking!", e);
false
}
}
}

/// Place take profit and stop loss orders
Expand All @@ -63,9 +120,6 @@ pub(crate) async fn place_trigger_orders(
ftx::rest::Side::Sell => ftx::rest::Side::Buy,
};

let take_profit_success;
let stop_loss_success;

let take_profit = api.request(ftx::rest::PlaceTriggerOrder {
market: String::from(market_name),
side: trigger_side,
Expand All @@ -78,14 +132,14 @@ pub(crate) async fn place_trigger_orders(
trail_value: None,
}).await;

match take_profit {
let take_profit_success = match take_profit {
Err(e) => {
log::error!("Unable to place take profit, Err: {:?}", e);
take_profit_success = false
false
}
Ok(o) => {
log::info!("Take profit placed successfully: {:?}", o);
take_profit_success = true
true
}
};

Expand All @@ -101,14 +155,14 @@ pub(crate) async fn place_trigger_orders(
trail_value: None,
}).await;

match stop_loss {
let stop_loss_success = match stop_loss {
Err(e) => {
log::error!("Unable to place stop loss, Err: {:?}", e);
stop_loss_success = false
false
}
Ok(o) => {
log::info!("Stop loss placed successfully: {:?}", o);
stop_loss_success = true
true
}
};

Expand Down

0 comments on commit b236491

Please sign in to comment.