wboayue / rust-ibapi

An implementation of the Interactive Brokers API for Rust
MIT License
36 stars 17 forks source link

Order Messages Don't get handled properly #115

Open Stropical opened 2 months ago

Stropical commented 2 months ago

I'm trying to wait for a stop loss it hit, and then use the order message to change the state. Everytime the stop loss hits however ibapi errors and cannot parse the order message coming back. Team's been looking at it for a sec, anyone have any ideas?


 INFO  ibapi::client::transport > timeout receiving message: channel is empty and disconnected
 INFO  ibapi::client::transport > timeout receiving message: channel is empty and disconnected
 INFO  ibapi::client::transport > no recipient found for: ResponseMessage { i: 0, fields: ["4", "2", "134050010", "105", "Order being modified does not match original order.", ""] }
 INFO  ibapi::client::transport > no recipient found for: ResponseMessage { i: 0, fields: ["4", "2", "134050010", "105", "Order being modified does not match original order.", ""] }
 ERROR ibapi::client::transport > could not route message ResponseMessage { i: 0, fields: ["11", "-1", "134050010", "12087792", "EUR", "CASH", "", "0.0", "", "", "IDEALPRO", "USD", "EUR.USD", "EUR.USD", "000132b0.665e3431.01.01", "20240603  20:36:38", "DU9273051", "IDEALPRO", "BOT", "1000000", "1.09097", "1899924411", "104", "0", "1000000", "1.09097", "", "", "", "", "2", ""] }
 ERROR ibapi::client::transport > no recipient found for: "000132b0.665e3431.01.01", ResponseMessage { i: 0, fields: ["59", "1", "000132b0.665e3431.01.01", "21.8194", "USD", "1.7976931348623157E308", "1.7976931348623157E308", "", ""] }```
lukefrugia commented 2 months ago

Every 10-15 seconds after we place an order, there is a message: INFO ibapi::client::transport > timeout receiving message: timed out waiting on receive operation

lukefrugia commented 2 months ago

Here is the code that places the order: ` let notifications = client .place_order(order_id, &contract, &order) .expect("could not place order");

    task::spawn(async move {handle_order_notifications(notifications).await});`

And here is the code that handles the order notifications: async fn handle_order_notifications(notifications: impl Iterator<Item = OrderNotification>) { for notification in notifications { match notification { OrderNotification::ExecutionData(execution) => log_trade(&execution), _ => {}, } } }

We are trying to log the execution data to csv

wboayue commented 2 months ago

@Stropical @lukefrugia this sounds like a case I thought might happen, but not frequently.

This is a trade-off with not having an asynchronous API. When you place the order with place_order we wait a certain amount of time for a response(s) (currently 10 secs).

see: https://github.com/wboayue/rust-ibapi/blob/ee926a16873b592bd0f9747acaa919619b5b6bb9/src/client/transport.rs#L176

If we don't have a timeout the client can potentially wait indefinitely. However, in some cases this may be the desired behavior. For example, if you're waiting for a stop 10 seconds may not be enough. I'm thinking the proper thing here is to allow the specification of a timeout when placing the order.

You can experiment with changing the timeout for place order to see if I'm on the right track.

Stropical commented 2 months ago

On top of the timeout error, what do you think about the no recipient found for: or could not route message errors? We've been getting a lot of these as well in the logs, and seem to be disrupting our local copy of orders.

Here's another example of live logs hitting this error:

NZD, delta 0, curr_pos 1000000 zz_res LONG stock.last_direction LONG curr_orders.is_empty() false
 WARN  ibkr_trader::algo        > Combining bars: 304 -> 10
 INFO  ibkr_trader::algo        > Calculating zigzag for bars: 30
 INFO  ibkr_trader::trade_logic > Zigzag for GBP: LONG
 WARN  ibkr_trader::trade_logic > No bid/ask data for GBP, using midpoint
GBP, delta 0, curr_pos 1000000 zz_res LONG stock.last_direction LONG curr_orders.is_empty() false
 ERROR ibapi::client::transport > no recipient found for: "000132b0.665f8594.01.01", ResponseMessage { i: 0, fields: ["59", "1", "000132b0.665f8594.01.01", "12.3718", "USD", "1.7976931348623157E308", "1.7976931348623157E308", "", ""] }
 ERROR ibapi::client::transport > no recipient found for: "000132b0.665f8596.01.01", ResponseMessage { i: 0, fields: ["59", "1", "000132b0.665f8596.01.01", "13.3178", "USD", "1.7976931348623157E308", "1.7976931348623157E308", "", ""] }
 ERROR ibapi::client::transport > no recipient found for: "000132b0.665f859f.01.01", ResponseMessage { i: 0, fields: ["59", "1", "000132b0.665f859f.01.01", "21.7582", "USD", "1.7976931348623157E308", "1.7976931348623157E308", "", ""] }
 ERROR ibapi::client::transport > could not route message ResponseMessage { i: 0, fields: ["11", "-1", "134948404", "12087797", "GBP", "CASH", "", "0.0", "", "", "IDEALPRO", "USD", "GBP.USD", "GBP.USD", "000132b0.665f85a0.01.01", "20240604  22:22:02", "DU9281270", "IDEALPRO", "SLD", "1000000", "1.27720", "478156735", "104", "0", "1000000", "1.27720", "", "", "", "", "2", ""] }
 ERROR ibapi::client::transport > no recipient found for: "000132b0.665f85a0.01.01", ResponseMessage { i: 0, fields: ["59", "1", "000132b0.665f85a0.01.01", "25.544", "USD", "1.7976931348623157E308", "1.7976931348623157E308", "", ""] }

I'd love to get to a solution to this problem this week, any help is appreciated

lukefrugia commented 2 months ago

Just to add to the last comment, it seems like after several errors the client hangs or stops receiving messages all together. Is there a message buffer that fills if messages aren't routed?