ibapi 5.2.0

An unofficial Rust client for the Interactive Brokers TWS API. Async (Tokio) and blocking clients for TWS and IB Gateway.
Documentation
//! [![github]](https://github.com/wboayue/rust-ibapi) [![crates-io]](https://crates.io/crates/ibapi) [![license]](https://opensource.org/licenses/MIT)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [license]: https://img.shields.io/badge/License-MIT-blue.svg?style=for-the-badge&labelColor=555555
//!
//! <br>
//!
//! A comprehensive Rust implementation of the Interactive Brokers TWS API, providing a robust and
//! user-friendly interface for TWS and IB Gateway. Designed with simplicity in mind, it integrates smoothly into trading systems.
//!
//! **API Documentation:**
//! * [TWS API Reference](https://www.interactivebrokers.com/docs/tws-api/doc/introduction) - Detailed technical documentation
//! * [IBKR Campus](https://ibkrcampus.com/ibkr-api-page/trader-workstation-api/) - IB's official learning platform
//!
//! This fully featured API enables the retrieval of account information, access to real-time and historical market data, order management,
//! market scanning, and access to news and Wall Street Horizons (WSH) event data. Future updates will focus on bug fixes,
//! maintaining parity with the official API, and enhancing usability.
//!
//! # Example
//!
//! Connect to TWS / IB Gateway and place a market order:
//!
#![cfg_attr(
    feature = "async",
    doc = r#"```no_run
use ibapi::prelude::*;

#[tokio::main]
async fn main() {
    let client = Client::connect("127.0.0.1:4002", 100)
        .await
        .expect("connection failed");

    let contract = Contract::stock("AAPL").build();
    let order_id = client
        .order(&contract)
        .buy(100)
        .market()
        .submit()
        .await
        .expect("order submission failed");
    println!("submitted order id: {order_id}");
}
```"#
)]
#![cfg_attr(
    not(feature = "async"),
    doc = r#"```no_run
use ibapi::prelude::*;

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

    let contract = Contract::stock("AAPL").build();
    let order_id = client
        .order(&contract)
        .buy(100)
        .market()
        .submit()
        .expect("order submission failed");
    println!("submitted order id: {order_id}");
}
```"#
)]
//!
//! For broader usage — quick start, examples, migration from v2, full API tour — see the
//! [README](https://github.com/wboayue/rust-ibapi/blob/main/README.md) and the
//! [`docs/`](https://github.com/wboayue/rust-ibapi/tree/main/docs) directory.

#![warn(missing_docs)]
// Allow octal-looking escapes in string literals (used in test data)
#![allow(clippy::octal_escapes)]
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::useless_format)]
#![allow(clippy::uninlined_format_args)]
#![allow(clippy::assertions_on_constants)]

// Feature guards
#[cfg(not(any(feature = "sync", feature = "async")))]
compile_error!(
    "You must enable at least one of the 'sync' or 'async' features to use this crate.\n\
     The 'async' feature is enabled by default; if you disabled default features, be sure to\n\
     opt back into either API:\n\
         ibapi = { version = \"4.0\", default-features = false, features = [\"sync\"] }\n\
         ibapi = { version = \"4.0\", default-features = false, features = [\"async\"] }\n\
     You may also enable both to access the synchronous API under `client::blocking`."
);

// The derives emit bare `utoipa::` paths, so the selected utoipa major is
// aliased to `utoipa` at the crate root. One major at a time: adding
// `utoipa-<N>` takes precedence over older ones, e.g. the alias below becomes
// `#[cfg(all(feature = "utoipa-6", not(feature = "utoipa-7")))]`, and the guard
// `not(any(feature = "utoipa-6", feature = "utoipa-7"))`.
#[cfg(all(feature = "utoipa", not(feature = "utoipa-6")))]
compile_error!("the `utoipa` feature is internal; enable a `utoipa-<major>` feature such as `utoipa-6`");

#[cfg(feature = "utoipa-6")]
extern crate utoipa6 as utoipa;

#[macro_use]
mod macros;

/// Describes items present in an account.
pub mod accounts;

/// TWS API Client.
///
/// The Client establishes the connection to TWS or the Gateway.
/// It manages the routing of messages between TWS and the application.
pub mod client;

pub(crate) mod transport;

/// Connection management
pub(crate) mod connection;

/// Typed handshake-time messages delivered to [`ClientBuilder::startup_callback`].
///
/// When TWS emits unsolicited `OpenOrder`, `OrderStatus`, account-update, or
/// other frames during the handshake, the startup callback receives them as
/// typed [`StartupMessage`] values instead of having them discarded.
///
/// # Example
///
#[cfg_attr(
    feature = "async",
    doc = r#"```no_run
use ibapi::{Client, StartupMessage};
use std::sync::{Arc, Mutex};

#[tokio::main]
async fn main() {
    let order_ids = Arc::new(Mutex::new(Vec::new()));
    let order_ids_clone = order_ids.clone();

    let client = Client::builder()
        .address("127.0.0.1:4002")
        .client_id(100)
        .startup_callback(move |msg| if let StartupMessage::OpenOrder(o) = msg {
            order_ids_clone.lock().unwrap().push(o.order_id);
        })
        .connect()
        .await
        .expect("connection failed");

    println!("Received {} startup open-orders", order_ids.lock().unwrap().len());
    drop(client);
}
```"#
)]
#[cfg_attr(
    not(feature = "async"),
    doc = r#"```no_run
use ibapi::{Client, StartupMessage};
use std::sync::{Arc, Mutex};

fn main() {
    let order_ids = Arc::new(Mutex::new(Vec::new()));
    let order_ids_clone = order_ids.clone();

    let client = Client::builder()
        .address("127.0.0.1:4002")
        .client_id(100)
        .startup_callback(move |msg| if let StartupMessage::OpenOrder(o) = msg {
            order_ids_clone.lock().unwrap().push(o.order_id);
        })
        .connect()
        .expect("connection failed");

    println!("Received {} startup open-orders", order_ids.lock().unwrap().len());
    drop(client);
}
```"#
)]
pub use connection::StartupMessage;

/// Common utilities shared across modules
pub(crate) mod common;

pub use common::timezone::register_timezone_alias;

/// Display groups subscription support
pub mod display_groups;

/// Subscription types for streaming data
pub mod subscriptions;

/// APIs for reading TWS/Gateway configuration (API, precautions, orders, lock-and-exit settings).
pub mod config;
/// A [Contract](crate::contracts::Contract) object represents trading instruments such as a stocks, futures or options.
///
/// Every time a new request that requires a contract (i.e. market data, order placing, etc.) is sent to the API, the system will try to match the provided contract object with a single candidate. If there is more than one contract matching the same description, the API will return an error notifying you there is an ambiguity. In these cases the API needs further information to narrow down the list of contracts matching the provided description to a single element.
pub mod contracts;
// Describes primary data structures used by the model.
pub mod errors;
/// APIs for retrieving market data
pub mod market_data;
pub(crate) mod messages;
/// APIs for retrieving news data including articles, bulletins, and providers
pub mod news;
/// Data types for building and placing orders.
pub mod orders;
/// APIs for working with the market scanner.
pub mod scanner;
/// APIs for working with Wall Street Horizon: Earnings Calendar & Event Data.
pub mod wsh;

/// A prelude module for convenient importing of commonly used types.
pub mod prelude;

/// Protocol version checking and constants for TWS API features.
pub mod protocol;

/// Generated protobuf message types for the TWS API wire protocol.
pub(crate) mod proto;

mod server_versions;

#[doc(inline)]
pub use errors::Error;

#[doc(inline)]
pub use client::Client;
#[doc(inline)]
pub use client::ClientBuilder;

#[doc(inline)]
pub use transport::rate_limiter::RateLimiter;

pub(crate) use messages::{encode_option_field, ToField};

#[doc(inline)]
pub use messages::{ConnectivityStatus, IncomingMessages, Notice, NoticeCategory, OutgoingMessages};

#[doc(inline)]
pub use messages::{
    DATA_ADVISORY_CODES, HANDSHAKE_DECODE_FAILURE_CODE, HANDSHAKE_UNKNOWN_FRAME_CODE, NOTICE_STREAM_LAG_CODE, ORDER_CANCELLED_CODE,
    ORDER_MESSAGE_CODE, ORDER_REJECTION_CODE_RANGE, REQUEST_ERROR_CODES, SUBSCRIPTION_LAG_CODE, SYSTEM_MESSAGE_CODES, TRANSPORT_RECONNECT_CODE,
    UNKNOWN_MESSAGE_TYPE_CODE, WARNING_CODE_RANGE,
};

#[cfg(test)]
pub(crate) mod stubs;

#[cfg(test)]
pub(crate) mod tests;

#[cfg(test)]
#[path = "lib_tests.rs"]
mod lib_tests;

#[cfg(test)]
pub(crate) mod testdata;