feat: add candle time-sort and duplicate timestamp validation to POST /predict

Sort incoming candles by their time field in ascending chronological order
before processing to ensure correct feature engineering regardless of input
order. Also validate that no duplicate timestamps are present, returning
HTTP 400 with details if duplicates are found.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marko Djordjevic 2026-02-18 11:28:02 +01:00
parent ff952aa083
commit d75b05b585
2 changed files with 16 additions and 3 deletions

View file

@ -657,6 +657,19 @@ async def predict(request: PredictRequest):
logger.info(f"Predict request: {request.pair or 'unknown'} {request.timeframe or 'unknown'}, {len(request.candles)} candles")
# Auto-sort candles by time in ascending order to ensure chronological processing
# regardless of the order in which the client sends them.
candles_sorted = sorted(request.candles, key=lambda c: c.time)
# Validate that there are no duplicate timestamps after sorting.
times = [c.time for c in candles_sorted]
duplicate_times = [t for i, t in enumerate(times) if i > 0 and t == times[i - 1]]
if duplicate_times:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=f"Duplicate candle timestamps detected: {duplicate_times[:5]}"
)
# Grab model reference under lock to prevent reading a partially-swapped model
with _model_swap_lock:
current_model = state.model
@ -669,8 +682,8 @@ async def predict(request: PredictRequest):
)
try:
# Convert candles to list of dicts
candles_data = [candle.model_dump() for candle in request.candles]
# Convert sorted candles to list of dicts
candles_data = [candle.model_dump() for candle in candles_sorted]
# Preprocess candles (feature engineering + windowing)
X, window_times = preprocess_candles(candles_data, state.pipeline_config)