fix: harden Structural S/R after OHLCV writes and surface cleanup failures
Honor custom S/R tolerance as a transient detect, refresh levels after OHLCV mutations without failing committed price writes, report per-ticker S/R rebuild failures from admin cleanup, and warn in the admin UI when refresh is partial.
This commit is contained in:
@@ -23,6 +23,15 @@ from app.services import price_service
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def _refresh_structural_sr(db: AsyncSession, symbol: str) -> None:
|
||||
"""Rebuild Structural S/R after batch OHLCV writes (best-effort).
|
||||
|
||||
Price bars are already committed; an S/R failure must not discard the
|
||||
ingestion result. Shared with single-bar upsert via price_service.
|
||||
"""
|
||||
await price_service._refresh_structural_sr_best_effort(db, symbol)
|
||||
|
||||
|
||||
@dataclass
|
||||
class IngestionResult:
|
||||
"""Result of an ingestion run."""
|
||||
@@ -213,6 +222,8 @@ async def fetch_and_ingest(
|
||||
low=record.low,
|
||||
close=record.close,
|
||||
volume=record.volume,
|
||||
# One S/R rebuild at the end of the batch, not per bar.
|
||||
refresh_sr=False,
|
||||
)
|
||||
ingested_count += 1
|
||||
last_ingested = record.date
|
||||
@@ -221,12 +232,15 @@ async def fetch_and_ingest(
|
||||
await _update_progress(db, ticker.id, record.date)
|
||||
|
||||
except RateLimitError:
|
||||
# Mid-ingestion rate limit — return partial progress
|
||||
# Mid-ingestion rate limit — return partial progress after
|
||||
# refreshing S/R from whatever bars we already wrote.
|
||||
logger.warning(
|
||||
"Rate limited during ingestion for %s after %d records",
|
||||
ticker.symbol,
|
||||
ingested_count,
|
||||
)
|
||||
if ingested_count > 0:
|
||||
await _refresh_structural_sr(db, ticker.symbol)
|
||||
return IngestionResult(
|
||||
symbol=ticker.symbol,
|
||||
records_ingested=ingested_count,
|
||||
@@ -235,6 +249,9 @@ async def fetch_and_ingest(
|
||||
message=f"Rate limited. Ingested {ingested_count} records. Resume available.",
|
||||
)
|
||||
|
||||
if ingested_count > 0:
|
||||
await _refresh_structural_sr(db, ticker.symbol)
|
||||
|
||||
return IngestionResult(
|
||||
symbol=ticker.symbol,
|
||||
records_ingested=ingested_count,
|
||||
|
||||
Reference in New Issue
Block a user