TradingAgents/orchestrator/tests/test_quant_runner.py

77 lines
2.3 KiB
Python

"""Tests for QuantRunner._calc_confidence()."""
import json
import sqlite3
import pytest
from orchestrator.config import OrchestratorConfig
from orchestrator.contracts.error_taxonomy import ReasonCode
from orchestrator.quant_runner import QuantRunner
def _make_runner(tmp_path):
"""Create a QuantRunner with a minimal SQLite DB so __init__ succeeds."""
db_dir = tmp_path / "research_results"
db_dir.mkdir(parents=True)
db_path = db_dir / "runs.db"
with sqlite3.connect(str(db_path)) as conn:
conn.execute(
"""CREATE TABLE backtest_results (
id INTEGER PRIMARY KEY,
strategy_type TEXT,
params TEXT,
sharpe_ratio REAL
)"""
)
conn.execute(
"INSERT INTO backtest_results (strategy_type, params, sharpe_ratio) VALUES (?, ?, ?)",
("BollingerStrategy", json.dumps({"period": 20, "num_std": 2.0,
"position_pct": 0.2,
"stop_loss_pct": 0.05,
"take_profit_pct": 0.15}), 1.5),
)
cfg = OrchestratorConfig(quant_backtest_path=str(tmp_path))
return QuantRunner(cfg)
@pytest.fixture
def runner(tmp_path):
return _make_runner(tmp_path)
def test_calc_confidence_max_sharpe_zero(runner):
assert runner._calc_confidence(1.0, 0) == 0.5
def test_calc_confidence_half(runner):
result = runner._calc_confidence(1.0, 2.0)
assert result == pytest.approx(0.5)
def test_calc_confidence_full(runner):
result = runner._calc_confidence(2.0, 2.0)
assert result == pytest.approx(1.0)
def test_calc_confidence_clamped_above(runner):
result = runner._calc_confidence(3.0, 2.0)
assert result == pytest.approx(1.0)
def test_calc_confidence_clamped_below(runner):
result = runner._calc_confidence(-1.0, 2.0)
assert result == pytest.approx(0.0)
def test_get_signal_returns_reason_code_when_no_data(runner, monkeypatch):
monkeypatch.setattr(
"orchestrator.quant_runner.yf.download",
lambda *args, **kwargs: type("EmptyFrame", (), {"empty": True})(),
)
signal = runner.get_signal("AAPL", "2024-01-02")
assert signal.degraded is True
assert signal.reason_code == ReasonCode.QUANT_NO_DATA.value