WebSocket Real-Time Data Stream Guide

This document explains how to use WebSocket to receive real-time market data in backtrader-ccxt.

Table of Contents

  1. Overview

  2. Installation

  3. Three Data Fetching Methods Compared

  4. Using WebSocket

  5. Configuration Parameters

  6. Troubleshooting


Overview

backtrader-ccxt supports three data fetching methods:

| Method | Latency | API Quota | Complexity | Dependency |

|--------|---------|-----------|------------|------------|

| REST Polling| High (per-minute requests) | High | Low | ccxt only |

|Multi-threaded| Medium | Medium | Medium | ccxt only |

|WebSocket|Very low (push)|Very low| Medium |ccxt.pro|

WebSocket Advantages

  • Low latency: Data is pushed by the exchange, no polling needed

  • Saves quota: Does not consume REST API request quota

  • Real-time: New bars pushed immediately after candle close

  • Multi-symbol: Subscribe to multiple trading pairs simultaneously


Installation

1. Install ccxt.pro

pip install ccxtpro

```bash

### 2. Verify Installation

```python
import ccxt.pro
print(ccxt.__version__)  # Should display version number

```bash

- --

## Three Data Fetching Methods Compared

### Method 1: REST Polling (Default)

```python
data = store.getdata(
    dataname='BTC/USDT',
    timeframe=bt.TimeFrame.Minutes,
    compression=1,

# Without use_websocket, defaults to REST

)

```bash

- *Characteristics**:
- Makes one HTTP request per minute
- Suitable for infrequent strategies
- Simple and reliable

### Method 2: Multi-threaded

```python
data = store.getdata(
    dataname='BTC/USDT',
    timeframe=bt.TimeFrame.Minutes,
    compression=1,
    use_threaded_data=True,  # Enable multi-threading

)

```bash

- *Characteristics**:
- Background thread fetches data on schedule
- Main thread is not blocked
- Still consumes REST API quota

### Method 3: WebSocket (Recommended)

```python
data = store.getdata(
    dataname='BTC/USDT',
    timeframe=bt.TimeFrame.Minutes,
    compression=1,
    use_websocket=True,  # Use WebSocket

)

```bash

- *Characteristics**:
- Ultra-low latency
- Exchange pushes data actively
- Most quota-efficient

- --

## Using WebSocket

### Basic Example

```python
import backtrader as bt
from backtrader.stores.ccxtstore import CCXTStore
from backtrader.feeds.ccxtfeed import CCXTFeed

# Create Store

store = CCXTStore(
    exchange='okx',
    currency='USDT',
    config={'apiKey': 'xxx', 'secret': 'xxx', 'password': 'xxx'},
)

# Create data feed with WebSocket

data = CCXTFeed(
    store=store,
    dataname='BTC/USDT',
    timeframe=bt.TimeFrame.Minutes,
    compression=1,
    fromdate=datetime.utcnow() - timedelta(minutes=100),  # Historical data
    backfill_start=True,      # Load historical data first
    historical=False,         # Continue in live mode after history
    use_websocket=True,       # Enable WebSocket

)

cerebro = bt.Cerebro()
cerebro.adddata(data)
cerebro.run()

```bash

### Complete Strategy Example

```python
import backtrader as bt
from backtrader.stores.ccxtstore import CCXTStore

class MyStrategy(bt.Strategy):
    def __init__(self):
        self.dataclose = self.data.close

    def next(self):
        if len(self.data) >= 10:  # Wait for enough data
            print(f"Price: {self.data.close[0]}")

# Create engine

cerebro = bt.Cerebro()

# Add strategy

cerebro.addstrategy(MyStrategy)

# Set initial capital

cerebro.broker.setcash(1000)

# Create Store

store = CCXTStore(
    exchange='okx',
    currency='USDT',
    config={'apiKey': 'your_key', 'secret': 'your_secret', 'password': 'your_pass'}
)

# Create data feed - using WebSocket

data = store.getdata(
    dataname='BTC/USDT',
    name='BTC/USDT',
    timeframe=bt.TimeFrame.Minutes,
    compression=1,
    fromdate=datetime.utcnow() - timedelta(minutes=100),
    use_websocket=True,
    backfill_start=True,
    historical=False
)

cerebro.adddata(data)
cerebro.run()

```bash

- --

## Configuration Parameters

### CCXTFeed Parameters

| Parameter | Default | Description |

|-----------|---------|-------------|

| `use_websocket` | `False` | Enable WebSocket |

| `use_threaded_data` | `False` | Enable multi-threading |

| `ohlcv_limit` | `100` | Max number of bars per fetch |

| `drop_newest` | `False` | Drop newest bar (may be incomplete) |

| `ws_reconnect_delay` | `5.0` | WebSocket reconnect delay (seconds) |

| `ws_max_reconnect_delay` | `60.0` | Max WebSocket reconnect delay (seconds) |

| `debug` | `False` | Enable debug output |

### WebSocket Supported Exchanges

The following exchanges support ccxt.pro WebSocket:

| Exchange | Support Status |

|----------|---------------|

| Binance |  Full support |

| OKX |  Full support |

| Bybit |  Full support |

| KuCoin |  Full support |

| Bitget |  Partial support |

| Kraken |  Partial support |

> **Note**: WebSocket implementations may vary by exchange. Please verify with actual testing.

- --

## Data Flow

### WebSocket Data Flow

```bash
┌─────────────────────────────────────────────────────────────┐
│               Exchange WebSocket Server                      │
│                                                             │
│                          Push                               │
│                                                             │
┌────────────────────────┴────────────────────────────────────┐
│          ccxt.pro WebSocket Client (background thread)       │
│                                                             │
│                         watch_ohlcv()                       │
│                                                             │
│                 ┌──────┴──────────────┐                      │
│                                                            │
│             ┌───┴────┐         ┌─────┴──────────┐           │
│              Queue            CCXTWebSocket              │
│             └───┬────┘             Manager                 │
│                               └─────────────────┘           │
│                                                             │
│                                                             │
┌────────────────┴────────────────────────────────────────────┐
│                  backtrader main thread                       │
│                                                              │
│  cerebro.run()  next()  _load()  _load_bar()            │
│                                                             │
│                      Read from Queue                        │
│                                                             │
│                 ┌───┴────────┐                               │
│                  CCXTFeed                                  │
│                 └────────────┘                               │
└──────────────────────────────────────────────────────────────┘

```bash

### Workflow

1. **Historical Data Loading**(REST API)
   - Uses REST API to load historical bars on startup
   - Used to initialize technical indicators (e.g., Bollinger Bands, ATR)
   - Does not trigger any trading signals

2.**Switch to Live Mode**(WebSocket)

   - Sends `LIVE` notification after historical data loading completes
   - Starts WebSocket connection
   - Subscribes to real-time OHLCV data

3.**Real-Time Data Push**

   - Exchange pushes new bar data every minute
   - Placed into queue via WebSocket callback
   - Main thread reads from queue and updates strategy

1. **Disconnect Reconnection**
   - Automatically detects connection status
   - Exponential backoff reconnection (1s  2s  4s...)
   - Auto-restores subscriptions after reconnect

- --

## Troubleshooting

### Issue 1: WebSocket Not Available

- *Error message**:

```bash
[WS] WebSocket not available. Install ccxt.pro: pip install ccxtpro

```bash

- *Solution**:

```bash
pip install ccxtpro

```bash

### Issue 2: Connection Failure

- *Error message**:

```bash
WebSocket connection error: ...

```bash

- *Possible causes**:
1. Network issues
2. Exchange maintenance
3. Incorrect API keys

- *Solutions**:
- Check network connection
- Verify API keys
- Check exchange status page

### Issue 3: No Data Push

- *Troubleshooting steps**:
1. Check if the trading pair is correct
2. Confirm the exchange supports WebSocket for that pair
3. Enable `debug=True` for detailed info

```python
data = store.getdata(
    ...
    debug=True,  # Enable debug output

)

```bash

### Issue 4: Duplicate or Missing Data

- *Possible causes**:
- Timezone issues
- Inaccurate exchange clock

- *Solutions**:
- Use `drop_newest=True` to drop potentially incomplete newest bar
- Ensure system time is accurate

- --

## Best Practices

### 1. Production Configuration

```python
data = store.getdata(
    dataname='BTC/USDT',
    timeframe=bt.TimeFrame.Minutes,
    compression=1,
    fromdate=datetime.utcnow() - timedelta(minutes=500),
    backfill_start=True,
    historical=False,
    use_websocket=True,          # Use WebSocket
    ohlcv_limit=100,
    drop_newest=True,            # Drop potentially incomplete bars
    ws_reconnect_delay=5.0,       # Reconnect delay
    ws_max_reconnect_delay=60.0,  # Max reconnect delay

)

```bash

### 2. Multi-Symbol Subscription

```python

# Create data feeds for multiple trading pairs

symbols = ['BTC/USDT', 'ETH/USDT', 'MINA/USDT:USDT']

for symbol in symbols:
    data = store.getdata(
        dataname=symbol,
        timeframe=bt.TimeFrame.Minutes,
        use_websocket=True,
        ...
    )
    cerebro.adddata(data)

```bash

### 3. Error Handling

Add error handling in your strategy:

```python
class MyStrategy(bt.Strategy):
    def notify_data(self, data, status, *args, **kwargs):
        if status == data.DISCONNECTED:
            self.log('[ERROR] Data connection lost!')

# Add alerting logic here

    def notify_order(self, order):
        if order.status in [order.Rejected, order.Margin]:
            self.log(f'[ERROR] Order failed: {order.status}')

```bash

- --

## Performance Comparison

### API Calls (Running for 1 Hour)

| Method | API Calls | Notes |

|--------|-----------|-------|

| REST Polling | ~60 | One request per minute |

| Multi-threaded | ~60 | Still REST, just runs in background |

| WebSocket | ~2 | Only initial connect + possible reconnects |

### Data Latency

| Method | Latency |

|--------|---------|

| REST Polling | 100-500ms |

| WebSocket | 10-50ms |

- --

## Related Documentation

- [CCXT Official Docs](<https://docs.ccxt.com/)>
- [ccxt.pro Docs](<https://docs.ccxt.com/#pro)>
- [Backtrader Docs](<https://www.backtrader.com/docu/)>