diff --git a/services/trading/backtest_replay.py b/services/trading/backtest_replay.py index 6e86839..e891d7e 100644 --- a/services/trading/backtest_replay.py +++ b/services/trading/backtest_replay.py @@ -127,6 +127,12 @@ class BacktestReplay: rec["current_price"] = company_prices.get(ticker, 50.0) if "sector" not in rec or not rec.get("sector"): rec["sector"] = company_sectors.get(ticker, "Unknown") + # Map 'id' to 'recommendation_id' for evaluate_recommendation() + if "recommendation_id" not in rec and "id" in rec: + rec["recommendation_id"] = str(rec["id"]) + # Ensure confidence is a float + if rec.get("confidence") is not None: + rec["confidence"] = float(rec["confidence"]) recs_by_date.setdefault(d, []).append(rec) @@ -139,6 +145,8 @@ class BacktestReplay: continue day_recs = recs_by_date.get(current_date, []) + act_count = 0 + skip_count = 0 # Process recommendations for this day for rec in day_recs: @@ -164,6 +172,7 @@ class BacktestReplay: ) if decision.decision == "act": + act_count += 1 ticker = decision.ticker price = rec.get("current_price", 0.0) qty = decision.computed_share_quantity or 0 @@ -183,6 +192,13 @@ class BacktestReplay: portfolio_state.active_pool -= cost portfolio_state.open_position_count += 1 + if day_recs: + logger.info( + "Backtest day %s: %d recs, %d act, %d skip, positions=%d, pool=$%.2f", + current_date, len(day_recs), act_count, len(day_recs) - act_count, + len(simulated_positions), portfolio_state.active_pool, + ) + # Simulate simple exit logic: close positions held > 5 days # (simplified — real engine uses stop-loss/take-profit) tickers_to_close = []