feat: add opportunity historical evaluation
This commit is contained in:
90
tests/test_opportunity_evaluation_service.py
Normal file
90
tests/test_opportunity_evaluation_service.py
Normal file
@@ -0,0 +1,90 @@
|
||||
"""Opportunity historical evaluation tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from coinhunter.services import opportunity_evaluation_service
|
||||
|
||||
|
||||
def _rows(start_ms: int, closes: list[float]) -> list[list[float]]:
|
||||
rows = []
|
||||
for index, close in enumerate(closes):
|
||||
open_time = start_ms + index * 3_600_000
|
||||
volume = 1_000 + index * 10
|
||||
rows.append(
|
||||
[
|
||||
float(open_time),
|
||||
close * 0.99,
|
||||
close * 1.02,
|
||||
close * 0.98,
|
||||
close,
|
||||
float(volume),
|
||||
float(open_time + 3_599_999),
|
||||
close * volume,
|
||||
]
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
class OpportunityEvaluationServiceTestCase(unittest.TestCase):
|
||||
def test_evaluate_opportunity_dataset_scores_historical_samples(self):
|
||||
start_ms = 1_767_225_600_000
|
||||
dataset = {
|
||||
"metadata": {
|
||||
"plan": {
|
||||
"intervals": ["1h"],
|
||||
"simulation_start": "2026-01-01T04:00:00Z",
|
||||
"simulation_end": "2026-01-01T07:00:00Z",
|
||||
"simulate_days": 1,
|
||||
}
|
||||
},
|
||||
"klines": {
|
||||
"GOODUSDT": {"1h": _rows(start_ms, [100, 101, 102, 103, 104, 106, 108, 109, 110])},
|
||||
"BADUSDT": {"1h": _rows(start_ms, [100, 99, 98, 97, 96, 95, 94, 93, 92])},
|
||||
},
|
||||
}
|
||||
config = {
|
||||
"market": {"default_quote": "USDT"},
|
||||
"opportunity": {
|
||||
"entry_threshold": 1.5,
|
||||
"watch_threshold": 0.6,
|
||||
"evaluation_horizon_hours": 2.0,
|
||||
"evaluation_take_profit_pct": 1.0,
|
||||
"evaluation_stop_loss_pct": 2.0,
|
||||
"evaluation_setup_target_pct": 0.5,
|
||||
"evaluation_lookback": 4,
|
||||
"top_n": 2,
|
||||
},
|
||||
}
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
dataset_path = Path(tmp_dir) / "opportunity-dataset.json"
|
||||
dataset_path.write_text(json.dumps(dataset), encoding="utf-8")
|
||||
|
||||
payload = opportunity_evaluation_service.evaluate_opportunity_dataset(
|
||||
config,
|
||||
dataset_path=str(dataset_path),
|
||||
horizon_hours=2.0,
|
||||
take_profit=0.01,
|
||||
stop_loss=0.02,
|
||||
setup_target=0.005,
|
||||
lookback=4,
|
||||
top_n=2,
|
||||
max_examples=3,
|
||||
)
|
||||
|
||||
self.assertEqual(payload["summary"]["symbols"], ["BADUSDT", "GOODUSDT"])
|
||||
self.assertEqual(payload["summary"]["interval"], "1h")
|
||||
self.assertGreater(payload["summary"]["count"], 0)
|
||||
self.assertIn("by_action", payload)
|
||||
self.assertIn("trade_simulation", payload)
|
||||
self.assertEqual(payload["rules"]["research_mode"], "disabled: dataset has no point-in-time research snapshots")
|
||||
self.assertLessEqual(len(payload["examples"]), 3)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user