Independent Rust data-source bridge for exchange, options, prediction-market, DeFi, macro, aggregate, and sentiment data. MarketBridge normalizes public data, caches fresh state, marks stale records, and exposes one stable API surface for downstream research systems.
Current version: v0.0.5
- Why This Project
- Tool Positioning
- Architecture Contract
- Tech Stack
- Architecture
- Runtime Pipeline
- Quick Start
- Use Downloaded Binaries
- Configuration
- Implemented Data Plane
- Data Sources and API Keys
- Strategy Readiness Matrix
- API Overview
- API Details
- Connection Model Matrix
- Bring-Up Guide
- Testing
- Extend New Exchange
MarketBridge solves three hard problems for quant research teams:
- Unified market model across multiple exchanges and both
spot/perp - Unified API layer (
REST + WebSocket + Redis) for downstream strategy systems - Data quality visibility (funding coverage, stale ratio, latency percentiles, health status, alerts)
MarketBridge is a data-plane tool, not a trading bot.
It owns:
- public market-data collection from CEX, DeFi, options, Polymarket, macro, aggregate, and sentiment sources
- normalization into source-agnostic REST/WebSocket APIs
- latest-state caches, freshness flags, source health, and optional Redis Stream persistence
- operational spread signals used as data sanity checks
It does not own:
- factor approval or alpha research decisions
- paper/live PnL attribution
- wallet signing or authenticated order placement
- Polymarket order submit/cancel/replace
Downstream systems such as PolyAlpha should call MarketBridge for data, then
run strategy logic, factor validation, paper execution, and live execution in
their own layer.
MarketBridge is being standardized around a source-agnostic data envelope:
connector source -> domain payload -> DataEnvelope -> cache/stream/API
The long-term architecture and /v1 API contract are maintained in
docs/architecture.md. Current endpoints remain supported
while existing exchange, Deribit, and Polymarket data is migrated into the new
domain model.
The consumer-facing endpoint map is maintained in docs/data_interfaces.md.
The full documentation index is maintained in docs/README.md.
The large copy-paste query cookbook is maintained in docs/query_examples.md.
The current performance review and next optimization roadmap are maintained in docs/performance_review.md.
The external source expansion inventory is tracked in docs/source_expansion_inventory.md. It uses third-party projects only as reference lists; MarketBridge does not call, embed, bridge, or depend on them at runtime. Use docs/feature_inventory.md for runtime coverage.
- Language:
Rust 2024 - Runtime:
Tokio - HTTP/WS API:
Axum - WS clients:
tokio-tungstenite - Serialization:
serde,serde_json,serde_yaml - Metrics:
prometheus - Stream sink:
redis(XADD) - Logging:
tracing,tracing-subscriber
flowchart LR
subgraph C[Public Data Connectors]
CEX[CEX Spot/Perp\nBBO/L2/Trades/Funding/OI/Liquidations]
OPT[Options REST\nDeribit/OKX/Bybit/Binance]
PM[Polymarket\nGamma + CLOB REST/WS]
DEFI[DeFi Quotes/Pools\nJupiter/Raydium/Uniswap/ParaSwap/1inch]
EXT[Macro/Aggregates/Sentiment\nDXY/VIX/US10Y/CoinGlass/News/Social]
ON[On-chain Transfers\nWhale Alert/mempool.space/Etherscan]
end
C --> RT[SourceRuntime\nReconnect + Backpressure]
RT --> Q[mpsc Queue]
Q --> R[EventRouter]
R --> BUS[EventBus\nDashMap Snapshots + Sharded Domain Broadcast]
R --> AGG[SpreadAggregator\nBBO + L2 Signals]
BUS --> OF[OrderFlow Store\nTrade Windows + CVD]
BUS --> K[SQLite Klines\nREST Backfill + Live Buckets]
AGG --> LOG[Signal Logs\nFILTERED/HOLDING/TRIGGER]
BUS --> API[Axum API\n/v1 REST + /v1/stream]
BUS --> REDIS[Optional Redis Sink\nbatched XADD + JSONL Dead Letters]
CFG[config.yaml\nsrc/config/*] --> RT
CFG --> AGG
CFG --> K
CFG --> OF
MET[Prometheus Metrics] --> API
- Public connectors collect CEX, options, prediction-market, DeFi, macro, sentiment, aggregate, and on-chain data.
SourceRuntimesupervises source tasks and reconnects with backoff.EventRouterfans data to bothEventBusandSpreadAggregator.EventBusmaintains DashMap latest snapshots and per-domain broadcast streams.OrderFlowStoreandKlineStorederive reusable market features from live trade/quote events.SpreadAggregatorcomputes cross-exchange opportunity signals with fee/slippage logic.- API/WebSocket/optional Redis expose normalized data to quant consumers.
The layers deliberately separate responsibilities:
| Layer | Owns | Does not own |
|---|---|---|
| Connector | Venue protocol, REST polling, websocket subscriptions, symbol conversion, parser tests | Cross-source strategy rules |
| Domain | Normalized DataEnvelope, cache keys, freshness, stale flags, query filters |
Venue-specific retry logic |
| Runtime | Source supervision, reconnect backoff, backpressure, broadcast fanout | Data interpretation |
| Derived stores | Basis, order flow, klines, health summaries | Alpha approval or execution |
| API | Stable REST/WebSocket/Redis delivery | Wallet signing or order routing |
MarketBridge does not downsample websocket feeds before cache/stream delivery. WebSocket sources are processed as venue messages arrive. Polling sources use configurable or connector-level intervals so rate-limited public APIs are not abused.
| Data family | Default behavior |
|---|---|
| Core CEX websocket quotes/trades/books | Event-driven, source-push speed |
| Binance depth | depth20@100ms stream |
| Binance mark/funding | markPrice@1s stream |
| REST-only CEX adapters | Usually 5 second polling |
| Options chains | refresh_secs, default 10 seconds |
| Polymarket CLOB books | REST seed plus websocket patch stream |
| Polymarket Gamma market discovery | refresh_secs, default 300 seconds |
| DeFi quote/pool sources | poll_secs, default 10 seconds |
| On-chain transfer sources | poll_secs, default 60 seconds |
| Macro/sentiment/aggregate sources | Source-specific poll_secs, usually 60 seconds or slower |
| Spread report logs | runtime.report_interval_ms, default 1000 ms, minimum 100 ms |
/v1/stream snapshot domains |
snapshot_interval_ms, default 1000 ms, minimum 250 ms |
If the goal is maximum raw ingestion, prefer websocket-capable CEX sources,
raise runtime.queue_capacity, keep runtime.backpressure: drop_newest for
low latency, and only lower REST polling intervals after checking venue rate
limits.
Requirements:
- Rust stable toolchain
- Linux, macOS, or Windows
- Optional: Redis if
runtime.redis_urlis configured
cargo build --releaseThe binary is created at:
target/release/market-bridge
On Windows:
target\release\market-bridge.exe
MARKETBRIDGE_CONFIG=./config.yaml cargo runUse full-exchange sample:
MARKETBRIDGE_CONFIG=./config.all-exchanges.example.yaml cargo runOr run the built binary directly:
MARKETBRIDGE_CONFIG=./config.yaml ./target/release/market-bridgecurl -s http://127.0.0.1:8080/health
curl -s http://127.0.0.1:8080/v1/system/info | jqcurl -s "http://127.0.0.1:8080/v1/catalog/sources" | jq
curl -s "http://127.0.0.1:8080/snapshot?symbol=BTCUSDT" | jq
curl -s "http://127.0.0.1:8080/funding?symbols=BTCUSDT" | jq
curl -s "http://127.0.0.1:8080/coverage?market=perp&symbols=BTCUSDT" | jqnpx wscat -c "ws://127.0.0.1:8080/v1/stream?domains=market_quote,trade,order_book&symbols=BTCUSDT&product_type=perp&snapshot_interval_ms=250"Keep MarketBridge running, then fetch a long-table context file from PolyAlpha:
cd /path/to/PolyAlpha
PYTHONPATH=profiler .venv/bin/python profiler/profile_wallets.py fetch-marketbridge-context \
--base-url http://127.0.0.1:8080 \
--symbol BTCUSDT \
--symbol ETHUSDT \
--exchange binance \
--exchange okx \
--market perp \
--include-snapshots \
--out data/profiler/marketbridge_context.csvDownload the latest published version from GitHub Releases. The full release history is available at https://github.com/tianrking/MarketBridge/releases.
GitHub Actions builds release packages for:
| Package suffix | Download file | Use when |
|---|---|---|
linux-x86_64 |
market-bridge-v0.0.5-linux-x86_64.tar.gz |
Normal 64-bit Intel/AMD Linux server or desktop. |
linux-i686 |
market-bridge-v0.0.5-linux-i686.tar.gz |
32-bit x86 Linux environments only. Most users should not pick this. |
macos-x86_64 |
market-bridge-v0.0.5-macos-x86_64.tar.gz |
Intel Mac. |
macos-aarch64 |
market-bridge-v0.0.5-macos-aarch64.tar.gz |
Apple Silicon Mac, M1/M2/M3/M4. |
windows-x86_64 |
market-bridge-v0.0.5-windows-x86_64.zip |
64-bit Windows. |
Each package contains:
market-bridgeormarket-bridge.exeREADME.mdconfig.yamlconfig.min.yamlconfig.all-exchanges.example.yamldocs/VERSION
Linux/macOS usage:
tar -xzf market-bridge-v0.0.5-linux-x86_64.tar.gz # replace suffix for your platform
cd market-bridge-v0.0.5-linux-x86_64
chmod +x ./market-bridge
MARKETBRIDGE_CONFIG=./config.yaml ./market-bridgemacOS may require allowing the downloaded binary:
xattr -d com.apple.quarantine ./market-bridge 2>/dev/null || trueWindows PowerShell:
Expand-Archive .\market-bridge-v0.0.5-windows-x86_64.zip
cd .\market-bridge-v0.0.5-windows-x86_64\market-bridge-v0.0.5-windows-x86_64
$env:MARKETBRIDGE_CONFIG = ".\config.yaml"
.\market-bridge.exeAfter startup, open another terminal and check:
curl -s http://127.0.0.1:8080/health
curl -s "http://127.0.0.1:8080/v1/catalog/sources" | jq
curl -s "http://127.0.0.1:8080/v1/market/quotes?symbols=BTCUSDT" | jqFor common perpetual-contract and funding-rate searches after the binary is
running, see
docs/perpetual_funding_cookbook.md.
The binary only needs to stay running; client scripts and curl examples call
the local HTTP API.
If you use keyed sources, set the relevant environment variables before starting the binary:
export COINGLASS_API_KEY="..."
export COINMARKETCAP_API_KEY="..."
export FRED_API_KEY="..."
export CRYPTOPANIC_API_KEY="..."
export SANTIMENT_API_KEY="..."
export LUNARCRUSH_API_KEY="..."GET /v1/catalog/sources reports runtime status:
enabled: source is enabled and has required key material if neededavailable: connector exists but is disabled in configenabled_missing_api_key: source is enabled but required API key is absent
The release binary reads the same configuration schema as cargo run.
Choose one of the included configs:
config.min.yaml: smallest smoke-test config.config.yaml: default practical config for local research.config.all-exchanges.example.yaml: broad connector example; edit before running if you do not want every public source enabled.
Synthetic local load test:
./market-bridge load-test --events 100000 --subscribers 8 --broadcast-capacity 65536 --event-bus-shards 1The load test does not connect to exchanges. It publishes synthetic normalized
events through the same EventBus/serialization path and prints JSON metrics
for publish throughput, subscriber deliveries, and lagged broadcast events.
Raise --event-bus-shards when measuring the sharded event/domain broadcast
path.
Default file: config.yaml
runtime.queue_capacity: source->router channel capacityruntime.router_publish_queue_capacity: router->bus worker channel capacity;0or omitted reusesqueue_capacityruntime.broadcast_capacity: per-domain websocket/redis broadcast bufferruntime.event_bus_shards: event/domain broadcast shard count; keep1for local research and raise after load testing broad multi-symbol deploymentsruntime.backpressure:blockordrop_newestruntime.report_interval_ms: signal report intervalruntime.stale_ttl_ms: stale thresholdruntime.api_addr: API bind addressruntime.api_key_env: optional environment variable used for API auth; default isMARKETBRIDGE_API_KEYruntime.api_key: optional direct API key value; prefer env for shared deploymentsruntime.api_rate_limit_per_minute: optional in-process per-client limiter;0disables itruntime.cors: browser UI integration for hosted static frontends that call a local MarketBridge service. Defaults allowlocalhost,127.0.0.1,https://*.pages.dev, andhttps://*.vercel.app, with Private Network Access preflight support enabled.runtime.redis_url: optional Redis sinkruntime.redis_stream_prefix: Redis Stream prefix when Redis is enabledruntime.redis_dead_letter_path: JSONL dead-letter path for Redis batches that still fail after retriesruntime.order_flow_large_trade_notional_usdt: large-trade threshold for/v1/market/order-flowruntime.ws_send_timeout_ms: websocket send timeout before disconnecting slow clientsstrategy.*: min profit, hold, slippage model, andfee_mode(taker,maker,maker_buy_taker_sell,taker_buy_maker_sell)strategy.book_signal_notional_usdt: L2 book notional used by book-level spread signalsstrategy.fallback_maker_fee_bps/strategy.fallback_taker_fee_bps: conservative fee assumptions for sources without explicit exchange fee configsymbols: global spot symbolsperp_symbols: global perp symbolsexchanges.<name>.enabled: source switchexchanges.<name>.symbols/perp_symbols: per-exchange overrideexchanges.<name>.fee: fixed/tiered fee modeldefi.<source>.enabled: DeFi quote/pool source switchdefi.<source>.pairs/defi.uniswap_v3.pools: configured DEX pairs and poolstradfi.<source>.enabled: DXY, VIX, and US10Y reference source switchtradfi.us10y.api_keyorFRED_API_KEY: FRED API credential for US10Yaggregates.<source>.enabled: CoinGecko, CoinMarketCap, and CoinGlass source switchsentiment.<source>.enabled: Fear & Greed, CryptoPanic, Santiment, and LunarCrush source switch*_API_KEYenv vars: optional or required keys for paid/free external APIs
This service is the unified data plane for downstream strategy engines such as
PolyAlpha. Strategy logic, factor validation, paper execution, and live order
management should stay outside this repo.
The complete source-by-source inventory, API-key requirements, and usage examples are maintained in docs/data_sources.md. The tables below are a shorter runtime summary.
| Data family | What you get | Primary interface | Stream support | Default freshness model | Key required |
|---|---|---|---|---|---|
| Spot quotes | bid/ask/mid, source, symbol, stale flag | GET /v1/market/quotes?product_type=spot |
WS /v1/stream?domains=market_quote |
websocket push where available; REST adapters usually 5s | No |
| Perp quotes | bid/ask/mid, mark/index when venue sends it | GET /v1/market/quotes?product_type=perp |
WS /v1/stream?domains=market_quote |
websocket push where available | No |
| L2 order books | normalized bid/ask levels, best bid/ask, depth metadata | GET /v1/market/order-books |
WS /v1/stream?domains=order_book |
source push where available; Binance depth is 100ms |
No |
| Public trades | price, size, side, trade id, source timestamp | GET /v1/market/trades |
WS /v1/stream?domains=trade |
source push where available | No |
| Funding rates | funding rate, next funding time, mark/index if present | GET /v1/market/funding |
WS /v1/stream?domains=funding |
source push or venue poller | No |
| Perp market discovery | latest public perpetual contract lists by exchange | GET /v1/catalog/perpetuals, GET /v1/catalog/markets |
No direct stream | on-demand public REST | No |
| On-demand perp funding | all supported current perp funding rows, not limited to configured symbols | GET /v1/market/perpetual-funding |
No direct stream | on-demand public REST | No |
| Open interest | OI quantity/notional where venue exposes it | GET /v1/market/open-interest |
WS /v1/stream?domains=open_interest |
source push or venue poller | No |
| Liquidations | public liquidation events | GET /v1/market/liquidations |
WS /v1/stream?domains=liquidation |
source push where stable public feed exists | No |
| Klines | SQLite OHLCV from REST backfill and live ticks | GET /v1/market/klines |
No direct stream | configured intervals, default 1m/5m/15m/1h |
No |
| Basis | spot-perp basis and basis bps | GET /v1/market/basis |
No direct stream | derived from latest quote cache | No |
| Order flow | buy/sell pressure, delta, CVD, large-trade count | GET /v1/market/order-flow |
No direct stream | derived from live trade events | No |
| Options chains | strikes, expiries, bid/ask/mark, IV-style fields, OI where present | GET /v1/options/chains |
WS /v1/stream?domains=options_chain snapshots |
REST cache, default 10s refresh | No |
| Polymarket books | YES/NO CLOB books, spreads, midpoints, executable prices | GET /v1/prediction/books, /polymarket/* |
WS /v1/stream?domains=prediction_book snapshots |
REST seed plus CLOB websocket patch | No |
| DeFi prices/quotes | Jupiter/Raydium/Uniswap/ParaSwap/1inch/DexScreener quote or pool price | GET /v1/market/quotes?exchanges=... |
market_quote when enabled |
poll_secs, default 10s |
Usually no; depends on configured gateway |
| TradFi references | DXY, VIX, US10Y | GET /v1/market/quotes?exchanges=dxy,vix,us10y |
market_quote when enabled |
poll_secs, usually 60s+ |
US10Y needs FRED key |
| Aggregate crypto signals | CoinGecko/CoinCap/CMC prices, CoinGlass derivatives metrics | GET /v1/external/signals, quote surface for price sources |
external_signal |
poll_secs, usually 60s+ |
Some sources require keys |
| Sentiment/news | Fear & Greed, CryptoPanic, Santiment, LunarCrush | GET /v1/external/signals?sources=... |
external_signal |
poll_secs, source-specific |
Most except Fear & Greed need keys |
| On-chain transfers | Whale Alert, mempool.space BTC, Etherscan watched-address transfers | GET /v1/onchain/transfers |
No direct stream | poll_secs, default 60s |
Whale Alert/Etherscan need keys |
| Catalog and health | enabled sources, API-key status, domains, instruments, freshness | /v1/catalog/*, /coverage, /metrics |
No | updated from runtime caches/metrics | No |
| Redis sink | normalized event stream export | runtime.redis_url |
Redis Streams | batched XADD with JSONL dead letters | Redis required |
Use docs/data_sources.md as the authoritative data-source operator guide. It lists every source family, whether it is keyless/keyed, which environment variable to set, and which REST/WebSocket surface to call.
Most CEX/perp, options, Polymarket, DeFi quote, DXY, VIX, and mempool.space sources are keyless. The sources below need or may benefit from keys:
| Source | Requirement | Env var |
|---|---|---|
| Architect | Required bearer token | ARCHITECT_API_TOKEN |
| Decibel | Required bearer token | DECIBEL_API_TOKEN |
| CoinGecko | Optional key | COINGECKO_API_KEY |
| CoinCap | Optional key | COINCAP_API_KEY |
| CoinMarketCap | Required key | COINMARKETCAP_API_KEY |
| CoinGlass | Required key | COINGLASS_API_KEY |
| FRED US10Y | Required key | FRED_API_KEY |
| CryptoPanic | Required key | CRYPTOPANIC_API_KEY |
| Santiment | Required key | SANTIMENT_API_KEY |
| LunarCrush | Required key | LUNARCRUSH_API_KEY |
| Whale Alert | Required key | WHALE_ALERT_API_KEY |
| Etherscan | Required key | ETHERSCAN_API_KEY |
Check active config and missing credentials at runtime:
curl -s "http://127.0.0.1:8080/v1/catalog/sources" | jqenabled_missing_api_key means the connector is configured on, but the required
credential is absent.
| Capability | Status | Interface | Notes |
|---|---|---|---|
| Spot and perp BBO | Implemented | GET /v1/market/quotes, GET /snapshot, WS /v1/stream, WS /ws/ticks |
Normalized bid, ask, symbol, exchange, and product type. |
| L2 order books | Implemented where public venue data exists | GET /v1/market/order-books, WS /v1/stream?domains=order_book |
Latest normalized depth snapshots with venue/source metadata. |
| Public trades | Implemented where public venue data exists | GET /v1/market/trades, WS /v1/stream?domains=trade |
Latest trade cache per venue/symbol plus rolling order-flow metrics. |
| Perp funding | Implemented where venue provides it | GET /v1/market/funding, GET /v1/market/perpetual-funding, GET /funding, WS /v1/stream?domains=funding |
Live-cache funding endpoints are fastest for configured symbols; on-demand perpetual funding covers supported public REST venues broadly. |
| Open interest | Implemented where venue provides it | GET /v1/market/open-interest, WS /v1/stream?domains=open_interest |
Native public perp metadata/ticker feeds. |
| Liquidations | Implemented where venue exposes a stable public feed | GET /v1/market/liquidations, WS /v1/stream?domains=liquidation |
Empty when a venue has no reliable public all-market signal. |
| Multi-exchange quality | Implemented | GET /coverage |
Stale ratio, latency percentiles, funding coverage, alerts. |
| Redis stream sink | Implemented optional | runtime.redis_url |
Emits normalized ticks and domain events to Redis streams when configured. |
| Capability | Status | Interface | Notes |
|---|---|---|---|
| Deribit option summaries | Implemented | GET /options/deribit/summary?currency=BTC |
Direct REST fetch. Returns strike, expiry, bid/ask, mark price, mark_iv, underlying price. |
| Unified option chain cache | Implemented | GET /v1/options/chains?venue=deribit¤cy=BTC |
Background REST cache for Deribit, OKX, Bybit, and Binance option chains with received_at_ms and stale. |
| Deribit option depth | Implemented | GET /options/deribit/book?instrument_name=BTC-29MAY26-70000-P&depth=10 |
Per-instrument book, mark fields, OI, and greeks when Deribit returns them. |
| OKX option summaries | Implemented | GET /v1/options/chains?venue=okx¤cy=BTC |
Public opt-summary; includes strike, expiry, IV-style fields and Black-Scholes greeks when venue returns them. |
| OKX option depth | Implemented | GET /options/okx/book?instrument_name=BTC-USD-260626-100000-C&depth=10 |
Public per-instrument option book. |
| Bybit option tickers | Implemented | GET /v1/options/chains?venue=bybit¤cy=BTC |
Public option tickers; includes bid/ask, mark, mark IV, underlying price, open interest, and greeks. |
| Bybit option depth | Implemented | GET /options/bybit/book?instrument_name=BTC-26MAR27-78000-P-USDT&depth=10 |
Public per-instrument option book. |
| Binance option tickers | Implemented | GET /v1/options/chains?venue=binance¤cy=BTC |
Public European option ticker plus optional mark data; WS ticker/mark streams refresh the cache when enabled. Open interest is not in this public ticker payload. |
| Binance option depth | Implemented | GET /options/binance/book?instrument_name=BTC-260626-140000-C&depth=10 |
Public per-instrument option book; requested depth is mapped to Binance's allowed depth buckets. |
| Options websocket cache updates | Implemented | N/A | Deribit, OKX, Bybit, and Binance public WS ticker/summary updates refresh the option cache; REST chain/depth coverage remains the source for per-instrument depth. Native WS option book/trade streams are tracked as latency extensions in docs/feature_inventory.md. |
| Capability | Status | Interface | Notes |
|---|---|---|---|
| Active BTC/ETH binary market discovery | Implemented first version | GET /polymarket/crypto-markets |
Parses base_asset, strike, direction, rule type, expiry, Yes/No token ids from Gamma. |
| Single outcome CLOB book | Implemented | GET /polymarket/book?token_id=... |
Returns full book plus best bid/ask, spread, bid/ask depth. |
| Batch outcome CLOB books | Implemented | GET /polymarket/books?token_ids=... |
Useful for Yes/No pair checks. |
| Crypto markets plus books | Implemented | GET /polymarket/crypto-books |
Convenience endpoint for strategy engines. |
| Polymarket CLOB websocket cache | Implemented first version | GET /polymarket/live-books, GET /polymarket/live-crypto-books |
Seeds from REST snapshots, subscribes public CLOB websocket updates, and exposes stale for strategy-side freshness gates. |
| Polymarket official SDK/CLI integration | Not implemented | N/A | Current implementation uses public REST endpoints. SDK/CLI integration is future work for authenticated execution and schema safety. |
| Live order placement / cancel / replace | Not implemented | N/A | Execution belongs in a later trading/execution layer, not in this data-plane pass. |
| Capability | Status | Interface | Notes |
|---|---|---|---|
| Jupiter quotes | Implemented | GET /v1/market/quotes?exchanges=jupiter |
Polls public Jupiter quote REST and emits normalized market_quote ticks. |
| Raydium prices | Implemented | GET /v1/market/quotes?exchanges=raydium |
Polls Raydium public price map and computes configured pair ratios. |
| Uniswap V3 pool prices | Implemented | GET /v1/market/quotes?exchanges=uniswap_v3 |
Polls configured V3 pools from a GraphQL subgraph. This is pool price, not routed execution. |
| ParaSwap quotes | Implemented | GET /v1/market/quotes?exchanges=paraswap |
Polls public /prices route and emits executable quote-derived prices. |
| 1inch quotes | Implemented configurable | GET /v1/market/quotes?exchanges=oneinch |
Uses configurable legacy public base URL; newer 1inch gateways may require replacing base_url. |
| Capability | Status | Interface | Notes |
|---|---|---|---|
| DXY | Implemented | GET /v1/market/quotes?exchanges=dxy |
Yahoo Finance chart API, normalized as symbol=DXY. Useful as USD strength proxy. |
| VIX | Implemented | GET /v1/market/quotes?exchanges=vix |
Yahoo Finance chart API, normalized as symbol=VIX. Useful as risk/fear proxy. |
| US10Y | Implemented | GET /v1/market/quotes?exchanges=us10y |
FRED DGS10; requires FRED_API_KEY or tradfi.us10y.api_key. |
| Capability | Status | Interface | Notes |
|---|---|---|---|
| CoinGecko prices | Implemented | GET /v1/market/quotes?exchanges=coingecko |
Public simple price API; optional COINGECKO_API_KEY. |
| CoinMarketCap prices | Implemented | GET /v1/market/quotes?exchanges=coinmarketcap |
Requires COINMARKETCAP_API_KEY. |
| CoinGlass derivatives aggregate | Implemented | GET /v1/external/signals?sources=coinglass |
Requires COINGLASS_API_KEY; emits funding/OI/liquidation/long-short/basis/options raw aggregate signals. |
| Crypto Fear & Greed | Implemented | GET /v1/external/signals?sources=fear_greed |
Public Alternative.me index. |
| CryptoPanic news | Implemented | GET /v1/external/signals?sources=cryptopanic |
Requires CRYPTOPANIC_API_KEY; emits scored news items. |
| Santiment metrics | Implemented | GET /v1/external/signals?sources=santiment |
Requires SANTIMENT_API_KEY; GraphQL metrics are config-driven. |
| LunarCrush social metrics | Implemented | GET /v1/external/signals?sources=lunarcrush |
Requires LUNARCRUSH_API_KEY; endpoint/base URL is configurable. |
| Capability | Status | Interface | Notes |
|---|---|---|---|
| Whale Alert large transfers | Implemented | GET /v1/onchain/transfers?source=whale_alert |
Requires WHALE_ALERT_API_KEY; global multi-chain large-transfer feed. |
| mempool.space BTC large transfers | Implemented | GET /v1/onchain/transfers?source=mempool_space&chain=bitcoin |
Keyless BTC mempool poller; filters by configured BTC threshold when value is available. |
| Etherscan watched-address transfers | Implemented | GET /v1/onchain/transfers?source=etherscan&chain=ethereum |
Requires ETHERSCAN_API_KEY; monitors configured addresses, not full-chain firehose. |
For the crypto binary fair-value / market-making strategy discussed with
PolyAlpha, the required inputs are:
| Strategy Input | Needed For | Status in MarketBridge |
Current Interface |
|---|---|---|---|
| BTC/ETH spot/perp bid/ask | Underlying price and basis | Implemented | /snapshot, /ws/ticks |
| DEX quote/pool price | CEX vs DEX basis and route sanity check | Implemented | /v1/market/quotes?exchanges=jupiter,raydium,uniswap_v3,paraswap,oneinch |
| Macro reference price | DXY, VIX, US10Y regime filters | Implemented | /v1/market/quotes?exchanges=dxy,vix,us10y |
| Aggregate and sentiment signals | Derivatives positioning, news and social regime filters | Implemented | /v1/external/signals?sources=coinglass,fear_greed,cryptopanic,santiment,lunarcrush |
| Perp funding | Basis/funding sanity check | Implemented where supported | /funding |
| Options IV / option chain | Theoretical digital probability | Implemented multi-venue REST cache | /v1/options/chains, /options/deribit/summary, /options/deribit/live-summary |
| Polymarket market id / strike / expiry | Map event to option inputs | Implemented first version | /polymarket/crypto-markets |
| Polymarket Yes/No token ids | Subscribe/query executable prices | Implemented first version | /polymarket/crypto-markets |
| Polymarket Yes/No bid/ask/depth | Entry, exit, pair discount, capacity | Implemented REST and live cache first versions | /polymarket/book, /polymarket/books, /polymarket/crypto-books, /polymarket/live-books, /polymarket/live-crypto-books |
| Stale/latency health | Decision input hygiene | Implemented first version | Exchange ticks expose stale/latency; Polymarket live cache exposes received_at_ms, source_latency_ms, source, and stale. |
| Paper decision/PnL loop | Validate signal after 5 minutes | Not implemented here | Belongs in PolyAlpha. |
| Live execution | Real order submit/cancel/fills | Not implemented | Future execution layer; not approved for live trading. |
Bottom line: MarketBridge now provides a first mature data-source surface for
paper decisions: exchange BBO/funding, DeFi quote and pool prices,
TradFi macro references,
aggregate market data and sentiment signals,
multi-venue option chains, Polymarket
market discovery, REST books, and a live Polymarket CLOB cache. It is still not
an execution engine: authenticated Polymarket order placement/cancel/replace and
strategy PnL validation belong in later layers.
Base URL: http://127.0.0.1:8080
| Method | Path | Purpose |
|---|---|---|
| GET | / |
Service metadata |
| GET | /health |
Liveness check |
| GET | /v1/system/info |
Version, API version, local UI connection hints, and capability list |
| GET | /v1/catalog/sources |
Implemented public data sources |
| GET | /v1/catalog/search |
Product search: where an asset/symbol trades and which data domains are available |
| GET | /v1/catalog/markets |
On-demand public market/symbol discovery by exchange |
| GET | /v1/catalog/perpetuals |
On-demand grouped perpetual contract discovery by exchange |
| GET | /v1/catalog/source-roadmap |
External source roadmap inventory and implementation status |
| GET | /v1/catalog/domains |
Implemented normalized data domains |
| GET | /v1/catalog/instruments |
Instruments currently visible in live caches |
| GET | /v1/catalog/health |
Source/domain record counts and freshness status |
| GET | /v1/market/quotes |
Envelope-based exchange spot/perp quote snapshots |
| GET | /v1/market/basis |
Spot-perp basis derived from quote snapshots |
| GET | /v1/market/funding |
Funding-rate snapshots from public perp feeds |
| GET | /v1/market/perpetual-funding |
On-demand current funding rows for supported perpetual markets |
| GET | /v1/market/open-interest |
Open-interest snapshots from public feeds/REST |
| GET | /v1/market/liquidations |
Latest public liquidation events |
| GET | /v1/market/order-books |
Latest L2 book snapshots |
| GET | /v1/market/trades |
Latest public trade snapshots |
| GET | /v1/market/order-flow |
Buy/sell pressure metrics derived from live trades |
| GET | /v1/market/order-flow/windows |
Multi-window order-flow and CVD buckets |
| GET | /v1/market/footprint |
Price-bin footprint/orderflow profile |
| GET | /v1/market/klines |
SQLite-backed OHLCV bars; can persist selected rows to the local Arrow IPC lake |
| GET | /v1/history/candles |
On-demand spot/futures/mark/index/premiumIndex/funding-rate candles |
| GET | /v1/options/chains |
Envelope-based cached Deribit/OKX/Bybit/Binance option chains |
| GET | /v1/prediction/books |
Envelope-based cached Polymarket CLOB books |
| GET | /v1/external/signals |
External aggregate, news, and sentiment signals |
| GET | /v1/onchain/transfers |
Large on-chain transfer feed from Whale Alert, mempool.space, and Etherscan |
| GET | /v1/universe/top-volume |
Universe filter by historical quote volume |
| GET | /v1/universe/percent-change |
Universe filter by percent change |
| GET | /v1/universe/volatility |
Universe filter by realized volatility |
| GET | /v1/universe/spread-filter |
Universe filter by current spread |
| GET | /v1/universe/cross-market |
Spot/perp and cross-exchange availability |
| GET | /v1/universe/market-cap |
Market-cap ranking from external aggregate signals |
| GET | /v1/universe/age-filter |
Listing-age filter based on first stored kline |
| GET | /v1/universe/new-listings |
Recent listing candidates from first stored kline |
| GET | /v1/universe/delist-risk |
Missing/stale quote risk for historically seen markets |
| GET | /v1/research/features |
Multi-timeframe research feature bundle |
| GET | /v1/research/market-regime |
Aggregate regime snapshot |
| GET | /v1/research/symbol-state |
Real-time per-symbol squeeze/exhaustion state machine |
| GET | /v1/storage/manifest |
Local lake manifest, quality, coverage, and file index |
| DELETE | /v1/storage/partitions |
Delete local lake partitions by filter |
| GET | /v1/agent/context |
AI/agent-friendly compact market context |
| GET | /v1/agent/capabilities |
AI/agent-friendly capability inventory |
| GET | /snapshot |
Latest normalized ticks |
| GET | /funding |
Unified perp funding view |
| GET | /options/deribit/summary |
Deribit option chain summaries and IV |
| GET | /options/deribit/live-summary |
Cached Deribit option summaries with freshness fields |
| GET | /options/deribit/book |
Deribit per-instrument option book |
| GET | /options/okx/book |
OKX per-instrument option book |
| GET | /options/bybit/book |
Bybit per-instrument option book |
| GET | /options/binance/book |
Binance per-instrument option book |
| GET | /polymarket/markets |
General active Polymarket Gamma markets with CLOB ids and outcomes |
| GET | /polymarket/crypto-markets |
Parsed Polymarket BTC/ETH binary markets |
| GET | /polymarket/book |
Polymarket CLOB book summary for one token |
| GET | /polymarket/books |
Polymarket CLOB book summaries for token ids |
| GET | /polymarket/midpoints |
Batch public CLOB midpoint prices; no API key |
| GET | /polymarket/spreads |
Batch public CLOB spreads; no API key |
| GET | /polymarket/last-trade-prices |
Batch public CLOB last trade prices; no API key |
| GET | /polymarket/prices |
Batch public CLOB executable BUY/SELL prices; no API key |
| GET | /polymarket/prices-history |
Single or batch public CLOB price history; no API key |
| GET | /polymarket/crypto-books |
Parsed crypto markets plus Yes/No CLOB books |
| GET | /polymarket/live-books |
Cached Polymarket CLOB books seeded by REST and patched by websocket |
| GET | /polymarket/live-crypto-books |
Parsed crypto markets plus cached Yes/No CLOB books |
| GET | /coverage |
Data quality dashboard model |
| GET | /metrics |
Prometheus metrics text |
| WS | /ws/ticks |
Real-time normalized tick stream |
| WS | /v1/stream |
Domain-filtered stream for quotes, extended market events, options, and prediction books |
DeFi quote and pool sources are exposed through the same market quote surface:
curl -s "http://127.0.0.1:8080/v1/market/quotes?exchanges=jupiter,raydium,uniswap_v3,paraswap,oneinch" | jqTraditional finance reference sources use the same quote surface:
curl -s "http://127.0.0.1:8080/v1/market/quotes?exchanges=dxy,vix,us10y" | jqAggregate and sentiment sources use the external signal surface:
curl -s "http://127.0.0.1:8080/v1/external/signals?sources=coinglass,fear_greed,cryptopanic,santiment,lunarcrush" | jqOn-chain transfer sources use their own surface:
curl -s "http://127.0.0.1:8080/v1/onchain/transfers?source=whale_alert&asset=BTC&min_amount_usd=500000" | jqThe table below is the current runtime/API coverage. The full operating matrix is maintained in docs/feature_inventory.md, and the CCXT reference gap audit lives in docs/ccxt_parity_audit.md. Both must be updated with connector changes.
| Venue group | BBO | L2 book | Trades | Funding | OI | Liquidations | Notes |
|---|---|---|---|---|---|---|---|
| Binance / Bybit / OKX | implemented | implemented | implemented | implemented | implemented | implemented | Highest-volume public derivatives venues. |
| Hyperliquid / dYdX / Backpack / MEXC / BingX / Bitget / Bitmart | implemented or partial | implemented | implemented | partial to implemented | partial to implemented | n/a where public feed is unavailable | Public feeds first; venue-specific unavailable domains stay explicit. |
| BitMEX / Deribit / Phemex / CoinEx / Crypto.com / WOO X / BloFin / Aevo / Pacifica / GRVT / Injective / Derive / Evedex | implemented or partial | implemented | implemented | implemented where venue provides it | implemented where venue provides it | implemented, partial, or n/a by venue | Native public perp/derivatives data paths. |
| Coinbase / Kraken / KuCoin / Gemini / Bithumb / Bitvavo / bitFlyer / bitbank / Coincheck / Coinone / Upbit / Bullish | implemented | implemented | implemented | n/a where spot-only | n/a or implemented by venue | n/a where spot-only or no public feed | Native spot REST/WS public market data. |
| Gate / HTX / Bitfinex / Bitstamp / Bitrue / AscendEX / BTC Markets / Dexalot / Vertex / XRPL / Cube / Foxbit / NDAX | implemented or partial | implemented | implemented or explicit n/a | implemented, partial, or n/a where product semantics apply | implemented, partial, or n/a where product semantics apply | n/a unless a stable public feed exists | Long-tail and CLOB/DEX venues are added as public data contracts mature. |
All exchange connectors are data-only. They do not sign requests, place orders, cancel orders, or depend on third-party trading libraries at runtime. Where a venue does not provide a stable public feed for a domain, MarketBridge leaves the domain empty instead of fabricating a signal.
The remaining non-Polymarket data gaps are tracked in docs/feature_inventory.md. At this checkpoint they are: credentialed live validation for Architect/Decibel OI field names, route-depth/protocol-native DeFi swap-stream extensions, and native option WS book/trade extensions. Aggregator analytics for funding divergence, OI change, trade imbalance, liquidation burst, and depth pressure are emitted by the spread aggregator.
Returns service info.
Example:
curl -s http://127.0.0.1:8080/Simple liveness endpoint.
Example:
curl -s http://127.0.0.1:8080/healthUI-friendly service metadata. Hosted static UIs should probe this endpoint first,
then fall back to /health.
Example:
curl -s http://127.0.0.1:8080/v1/system/info | jqCatalog endpoints for discovering what MarketBridge can provide right now.
Examples:
curl -s "http://127.0.0.1:8080/v1/catalog/sources" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/source-roadmap" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/domains" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/instruments" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/health" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/search?q=HOME&exchanges=binance,okx,bybit,bitget,gate,mexc" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/perpetuals?exchange=binance"e=USDT&limit=20" | jqProduct search for UI and client onboarding. A client can pass an asset such as
HOME, or a symbol such as HOMEUSDT, and receive the exchanges, spot/perp
markets, quotes, supported data domains, derived metrics, and ready-to-call
REST/WebSocket endpoints for each listing.
Query params:
q=HOMEorproduct=HOMEUSDT, user-facing search inputbase=HOME, explicit base asset overridesymbol=HOMEUSDT, exact symbol-oriented searchexchanges=binance,okx,bybit, optional venue filtermarket=spot|perp, optional product filterquote=USDT, optional quote filterinclude_endpoints=true|false, defaulttrue
Examples:
curl -s "http://127.0.0.1:8080/v1/catalog/search?q=HOME" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/search?q=HOMEUSDT&market=perp" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/search?base=HOME&exchanges=binance,okx,bybit,bitget,gate,mexc" | jqOn-demand public market discovery. Use this when a client needs the latest exchange symbol list rather than only the instruments currently configured for live ingestion.
Query params:
exchange=binance, one exchangeexchanges=binance,okx,bybit, comma-separated exchangesmarket=spot|perp|swap, optional; omit to include spot and perp where supportedquote=USDT, optional quote filterbase=BTC, optional base filteractive_only=true|false, defaulttruelimit, default5000, max50000
Response fields:
- top level:
version,domain,supported_exchanges,markets,errors markets[]:exchange,market,symbol,native_symbol,base,quote,active,status,contract_type,settle_asset,sourceerrors[]: per-exchange adapter failures; an empty result with non-emptyerrorsmeans data retrieval failed for at least one requested venue
Examples:
curl -s "http://127.0.0.1:8080/v1/catalog/markets?exchange=binance&market=perp"e=USDT&limit=20" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/markets?exchanges=okx,bybit,bitget&market=spot"e=USDT" | jqDirect answer to "which perpetual contracts does this exchange list?" The response is grouped by exchange so clients can first discover the full perpetual universe, then choose their own watchlist and monitoring logic.
Query params:
exchange=bybitorexchanges=binance,okx,bybitquote=USDT, optionalbase=BTC, optionalactive_only=true|false, defaulttruelimit, per-exchange result cap, default50000
Response fields:
- top level:
version,domain,supported_exchanges,exchanges,errors exchanges[]:exchange,contracts_total,contracts_returned,base_assets_total,base_assets,contractscontracts[]: same listing fields as/v1/catalog/markets
Examples:
curl -s "http://127.0.0.1:8080/v1/catalog/perpetuals?exchange=okx"e=USDT&limit=50" | jq
curl -s "http://127.0.0.1:8080/v1/catalog/perpetuals?exchanges=binance,bybit,bitget"e=USDT&limit=10" | jqEnvelope-based exchange quote snapshots. This is the first /v1 domain endpoint
and should be preferred by new consumers.
Query params:
symbols=BTCUSDT,ETHUSDTexchanges=okx,bybit,bitgetproduct_type=spot|perpinclude_stale=true|false, defaultfalse
Examples:
curl -s "http://127.0.0.1:8080/v1/market/quotes?symbols=BTCUSDT&product_type=perp" | jqThese market domain endpoints expose the latest normalized rows from live public feeds and REST pollers.
Shared query params:
symbols=BTCUSDT,ETHUSDTexchanges=binance,okx,deribitmarket=spot|perpfor trade and order-book endpoints
Examples:
curl -s "http://127.0.0.1:8080/v1/market/funding?symbols=BTCUSDT&exchanges=binance,okx,deribit" | jq
curl -s "http://127.0.0.1:8080/v1/market/open-interest?symbols=BTCUSDT&exchanges=binance,okx,deribit" | jq
curl -s "http://127.0.0.1:8080/v1/market/order-books?symbols=BTCUSDT&market=perp&exchanges=binance,okx" | jq
curl -s "http://127.0.0.1:8080/v1/market/trades?symbols=BTCUSDT&market=perp&exchanges=binance,okx" | jq
curl -s "http://127.0.0.1:8080/v1/market/liquidations?symbols=BTCUSDT&exchanges=binance,bybit,okx" | jqOn-demand current funding rows for supported perpetual markets. This endpoint pulls public REST data directly and is not limited to the symbols configured in the live runtime. MarketBridge returns raw normalized data only; threshold filters, watchlists, alerts, and strategy rules belong in the client.
For a larger copy-paste cookbook with common curl + jq searches, CSV exports,
cross-exchange comparisons, and watchlist generation, see
docs/perpetual_funding_cookbook.md.
For a broader 100+ example reference across symbols, exchanges, price change,
basis, order flow, liquidations, exports, and operations, see
docs/query_examples.md.
Supported first-pass venues: binance, okx, bybit, bitget, kucoin,
gate, mexc, bingx, bitmart.
Query params:
exchange=bybitorexchanges=binance,okx,bybitsymbols=BTCUSDT,ETHUSDT, optional normalized symbolsquote=USDT, optional quote filteractive_only=true|false, defaulttruelimit, default5000, max50000
Response fields:
- top level:
version,domain,supported_exchanges,funding,errors funding[]:exchange,symbol,native_symbol,funding_rate,funding_rate_pct,next_funding_time_ms,mark_price,index_price,active,source,ts_msfunding_rateis the decimal rate, for example-0.001funding_rate_pctis already percent, for example-0.1means-0.1%
Examples:
curl -s "http://127.0.0.1:8080/v1/market/perpetual-funding?exchange=bybit"e=USDT&limit=50000" | jq
curl -s "http://127.0.0.1:8080/v1/market/perpetual-funding?exchanges=binance,okx,bitget&symbols=BTCUSDT,ETHUSDT" | jqClient-side extreme negative funding filter, for example Binance contracts
between -2% and -0.2%:
curl -s "http://127.0.0.1:8080/v1/market/perpetual-funding?exchange=binance"e=USDT&limit=50000" \
| jq '.funding
| map(select(.funding_rate_pct >= -2 and .funding_rate_pct <= -0.2))
| sort_by(.funding_rate_pct)
| .[]
| {exchange, symbol, funding_rate_pct, mark_price, next_funding_time_ms}'Multi-exchange version:
curl -s "http://127.0.0.1:8080/v1/market/perpetual-funding?exchanges=binance,okx,bybit,bitget"e=USDT&limit=50000" \
| jq '.funding
| map(select(.funding_rate_pct >= -2 and .funding_rate_pct <= -0.2))
| sort_by(.funding_rate_pct)
| .[]
| {exchange, symbol, funding_rate_pct, mark_price, next_funding_time_ms}'SQLite-backed OHLCV bars. Historical REST backfill supports Binance and OKX;
realtime bars are aggregated from live quote ticks and written once per update
batch. Add persist=true only when you want the returned rows written to the
local Arrow IPC lake. Enable it in config:
klines:
enabled: true
sqlite_path: "data/marketbridge.sqlite"
lake_root: "data/lake"
intervals: [1m, 5m, 15m, 1h]
history_limit: 1500
backfill_on_start: false
sources: [binance, okx]Query params:
exchange=binance|okx|...market=spot|perpsymbol=BTCUSDTinterval=1m|5m|15m|1hstart_ms,end_ms, optional Unix millisecondslimit, default500, max5000persist=true|false, defaultfalsecandle_type=spot|futures|perp|mark|index|premiumIndex|funding_rate
Examples:
curl -s "http://127.0.0.1:8080/v1/market/klines?exchange=binance&market=perp&symbol=BTCUSDT&interval=1m&limit=100" | jq
curl -s "http://127.0.0.1:8080/v1/market/klines?exchange=binance&market=perp&symbol=BTCUSDT&interval=1m&limit=1000&persist=true" | jqOn-demand public historical candles. This is the preferred endpoint for
research candles beyond ordinary OHLCV. It can write only the requested result
to the local Arrow IPC lake with persist=true.
Supported candle types:
- Binance:
spot,futures,perp,mark,index,premiumIndex,funding_rate - OKX:
spot,perp,mark,index,funding_rate
Query params:
exchange=binance|okxsymbol=BTCUSDTcandle_type=spot|futures|perp|mark|index|premiumIndex|funding_rateinterval=1m|3m|5m|15m|30m|1h|4h|1d, where supported by the venuestart_ms,end_mslimitpersist=true|false
Examples:
curl -s "http://127.0.0.1:8080/v1/history/candles?exchange=binance&symbol=BTCUSDT&candle_type=mark&interval=1m&limit=1000&persist=true" | jq
curl -s "http://127.0.0.1:8080/v1/history/candles?exchange=binance&symbol=BTCUSDT&candle_type=premiumIndex&interval=1m&limit=500&persist=true" | jq
curl -s "http://127.0.0.1:8080/v1/history/candles?exchange=okx&symbol=BTCUSDT&candle_type=funding_rate&limit=100&persist=true" | jqMarketBridge uses SQLite as the manifest/index and Arrow IPC files as the local
columnar lake. The lake is opt-in: no request is persisted unless it sets
persist=true.
Manifest:
curl -s "http://127.0.0.1:8080/v1/storage/manifest?domain=candles&symbol=BTCUSDT" | jqDelete by filter:
curl -X DELETE "http://127.0.0.1:8080/v1/storage/partitions?domain=candles&exchange=binance&symbol=BTCUSDT&interval=1m&candle_type=mark" | jqManifest fields include rows, bytes, first/last timestamps, latest watermark, gap count, duplicate count, coverage ratio, latency p50/p95, stale count, file format, and file path.
Buy/sell pressure metrics derived from live trade events. No new exchange data
source is needed; this endpoint aggregates market_trade events into rolling
time buckets.
Query params:
exchange=binance|okx|bybitmarket=spot|perpsymbol=BTCUSDTwindow_ms=60000|300000|900000limit, default500
Example:
curl -s "http://127.0.0.1:8080/v1/market/order-flow?exchange=binance&market=perp&symbol=BTCUSDT&window_ms=60000" | jqKey fields:
buy_qty,sell_qtybuy_notional,sell_notionalbuy_trade_count,sell_trade_countdelta_qty,delta_notionalcumulative_delta_qty,cumulative_delta_notionalaggressive_buy_ratio,aggressive_sell_ratiolarge_trade_count
Multi-window query:
curl -s "http://127.0.0.1:8080/v1/market/order-flow/windows?exchange=binance&market=perp&symbol=BTCUSDT&windows_ms=60000,300000,900000" | jqFootprint/orderflow profile derived from recent live trades kept in the rolling in-memory trade buffer.
Query params:
exchangemarket=spot|perpsymbolinterval_ms, default60000scale, price-bin size, default1.0start_ms,end_msimbalance_ratio, default3.0imbalance_volume, default0.0stacked_imbalance_range, default3include_trades=true|falselimit
Example:
curl -s "http://127.0.0.1:8080/v1/market/footprint?exchange=binance&market=perp&symbol=BTCUSDT&interval_ms=60000&scale=1" | jqUniverse filters:
curl -s "http://127.0.0.1:8080/v1/universe/top-volume?exchange=binance&market=perp&interval=1d&limit=50" | jq
curl -s "http://127.0.0.1:8080/v1/universe/spread-filter?product_type=perp&max_spread_bps=5" | jq
curl -s "http://127.0.0.1:8080/v1/universe/new-listings?max_age_days=7" | jqResearch features:
curl -s "http://127.0.0.1:8080/v1/research/features?symbols=BTCUSDT,ETHUSDT&intervals=1h,4h,1d&benchmark_symbol=BTCUSDT&correlated_symbols=ETHUSDT,SOLUSDT" | jq
curl -s "http://127.0.0.1:8080/v1/research/market-regime?symbols=BTCUSDT,ETHUSDT&intervals=1h,4h" | jqAgent-friendly read-only context:
curl -s "http://127.0.0.1:8080/v1/agent/capabilities" | jq
curl -s "http://127.0.0.1:8080/v1/agent/context?symbols=BTCUSDT,ETHUSDT&include_storage=true" | jqFor a full walkthrough, see docs/usage_full.md.
Spot-perp basis computed from current quote snapshots. No new venue data source
is required: MarketBridge pairs spot and perp quotes from the same exchange
and symbol.
Query params:
symbols=BTCUSDT,ETHUSDTexchanges=binance,okx,bybit
Example:
curl -s "http://127.0.0.1:8080/v1/market/basis?symbols=BTCUSDT&exchanges=binance,okx" | jqKey fields:
spot_mid,perp_midbasis = perp_mid - spot_midbasis_bps = basis / spot_mid * 10000
Envelope-based option chain snapshots from the unified option cache.
Query params:
venue, optional,deribit,okx,bybit, orbinancecurrency, optional, e.g.BTCoption_type, optional,callorputstrike_min,strike_max, optional numeric filtersexpiry_after,expiry_before, optional ISO timestamp string filtersinclude_stale=true|false, defaultfalse
Example:
curl -s "http://127.0.0.1:8080/v1/options/chains?venue=bybit¤cy=BTC&option_type=call" | jqEnvelope-based prediction-market order books from the Polymarket live cache.
Query params:
token_ids, optional comma-separated Polymarket token idsinclude_stale=true|false, defaultfalse
Example:
curl -s "http://127.0.0.1:8080/v1/prediction/books?token_ids=YES_TOKEN,NO_TOKEN" | jqReturns in-memory latest snapshots from EventBus.
Query params:
symboloptional, e.g.BTCUSDT
Examples:
curl -s http://127.0.0.1:8080/snapshot | jq
curl -s "http://127.0.0.1:8080/snapshot?symbol=BTCUSDT" | jqKey fields in each item:
exchange,market,symbolbid,ask,mark,fundingts,source_latency_ms,stale
Normalized tick stream subscription.
Query params:
symbols=BTCUSDT,ETHUSDTexchanges=okx,bybitmarket=spot|perp
Example:
wscat -c "ws://127.0.0.1:8080/ws/ticks?market=perp&symbols=BTCUSDT"Domain-filtered websocket stream. It supports live market_quote,
funding, open_interest, trade, liquidation, order_book, and
external_signal events, plus cached snapshot streaming for options_chain
and prediction_book.
Query params:
domains=market_quote,funding,open_interest,trade,liquidation,order_book,external_signal,options_chain,prediction_booksymbols=BTCUSDTexchanges=okx,deribit,polymarketor external signal source namesproduct_type=spot|perp|option|binary_outcomeinclude_stale=true|falsedefaultfalsesnapshot_interval_ms=1000for cached domains, clamped to250..60000
Example:
wscat -c "ws://127.0.0.1:8080/v1/stream?domains=market_quote&symbols=BTCUSDT&product_type=perp"
wscat -c "ws://127.0.0.1:8080/v1/stream?domains=funding&symbols=BTCUSDT&exchanges=binance,okx"
wscat -c "ws://127.0.0.1:8080/v1/stream?domains=order_book,trade&symbols=BTCUSDT&product_type=perp"
wscat -c "ws://127.0.0.1:8080/v1/stream?domains=options_chain,prediction_book&include_stale=false"Unified perp funding view by canonical symbol.
Query params:
symbols=BTCUSDT,ETHUSDTexchanges=okx,bybit,bitgetonly_with_funding=true|falsedefaulttrueinclude_stale=true|falsedefaultfalse
Examples:
curl -s "http://127.0.0.1:8080/funding" | jq
curl -s "http://127.0.0.1:8080/funding?symbols=BTCUSDT&exchanges=okx,bybit,bitget" | jqResponse model per symbol:
symbolexchanges_total,exchanges_with_fundingmin_funding,max_funding,funding_spreadupdated_atpoints[]withexchange/raw_symbol/funding/mark/stale/source_latency_ms/ts
Unified Deribit option summary feed for crypto binary-pricing models.
Query params:
currency=BTC|ETH, defaultBTC
Example:
curl -s "http://127.0.0.1:8080/options/deribit/summary?currency=BTC" | jqKey fields in summaries[]:
instrument_name,option_type,strike,expiry_timebid_price,ask_price,mark_price,mark_ivunderlying_price,underlying_index,open_interest
Cached Deribit option summary feed. This endpoint reads the in-process data cache instead of hitting Deribit on every strategy decision.
Enable the background cache in config:
deribit:
enabled: true
base_url: "https://www.deribit.com/api/v2/"
currencies: [BTC, ETH]
refresh_secs: 10
stale_ttl_ms: 30000
okx_options:
enabled: true
base_url: "https://www.okx.com/api/v5/"
currencies: [BTC, ETH]
refresh_secs: 10
bybit_options:
enabled: true
base_url: "https://api.bybit.com/v5/"
currencies: [BTC, ETH]
refresh_secs: 10
binance_options:
enabled: true
base_url: "https://eapi.binance.com/"
ws_url: "wss://nbstream.binance.com/eoptions/ws"
currencies: [BTC, ETH]
refresh_secs: 10Query params:
currency, optional, e.g.BTCoption_type, optional,callorputstrike_min,strike_max, optional numeric filtersexpiry_after,expiry_before, optional ISO timestamp string filtersinclude_stale=true|false, defaultfalse
Example:
curl -s "http://127.0.0.1:8080/options/deribit/live-summary?currency=BTC&option_type=call&strike_min=90000&strike_max=120000" | jqKey fields in summaries[]:
source:deribit_rest_cachereceived_at_ms,stale- all direct Deribit summary fields from
/options/deribit/summary
These endpoints fetch a single listed option contract from the venue's public REST book endpoint. They are intended for strategy checks that need executable depth around one candidate instrument rather than the full option chain.
Examples:
curl -s "http://127.0.0.1:8080/options/deribit/book?instrument_name=BTC-29MAY26-70000-P&depth=10" | jq
curl -s "http://127.0.0.1:8080/options/okx/book?instrument_name=BTC-USD-260626-100000-C&depth=10" | jq
curl -s "http://127.0.0.1:8080/options/bybit/book?instrument_name=BTC-26MAR27-78000-P-USDT&depth=10" | jq
curl -s "http://127.0.0.1:8080/options/binance/book?instrument_name=BTC-260626-140000-C&depth=10" | jqCommon response fields:
book.venue,book.instrument_name,book.timestampbook.bid_price,book.ask_pricebook.bids[],book.asks[]withpriceandqty- Greeks and mark fields when the upstream venue includes them
Parsed active Polymarket BTC/ETH binary markets for downstream strategy engines.
Query params:
limit, default500max_offset, default5000gamma_base_url, defaulthttps://gamma-api.polymarket.com/
Example:
curl -s "http://127.0.0.1:8080/polymarket/crypto-markets?limit=500&max_offset=500" | jqResponse fields:
markets[]: parsedbase_asset,strike,direction,rule_type,expiry_time, Yes/No token idsclob_asset_ids[]: token ids that a Polymarket CLOB collector should subscribe to
General active Polymarket Gamma market discovery. Use this when a client needs
all categories instead of only the BTC/ETH parser from /polymarket/crypto-markets.
Query params are the same as /polymarket/crypto-markets: limit,
max_offset, and optional gamma_base_url.
Example:
curl -s "http://127.0.0.1:8080/polymarket/markets?limit=500&max_offset=500" | jqResponse fields:
markets[]: active Gamma markets with question/title metadata, outcomes, CLOB ids, liquidity/volume/open-interest fields where availableclob_asset_ids[]: CLOB token ids discovered from those markets
Polymarket CLOB book summary for one outcome token.
Query params:
token_idrequired
Example:
curl -s "http://127.0.0.1:8080/polymarket/book?token_id=TOKEN_ID" | jqKey fields in book:
asset_id,market,timestampbest_bid,best_ask,spreadbid_depth,ask_depth- full raw
book.bids[]andbook.asks[]
Batch Polymarket CLOB book summaries.
Query params:
token_idscomma-separated token ids
Example:
curl -s "http://127.0.0.1:8080/polymarket/books?token_ids=YES_TOKEN,NO_TOKEN" | jqBatch wrapper for public Polymarket CLOB POST /midpoints.
Query params:
token_idscomma-separated token ids, max 500
Batch wrapper for public Polymarket CLOB POST /spreads.
Query params:
token_idscomma-separated token ids, max 500
Batch wrapper for public Polymarket CLOB POST /last-trades-prices.
Query params:
token_idscomma-separated token ids, max 500
Batch wrapper for public Polymarket CLOB POST /prices.
Query params:
token_idscomma-separated token ids, max 500sidesoptional comma-separated sides,BUY,SELL, or omitted for both
Wrapper for public Polymarket CLOB GET /prices-history and POST /batch-prices-history.
Query params:
token_idfor a single token, ortoken_idscomma-separated for batch, max 20start_ts,end_ts,interval,fidelityoptional history controls
Examples:
curl -s "http://127.0.0.1:8080/polymarket/midpoints?token_ids=YES_TOKEN,NO_TOKEN" | jq
curl -s "http://127.0.0.1:8080/polymarket/prices?token_ids=YES_TOKEN&sides=BUY,SELL" | jq
curl -s "http://127.0.0.1:8080/polymarket/prices-history?token_id=YES_TOKEN&interval=1h&fidelity=1" | jqConvenience endpoint for strategy engines: parsed active BTC/ETH binary markets plus the current Yes/No CLOB book summaries.
Query params are the same as /polymarket/crypto-markets.
Cached Polymarket CLOB books for outcome token ids. The cache is populated by REST snapshots first, then patched by public Polymarket CLOB websocket events when they arrive.
Enable the background cache in config:
polymarket:
enabled: true
ws_url: "wss://ws-subscriptions-clob.polymarket.com/ws/market"
gamma_base_url: "https://gamma-api.polymarket.com/"
limit: 500
max_offset: 5000
refresh_secs: 300
ping_secs: 10
chunk_size: 500
stale_ttl_ms: 1500Query params:
token_idsoptional comma-separated token ids. If omitted, returns all cached books.
Example:
curl -s "http://127.0.0.1:8080/polymarket/live-books?token_ids=YES_TOKEN,NO_TOKEN" | jqKey fields in books[]:
source:polymarket_clob_restfor seed snapshots,polymarket_clob_wsfor websocket updateslast_event_type:book,best_bid_ask, orprice_changebest_bid,best_ask,spread,bid_depth,ask_depthreceived_at_ms,source_latency_ms,stale
Decision runners should reject a Polymarket book when stale=true or when the
source is not fresh enough for the intended holding period. This is deliberate:
the data plane exposes truth, the strategy layer decides whether to trade.
Parsed active BTC/ETH binary markets plus cached Yes/No books from the live Polymarket cache.
Query params are the same as /polymarket/crypto-markets.
Example:
curl -s "http://127.0.0.1:8080/polymarket/live-crypto-books?limit=500&max_offset=500" | jqDashboard-grade quality model with global summary, market summary, exchange summary, symbol detail, and alerts.
Query params:
symbols=BTCUSDT,ETHUSDTexchanges=okx,bybit,bitget,binancemarket=spot|perpinclude_stale=true|falsedefaulttrueonly_with_funding=true|falsedefaultfalse
Examples:
curl -s "http://127.0.0.1:8080/coverage" | jq
curl -s "http://127.0.0.1:8080/coverage?market=perp&symbols=BTCUSDT" | jq
curl -s "http://127.0.0.1:8080/coverage?market=perp&exchanges=okx,bybit,bitget" | jqTop-level fields:
generated_atquerynormalized effective filterssummaryglobal KPIssummary.markets[]market-level KPIsexchange_summaries[]per-exchange health profilealerts[]global/exchange/symbol alertssymbols[]symbol-level details
summary KPIs include:
total_symbols,total_pointshealthy_symbols,warning_symbols,critical_symbolsstale_ratio,funding_coverage_ratioonline_exchange_count,expected_exchange_count,exchange_online_ratiolatency_ms_p50,latency_ms_p95
symbols[] fields include:
symbol,market,health_status,alerts[]exchanges_total,exchanges_with_funding,funding_coverage_ratioexchanges_stale,stale_ratiolatency_ms_min,latency_ms_p50,latency_ms_avg,latency_ms_p95,latency_ms_maxpoints[]per-exchange latest data
Prometheus text metrics endpoint.
Example:
curl -s http://127.0.0.1:8080/metricsCurrent metrics include:
ticks_ingested_totalbus_publish_totalevents_ingested_total{event_type=...}bus_events_published_total{event_type=...}ws_subscribersredis_xadd_totalredis_dead_letter_totalticks_dropped_total
When Redis is enabled and a batch still cannot be written after retries,
MarketBridge appends the failed rows to runtime.redis_dead_letter_path for
operator inspection.
Large transfer cache populated by optional on-chain collectors.
Config:
onchain:
whale_alert:
enabled: true
api_key_env: WHALE_ALERT_API_KEY
min_value_usd: 500000
mempool_space:
enabled: true
min_value_btc: 100
etherscan:
enabled: true
api_key_env: ETHERSCAN_API_KEY
min_value_eth: 1000
addresses:
- "0x..."Query params:
source=whale_alert|mempool_space|etherscanchain=bitcoin|ethereum|...asset=BTC|ETH|USDTmin_amount_usd, only applies when the source provides USD valuelimit, default500
Examples:
curl -s "http://127.0.0.1:8080/v1/onchain/transfers?source=whale_alert&min_amount_usd=1000000" | jq
curl -s "http://127.0.0.1:8080/v1/onchain/transfers?source=mempool_space&chain=bitcoin&asset=BTC" | jq
curl -s "http://127.0.0.1:8080/v1/onchain/transfers?source=etherscan&chain=ethereum&asset=ETH" | jqImportant source boundaries:
- Whale Alert is the simplest global large-transfer feed but requires an API key.
- mempool.space is keyless and BTC-focused; its recent mempool endpoint may not expose full address-level transfer semantics.
- Etherscan in this project monitors configured addresses. It is not a full-chain firehose.
| Exchange | Spot model | Perp model (this project) | Notes |
|---|---|---|---|
| Binance | Single WS combined stream | Single WS combined stream | Spot stream.binance.com, perp fstream.binance.com |
| OKX | Single WS multi-subscribe | Single WS multi-subscribe | tickers + -SWAP mapping |
| Bybit | Single WS multi-subscribe | Single WS multi-subscribe | v5 spot / linear |
| Bitget | Single WS multi-subscribe | Single WS multi-subscribe | v2 public WS |
| KuCoin | Single WS multi-topic | Single WS multi-topic | tokenized endpoint |
| Gate | Single WS multi-symbol | Single WS multi-symbol | separate spot/perp WS domains |
| Kraken | Single WS multi-symbol | Single WS multi-symbol | perp symbol naming is venue-specific |
| HTX | Single WS multi-channel | Single WS multi-channel | gzip payload |
| Bitfinex | Single WS multi-channel | Single WS multi-channel | chanId -> symbol map |
| Coinbase | Single WS multi-product | Not implemented | spot only in this project |
Perp adapters enabled in code:
okx_perp,bybit_perp,bitget_perp,binance_perp,kucoin_perp,gate_perp,kraken_perp,htx_perp,bitfinex_perp
Perp symbol conversion defaults:
- Binance / Bybit / Bitget:
BTCUSDT - OKX / HTX:
BTC-USDT-SWAP(OKX) /BTC-USDT(HTX) - KuCoin Perp:
BTCUSDTM - Gate Perp:
BTC_USDT - Bitfinex Perp:
tBTCF0:USDTF0 - Kraken Perp: pass-through (configure exact venue symbol)
- Start with one spot exchange (
binanceorokx) and verify steady snapshot updates. - Enable one perp exchange and verify
market=perpplusmark/fundingfields. - Enable two perp exchanges and verify
/fundingspread and/coveragehealth split. - Expand to full config and monitor
/coverage+/metricscontinuously.
Practical notes:
- If an exchange is region-restricted, keep
enabled: false. - Kraken perp symbol naming is pass-through in this repo.
- Coinbase is spot-only in this repo.
Run checks:
cargo fmt
cargo check
cargo test- Add
src/connectors/cex/<name>.rs - Implement
ExchangeSource - Convert payloads into
MarketTick(SpotorPerp) - Register source in
src/connectors/cex/registry.rs