Implements FastAPI backend with ML model support for energy trading, including price prediction models and RL-based battery trading policy. Features dashboard, trading, backtest, and settings API routes with WebSocket support for real-time updates.
78 lines
2.4 KiB
Python
78 lines
2.4 KiB
Python
from typing import Dict, List
|
|
import numpy as np
|
|
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
|
|
|
|
|
|
class ModelEvaluator:
|
|
@staticmethod
|
|
def calculate_metrics(y_true, y_pred) -> Dict[str, float]:
|
|
mae = mean_absolute_error(y_true, y_pred)
|
|
rmse = mean_squared_error(y_true, y_pred, squared=False)
|
|
mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
|
|
r2 = r2_score(y_true, y_pred)
|
|
|
|
return {
|
|
"mae": float(mae),
|
|
"rmse": float(rmse),
|
|
"mape": float(mape) if not np.isnan(mape) else 0.0,
|
|
"r2": float(r2),
|
|
}
|
|
|
|
@staticmethod
|
|
def calculate_sharpe_ratio(returns: np.ndarray, risk_free_rate: float = 0.0) -> float:
|
|
if len(returns) == 0 or np.std(returns) == 0:
|
|
return 0.0
|
|
|
|
excess_returns = returns - risk_free_rate
|
|
return float(np.mean(excess_returns) / np.std(excess_returns))
|
|
|
|
@staticmethod
|
|
def calculate_max_drawdown(values: np.ndarray) -> float:
|
|
if len(values) == 0:
|
|
return 0.0
|
|
|
|
cumulative = np.cumsum(values)
|
|
running_max = np.maximum.accumulate(cumulative)
|
|
drawdown = (cumulative - running_max)
|
|
return float(drawdown.min())
|
|
|
|
|
|
class BacktestEvaluator:
|
|
def __init__(self):
|
|
self.trades: List[Dict] = []
|
|
|
|
def add_trade(self, trade: Dict):
|
|
self.trades.append(trade)
|
|
|
|
def evaluate(self) -> Dict[str, float]:
|
|
if not self.trades:
|
|
return {
|
|
"total_revenue": 0.0,
|
|
"total_trades": 0,
|
|
"win_rate": 0.0,
|
|
"sharpe_ratio": 0.0,
|
|
"max_drawdown": 0.0,
|
|
}
|
|
|
|
total_revenue = sum(t.get("revenue", 0) for t in self.trades)
|
|
winning_trades = sum(1 for t in self.trades if t.get("revenue", 0) > 0)
|
|
win_rate = winning_trades / len(self.trades) if self.trades else 0.0
|
|
|
|
returns = np.array([t.get("revenue", 0) for t in self.trades])
|
|
sharpe_ratio = ModelEvaluator.calculate_sharpe_ratio(returns)
|
|
max_drawdown = ModelEvaluator.calculate_max_drawdown(returns)
|
|
|
|
return {
|
|
"total_revenue": total_revenue,
|
|
"total_trades": len(self.trades),
|
|
"win_rate": win_rate,
|
|
"sharpe_ratio": sharpe_ratio,
|
|
"max_drawdown": max_drawdown,
|
|
}
|
|
|
|
def reset(self):
|
|
self.trades = []
|
|
|
|
|
|
__all__ = ["ModelEvaluator", "BacktestEvaluator"]
|