27 lines
1.2 KiB
Python
27 lines
1.2 KiB
Python
from typing import Dict, Tuple
|
|
import numpy as np
|
|
from sklearn.metrics import mean_squared_error, r2_score
|
|
|
|
|
|
def compute_price_series_from_log_returns(start_price: float, log_returns: np.ndarray) -> np.ndarray:
|
|
"""Reconstruct price series from log returns starting at start_price."""
|
|
prices = [start_price]
|
|
for r in log_returns:
|
|
prices.append(prices[-1] * float(np.exp(r)))
|
|
return np.asarray(prices[1:])
|
|
|
|
|
|
def compute_metrics_from_prices(actual_prices: np.ndarray, predicted_prices: np.ndarray) -> Dict[str, float]:
|
|
"""Compute RMSE, MAPE, R2, and directional accuracy given price series."""
|
|
rmse = float(np.sqrt(mean_squared_error(actual_prices, predicted_prices)))
|
|
with np.errstate(divide='ignore', invalid='ignore'):
|
|
mape_arr = np.abs((actual_prices - predicted_prices) / np.where(actual_prices == 0, np.nan, actual_prices))
|
|
mape = float(np.nanmean(mape_arr) * 100.0)
|
|
r2 = float(r2_score(actual_prices, predicted_prices))
|
|
direction_actual = np.sign(np.diff(actual_prices))
|
|
direction_pred = np.sign(np.diff(predicted_prices))
|
|
dir_acc = float((direction_actual == direction_pred).mean()) if len(direction_actual) > 0 else 0.0
|
|
return {"rmse": rmse, "mape": mape, "r2": r2, "directional_accuracy": dir_acc}
|
|
|
|
|