dalsi rozvolneni at vic jedeme arbitraz
This commit is contained in:
@@ -14,7 +14,7 @@ Discharge-export mask:
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from datetime import date, datetime, timezone, timedelta
|
||||
from types import SimpleNamespace
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
@@ -27,6 +27,24 @@ _BUY_CHARGE_BAND = 0.40
|
||||
_MAX_GRID_CHARGE_CAP = 24
|
||||
|
||||
|
||||
def _prague_date(s: PlanningSlot) -> date:
|
||||
return s.interval_start.astimezone(_PRAGUE).date()
|
||||
|
||||
|
||||
def _export_window_start(slots: list[PlanningSlot], degrad: float) -> datetime | None:
|
||||
"""Kopie R__063: sell > min(buy) téhož kalendářního dne (Prague) + degrad."""
|
||||
result: datetime | None = None
|
||||
for s in slots:
|
||||
day = _prague_date(s)
|
||||
day_min = min(
|
||||
float(x.buy_price) for x in slots if _prague_date(x) == day
|
||||
)
|
||||
if float(s.sell_price) > day_min + degrad:
|
||||
if result is None or s.interval_start < result:
|
||||
result = s.interval_start
|
||||
return result
|
||||
|
||||
|
||||
def _future_sell(slots: list[PlanningSlot], t: int) -> float:
|
||||
tail = [float(slots[i].sell_price) for i in range(t + 1, len(slots))]
|
||||
return max(tail) if tail else float(slots[t].sell_price)
|
||||
@@ -82,11 +100,8 @@ def _select_charge_slots(
|
||||
default=min(float(s.buy_price) for s in slots),
|
||||
)
|
||||
ref_buy_global = min(float(s.buy_price) for s in slots)
|
||||
export_window_start: datetime | None = None
|
||||
for s in slots:
|
||||
if float(s.sell_price) > ref_buy_global + degrad:
|
||||
if export_window_start is None or s.interval_start < export_window_start:
|
||||
export_window_start = s.interval_start
|
||||
export_window_start = _export_window_start(slots, degrad)
|
||||
plan_day = _prague_date(slots[0])
|
||||
|
||||
eta = float(getattr(battery, "charge_efficiency", 1.0) or 1.0)
|
||||
max_p_w = float(getattr(battery, "max_charge_power_w", 0.0) or 0.0)
|
||||
@@ -135,13 +150,15 @@ def _select_charge_slots(
|
||||
return False
|
||||
return True
|
||||
|
||||
def _grid_sort_key(t: int, pred: bool, price: float) -> tuple[int, int, float, int]:
|
||||
before_export = 0
|
||||
if export_window_start is not None and slots[t].interval_start < export_window_start:
|
||||
before_export = 0
|
||||
else:
|
||||
before_export = 1
|
||||
return (before_export, int(pred), price, t)
|
||||
def _grid_sort_key(t: int, pred: bool, price: float) -> tuple[int, int, int, float, int]:
|
||||
today_first = 0 if _prague_date(slots[t]) == plan_day else 1
|
||||
before_export = (
|
||||
0
|
||||
if export_window_start is not None
|
||||
and slots[t].interval_start < export_window_start
|
||||
else 1
|
||||
)
|
||||
return (today_first, before_export, int(pred), price, t)
|
||||
|
||||
if purchase_pricing_mode != "fixed":
|
||||
am_candidates = [
|
||||
|
||||
Reference in New Issue
Block a user