Skip to content

v5.3.0

Choose a tag to compare

@wboayue wboayue released this 25 Oct 19:24
· 43 commits to main since this release
875e03d

5.3 adds Client::wait_connected for resubscribing after a connection loss, Client::display_groups, and five order parameters that were previously dropped on the wire. No breaking changes.

What's New

Client::wait_connected (#1052, #1061)

Waits out an automatic reconnect. Fails with Error::ConnectionFailed once the reconnect gives up, or Error::Shutdown after a shutdown. A stream loop calls it before resubscribing:

use ibapi::prelude::*;

loop {
    // Waits out a reconnect; Err(ConnectionFailed) once it gives up.
    client.wait_connected().await?;

    let mut bars = client.realtime_bars(&contract).subscribe().await?;
    while let Some(item) = bars.next().await {
        match item {
            Ok(SubscriptionItem::Data(bar)) => println!("{bar:?}"),
            Ok(SubscriptionItem::Notice(notice)) => eprintln!("{notice}"),
            Err(e) if e.is_connection_lost() => break, // resubscribe after the reconnect
            Err(e) => return Err(e.into()),
        }
    }
}

Thanks to @tradatious for the report.

Client::display_groups (#1058)

Returns the ids of the display groups visible in TWS, most used first, so you no longer have to guess the id for subscribe_to_group_events. TWS only; IB Gateway has no display groups.

let groups = client.display_groups().await?;
if let Some(&group_id) = groups.first() {
    let events = client.subscribe_to_group_events(group_id).await?;
    // ...
}

Thanks to @tradatious for the contribution.

Additional order parameters (#1065)

Order::post_only, allow_pre_open, ignore_open_auction (server 216+), and seek_price_improvement and what_if_type (server 217+) are now sent with the order and read back from open-order reports. Previously they were silently dropped. Below the required server version, place_order / submit_order return Error::ServerVersion.

use ibapi::orders::WhatIfType;

// Margin-only what-if check
let state = client
    .order(&contract)
    .buy(100)
    .limit(150.0)
    .what_if_type(WhatIfType::MarginRequirements)
    .analyze()
    .await?;
println!("initial margin after: {:?}", state.initial_margin_after);

// Post-only limit order
let mut order = client.order(&contract).buy(100).limit(150.0).build()?;
order.post_only = true;
client.submit_order(client.next_order_id(), &contract, &order).await?;

what_if_type takes effect only on a what-if order (.analyze()); with .submit() the order is placed live.

Thanks to @tradatious for the contribution.

Changed

Reconnect errors (#1052, #1061)

After the automatic reconnect gives up, requests fail with Error::ConnectionFailed, and after a shutdown with Error::Shutdown. Both used to report Error::ConnectionReset, the error for "still reconnecting", so callers could not tell the states apart. Streams open when the connection dropped still end with ConnectionReset.

Bug Fixes

  • The README / examples/sync/stream_retry.rs retry loop no longer panics on a connection loss; it calls wait_connected before resubscribing (#1061).
  • Historical bars with a missing or unparseable date, and update frames with no bar, fail with Error::Parse instead of producing a bar dated 1970-01-01. Update bars without a trade count have count -1, matching the initial batch. Thanks to @tradatious for the contribution (#1057).
  • Async Client::disconnect called right after connect waits for the message-processing task, as documented. Thanks to @tradatious for the contribution (#1059).

See CHANGELOG.md for the full list.

Thanks to @tradatious for the internal cleanups in this release (#1053–#1056, #1060).