posun dovybijejiciho okna tesne pred zapornou cenu
This commit is contained in:
@@ -37,9 +37,9 @@ SOLVER_TIME_LIMIT = 10 # sekund
|
||||
# (rezerva z DB). Při relaxaci spodku před extrémně záporným buy je podlaha soc_panel_min[t]
|
||||
# (planner floor), jinak by šlo jen do zátěže a nešlo by „vypustit do sítě“ před levným nákupem.
|
||||
GE_MIN_EXPORT_W = 1.0
|
||||
# Dokud je první „extrémní“ buy dál než tento počet 15min slotů, držíme plánovací spodek na rezervě
|
||||
# (arb_base_wh) místo hlubokého planner floor — aby šlo nejdřív vybíjet „standardně“ a hluboký
|
||||
# dump až těsně před oknem záporných cen (operativní buffer).
|
||||
# Dokud je kotva pro hluboký dump (první sell < 0 v horizontu, jinak první extrémní buy) dál než
|
||||
# tento počet 15min slotů, držíme plánovací spodek na rezervě (arb_base_wh) místo planner floor —
|
||||
# priorita: beze „ztráty na prodeji“ (sell >= 0) držet buffer, hluboký vývoz až těsně před záporným prodejem.
|
||||
DEFAULT_PLANNER_DISCHARGE_RELAX_PREWINDOW_SLOTS = 8
|
||||
CORRECTION_WINDOW_H = 1 # hodina zpět pro výpočet korekčního faktoru
|
||||
CORRECTION_MIN_CLAMP = 0.5 # spodní limit korekčního faktoru
|
||||
@@ -242,22 +242,68 @@ def _slots_until_buy_le_threshold(
|
||||
return out
|
||||
|
||||
|
||||
def _slots_until_sell_lt(slots: list[PlanningSlot], sell_upper: float) -> list[int]:
|
||||
"""
|
||||
Pro slot t: kolik slotů (0 = tento slot) do nejbližšího k>=t s sell_price < sell_upper.
|
||||
Typicky sell_upper=0 (první záporný / „ztrátový“ prodej z pohledu OTE).
|
||||
Pokud v [t, T) žádný takový není, vrátí T + 1.
|
||||
"""
|
||||
t_len = len(slots)
|
||||
sentinel = t_len + 1
|
||||
next_lt = sentinel
|
||||
next_at_or_after: list[int] = [sentinel] * t_len
|
||||
for t in range(t_len - 1, -1, -1):
|
||||
if float(slots[t].sell_price) < sell_upper:
|
||||
next_lt = t
|
||||
next_at_or_after[t] = next_lt
|
||||
out: list[int] = []
|
||||
for t in range(t_len):
|
||||
nxt = next_at_or_after[t]
|
||||
if nxt >= t_len:
|
||||
out.append(sentinel)
|
||||
else:
|
||||
out.append(nxt - t)
|
||||
return out
|
||||
|
||||
|
||||
def _prewindow_deferral_slots(
|
||||
slots: list[PlanningSlot], buy_extreme_threshold: float, sell_upper: float = 0.0
|
||||
) -> list[int]:
|
||||
"""
|
||||
Vzdálenost (v 15min slotech) pro zpoždění hlubokého planner flooru:
|
||||
primárně do prvního sell < sell_upper (poslední „bez ztráty na prodeji“ je k-1),
|
||||
pokud v horizontu není záporný prodej, fallback na první buy <= buy_extreme_threshold.
|
||||
"""
|
||||
t_len = len(slots)
|
||||
sell_d = _slots_until_sell_lt(slots, sell_upper)
|
||||
buy_d = _slots_until_buy_le_threshold(slots, buy_extreme_threshold)
|
||||
sentinel = t_len + 1
|
||||
out: list[int] = []
|
||||
for t in range(t_len):
|
||||
if sell_d[t] < sentinel:
|
||||
out.append(sell_d[t])
|
||||
else:
|
||||
out.append(buy_d[t])
|
||||
return out
|
||||
|
||||
|
||||
def _soc_panel_min_wh_series(
|
||||
soc_min_series: list[float],
|
||||
slots_until_buy_extreme: list[int],
|
||||
slots_until_relax_anchor: list[int],
|
||||
min_soc_wh: float,
|
||||
arb_base_wh: float,
|
||||
prewindow_slots: int,
|
||||
) -> list[float]:
|
||||
"""
|
||||
Zpoždění hluboké relaxace: pokud je lookahead extrémní, ale první extrémní buy je dál než
|
||||
prewindow_slots, drž spodek na max(relax_wh, arb_base_wh) — prakticky na rezervě.
|
||||
Zpoždění hluboké relaxace: pokud je lookahead extrémní (soc_min pod min_soc), ale kotva
|
||||
(záporný prodej / fallback extrémní buy) je dál než prewindow_slots, drž spodek na
|
||||
max(relax_wh, arb_base_wh) — prakticky na rezervě.
|
||||
"""
|
||||
t_len = len(soc_min_series)
|
||||
out: list[float] = []
|
||||
for t in range(t_len):
|
||||
sm = float(soc_min_series[t])
|
||||
if sm < min_soc_wh - 1e-3 and slots_until_buy_extreme[t] > prewindow_slots:
|
||||
if sm < min_soc_wh - 1e-3 and slots_until_relax_anchor[t] > prewindow_slots:
|
||||
out.append(max(sm, float(arb_base_wh)))
|
||||
else:
|
||||
out.append(sm)
|
||||
@@ -443,10 +489,10 @@ def solve_dispatch(
|
||||
)
|
||||
),
|
||||
)
|
||||
slots_until_buy_extreme = _slots_until_buy_le_threshold(slots, buy_extreme_thr)
|
||||
deferral_slots = _prewindow_deferral_slots(slots, buy_extreme_thr)
|
||||
soc_panel_min = _soc_panel_min_wh_series(
|
||||
soc_min_series,
|
||||
slots_until_buy_extreme,
|
||||
deferral_slots,
|
||||
min_soc_wh,
|
||||
arb_base_wh,
|
||||
prewin,
|
||||
|
||||
Reference in New Issue
Block a user