Files
myquant/finance/tests/test_agents.py
T
Simon 73d191b43a feat: 量化引擎加固 — 新增测试 + 数据/因子/回测层优化
- 新增 finance/tests/ 6 个测试套件(agents/backtest/dao_upsert/factors/features/fundamental_lookahead)
- 数据层: data_manager / dao 优化,新增 upsert 逻辑
- 因子层: 基本面因子抽象定位 _mapping、ROE/PE/PB 重构
- 回测层: vectorbt/engine 大改动(251 行),report 增强
- ML 层: features/backtest_integration 特征工程与回测优化
- CLI: agent_cli 重构
- config/settings 扩充配置项
2026-08-31 14:01:06 +08:00

87 lines
2.9 KiB
Python

"""
Agent 层回归测试:RiskAgent 配置集中可用性 + Orchestrator 每日流程步骤隔离。
"""
import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import numpy as np
import pandas as pd
import pytest
from unittest.mock import patch
from agents.risk_agent import RiskAgent
from agents.orchestrator import AgentOrchestrator, TOTAL_STEPS
def _flat_dm():
"""给出平淡行情 → 风险 low。"""
class _DM:
def get_daily(self, code):
idx = pd.date_range('2025-01-01', periods=300, freq='B').strftime('%Y%m%d')
close = np.linspace(100, 100 + 0.03 * 300, 300) + np.random.default_rng(0).normal(0, 0.2, 300)
return pd.DataFrame({'trade_date': idx, 'close': close})
return _DM()
def _hot_dm():
class _DM:
def get_daily(self, code):
idx = pd.date_range('2025-01-01', periods=300, freq='B').strftime('%Y%m%d')
close = 100 * np.exp(np.cumsum(np.random.default_rng(1).normal(0, 0.03, 300)))
return pd.DataFrame({'trade_date': idx, 'close': close})
return _DM()
def test_risk_config_low_level():
r = RiskAgent(dm=_flat_dm()).execute()
assert r['risk_level'] in ('low', 'medium', 'high')
assert r['target_exposure'] in (0.85, 0.60, 0.30)
def test_risk_config_high_level():
r = RiskAgent(dm=_hot_dm()).execute()
assert r['risk_level'] in ('high', 'medium')
class _FailAgent:
def execute(self, **kw):
raise RuntimeError("boom")
class _OkAgent:
def execute(self, **kw):
return {"report_path": "/tmp/x.md", "risk_level": "low",
"target_exposure": 0.8, "top_picks": [], "date": "20260601"}
class _FakeDM:
def get_stock_list(self):
return pd.DataFrame(index=['000001.SZ', '600519.SH'])
def sync_daily(self, code):
return 5
class _FakeSent:
def get_scope_stocks(self):
return ["000001.SZ", "600519.SH"]
def compute(self, *a, **k):
return pd.DataFrame({"news_sent_5": [0.1, 0.2]})
def test_run_daily_steps_isolated():
"""risk/selection 抛错被隔离,report/sentiment/sync 仍成功。"""
with patch('database.dao.get_latest_trade_date', side_effect=lambda c: "20260530"):
orch = AgentOrchestrator(dm=_FakeDM(), sent=_FakeSent())
orch.agents = {"risk": _FailAgent(), "selection": _FailAgent(),
"report": _OkAgent(), "research": _OkAgent()}
res = orch.run_daily(date="20260601")
assert "risk" in res and isinstance(res["risk"], dict) and "error" in res["risk"]
assert "selection" in res and isinstance(res["selection"], dict) and "error" in res["selection"]
# 失败不中断:report/sentiment 仍成功
assert "report" in res and "error" not in res["report"]
assert isinstance(res.get("sentiment"), pd.DataFrame)
def test_orchestrator_total_steps_is_5():
assert TOTAL_STEPS == 5