mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-08-03 10:27:42 +00:00
fix: Handle failed experiments in feedback step to prevent crashes
Problem: - When Qlib Docker backtest failed (result is None), the experiment was marked as failed - However, the 'feedback' step still tried to call self.factor_summarizer.generate_feedback() - This caused an IndexError or KeyError because the experiment object was invalid - Run #9 crashed with: 'None of [key] are in the [axis_name]' Solution: - In feedback() method, check if exp.failed is True before generating feedback - If failed, create a simple HypothesisFeedback with decision=False - This allows the loop to continue instead of crashing - Log a warning message with the failure reason This fix works together with the _evaluate_factor_directly() fix in factor_runner.py to ensure that even when Docker fails, the loop continues smoothly.
This commit is contained in:
@@ -217,10 +217,27 @@ class QuantRDLoop(RDLoop):
|
||||
decision=False,
|
||||
)
|
||||
else:
|
||||
if prev_out["direct_exp_gen"]["propose"].action == "factor":
|
||||
feedback = self.factor_summarizer.generate_feedback(prev_out["running"], self.trace)
|
||||
elif prev_out["direct_exp_gen"]["propose"].action == "model":
|
||||
feedback = self.model_summarizer.generate_feedback(prev_out["running"], self.trace)
|
||||
# Handle cases where the experiment failed during execution (e.g., Docker error)
|
||||
exp = prev_out.get("running")
|
||||
if exp is not None and getattr(exp, "failed", False):
|
||||
reason = getattr(exp, "failure_reason", "Unknown failure reason")
|
||||
factor_name = "unknown"
|
||||
if hasattr(exp, "hypothesis") and exp.hypothesis is not None:
|
||||
factor_name = getattr(exp.hypothesis, "hypothesis", "unknown")
|
||||
|
||||
logger.warning(f"Skipping feedback for failed factor '{factor_name}'. Reason: {reason}")
|
||||
feedback = HypothesisFeedback(
|
||||
observations=f"Factor '{factor_name}' failed execution.",
|
||||
hypothesis_evaluation="Failed",
|
||||
new_hypothesis="Try a different approach.",
|
||||
reason=reason,
|
||||
decision=False,
|
||||
)
|
||||
else:
|
||||
if prev_out["direct_exp_gen"]["propose"].action == "factor":
|
||||
feedback = self.factor_summarizer.generate_feedback(prev_out["running"], self.trace)
|
||||
elif prev_out["direct_exp_gen"]["propose"].action == "model":
|
||||
feedback = self.model_summarizer.generate_feedback(prev_out["running"], self.trace)
|
||||
|
||||
# NOTE: DB save is handled by factor_runner.py _save_result_to_database()
|
||||
# which runs immediately after Docker execution. No duplicate save needed here.
|
||||
|
||||
Reference in New Issue
Block a user