# Streaming Overview

The `tv_scraper.streaming` package provides real-time and historical market data
via TradingView's WebSocket API.

| Class | Use case |
|---|---|
| [`Streamer`](streamer.md) | Fetch OHLCV candles, indicators, forecast snapshots, and continuous price updates |

## Performance Optimizations

As of version 1.0.2, the streaming module includes WebSocket optimizations for low-latency real-time data:

- **TCP_NODELAY**: Socket option enabled to disable Nagle's algorithm, reducing packet transmission latency
- **Dual Session Subscription**: Real-time price streaming subscribes to both quote and chart sessions
- **Multi-Message Processing**: Handles QSD (quote session data) and DU (data update) messages for maximum update frequency

These optimizations deliver approximately 1 update every 3-4 seconds for active symbols, matching browser performance.

## Architecture

```
tv_scraper/streaming/
├── __init__.py          # Package exports
├── stream_handler.py    # Low-level WebSocket protocol handler
├── streamer.py          # Streamer class (candles + indicators + forecast + realtime)
└── utils.py             # Symbol validation, indicator metadata fetching
```

### StreamHandler (Low-level)

`StreamHandler` manages the raw WebSocket connection:

- Connects to `wss://data.tradingview.com/socket.io/websocket`
- Generates session identifiers (`qs_*` for quotes, `cs_*` for charts)
- Frames messages with TradingView's `~m~{length}~m~{payload}` protocol
- Initialises sessions (auth, locale, chart/quote creation, field setup)
- Applies TCP_NODELAY socket option for low-latency streaming

You rarely need to use `StreamHandler` directly — `Streamer` composes it
internally.

### Response Format

All `Streamer` methods return the standard response envelope:

```python
{
    "status": "success" | "failed",
    "data": { ... },
    "metadata": { "exchange": "...", "symbol": "...", ... },
    "error": None | "error message"
}
```

Errors are returned (not raised) from public methods.

## Quick Start

```python
from tv_scraper.streaming import Streamer

# Fetch 10 candles
s = Streamer()
result = s.get_candles(exchange="BINANCE", symbol="BTCUSDT", timeframe="1h")
print(result["data"]["ohlcv"])

# Continuous realtime price updates
for tick in s.stream_realtime_price(exchange="BINANCE", symbol="BTCUSDT"):
    print(tick["price"], tick["change_percent"])
```
