Cross-Market State Fusion

repository·master·Indexed 18 days ago

https://github.com/humanplane/cross-market-state-fusion

An RL-based paper trading system that exploits information lag between fast markets (Binance futures) and slow markets (Polymarket prediction markets). It uses a PPO agent with a shared policy to trade concurrent crypto markets (BTC, ETH, SOL, XRP) using an 18-dimensional state space fused from real-time WebSocket streams. The system includes a trading engine, a real-time web dashboard, and implementations for both RL and baseline strategies (momentum, mean_revert, random), requiring mlx for on-device training on Apple Silicon.

Tokens
2.6K
Snippets
8
Records
14
Agent score
14%

What's inside cross-market-state-fusion

  1. Understand the RL trading experiment setup

    master

    The project implements a Proximal Policy Optimization (PPO) agent designed to trade 15-minute binary prediction markets on Polymarket. The agent uses a single shared policy to trade 4 concurrent crypto markets (BTC, ETH, SOL, XRP) simultaneously.

    Key Setup Details:

    • Markets: 4 concurrent crypto markets.
    • Data Sources: Fuses live data from Binance Futures (fast signal) and Polymarket CLOB (slow execution venue).
    • Architecture: Uses a temporal architecture and an 18-dimensional state space.
    • Goal: Learn profitable trading patterns from sparse PnL rewards by observing price discovery in the fast market (Binance) before it reflects in the slow market (Polymarket).
  2. How multi-asset trading works with a shared policy

    master

    The agent employs a single neural network to manage multiple assets simultaneously. This approach requires the agent to:

    • Allocate attention across all active markets.
    • Learn asset-specific patterns while sharing weights across the network.
    • Handle asynchronous expirations and refreshes for each market.

    This design encourages the learning of generalizable crypto patterns rather than overfitting to a single specific market.

  3. How data fusion is used for arbitrage

    master

    The agent utilizes a 'fast signal source + slow execution venue' pattern to exploit cross-exchange lag. It fuses two real-time WebSocket (WSS) streams:

    1. Binance Futures WSS (Fast Market): Provides price returns (1m, 5m, 10m), volatility, order flow, CVD, and large trades. This represents institutional flow and sub-second price discovery.
    2. Polymarket CLOB WSS (Slow Market): Provides bid/ask spread and orderbook imbalance. This represents the execution venue where prices often lag Binance by seconds.

    By observing the movement in the Binance 'fast' market, the agent can attempt to bet on Polymarket before the orderbook adjusts to the new price.

    Binance Futures WSS  → Price returns (1m, 5m, 10m), volatility, order flow, CVD, large trades
    Polymarket CLOB WSS  → Bid/ask spread, orderbook imbalance
  4. Calculate rewards using share-based PnL

    master

    The current recommended approach (Phase 4+) for training uses share-based PnL rather than probability-based PnL. This better reflects the actual economics of binary markets, where low-probability entries provide higher proportional returns.

    Rewards are sparse: the agent only receives a reward signal when a position closes, rather than receiving feedback at every step.

    Calculation Logic:

    1. Calculate the number of shares acquired: shares = dollars / entry_price
    2. Calculate the PnL: pnl = (exit_price - entry_price) × shares
    shares = dollars / entry_price
    pnl = (exit_price - entry_price) × shares
  5. Project Architecture Overview

    master

    The project is organized into a main engine, a dashboard, strategy implementations, and data helpers:

    • run.py: Main trading engine.
    • dashboard.py: Real-time web dashboard.
    • strategies/: Contains base.py (abstractions), rl_mlx.py (PPO implementation), and various baselines (momentum.py, mean_revert.py, fade_spike.py).
    • helpers/: Handles data ingestion via polymarket_api.py, binance_wss.py, binance_futures.py, and orderbook_wss.py.
  6. Compare reward shaping vs. sparse rewards

    master

    The training evolution shows two distinct approaches to reward signals:

    Phase 1: Shaped Rewards (Dense)

    • Method: Rewards were given at every step (not just on close).
    • Components:
      1. Unrealized PnL delta (scaled down by 0.1).
      2. Transaction cost penalty.
    • Outcome: This approach failed and backfired.

    Phase 4+: Sparse Rewards

    • Method: The agent only receives a reward when a position closes.
    • Components: Share-based PnL.
    • Outcome: Significant improvement in ROI (4.5x improvement compared to previous phases).
  7. Understand the RL Agent's State and Action Spaces

    master

    The RL agent operates on a 18-dimensional state space and a discrete action space designed for binary crypto markets on Polymarket.

    State Space (18 dimensions)

    Data is fused from Binance futures and Polymarket CLOB:

    • Momentum: returns_1m, returns_5m, returns_10m (Binance)
    • Order Flow: ob_imbalance_l1, ob_imbalance_l5, trade_flow, cvd_accel (Binance)
    • Microstructure: spread_pct, trade_intensity, large_trade_flag (Polymarket)
    • Volatility: vol_5m, vol_expansion (Polymarket/Binance)
    • Position: has_position, position_side, position_pnl, time_remaining (Internal)
    • Regime: vol_regime, trend_regime (Derived)

    Note: Returns and spread are scaled by 100x. CVD acceleration is divided by 1e6.

    Action Space

    The agent uses fixed 50% position sizing with three possible actions:

    • 0: HOLD (No action)
    • 1: BUY (Long UP token)
    • 2: SELL (Long DOWN token)
  8. Use Share-Based PnL for Binary Markets

    master

    In binary markets, using a share-based PnL reward signal is more effective than a probability-based signal. Share-based rewards capture the asymmetric payoff structure where lower entry probabilities yield proportionally larger returns for the same price move.

    Comparison:

    • Probability-based (Less effective): pnl = (exit_price - entry_price) * dollars
    • Share-based (More effective): shares = dollars / entry_price followed by pnl = (exit_price - entry_price) * shares
    # Old (Phases 1-3): probability-based
    pnl = (exit_price - entry_price) * dollars
    
    # New (Phase 4): share-based
    shares = dollars / entry_price
    pnl = (exit_price - entry_price) * shares
  9. Avoid Reward Shaping Pitfalls in RL Training

    master

    When designing reward functions for Reinforcement Learning (RL) in trading, avoid 'shaping rewards' (micro-bonuses) that are similar in magnitude to the actual PnL signal. If bonuses for momentum, position size, or transaction costs are too large, the agent may learn to 'game' the reward function—optimizing for the bonuses rather than actual profitability.

    Signs of Reward Shaping Failure:

    • Entropy Collapse: The policy becomes nearly deterministic (e.g., dropping from 1.09 to 0.36).
    • Win Rate Divergence: A significant gap between the Buffer win rate (% of experiences with reward > 0, including bonuses) and the Cumulative win rate (% of closed trades that were actually profitable).
  10. Implement Sparse PnL Rewards

    master

    To prevent agents from gaming the reward function, use a sparse reward signal that only triggers upon position closure. This ensures the agent optimizes for realized profit rather than unrealized PnL deltas or micro-bonuses.

    Implementation Pattern:

    1. Set reward to 0 for all steps except when a position closes.
    2. Store pending rewards in a dictionary keyed by the contract ID (cid).
    3. When a position closes, calculate the PnL and pop it from the pending rewards to be used as the step reward.
    # Reward is 0 for all steps EXCEPT position close
    def _compute_step_reward(self, cid, state, action, pos):
        return self.pending_rewards.pop(cid, 0.0)
    
    # pending_rewards is set when position closes:
    # pnl = (exit_prob - entry_prob) * size
    self.pending_rewards[cid] = pnl
  11. Install Cross-Market State Fusion

    master

    To set up the environment, navigate to the experiment directory, create a virtual environment, and install the required dependencies. This project requires mlx for on-device training on Apple Silicon.

    Requirements:

    • mlx>=0.5.0
    • websockets>=12.0
    • flask>=3.0.0
    • flask-socketio>=5.3.0
    • numpy>=1.24.0
    • requests>=2.31.0
    cd experiments/03_polymarket
    python -m venv venv
    source venv/bin/activate
    pip install mlx websockets flask flask-socketio numpy requests