Spaces:
Running on Zero
Running on Zero
File size: 5,068 Bytes
3e33e2e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | 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
|