# DepthSignal Python SDK

Official Python client for the [DepthSignal API](https://depthsignal.io) — institutional-grade orderbook microstructure intelligence for crypto markets.

**Target API**: DepthSignal REST API v1

## Requirements

- Python 3.9+
- `httpx` (installed automatically)

## Installation

```bash
pip install depthsignal
```

For HTTP/2 support:

```bash
pip install depthsignal[http2]
```

## Quick Start

```python
from depthsignal import DepthSignal

ds = DepthSignal(api_key="your-api-key")

# Orderbook features (Basic+ tier)
features = ds.orderbook_features("BTCUSDT")
for exchange, metrics in features.features.items():
    print(f"{exchange}: VPIN={metrics.get('vpin')}")

# Composite signals (Pro+ tier)
composites = ds.composites("BTCUSDT")
print(f"Directional pressure: {composites.composites.get('directional_pressure')}")

# Support/resistance zones (Pro+ tier)
sr = ds.support_resistance("BTCUSDT")
for zone in sr.zones:
    print(f"{zone['type']}: ${zone['price']} (strength: {zone['strength']})")
```

## Configuration

```python
ds = DepthSignal(
    api_key="your-api-key",
    base_url="https://api.depthsignal.io",  # default
    timeout=10.0,                             # seconds, default 10
    max_retries=2,                            # retries on 429/503/network, default 2
)
```

The client enforces HTTPS in production. HTTP is only allowed for `localhost` and `127.0.0.1` during development.

## Endpoints

### Orderbook (Basic+ tier)
```python
features = ds.orderbook_features("BTCUSDT")
composites = ds.composites("BTCUSDT")        # Pro+
sr = ds.support_resistance("BTCUSDT")        # Pro+
```

### Flow Intelligence
```python
overview = ds.flow_overview()                 # Enterprise
asset = ds.flow_asset("BTCUSDT")             # Enterprise
liqs = ds.liquidations("BTCUSDT")            # Pro+
whales = ds.large_trades("BTCUSDT")          # Pro+
cvd = ds.cvd("BTCUSDT")                      # Pro+
sf = ds.spot_futures("BTCUSDT")              # Enterprise
derivs = ds.derivatives("BTCUSDT")           # Enterprise
pos = ds.positioning("BTCUSDT")              # Enterprise
sent = ds.sentiment("BTCUSDT")              # Pro+
```

### Aggregated Timeframes (Pro+ tier)
```python
agg_feat = ds.aggregated_features("BTCUSDT", timeframe="1h")
agg_comp = ds.aggregated_composites("BTCUSDT", timeframe="4h")
```

### Historical (Pro+ tier)
```python
hist = ds.historical_features("BTCUSDT", exchange="binance", hours=24, limit=500)
hist_comp = ds.historical_composites("BTCUSDT", hours=12)
```

### Venue Analytics
```python
venue = ds.venue_selection("BTCUSDT")        # Pro+
depth = ds.depth_resilience("BTCUSDT")       # Starter+
events = ds.spread_events("BTCUSDT")         # Starter+
cost = ds.execution_cost("BTCUSDT")          # Enterprise
corr = ds.correlation("BTCUSDT", "ETHUSDT")  # Pro+
whale = ds.whale_flow("BTCUSDT")             # Enterprise
```

### Discovery (Public)
```python
symbols = ds.symbols()
tiers = ds.tiers()
health = ds.health()
```

### Real-Time Streaming (Enterprise)
```python
for event in ds.stream("BTCUSDT"):
    print(event["type"], event.get("data", {}).get("symbol"))
    if should_stop():
        break
```

## Error Handling

```python
from depthsignal import (
    DepthSignalError,
    AuthenticationError,
    TierAccessError,
    RateLimitError,
    APIConnectionError,
)

try:
    features = ds.orderbook_features("BTCUSDT")
except AuthenticationError:
    print("Invalid API key")
except TierAccessError:
    print("Upgrade your tier for this endpoint")
except RateLimitError as e:
    print(f"Rate limited — retry after {e.retry_after}s")
except APIConnectionError:
    print("Could not reach the API")
except DepthSignalError as e:
    print(f"API error {e.status_code}: {e.detail}")
```

## Context Manager

```python
with DepthSignal(api_key="your-api-key") as ds:
    features = ds.orderbook_features("BTCUSDT")
# Client is automatically closed
```

## Async Client

The SDK includes `AsyncDepthSignal` for use with `asyncio`. It mirrors every method from the sync client with `async`/`await`.

### Quick Start (Async)

```python
import asyncio
from depthsignal import AsyncDepthSignal

async def main():
    async with AsyncDepthSignal(api_key="your-api-key") as ds:
        # All methods are async — same names, same params, same return types
        features = await ds.orderbook_features("BTCUSDT")
        for exchange, metrics in features.features.items():
            print(f"{exchange}: VPIN={metrics.get('vpin')}")

        composites = await ds.composites("BTCUSDT")
        print(f"Directional pressure: {composites.composites.get('directional_pressure')}")

        # Concurrent requests
        regime, drift = await asyncio.gather(
            ds.regime("BTCUSDT"),
            ds.drift("BTCUSDT"),
        )
        print(f"Regime: {regime.regime}, Drift: {drift.drift_score}")

asyncio.run(main())
```

### Async Streaming (SSE)

```python
async with AsyncDepthSignal(api_key="your-api-key") as ds:
    async for event in ds.stream("BTCUSDT"):
        print(event["type"], event.get("data", {}).get("symbol"))
        if should_stop():
            break
```

## Thread Safety

The sync client is **not thread-safe**. Create one instance per thread, or protect calls with a lock. The async client should be used within a single event loop.

## Version Sync

Both the Python and TypeScript SDKs follow the same semantic versioning and target the same DepthSignal API version (v1). Breaking API changes are released as major version bumps in both SDKs simultaneously.

## License

MIT — Ravenna OÜ
