drift-quant / tests /test_api_v2.py
deveshc23
feat: Add Free Gradio Space support, Git LFS tracking for data artifacts, and Quant Allocator
3e33e2e
Raw History Blame Contribute Delete
5.07 kB
from __future__ import annotations
import json
from pathlib import Path
from fastapi.testclient import TestClient
from drift_quant.api.app import app
def test_api_v2_endpoints(tmp_path: Path, monkeypatch: object) -> None:
# Set up realistic artifact folder
experiments = tmp_path / "experiments"
experiments.mkdir(parents=True)
cache = tmp_path / "cache"
cache.mkdir(parents=True)
exp_id = "test-exp-001"
index = [
{
"experiment_id": exp_id,
"strategy_name": "buy_and_hold_baseline",
"strategy_version": "1.0.0",
"dataset_id": "test_ds",
"period_start": "2024-01-01 09:15:00",
"period_end_exclusive": "2024-01-10 15:30:00",
"metrics": {
"cumulative_return": 0.05,
"maximum_drawdown": -0.02,
"sharpe_ratio": 1.5,
"trade_count": 2,
"transaction_costs": 150.0,
},
"currency": "INR",
}
]
exp_payload = {
**index[0],
"config": {"initial_capital": 100000.0, "max_gross_exposure": 0.95},
"equity_curve": [
{"timestamp": "2024-01-01 09:15:00", "equity": 100000.0, "gross_exposure": 0.0},
{"timestamp": "2024-01-02 09:15:00", "equity": 102000.0, "gross_exposure": 95000.0},
{"timestamp": "2024-01-03 09:15:00", "equity": 105000.0, "gross_exposure": 0.0},
],
"trades": [
{
"symbol": "RELIANCE",
"entry_time": "2024-01-01 09:30:00",
"exit_time": "2024-01-03 15:15:00",
"quantity": 50,
"entry_price": 2000.0,
"exit_price": 2100.0,
"gross_pnl": 5000.0,
"costs": 100.0,
"net_pnl": 4900.0,
"exit_reason": "strategy_signal",
}
],
}
(experiments / "index.json").write_text(json.dumps(index), encoding="utf-8")
(experiments / f"{exp_id}.json").write_text(json.dumps(exp_payload), encoding="utf-8")
audit = {
"rows": 17808743,
"symbols": 488,
"archive_bytes": 260079380,
"archive_sha256": "039c081e",
"first_timestamp": "2019-01-01 09:15:00",
"last_timestamp": "2025-07-14 11:00:00",
"zero_volume_rows": 34867,
"invalid_ohlc_rows": 72,
"intraday_unexpected_gaps": 4894,
"symbol_stats": {
"RELIANCE": {
"rows": 39653,
"first_timestamp": "2019-01-01 09:15:00",
"last_timestamp": "2025-07-14 11:00:00",
"zero_volume_rows": 0,
"invalid_ohlc_rows": 0,
"intraday_unexpected_gaps": 5,
"bars_by_weekday": {"Monday": 7810, "Tuesday": 7975},
}
},
}
(tmp_path / "dataset_audit.json").write_text(json.dumps(audit), encoding="utf-8")
monkeypatch.setenv("DRIFT_ARTIFACTS_DIR", str(tmp_path)) # type: ignore[attr-defined]
client = TestClient(app)
# 1. Health
res = client.get("/health")
assert res.status_code == 200
assert res.json()["currency"] == "INR"
# 2. Dataset summary
res = client.get("/api/v1/dataset/summary")
assert res.status_code == 200
assert res.json()["total_rows"] == 17808743
assert res.json()["currency"] == "INR"
# 3. Symbols catalog
res = client.get("/api/v1/dataset/symbols")
assert res.status_code == 200
symbols = res.json()
assert len(symbols) == 1
assert symbols[0]["symbol"] == "RELIANCE"
assert symbols[0]["sector"] == "Energy"
# 4. Coverage timeline
res = client.get("/api/v1/dataset/coverage-timeline")
assert res.status_code == 200
assert len(res.json()["yearly"]) > 0
# 5. Strategies catalog
res = client.get("/api/v1/strategies")
assert res.status_code == 200
strategies = res.json()
assert any(s["name"] == "sector_pairs_reversion" for s in strategies)
assert any(s["name"] == "sector_cross_momentum" for s in strategies)
# 6. Attribution
res = client.get(f"/api/v1/experiments/{exp_id}/attribution")
assert res.status_code == 200
attr = res.json()
assert len(attr) == 1
assert attr[0]["symbol"] == "RELIANCE"
assert attr[0]["net_pnl"] == 4900.0
# 7. Drawdown
res = client.get(f"/api/v1/experiments/{exp_id}/drawdown")
assert res.status_code == 200
assert len(res.json()) == 3
# 8. Monthly matrix
res = client.get(f"/api/v1/experiments/{exp_id}/monthly")
assert res.status_code == 200
assert "2024" in res.json()["years"]
# 9. CSV Export trades
res = client.get(f"/api/v1/reports/{exp_id}/export-csv?kind=trades")
assert res.status_code == 200
assert "text/csv" in res.headers["content-type"]
assert "RELIANCE" in res.text
# 10. CSV Export equity
res = client.get(f"/api/v1/reports/{exp_id}/export-csv?kind=equity")
assert res.status_code == 200
assert "timestamp,equity" in res.text