fix: backtest replay field mapping and logging
- Map DB 'id' field to 'recommendation_id' for evaluate_recommendation() - Ensure confidence is cast to float (asyncpg may return Decimal) - Add per-day logging showing rec count, act/skip, positions, pool balance - Helps diagnose why backtests produce 0 trades
This commit is contained in:
@@ -127,6 +127,12 @@ class BacktestReplay:
|
|||||||
rec["current_price"] = company_prices.get(ticker, 50.0)
|
rec["current_price"] = company_prices.get(ticker, 50.0)
|
||||||
if "sector" not in rec or not rec.get("sector"):
|
if "sector" not in rec or not rec.get("sector"):
|
||||||
rec["sector"] = company_sectors.get(ticker, "Unknown")
|
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)
|
recs_by_date.setdefault(d, []).append(rec)
|
||||||
|
|
||||||
@@ -139,6 +145,8 @@ class BacktestReplay:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
day_recs = recs_by_date.get(current_date, [])
|
day_recs = recs_by_date.get(current_date, [])
|
||||||
|
act_count = 0
|
||||||
|
skip_count = 0
|
||||||
|
|
||||||
# Process recommendations for this day
|
# Process recommendations for this day
|
||||||
for rec in day_recs:
|
for rec in day_recs:
|
||||||
@@ -164,6 +172,7 @@ class BacktestReplay:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if decision.decision == "act":
|
if decision.decision == "act":
|
||||||
|
act_count += 1
|
||||||
ticker = decision.ticker
|
ticker = decision.ticker
|
||||||
price = rec.get("current_price", 0.0)
|
price = rec.get("current_price", 0.0)
|
||||||
qty = decision.computed_share_quantity or 0
|
qty = decision.computed_share_quantity or 0
|
||||||
@@ -183,6 +192,13 @@ class BacktestReplay:
|
|||||||
portfolio_state.active_pool -= cost
|
portfolio_state.active_pool -= cost
|
||||||
portfolio_state.open_position_count += 1
|
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
|
# Simulate simple exit logic: close positions held > 5 days
|
||||||
# (simplified — real engine uses stop-loss/take-profit)
|
# (simplified — real engine uses stop-loss/take-profit)
|
||||||
tickers_to_close = []
|
tickers_to_close = []
|
||||||
|
|||||||
Reference in New Issue
Block a user