improve error handling and backtest metrics calculation
This commit is contained in:
parent
8c8f7c5d36
commit
949a8c7343
@ -155,14 +155,28 @@ class DecisionEnv:
|
|||||||
else:
|
else:
|
||||||
applied_controls = self._apply_department_controls(engine, department_controls)
|
applied_controls = self._apply_department_controls(engine, department_controls)
|
||||||
|
|
||||||
|
records_list: List[Dict[str, Any]] = []
|
||||||
try:
|
try:
|
||||||
records, done = engine.step_session(session)
|
records, done = engine.step_session(session)
|
||||||
|
records_list = list(records) if records is not None else []
|
||||||
except Exception as exc: # noqa: BLE001
|
except Exception as exc: # noqa: BLE001
|
||||||
LOGGER.exception("backtest failed under action", extra={**LOG_EXTRA, "error": str(exc)})
|
LOGGER.exception("backtest failed under action", extra={**LOG_EXTRA, "error": str(exc)})
|
||||||
info = {"error": str(exc)}
|
failure_metrics = self._empty_metrics(getattr(session, "result", None))
|
||||||
return {"failure": 1.0}, -1.0, True, info
|
self._last_metrics = failure_metrics
|
||||||
|
self._last_department_controls = applied_controls
|
||||||
records_list = list(records) if records is not None else []
|
observation = self._build_observation(failure_metrics, records_list, True)
|
||||||
|
observation["failure"] = 1.0
|
||||||
|
info = {
|
||||||
|
"error": str(exc),
|
||||||
|
"weights": weights,
|
||||||
|
"department_controls": applied_controls,
|
||||||
|
"nav_series": failure_metrics.nav_series,
|
||||||
|
"trades": failure_metrics.trades,
|
||||||
|
"risk_breakdown": failure_metrics.risk_breakdown,
|
||||||
|
"session_done": True,
|
||||||
|
"raw_records": records_list,
|
||||||
|
}
|
||||||
|
return observation, -1.0, True, info
|
||||||
|
|
||||||
snapshots, trades_override = self._fetch_portfolio_records()
|
snapshots, trades_override = self._fetch_portfolio_records()
|
||||||
metrics = self._compute_metrics(
|
metrics = self._compute_metrics(
|
||||||
@ -584,3 +598,40 @@ class DecisionEnv:
|
|||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
return default
|
return default
|
||||||
return default
|
return default
|
||||||
|
|
||||||
|
def _empty_metrics(self, result: Optional[BacktestResult]) -> EpisodeMetrics:
|
||||||
|
nav_series: List[Dict[str, Any]] = []
|
||||||
|
trades: List[Dict[str, Any]] = []
|
||||||
|
risk_events: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
if result is not None:
|
||||||
|
try:
|
||||||
|
nav_series = list(result.nav_series or [])
|
||||||
|
except Exception: # noqa: BLE001
|
||||||
|
nav_series = []
|
||||||
|
try:
|
||||||
|
trades = list(result.trades or [])
|
||||||
|
except Exception: # noqa: BLE001
|
||||||
|
trades = []
|
||||||
|
try:
|
||||||
|
risk_events = list(getattr(result, "risk_events", []) or [])
|
||||||
|
except Exception: # noqa: BLE001
|
||||||
|
risk_events = []
|
||||||
|
|
||||||
|
risk_breakdown: Dict[str, int] = {}
|
||||||
|
for event in risk_events:
|
||||||
|
reason = str(event.get("reason") or "unknown")
|
||||||
|
risk_breakdown[reason] = risk_breakdown.get(reason, 0) + 1
|
||||||
|
|
||||||
|
return EpisodeMetrics(
|
||||||
|
total_return=0.0,
|
||||||
|
max_drawdown=0.0,
|
||||||
|
volatility=0.0,
|
||||||
|
nav_series=nav_series,
|
||||||
|
trades=trades,
|
||||||
|
turnover=0.0,
|
||||||
|
turnover_value=0.0,
|
||||||
|
trade_count=len(trades),
|
||||||
|
risk_count=len(risk_events),
|
||||||
|
risk_breakdown=risk_breakdown,
|
||||||
|
)
|
||||||
|
|||||||
@ -25,6 +25,6 @@
|
|||||||
"preset": "base"
|
"preset": "base"
|
||||||
},
|
},
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"activate": true
|
"activate": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,6 +27,6 @@
|
|||||||
"label": "reasoned_quality_guard",
|
"label": "reasoned_quality_guard",
|
||||||
"notes": "引导链式推理、事实核对与示例锚定。"
|
"notes": "引导链式推理、事实核对与示例锚定。"
|
||||||
},
|
},
|
||||||
"activate": false
|
"activate": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user