117 lines
4.2 KiB
Python
117 lines
4.2 KiB
Python
import os
|
||
import sys
|
||
from datetime import datetime, timedelta
|
||
|
||
import pytest
|
||
from fastapi.testclient import TestClient
|
||
|
||
PROJECT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||
if PROJECT_DIR not in sys.path:
|
||
sys.path.insert(0, PROJECT_DIR)
|
||
|
||
from app.db import altcoin_db
|
||
from app.web import web_server
|
||
|
||
|
||
@pytest.fixture
|
||
def temp_db(monkeypatch, tmp_path):
|
||
db_path = tmp_path / "altcoin_monitor.db"
|
||
monkeypatch.setattr(altcoin_db, "DB_PATH", str(db_path))
|
||
monkeypatch.setattr(web_server, "init_db", altcoin_db.init_db)
|
||
monkeypatch.setattr(web_server, "get_review_stats", altcoin_db.get_review_stats)
|
||
monkeypatch.setattr(web_server, "get_stats", altcoin_db.get_stats)
|
||
altcoin_db.init_db()
|
||
return db_path
|
||
|
||
|
||
def test_iteration_log_supports_rule_diff_and_effect_summary(temp_db):
|
||
conn = altcoin_db.get_conn()
|
||
base_time = datetime(2026, 4, 29, 10, 0, 0)
|
||
for idx, (outcome, pnl) in enumerate([
|
||
("爆发", 12.5),
|
||
("失败", -4.2),
|
||
("横盘", 0.8),
|
||
], start=1):
|
||
conn.execute(
|
||
"""
|
||
INSERT INTO review_log (rec_id, symbol, review_time, outcome, pnl_48h, max_pnl_48h, triggered_signals, hit_signals, miss_signals, lesson)
|
||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||
""",
|
||
(
|
||
idx,
|
||
f"COIN{idx}/USDT",
|
||
(base_time + timedelta(hours=idx)).isoformat(),
|
||
outcome,
|
||
pnl,
|
||
10 + idx,
|
||
'[]',
|
||
'[]',
|
||
'[]',
|
||
f"lesson-{idx}"
|
||
)
|
||
)
|
||
conn.commit()
|
||
conn.close()
|
||
|
||
altcoin_db.log_strategy_iteration(
|
||
run_date="2026-04-29",
|
||
trigger_source="daily_review",
|
||
title="增加静K蓄力优先级",
|
||
summary="基于漏选币复盘,提高静K蓄力相关因子的优先级。",
|
||
findings=["静K蓄力类漏选较集中"],
|
||
problems=["旧参数对蓄力型起爆敏感度不足"],
|
||
actions=["提高静K蓄力权重并降低滞后信号优先级"],
|
||
changed_rules=[{"field": "signal_weights.静K蓄力", "old": 1.0, "new": 1.6}],
|
||
metrics={"reviews_done": 3},
|
||
related_symbols=["PNT/USDT"],
|
||
config_diff={
|
||
"changed": [
|
||
{"path": "signal_weights.静K蓄力", "old": 1.0, "new": 1.6},
|
||
{"path": "meta.iteration_count", "old": 4, "new": 5},
|
||
],
|
||
"added": [
|
||
{"path": "learned_rules.rule_20260429_001", "new": {"description": "静K蓄力增强"}},
|
||
],
|
||
"removed": []
|
||
},
|
||
effect_summary={
|
||
"review_count_window": 3,
|
||
"hit_rate_pct": 33.3,
|
||
"avg_pnl": 3.03,
|
||
"fail_rate_pct": 33.3,
|
||
"flat_rate_pct": 33.3,
|
||
}
|
||
)
|
||
|
||
logs = altcoin_db.get_strategy_iteration_logs(limit=5)
|
||
assert logs[0]["config_diff"]["changed"][0]["path"] == "signal_weights.静K蓄力"
|
||
assert logs[0]["effect_summary"]["avg_pnl"] == 3.03
|
||
|
||
summary = altcoin_db.get_strategy_iteration_summary(days=30)
|
||
assert summary["config_change_count"] == 3
|
||
assert summary["effect_overview"]["avg_hit_rate_pct"] == 33.3
|
||
|
||
|
||
def test_review_api_returns_diff_and_effect_fields(temp_db):
|
||
altcoin_db.log_strategy_iteration(
|
||
run_date="2026-04-29",
|
||
trigger_source="manual",
|
||
title="补充diff与效果回看",
|
||
summary="让网站能看见参数改了多少,以及改后效果。",
|
||
findings=["用户需要参数审计"],
|
||
problems=["之前只能看文字描述"],
|
||
actions=["给迭代日志增加config_diff/effect_summary"],
|
||
changed_rules=[],
|
||
metrics={"items": 1},
|
||
related_symbols=[],
|
||
config_diff={"changed": [{"path": "review.min_samples", "old": 5, "new": 4}], "added": [], "removed": []},
|
||
effect_summary={"review_count_window": 0, "hit_rate_pct": 0, "avg_pnl": 0},
|
||
)
|
||
|
||
client = TestClient(web_server.app)
|
||
resp = client.get("/api/review")
|
||
assert resp.status_code == 200
|
||
data = resp.json()
|
||
assert data["iteration_logs"][0]["config_diff"]["changed"][0]["path"] == "review.min_samples"
|
||
assert "effect_overview" in data["iteration_summary"]
|