Add FastAPI backend for energy trading system
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.
This commit is contained in:
87
backend/app/ml/rl_battery/environment.py
Normal file
87
backend/app/ml/rl_battery/environment.py
Normal file
@@ -0,0 +1,87 @@
|
||||
from typing import Dict, Tuple
|
||||
import numpy as np
|
||||
|
||||
|
||||
class BatteryEnvironment:
|
||||
def __init__(
|
||||
self,
|
||||
capacity: float = 100.0,
|
||||
charge_rate: float = 50.0,
|
||||
discharge_rate: float = 50.0,
|
||||
efficiency: float = 0.9,
|
||||
min_reserve: float = 0.1,
|
||||
max_charge: float = 0.9,
|
||||
):
|
||||
self.capacity = capacity
|
||||
self.charge_rate = charge_rate
|
||||
self.discharge_rate = discharge_rate
|
||||
self.efficiency = efficiency
|
||||
self.min_reserve = min_reserve
|
||||
self.max_charge = max_charge
|
||||
|
||||
self.charge_level = capacity * 0.5
|
||||
self.current_price = 50.0
|
||||
self.time_step = 0
|
||||
|
||||
def reset(self) -> np.ndarray:
|
||||
self.charge_level = self.capacity * 0.5
|
||||
self.current_price = 50.0
|
||||
self.time_step = 0
|
||||
return self._get_state()
|
||||
|
||||
def _get_state(self) -> np.ndarray:
|
||||
charge_pct = self.charge_level / self.capacity
|
||||
price_norm = np.clip(self.current_price / 200.0, 0, 1)
|
||||
time_norm = (self.time_step % 1440) / 1440.0
|
||||
|
||||
return np.array([charge_pct, price_norm, time_norm])
|
||||
|
||||
def step(self, action: int) -> Tuple[np.ndarray, float, bool, Dict]:
|
||||
old_price = self.current_price
|
||||
|
||||
if action == 0:
|
||||
charge_amount = min(self.charge_rate, self.capacity * self.max_charge - self.charge_level)
|
||||
self.charge_level += charge_amount * self.efficiency
|
||||
reward = -charge_amount * old_price / 1000.0
|
||||
elif action == 1:
|
||||
reward = 0.0
|
||||
elif action == 2:
|
||||
discharge_amount = min(
|
||||
self.discharge_rate,
|
||||
self.charge_level - self.capacity * self.min_reserve
|
||||
)
|
||||
revenue = discharge_amount * old_price
|
||||
self.charge_level -= discharge_amount / self.efficiency
|
||||
reward = revenue / 1000.0
|
||||
else:
|
||||
reward = 0.0
|
||||
|
||||
self.charge_level = np.clip(self.charge_level, self.capacity * self.min_reserve, self.capacity * self.max_charge)
|
||||
|
||||
self.current_price = old_price + np.random.randn() * 5
|
||||
self.current_price = np.clip(self.current_price, 0, 300)
|
||||
|
||||
self.time_step += 1
|
||||
|
||||
state = self._get_state()
|
||||
|
||||
info = {
|
||||
"charge_level": self.charge_level,
|
||||
"price": self.current_price,
|
||||
"action": action,
|
||||
}
|
||||
|
||||
done = self.time_step >= 1440
|
||||
|
||||
return state, reward, done, info
|
||||
|
||||
@property
|
||||
def action_space(self):
|
||||
return 3
|
||||
|
||||
@property
|
||||
def observation_space(self):
|
||||
return 3
|
||||
|
||||
|
||||
__all__ = ["BatteryEnvironment"]
|
||||
Reference in New Issue
Block a user