trading-ig
🤖 About this crate
This crate was generated by Claude Opus (Anthropic), working from the Python library
ig-python/trading-igas the reference specification. The Rust API mirrors the Python one endpoint-for- endpoint. Huge thanks to the originaltrading-igauthors and contributors — without their work (and their BSD-3 license) this port wouldn't exist.
Async Rust client for the IG Markets REST and Lightstreamer streaming APIs.
- Crate: https://crates.io/crates/trading-ig
- Docs: https://docs.rs/trading-ig
- Repository: https://github.com/tibs245/trading-ig-rust
- Changelog:
CHANGELOG.md
Install
[]
= "0.1"
# Optional features:
# trading-ig = { version = "0.1", features = ["stream", "polars"] }
Goals
- Async-first (
tokio),reqwestunder the hood. - Strongly typed: all requests/responses modelled with
serde. - Composable: usable as a library independently of any framework.
- Minimal dependencies.
- Structured logs/tracing via the
tracingcrate. - Well-tested: HTTP responses are covered by mock-server tests built from reusable fixtures.
Quick start
use ;
async
Examples
Three self-contained examples live in examples/:
| Example | What it shows |
|---|---|
login_and_list_accounts |
Log in (v3) and print all account IDs |
search_market_and_get_history |
Search for EUR/USD, fetch the last hour of minute bars |
open_then_close_position |
Type-state builder syntax for opening and closing a position |
All examples read credentials from IG_API_KEY, IG_USERNAME, and IG_PASSWORD:
IG_API_KEY=xxx IG_USERNAME=you IG_PASSWORD=secret \
🔒 Recommended for funded accounts
For any account that holds real money (live, or funded demo), we
recommend enabling the encryption feature and using
session().login_with_encryption() instead of session().login().
The password is then RSA-encrypted client-side with IG's public key
before transmission — it never appears in plaintext in any
intermediate proxy or server-side log, even in the event of a
TLS MITM or compromised CA.
[]
= { = "0.1", = ["encryption"] }
client.session.login_with_encryption.await?;
// instead of:
// client.session().login().await?;
See SECURITY.md for the full rationale and our
disclosure policy.
Cargo features
| feature | default | description |
|---|---|---|
rustls-tls |
yes | TLS via rustls |
native-tls |
no | TLS via system OpenSSL |
stream |
no | Lightstreamer streaming client |
encryption |
no | Encrypted-password login (RSA) |
polars |
no | Conversions from tabular API responses to DataFrame |
live |
no | Compile the live integration test suite (read-only path) |
live-trading |
no | Also compile write/mutation live tests (implies live) |
polars feature
Enable the polars feature to convert tabular API responses directly into
Polars DataFrames for analysis:
[]
= { = "0.1", = ["polars"] }
use IntoDataFrame;
// Convert a list of open positions into a DataFrame.
let positions = client.dealing.positions.list_v2.await?;
let df = positions.to_dataframe?;
println!;
// Convert historical prices into a DataFrame (one row per bar).
let prices = client.prices.history_v3.await?;
let df = prices.to_dataframe?;
println!;
The IntoDataFrame trait is implemented on Vec<Account>,
Vec<PositionV2>, Vec<WorkingOrderV2>, HistoricalPrices,
Vec<Activity>, Vec<Transaction>, Vec<MarketSummary>, and
Vec<Sentiment>.
Live integration tests
A separate test file (tests/live_integration.rs) exercises the real IG Demo
API end-to-end. All tests are #[ignore]d and require explicit credentials,
so they never run in CI.
Read-only tests (session, accounts, markets, prices, positions, watchlists, client sentiment, history):
IG_API_KEY=your-key IG_USERNAME=you IG_PASSWORD=secret \
Write / mutation tests (watchlist create/delete, preferences round-trip)
additionally require the live-trading feature and IG_LIVE_TRADING_OK=1:
IG_API_KEY=your-key IG_USERNAME=you IG_PASSWORD=secret IG_LIVE_TRADING_OK=1 \
If IG_API_KEY is absent the whole suite skips gracefully, so
cargo test --all-features in CI passes without hitting the network.
Contributing
After cloning, opt into the project's git hooks:
This enables:
- pre-commit — runs
cargo fmt --checkandcargo clippy --all-targets --all-features --no-deps -- -D warningson commits that touch Rust or Cargo files. Skipped for doc-only / fixture-only commits. - pre-push — runs
cargo test --all-targets --all-featuresbefore pushing to a remote.
Skip a check if you really need to: git commit --no-verify /
git push --no-verify. The CI workflow runs the same checks regardless,
so anything you bypass locally will fail in PR.
Project knowledge
Internal conventions, architecture decisions, and the IG API spec live
under _knowledge/. Start with
_knowledge/index.md — it lists every file with
a one-line summary so you can load only what you need.
License
BSD-3-Clause, mirroring the original trading-ig
Python project.