Skip to content

Aathirajan/Polyedge_rust

Repository files navigation

Polyedge — Polymarket BTC 5-Minute Trading Bot

Rust Tokio WebSocket SQLite License

A high-performance, event-driven automated trading system that ingests real-time BTC price data from Binance, streams live orderbooks from Polymarket, and executes trades on binary prediction markets — all in a single Rust binary with sub-200ms end-to-end latency.


At a Glance

Metric Value
Tick-to-signal latency < 200ms
Live data feeds 3 — Binance · Polymarket · Gamma
Deployment footprint 1 binary — Bot + REST API + Dashboard
Structured log streams 7 JSONL files

Data Pipeline

┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│    Ingest    │ ──▶ │    Signal    │ ──▶ │   Strategy   │ ──▶ │   Execute    │ ──▶ │   Observe    │
│              │     │              │     │              │     │              │     │              │
│ Binance WS   │     │  Momentum    │     │ Gates + risk │     │ CLOB API /   │     │ Dashboard +  │
│ Polymarket WS│     │  scoring     │     │ rules        │     │ dry-run      │     │ JSONL logs   │
└──────────────┘     └──────────────┘     └──────────────┘     └──────────────┘     └──────────────┘

Key Engineering Highlights

  • Fully async — Tokio multi-thread runtime with zero blocking I/O across all pipeline stages
  • Sub-200ms latency — per-stage tracking with warn thresholds at 200ms / 500ms / 1s; critical paths instrumented end-to-end
  • Triple-gated safety — emergency stop, daily loss limit, and consecutive-loss halt; any mismatch blocks live orders and logs the exact reason
  • Preflight liquidity checks — verifies orderbook depth before every order placement via the CLOB API
  • Window time guards — prevents entries in the first 45s and last 30s of each 5-minute market window
  • Auto-reconnecting feeds — all WebSocket connections recover with exponential backoff; no manual intervention needed
  • Full REST + WebSocket API — 200ms push cadence for live UI control; hot-reload of strategy parameters without restart
  • SQLite persistence — trades, signals, orders, latency events, and config snapshots stored locally; schema auto-created on first run

Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Trading Bot (Rust)                      │
├─────────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐  │
│  │   Binance    │  │  Polymarket  │  │     Gamma API    │  │
│  │   WebSocket  │  │   WebSocket  │  │  Market Discovery│  │
│  └──────┬───────┘  └──────┬───────┘  └────────┬─────────┘  │
│         └─────────────────┴────────────────────┘            │
│                           │                                 │
│                    ┌──────▼───────┐                         │
│                    │  AppState    │                         │
│                    │  (Central)   │                         │
│                    └──────┬───────┘                         │
│                           │                                 │
│         ┌─────────────────┼──────────────────┐             │
│         │                 │                  │             │
│    ┌────▼────┐      ┌────▼────┐      ┌──────▼─────┐       │
│    │ Signal  │      │Strategy │      │ Execution  │       │
│    │ Engine  │      │ Engine  │      │Orchestrator│       │
│    └────┬────┘      └────┬────┘      └─────┬──────┘       │
│         │                │                  │              │
│    ┌────▼────────────────▼──────────────────▼─────┐       │
│    │         HTTP API + WebSocket                  │       │
│    │      (Port 8080 · /ws/live · /api/*)          │       │
│    └───────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────┘

Tech Stack

Layer Libraries
Runtime & web tokio (multi-thread) · axum 0.7 · tower-http
WebSocket tokio-tungstenite (client) · axum WS (server)
HTTP client reqwest
Serialisation serde · serde_json
Database sqlx + SQLite
Crypto & signing alloy (secp256k1 signers)
Polymarket polymarket_client_sdk_v2 0.6 (CLOB + WS)
Observability tracing · tracing-subscriber (JSON) · tracing-appender
Error handling anyhow · thiserror
Concurrency dashmap · tokio::sync

Project Structure

src/
├── main.rs              # Entry point, TradingBot struct
├── config.rs            # StrategyConfig, EnvConfig
├── state.rs             # AppState — central shared state
├── types.rs             # Core data structures
├── api/
│   ├── routes.rs        # REST endpoints
│   └── ws.rs            # WebSocket handler
├── execution/
│   ├── dry_run.rs       # Simulation executor
│   ├── polymarket.rs    # Live trading executor
│   └── preflight.rs     # Liquidity checks
├── ingestion/
│   ├── binance_ws.rs    # Binance price feed
│   ├── polymarket_ws.rs # Polymarket orderbook feed
│   └── gamma.rs         # Market discovery
├── signal/
│   ├── features.rs      # Feature extraction
│   └── scorer.rs        # Signal scoring
├── strategy/
│   ├── gates.rs         # Entry gates
│   ├── exits.rs         # Exit management
│   └── risk.rs          # Risk management
├── storage/
│   ├── db.rs            # SQLite schema + queries
│   └── jsonl.rs         # JSONL file logging
└── observability/
    ├── latency.rs       # Latency tracking
    └── metrics.rs       # Metrics calculation

Quick Start

Prerequisites: Rust 1.70+ (via rustup.rs)

# Clone and enter the project
git clone https://github.com/Aathirajan/Polyedge_rust.git
cd Polyedge_rust

# Copy config templates
cp config.example.json config.json
cp .env.example .env   # edit before running

# Build and run
cargo run --release

The API server starts at http://localhost:8080 · WebSocket at ws://localhost:8080/ws/live.


Configuration

Environment variables (.env)

Variable Required Default Description
DRY_RUN Yes true = paper trading, false = live
ENABLE_REAL_TRADING Yes Must also be true for live orders
PRIVATE_KEY Live only Ethereum private key (0x...)
DATABASE_URL No sqlite:./data/trader.db SQLite path
LOG_LEVEL No info trace / debug / info / warn / error
LOG_DIR No ./logs JSONL output directory

Strategy parameters (config.json) — hot-reloadable

Parameter Default Description
stake_per_trade_usd 5.0 USD amount per trade
max_daily_loss_usd 10.0 Halt after this cumulative loss
max_trades_per_day 5 Hard daily trade cap
min_signal_score 0.12 Minimum score to enter
min_edge_pct 0.05 Minimum edge over market price
take_profit_pct 0.25 Exit at 25% profit
stop_loss_pct 0.18 Exit at 18% loss
entry_window_min_sec 45 Skip first 45s of each window
min_seconds_before_close 30 Skip if < 30s left in window

Execution Modes

Dry-run (paper trading)

DRY_RUN=true
ENABLE_REAL_TRADING=false

Simulates trades against live orderbook data with realistic 2% fees. No Polymarket API calls made.

Live trading

⚠️ Real orders will be placed. Real money is at risk.

All three conditions must be satisfied simultaneously:

DRY_RUN=false
ENABLE_REAL_TRADING=true
PRIVATE_KEY=0x<your-key>

If any condition fails, orders are blocked and the specific reason is logged:

Log tag Cause
REAL_TRADING_BLOCKED_DRY_RUN_TRUE DRY_RUN=true overrides
REAL_TRADING_BLOCKED_ENABLE_FALSE ENABLE_REAL_TRADING=false
REAL_TRADING_BLOCKED_PRIVATE_KEY_MISSING No key configured

Safety Architecture

Mechanism Behaviour
Emergency stop Immediately halts all new trades; clearable via API or dashboard
Daily loss limit Stops when cumulative loss exceeds max_daily_loss_usd
Consecutive loss guard Halts after 3 losses in a row
Preflight liquidity check Verifies orderbook depth before every order
Window time guards Blocks entries in first 45s and last 30s of each 5-minute window

API Reference

REST endpoints

Endpoint Method Description
/health GET Health check
/api/status GET Full bot status snapshot
/api/config GET / POST Read or hot-reload strategy config
/api/emergency-stop POST Halt all trading immediately
/api/emergency-stop/clear POST Resume after emergency stop
/api/force-exit POST Force-close the current position
/api/trades GET Trade history
/api/latency GET Latency metrics

WebSocket

URL: ws://localhost:8080/ws/live · Cadence: ~200ms

{
  "type": "state",
  "data": {
    "dry_run": true,
    "btc_price": 104250.50,
    "market": { "slug": "btc-updown-5m-...", "seconds_left": 183 },
    "signal": { "side": "UP", "score": 0.61, "edge_pct": 0.14 },
    "position": {},
    "metrics": {}
  }
}

Monitoring & Observability

Structured JSONL logs (./logs/)

File Contents
ingestion.jsonl Feed connection events
signal.jsonl Per-cycle signal generation
strategy.jsonl Entry/exit decisions
execution.jsonl Order placement and fills
risk.jsonl Risk limit events
latency.jsonl Per-step timing records
errors.jsonl Aggregated error events

Latency thresholds

Metric Description
market_to_signal_ms Price tick → signal score
signal_to_order_ack_ms Signal → exchange acknowledgement
full_decision_to_fill_ms Total round-trip

Warn at > 200ms · Critical at > 500ms · Stale at > 1000ms


Testing

cargo test                  # all unit tests
cargo test -- --nocapture   # with stdout
cargo test execution::      # specific module

Disclaimer

This software is provided for educational and research purposes only. Prediction market trading involves substantial risk of financial loss. Past performance does not indicate future results. Always run in dry-run mode before using real funds.


License

MIT — see LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors