<p align="center">
  <a href="https://www.cpz-lab.com/">
    <img src="https://drive.google.com/uc?id=1JY-PoPj9GHmpq3bZLC7WyJLbGuT1L3hN" alt="CPZ" width="180">
  </a>
</p>

<h1 align="center">CPZ Python SDK</h1>

<p align="center">
  <strong>Systematic Trading, Risk Analytics, Market Data, and Multi-Broker Execution</strong>
</p>

<p align="center">
  <a href="https://pypi.org/project/cpz-ai/"><img src="https://img.shields.io/badge/version-2.0.0-blue.svg" alt="Version"></a>
  <a href="https://github.com/CPZ-Lab/cpz-py"><img src="https://img.shields.io/badge/coverage-85%25%2B-brightgreen.svg" alt="Coverage"></a>
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.9%20%7C%203.10%20%7C%203.11%20%7C%203.12-blue.svg" alt="Python"></a>
  <a href="https://github.com/CPZ-Lab/cpz-py/actions"><img src="https://img.shields.io/badge/build-passing-brightgreen.svg" alt="Build"></a>
</p>

---

## Overview

The CPZ Python SDK is the unified interface for the CPZ quantitative trading platform. It provides everything needed for systematic strategy development, from market data and execution to portfolio risk analytics.

| Module | Description |
|--------|-------------|
| **`client.risk`** | Portfolio risk analytics — VaR, Sharpe inference, Monte Carlo, stress testing, position sizing |
| **`client.execution`** | Multi-broker order management (Alpaca, IBKR) with strategy attribution |
| **`client.engine`** | Low-latency HFT engine deployment (Rust) for autonomous execution |
| **`client.data`** | Stocks, crypto, options, 800K+ FRED series, SEC filings, social sentiment, 100+ technical indicators |
| **`client.simons`** | Simons — quantitative trading strategist for analysis, code generation, and strategy review |

---

## Installation

```bash
pip install cpz-ai               # core SDK
pip install cpz-ai[risk]          # + numpy/scipy for risk analytics
pip install cpz-ai[all]           # + all optional dependencies
```

---

## Quick Start

```python
from cpz import CPZClient

client = CPZClient()

# ── Risk Analytics ──────────────────────────────────────
sharpe = client.risk.sharpe(daily_returns)
snapshot = client.risk.compute(daily_returns, spy_returns, weights)
mc = client.risk.monte_carlo(daily_returns, num_simulations=10000)

# ── Trading ─────────────────────────────────────────────
client.execution.use_broker("alpaca", environment="paper")
order = client.execution.order(symbol="AAPL", qty=10, side="buy", strategy_id="my-strat")

# ── Market Data ─────────────────────────────────────────
bars = client.data.bars("AAPL", timeframe="1D", limit=100)
quotes = client.data.quotes(["AAPL", "MSFT", "GOOGL"])
gdp = client.data.economic("GDP")

# ── Simons (Quant Strategist) ───────────────────────────
response = client.simons.chat("Analyze AAPL for momentum trading")
print(response.content)
```

---

## Risk Analytics

Comprehensive quantitative risk computation powered by numpy/scipy. Install with `pip install cpz-ai[risk]`.

The risk-free rate is automatically fetched from FRED (3-Month Treasury) on first use. All methods accept daily returns as a list of floats.

### Core Metrics

```python
from cpz import CPZClient

client = CPZClient()

# Individual metrics
sharpe = client.risk.sharpe(daily_returns)               # Annualized Sharpe ratio
sortino = client.risk.sortino(daily_returns)              # Sortino (downside vol only)
vol = client.risk.volatility(daily_returns)               # Annualized volatility (%)
mdd = client.risk.max_drawdown(daily_returns)             # Maximum drawdown (%)
b = client.risk.beta(daily_returns, spy_returns)          # Beta vs benchmark
a = client.risk.alpha(daily_returns, spy_returns)         # Jensen's alpha (annualized)

# Full risk snapshot (all metrics at once)
snapshot = client.risk.compute(
    daily_returns=portfolio_returns,
    benchmark_returns=spy_returns,
    position_weights={"AAPL": 0.4, "NVDA": 0.35, "BTC/USD": 0.25},
    total_exposure=100000,
)
print(f"VaR 95%: {snapshot.portfolio_var_95}%")
print(f"Sharpe: {snapshot.sharpe_ratio}, Sortino: {snapshot.sortino_ratio}")
print(f"Beta: {snapshot.beta}, Alpha: {snapshot.alpha}")
print(f"Calmar: {snapshot.calmar_ratio}, Treynor: {snapshot.treynor_ratio}")
print(f"Information Ratio: {snapshot.information_ratio}")
print(f"Risk Score: {snapshot.risk_score}/100")
```

### Sharpe Inference (Lopez de Prado Framework)

Statistical significance testing for the Sharpe ratio. Implements all 5 corrections from Lopez de Prado (2012, 2018):

1. **Non-normality** — SE adjusted for skewness and kurtosis
2. **Serial correlation** — Lo (2002) autocorrelation adjustment
3. **Probabilistic Sharpe Ratio (PSR)** — P(true Sharpe > benchmark)
4. **Deflated Sharpe Ratio (DSR)** — Multiple-testing correction
5. **Minimum Track Record Length** — How long before the Sharpe is credible?

```python
# Is this strategy actually skilled, or just lucky?
inference = client.risk.sharpe_inference(daily_returns, num_trials=20)

print(f"Annualized Sharpe: {inference.annualized_sharpe}")
print(f"p-value: {inference.p_value}")
print(f"Significant at 95%? {inference.is_significant_95}")
print(f"PSR (prob true SR > 0): {inference.psr:.1%}")
print(f"DSR (adjusted for 20 trials): {inference.deflated_sharpe}")
print(f"Lo-adjusted Sharpe: {inference.lo_adjusted_sharpe}")
print(f"Min track record needed: {inference.min_track_record_months} months")
print(f"95% CI: {inference.confidence_interval_95}")
```

### Value at Risk

```python
# Parametric (Gaussian) VaR
var_95 = client.risk.parametric_var(daily_returns, confidence=0.95)
var_99 = client.risk.parametric_var(daily_returns, confidence=0.99)

# Historical simulation VaR
hist_var = client.risk.historical_var(daily_returns, confidence=0.95)

# Monte Carlo VaR (10,000 simulated paths)
mc = client.risk.monte_carlo(daily_returns, num_simulations=10000, horizon_days=5, seed=42)
print(f"VaR 95%: {mc.var_95}%, VaR 99%: {mc.var_99}%")
print(f"Expected Shortfall 95%: {mc.expected_shortfall_95}%")
print(f"Worst case: {mc.worst_case}%, Best case: {mc.best_case}%")
print(f"Percentiles: {mc.percentiles}")
```

### Drawdown Analysis

```python
dd = client.risk.drawdown_analysis(daily_returns)
print(f"Current drawdown: {dd.current_drawdown}%")
print(f"Max drawdown: {dd.max_drawdown}%, Duration: {dd.max_drawdown_duration_days} days")
print(f"Number of drawdowns: {dd.num_drawdowns}")
print(f"Avg recovery: {dd.avg_recovery_days} days")
print(f"Time underwater: {dd.underwater_pct}%")
```

### Tail Risk

```python
tail = client.risk.tail_risk(daily_returns)
print(f"Skewness: {tail.skewness}, Kurtosis: {tail.kurtosis}")
print(f"Normal distribution? {tail.is_normal} (Jarque-Bera p={tail.jarque_bera_p})")
print(f"Cornish-Fisher VaR 95%: {tail.cornish_fisher_var_95}%")  # better for fat tails
print(f"Max daily loss: {tail.max_daily_loss}%")
```

### Position Sizing

```python
sizing = client.risk.position_size(
    portfolio_value=100000,
    daily_returns=strategy_returns,
    risk_per_trade_pct=1.0,
    target_volatility_pct=15.0,
)
print(f"Kelly fraction: {sizing.kelly_fraction}")
print(f"Half-Kelly (recommended): {sizing.half_kelly}")
print(f"Recommended size: ${sizing.recommended_size} ({sizing.recommended_pct}%)")
```

### Factor Exposure

```python
exposure = client.risk.factor_exposure(
    daily_returns=portfolio_returns,
    factor_returns={"Market": spy_returns, "Size": smb_returns, "Value": hml_returns},
)
print(f"Market beta: {exposure.factors['Market']}")
print(f"R²: {exposure.r_squared}")
print(f"Systematic risk: {exposure.systematic_risk_pct}%")
print(f"Idiosyncratic risk: {exposure.idiosyncratic_risk_pct}%")
```

### Stress Testing

```python
# Run all 7 historical crisis scenarios against your positions
impacts = client.risk.stress_test_all({"AAPL": 0.4, "TLT": 0.2, "GLD": 0.15, "BTC/USD": 0.25})
for scenario, impact in impacts.items():
    print(f"  {scenario}: {impact}%")
# Applies correct shocks per asset class (equities, bonds, commodities, crypto)
```

### Rolling Metrics

```python
rolling = client.risk.rolling_metrics(daily_returns, spy_returns, window=20)
# rolling.sharpe   — list of rolling Sharpe ratios
# rolling.volatility — list of rolling annualized vol
# rolling.beta     — list of rolling beta vs benchmark
# rolling.var_95   — list of rolling VaR
```

### Correlation

```python
corr = client.risk.correlation_matrix({"strat_a": returns_a, "strat_b": returns_b})
risk = client.risk.correlation_risk({"strat_a": returns_a, "strat_b": returns_b})
```

### Risk-Free Rate

Automatically fetched from FRED (3-Month Treasury Bill) on first use. Override manually:

```python
client.risk.set_risk_free_rate(0.043)  # 4.3% annual
```

---

## Trading

### Broker Configuration

```python
from cpz import CPZClient

client = CPZClient()

# Single account
client.execution.use_broker("alpaca", environment="paper")
client.execution.use_broker("alpaca", environment="live")

# Multi-account: select by account ID
client.execution.use_broker("alpaca", account_id="PA3FHUB575J3")
```

### Order Placement

```python
# Simple order
order = client.execution.order(
    symbol="AAPL",
    qty=10,
    side="buy",
    strategy_id="my-strategy"
)

# Full control
from cpz import OrderSubmitRequest, OrderSide, OrderType, TimeInForce

request = OrderSubmitRequest(
    symbol="AAPL",
    side=OrderSide.BUY,
    qty=10,
    order_type=OrderType.LIMIT,
    time_in_force=TimeInForce.GTC,
    limit_price=150.00,
    strategy_id="my-strategy"
)
order = client.execution.submit_order(request)
```

### Account and Positions

```python
account = client.execution.get_account()
print(f"Buying Power: ${account.buying_power:,.2f}")

positions = client.execution.get_positions()
for pos in positions:
    print(f"{pos.symbol}: {pos.qty} shares @ ${pos.avg_entry_price}")
```

---

## HFT Engine

Deploy strategies to the Rust HFT engine for autonomous microsecond-latency execution.

```python
# Check engine status
status = client.engine.status()
print(f"Active executors: {status.active_executors}")

# Deploy a strategy
client.engine.deploy(
    strategy_id="my-strategy",
    symbols=["AAPL", "NVDA"],
    broker="alpaca",
    environment="paper",
    strategy_type="momentum",
    params={"lookback": 20, "threshold": 0.02},
    risk={"max_position_size_usd": 10000, "max_loss_per_day_usd": 1000},
)

# Stop a strategy
client.engine.stop("my-strategy")

# List active executors
executors = client.engine.list_executors()
```

---

## Data

### Market Data

```python
# Stock bars
bars = client.data.bars("AAPL", timeframe="1D", limit=100)

# Crypto bars
btc = client.data.bars("BTC/USD", timeframe="1H", limit=50)

# Latest quotes
quotes = client.data.quotes(["AAPL", "MSFT", "GOOGL"])

# News articles
news = client.data.news("TSLA", limit=10)

# Options chain
options = client.data.options("AAPL", option_type="call")
```

### Economic Data (FRED)

```python
# 800,000+ economic time series
gdp = client.data.economic("GDP")
unemployment = client.data.economic("UNRATE", limit=12)
cpi = client.data.economic("CPIAUCSL")
fed_rate = client.data.economic("FEDFUNDS")

# Search
results = client.data.fred.search("housing prices")
```

### SEC Filings (EDGAR)

```python
filings = client.data.filings("AAPL", form="10-K", limit=5)
facts = client.data.edgar.get_facts("AAPL")
insider = client.data.edgar.insider_transactions("TSLA")
```

### Social Sentiment

```python
sentiment = client.data.sentiment("GME")
trending = client.data.trending()
posts = client.data.social.get_posts(symbols=["AAPL"], source="reddit")
```

### Technical Indicators

> Requires Twelve Data connected in Settings > Data page.

```python
# Trend
sma = client.data.sma("AAPL", period=20)
ema = client.data.ema("AAPL", period=20)
bbands = client.data.bbands("AAPL", period=20)
ichimoku = client.data.ichimoku("AAPL")

# Momentum
rsi = client.data.rsi("AAPL", period=14)
macd = client.data.macd("AAPL")
stoch = client.data.stoch("AAPL")
adx = client.data.adx("AAPL", period=14)

# Volatility
atr = client.data.atr("AAPL", period=14)

# Volume
obv = client.data.obv("AAPL")

# Any TwelveData indicator by name
custom = client.data.indicator("stochrsi", "AAPL", time_period=14)
```

---

## Simons — Quantitative Trading Strategist

Simons is a specialized quantitative trading strategist built into the SDK. It provides trading analysis, strategy development, code generation, and debugging.

> Enable the `simons` scope on your API key in [Settings > API Keys](https://ai.cpz-lab.com/settings?tab=api-keys)

```python
# Chat
response = client.simons.chat("Analyze AAPL for momentum trading")
print(response.content)

# Streaming
for chunk in client.simons.stream("Write a mean-reversion backtest"):
    if chunk.type == "text":
        print(chunk.content, end="", flush=True)

# With strategy context
response = client.simons.chat(
    message="Review my strategy's risk profile",
    strategy_id=strategy_id,
    mode="ask"   # "ask" (read-only), "agent" (code changes), "debug"
)

# Memory
memory = client.simons.get_memory()
client.simons.update_memory(
    preferences={"risk_profile": "moderate"},
    facts=["Prefers momentum strategies"]
)
```

---

## Architecture

```
CPZClient
├── risk               Portfolio risk analytics (numpy/scipy)
│   ├── compute()      Full risk snapshot
│   ├── sharpe()       Sharpe ratio
│   ├── sortino()      Sortino ratio
│   ├── beta()         Beta vs benchmark
│   ├── alpha()        Jensen's alpha
│   ├── volatility()   Annualized vol
│   ├── max_drawdown() Max drawdown
│   ├── parametric_var()   Gaussian VaR
│   ├── historical_var()   Historical VaR
│   ├── monte_carlo()      Monte Carlo VaR
│   ├── sharpe_inference() Lopez de Prado framework (PSR, DSR)
│   ├── drawdown_analysis() Drawdown decomposition
│   ├── tail_risk()        Skewness, kurtosis, Cornish-Fisher
│   ├── position_size()    Kelly criterion + vol targeting
│   ├── factor_exposure()  OLS factor decomposition
│   ├── stress_test_all()  Historical crisis scenarios
│   ├── rolling_metrics()  Rolling Sharpe, vol, beta
│   ├── correlation_matrix() Pairwise correlations
│   └── correlation_risk()   Avg off-diagonal correlation
│
├── execution          Trading operations
│   ├── use_broker()   Configure broker
│   ├── order()        Place orders
│   ├── get_account()  Account info
│   └── get_positions() Current positions
│
├── engine             HFT engine (Rust)
│   ├── status()       Engine health
│   ├── deploy()       Deploy strategy
│   ├── stop()         Stop strategy
│   └── list_executors() Active executors
│
├── data               Market and reference data
│   ├── bars()         OHLCV price data
│   ├── quotes()       Real-time quotes
│   ├── news()         News articles
│   ├── options()      Options chains
│   ├── economic()     FRED (800K+ series)
│   ├── filings()      SEC EDGAR
│   ├── sentiment()    Social sentiment
│   ├── [indicators]   100+ technical indicators
│   └── [providers]    Direct provider access
│
├── simons             Quantitative trading strategist
│   ├── chat()         Analysis and code generation
│   ├── stream()       Streaming responses
│   ├── get_memory()   User preferences
│   └── update_memory() Update preferences
│
└── platform           Platform services
    ├── health()       Platform status
    └── list_tables()  Available tables
```

---

## Configuration

| Variable | Description | Required |
|----------|-------------|----------|
| `CPZ_AI_API_KEY` | CPZ API key | Yes |
| `CPZ_AI_SECRET_KEY` | CPZ API secret | Yes |
| `CPZ_AI_STRATEGY_ID` | Strategy ID for orders | For trading |

Get credentials at [ai.cpz-lab.com/settings](https://ai.cpz-lab.com/settings?tab=api-keys).

---

## Error Handling

```python
from cpz.common.errors import CPZBrokerError

try:
    order = client.execution.order(symbol="AAPL", qty=10, side="buy", strategy_id="my-strat")
except CPZBrokerError as e:
    print(f"Order failed: {e}")
```

---

## Testing

```bash
pytest --cov=cpz --cov-report=term-missing
```

| Python | Status |
|--------|--------|
| 3.9 | Supported |
| 3.10 | Supported |
| 3.11 | Supported |
| 3.12 | Supported |

---

## Support

- **Platform**: [ai.cpz-lab.com](https://ai.cpz-lab.com/)
- **Repository**: [github.com/CPZ-Lab/cpz-py](https://github.com/CPZ-Lab/cpz-py)
- **Email**: contact@cpz-lab.com

---

<p align="center">
  <sub>Built by <a href="https://www.cpz-lab.com/">CPZ</a></sub>
</p>
