Skip to content

Fix Interactive Brokers v2 crypto market data (support PAXOS and ZeroHash)#4389

Draft
bebop23 wants to merge 1 commit into
nautechsystems:developfrom
bebop23:bebop23/fix-issue-3
Draft

Fix Interactive Brokers v2 crypto market data (support PAXOS and ZeroHash)#4389
bebop23 wants to merge 1 commit into
nautechsystems:developfrom
bebop23:bebop23/fix-issue-3

Conversation

@bebop23

@bebop23 bebop23 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Pull Request

  • I have reviewed the CONTRIBUTING.md and followed the established practices

Summary

Makes the v2 Interactive Brokers adapter work with both of IBKR's crypto
venues — PAXOS and ZeroHash (which one applies depends on the account/region,
see IBKR's crypto trading-permissions docs). The adapter previously hardcoded
PAXOS, so ZeroHash-routed instruments like BTC/USD.ZEROHASH failed contract
resolution, and several stacked defects broke crypto market data. This PR
derives the crypto venue from the contract's exchange (falling back to PAXOS),
registers the client for default multi-venue routing, honors the bar's price
type on real-time bars, and maps crypto trade-price bars to AGGTRADES (TWS
rejects TRADES for crypto with error 10299 on both venues). PAXOS continues
to work unchanged.

Related Issues/PRs

Expected CI note — cargo-deny fails by design (temporary). The
[sources] policy in deny.toml is crates.io-only (unknown-git = "deny"),
so the interim git-fork ibapi patch trips the cargo-deny sources check.
This is not fixable while pointing at a fork; it clears automatically once
wboayue/rust-ibapi#693 ships in a crates.io release and this PR swaps the patch
for a plain ibapi version bump. All other checks (fmt, conventions, build,
tests) are green.

Type of change

  • Bug fix (non-breaking)

Breaking change details (if applicable)

None. Both PAXOS and ZeroHash are supported concurrently — PAXOS is retained as
the fallback and in VENUES_CRYPTO, so existing PAXOS routing is unchanged.
venue() now returns None (default routing), matching the other multi-venue
adapters (Tardis, Databento).

Documentation

  • Documentation changes follow the style guide (docs/developer_guide/docs.md)

Release notes

  • I added a concise entry to RELEASES.md that follows the existing conventions (when applicable)

Testing

Ensure new or changed logic is covered by tests.

  • I added/updated tests to cover new or changed logic

Rust unit tests added in parse.rs (ZeroHash and PAXOS symbol parse +
contract→instrument venue derivation, explicit and fallback), convert.rs
(crypto→AGGTRADES on historical and realtime paths, non-crypto unaffected,
wire-string check), and core.rs (venue() is None for default routing);
the standalone HistoricalInteractiveBrokersClient bar path now applies the
same crypto AGGTRADES rule. Live-verified against an IB paper gateway
(2026-07-05): BTC/USD.ZEROHASH 5-second bars flow post-fix (3/3 bars in ~19s),
cross-checked against a direct TWS-API reqRealTimeBars
(secType=CRYPTO, exchange=ZEROHASH, whatToShow=AGGTRADES).

@bebop23 bebop23 force-pushed the bebop23/fix-issue-3 branch 3 times, most recently from 28127b9 to b3b5c62 Compare July 5, 2026 09:31
@bebop23 bebop23 changed the title Fix Interactive Brokers v2 crypto market data (PAXOS→ZeroHash migration) Fix Interactive Brokers v2 crypto market data (support PAXOS and ZeroHash) Jul 5, 2026
…Hash)

IBKR routes retail crypto to both PAXOS and ZeroHash (which venue applies
depends on the account/region). The v2 IB adapter hardcoded PAXOS, so
ZeroHash-routed instruments like BTC/USD.ZEROHASH were unusable, and several
stacked defects broke crypto market data:

- Crypto venue was hardcoded to PAXOS, so BTC/USD.ZEROHASH failed contract
  resolution ([200] No security definition). Derive the venue from the
  contract's exchange (ZEROHASH or PAXOS), fall back to PAXOS when unspecified,
  and accept both in VENUES_CRYPTO. PAXOS continues to work unchanged.
- The data client registered for a single venue, so venue-routed subscriptions
  (e.g. BTC/USD.ZEROHASH) were silently dropped by the data engine. Return None
  from venue() for default multi-venue routing, matching Tardis/Databento.
- Real-time (5s) bars hardcoded whatToShow=TRADES, ignoring the bar's price
  type. Honor the requested price type.
- TWS rejects whatToShow=TRADES for crypto with error 10299 on both
  reqHistoricalData and reqRealTimeBars (for PAXOS and ZeroHash alike); the
  venue serves trade-price data only under AGGTRADES. Map crypto trade-price
  bars to AGGTRADES on the realtime path, the live-client historical path, and
  the standalone HistoricalInteractiveBrokersClient path.

AGGTRADES requires a WhatToShow::AggTrades variant that stock ibapi 3.0.1 lacks;
this is added via a temporary [patch.crates-io] ibapi (submitted upstream to
wboayue/rust-ibapi), to be replaced by a version bump once released.

Adds Rust unit tests for both PAXOS and ZeroHash venue derivation (explicit and
fallback), the crypto AGGTRADES mapping on all bar paths, and default routing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cjdsellers

Copy link
Copy Markdown
Member

Hi @bebop23,

Thanks for the detailed write-up, especially the note about the temporary ibapi git patch and the expected cargo-deny failure.

One process note: this PR has triggered several project CI runs while the branch was still changing, including builds that were canceled by later pushes. Please avoid using the project CI as the main feedback loop. For future PRs, please run the relevant checks locally first and open the PR once the branch is in its final shape and ready for review. If there is a known external blocker, it is fine to call that out clearly, but please avoid pushing intermediate WIP states that burn CI compute.

Let me know if anything is unclear.

@cjdsellers

Copy link
Copy Markdown
Member

Hi @bebop23,

Regarding the upstream rust-ibapi PR for AggTrades. I checked the current crates.io release (ibapi 3.1.0) and it still does not expose WhatToShow::AggTrades, so we cannot clear the audit failure by taking the temporary git patch or bumping to the latest published crate.

This PR will need to wait until wboayue/rust-ibapi#693 lands in an upstream crates.io release. Once that is available, please remove the [patch.crates-io] git dependency, bump ibapi to the released version, update the lockfiles, and rerun make security-audit locally before moving this out of draft.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants