fix: market data rate limiting and backtest price lookup
- Increase market_api polling cadence from 60s to 900s (15 min). The prev-day bar endpoint returns the same data all day, so polling every minute wastes API quota. 50 tickers at 15-min cadence = ~3.3 req/min, well within the 5/min rate limit. - Reduce market_api rate limit from 30/min to 5/min to match. - Fix backtest replay to query market_snapshots with data->>'c' for close prices instead of nonexistent market_data.close_price column. - Enrich backtest recommendations with prices from market_snapshots and sectors from companies table.
This commit is contained in:
@@ -86,6 +86,32 @@ class BacktestReplay:
|
||||
prev_value = config.initial_capital
|
||||
trade_log: list[dict] = []
|
||||
|
||||
# Pre-load company sectors and latest prices for enrichment
|
||||
company_sectors: dict[str, str] = {}
|
||||
company_prices: dict[str, float] = {}
|
||||
if self.pool is not None:
|
||||
try:
|
||||
sector_rows = await self.pool.fetch(
|
||||
"SELECT ticker, sector FROM companies WHERE active = TRUE"
|
||||
)
|
||||
for sr in sector_rows:
|
||||
company_sectors[sr["ticker"]] = sr["sector"] or "Unknown"
|
||||
except Exception:
|
||||
logger.debug("Could not load company sectors")
|
||||
|
||||
# Load latest market prices (use most recent close from market_snapshots JSONB)
|
||||
try:
|
||||
price_rows = await self.pool.fetch(
|
||||
"SELECT DISTINCT ON (ticker) ticker, (data->>'c')::float as close_price "
|
||||
"FROM market_snapshots WHERE snapshot_type = 'bar' "
|
||||
"ORDER BY ticker, captured_at DESC"
|
||||
)
|
||||
for pr in price_rows:
|
||||
if pr["close_price"]:
|
||||
company_prices[pr["ticker"]] = float(pr["close_price"])
|
||||
except Exception:
|
||||
logger.debug("Could not load market prices — using portfolio_pct fallback")
|
||||
|
||||
# Group recommendations by date
|
||||
recs_by_date: dict[date, list[dict]] = {}
|
||||
for rec in recs:
|
||||
@@ -94,6 +120,14 @@ class BacktestReplay:
|
||||
d = rec_date.date()
|
||||
else:
|
||||
d = rec_date
|
||||
|
||||
# Enrich rec with price and sector if missing
|
||||
ticker = rec.get("ticker", "")
|
||||
if "current_price" not in rec or not rec.get("current_price"):
|
||||
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")
|
||||
|
||||
recs_by_date.setdefault(d, []).append(rec)
|
||||
|
||||
# Iterate through each trading day
|
||||
|
||||
Reference in New Issue
Block a user