Skip to content

Commit

Permalink
adjust storage strategy
Browse files Browse the repository at this point in the history
fix tests
  • Loading branch information
nick-harder committed Dec 16, 2024
1 parent 4c2b9cf commit f762d7d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 76 deletions.
15 changes: 3 additions & 12 deletions assume/strategies/learning_advanced_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from assume.common.base import SupportsMinMax
from assume.common.market_objects import MarketConfig, Orderbook, Product
from assume.common.utils import get_products_index, min_max_scale
from assume.common.utils import get_products_index
from assume.strategies.learning_strategies import RLStrategy


Expand Down Expand Up @@ -306,19 +306,10 @@ def create_observation(

# scale unit outputs
# if unit is not running, total dispatch is 0
scaled_total_dispatch = min_max_scale(
current_volume,
0,
unit.max_power,
)
scaled_total_dispatch = current_volume / unit.max_power

# marginal cost
# Could theoretically be negative (eg. subsidies), but assumed to be always positive in the simulation
scaled_marginal_cost = min_max_scale(
current_costs,
0,
self.max_bid_price,
)
scaled_marginal_cost = current_costs / self.max_bid_price

# calculate the time the unit has to continue to run or be down
op_time = unit.get_operation_time(start)
Expand Down
82 changes: 18 additions & 64 deletions assume/strategies/learning_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,18 +458,10 @@ def create_observation(

# scale unit outputs
# if unit is not running, total dispatch is 0
scaled_total_dispatch = min_max_scale(
current_volume,
0,
unit.max_power,
)
scaled_total_dispatch = current_volume / unit.max_power

# marginal cost
# Could theoretically be negative (eg. subsidies), but assumed to be always positive in the simulation
scaled_marginal_cost = min_max_scale(
current_costs,
0,
self.max_bid_price,
)
scaled_marginal_cost = current_costs / self.max_bid_price

# concat all obsverations into one array
observation = np.concatenate(
Expand Down Expand Up @@ -1012,83 +1004,45 @@ def create_observation(
# =============================================================================
# 1.1 Get the Observations, which are the basis of the action decision
# =============================================================================
# defines bounds of observation space
# stays here as it is unit specific, and different forecasts might apply for different units
# different handling would require an extra unit loop at learning role intiliazation and unit specific max/min values
# further forecasts might change during the simulation if advanced forecasting is used
self.max_market_price = max(unit.forecaster[f"price_{market_id}"])
self.min_market_price = min(unit.forecaster[f"price_{market_id}"])
self.max_residual = max(unit.forecaster[f"residualy_load_{market_id}"])
self.min_residual = min(unit.forecaster[f"residual_load_{market_id}"])

upper_scaling_factor_res_load = self.max_residual
lower_scaling_factor_res_load = self.min_residual
upper_scaling_factor_price = self.max_market_price
lower_scaling_factor_price = self.min_market_price

upper_scaling_factor_energy_cost = self.max_bid_price
lower_scaling_factor_energy_cost = 0

# checks if we are at end of simulation horizon, since we need to change the forecast then
# for residual load and price forecast and scale them
if (
end_excl + forecast_len
> unit.forecaster[f"residual_load_{market_id}"].index[-1]
):
scaled_res_load_forecast = min_max_scale(
unit.forecaster[f"residual_load_{market_id}"].loc[start:],
lower_scaling_factor_res_load,
upper_scaling_factor_res_load,
)
if end_excl + forecast_len > self.scaled_res_load_obs.index[-1]:
scaled_res_load_forecast = self.scaled_res_load_obs.loc[start:]

Check warning on line 1011 in assume/strategies/learning_strategies.py

View check run for this annotation

Codecov / codecov/patch

assume/strategies/learning_strategies.py#L1011

Added line #L1011 was not covered by tests

scaled_res_load_forecast = np.concatenate(
[
scaled_res_load_forecast,
unit.forecaster[f"residual_load_{market_id}"].iloc[
self.scaled_res_load_obs.iloc[
: self.foresight - len(scaled_res_load_forecast)
],
]
)

else:
scaled_res_load_forecast = min_max_scale(
unit.forecaster[f"residual_load_{market_id}"].loc[
start : end_excl + forecast_len
],
lower_scaling_factor_res_load,
upper_scaling_factor_res_load,
)
scaled_res_load_forecast = self.scaled_res_load_obs.loc[
start : end_excl + forecast_len
]

if end_excl + forecast_len > unit.forecaster[f"price_{market_id}"].index[-1]:
scaled_price_forecast = min_max_scale(
unit.forecaster[f"price_{market_id}"].loc[start:],
lower_scaling_factor_price,
upper_scaling_factor_price,
)
if end_excl + forecast_len > self.scaled_pices_obs.index[-1]:
scaled_price_forecast = self.scaled_pices_obs.loc[start:]

Check warning on line 1028 in assume/strategies/learning_strategies.py

View check run for this annotation

Codecov / codecov/patch

assume/strategies/learning_strategies.py#L1028

Added line #L1028 was not covered by tests
scaled_price_forecast = np.concatenate(
[
scaled_price_forecast,
unit.forecaster[f"price_{market_id}"].iloc[
self.scaled_pices_obs.iloc[
: self.foresight - len(scaled_price_forecast)
],
]
)

else:
scaled_price_forecast = min_max_scale(
unit.forecaster[f"price_{market_id}"].loc[
start : end_excl + forecast_len
],
lower_scaling_factor_price,
upper_scaling_factor_price,
)
scaled_price_forecast = self.scaled_pices_obs.loc[
start : end_excl + forecast_len
]

# get the current soc value
soc_scaled = min_max_scale(unit.outputs["soc"].at[start], 0, unit.max_soc)
energy_cost_scaled = min_max_scale(
unit.outputs["energy_cost"].at[start],
lower_scaling_factor_energy_cost,
upper_scaling_factor_energy_cost,
)
soc_scaled = unit.outputs["soc"].at[start] / unit.max_soc
energy_cost_scaled = unit.outputs["energy_cost"].at[start] / self.max_bid_price

# concat all obsverations into one array
observation = np.concatenate(
Expand Down
3 changes: 3 additions & 0 deletions tests/test_drl_storage_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def test_storage_rl_strategy_sell_bid(mock_market_config, storage_unit):

# get the strategy
strategy = storage_unit.bidding_strategies["EOM"]
strategy.prepare_observations(storage_unit, mc.market_id)

# Define the 'sell' action: [0.2, 0.5] -> price=20, direction='sell'
sell_action = [0.2, 0.5]
Expand Down Expand Up @@ -181,6 +182,7 @@ def test_storage_rl_strategy_buy_bid(mock_market_config, storage_unit):

# Instantiate the StorageRLStrategy
strategy = storage_unit.bidding_strategies["EOM"]
strategy.prepare_observations(storage_unit, mc.market_id)

# Define the 'buy' action: [0.3, -0.5] -> price=30, direction='buy'
buy_action = [0.3, -0.5]
Expand Down Expand Up @@ -274,6 +276,7 @@ def test_storage_rl_strategy_ignore_bid(mock_market_config, storage_unit):

# Instantiate the StorageRLStrategy
strategy = storage_unit.bidding_strategies["EOM"]
strategy.prepare_observations(storage_unit, mc.market_id)

# Define the 'ignore' action: [0.0, 0.0] -> price=0, direction='ignore'
ignore_action = [0.0, 0.0]
Expand Down

0 comments on commit f762d7d

Please sign in to comment.