RINKING / models /base_model.py
openhands
openhands
Fix 7 bugs found in full online testing; 89/89 tests green, 0 skips
1f64f81
Raw History Blame Contribute Delete
1.78 kB
"""Common interface implemented by every forecasting model, so the backtester
and UI can treat them interchangeably."""
import numpy as np
import pandas as pd
from abc import ABC, abstractmethod
def validate_history_and_horizon(history, horizon: int, model_name: str) -> None:
"""Enforce the BaseForecastModel input contract for every model: a
horizon of at least 1, and a price history that is entirely finite.
A NaN/inf close (a vendor data glitch, a forming candle read mid-write)
must surface as a ValueError the caller can report per model, not leak
into a fit that silently produces a number anyway.
"""
if horizon < 1:
raise ValueError(f"{model_name}: horizon must be >= 1, got {horizon}.")
values = np.asarray(pd.Series(history).astype(float), dtype=float)
if not np.all(np.isfinite(values)):
raise ValueError(
f"{model_name}: price history contains NaN/inf. This usually means "
f"a data glitch left a missing or malformed candle -- re-fetch the "
f"history and try again."
)
class BaseForecastModel(ABC):
name = "base"
@abstractmethod
def predict(self, history: pd.Series, horizon: int = 1, features: pd.DataFrame = None) -> list:
"""Forecast `horizon` future closing prices from past closes
(oldest -> newest).
`features`, when given, holds one row per candle of `history`, in the
same order, containing only values already known as of that candle
(see features/feature_pipeline.py). `features=None` is Close-only.
Raise ImportError for a missing dependency and ValueError for bad
input: callers report those per model and keep the others running.
"""
raise NotImplementedError