You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Mooi-Kickstart/pyrecoy/pyrecoy/pyrecoy2/intelligent_baseline.py

227 lines
5.6 KiB
Python

import numpy as np
import pandas as pd
import warnings
from tqdm.notebook import tqdm
from .prices import get_tennet_data, get_balansdelta_nl
from .forecasts import Forecast
# TODO: This whole thing needs serious refactoring /MK
def generate_intelligent_baseline(startdate, enddate):
bd = get_balansdelta_nl(start=startdate, end=enddate)
bd.drop(
columns=[
"datum",
"volgnr",
"tijd",
"IGCCBijdrage_op",
"IGCCBijdrage_af",
"opregelen_reserve",
"afregelen_reserve",
],
inplace=True,
)
net_regelvolume = bd["opregelen"] - bd["Afregelen"]
bd.insert(2, "net_regelvolume", net_regelvolume)
vol_delta = bd["net_regelvolume"].diff(periods=1)
bd.insert(3, "vol_delta", vol_delta)
pc = get_tennet_data(
exporttype="verrekenprijzen", start=startdate, end=enddate
).reindex(index=bd.index, method="ffill")[["prikkelcomponent"]]
if len(pc) == 0:
pc = pd.Series(0, index=bd.index)
prices = Forecast("marketprices_nl.csv", start=startdate, end=enddate)
prices.reindex_to_freq("1T")
prices = prices.data
inputdata = pd.concat([prices, bd, pc], axis=1)
Qhs = len(inputdata) / 15
if Qhs % 1 > 0:
raise Exception(
"A dataset with incomplete quarter-hours was passed in, please insert new dataset!"
)
data = np.array([inputdata[col].to_numpy() for col in inputdata.columns])
lstoutput = []
for q in tqdm(range(int(Qhs))):
q_data = [col[q * 15 : (q + 1) * 15] for col in data]
q_output = apply_imbalance_logic_for_quarter_hour(q_data)
if lstoutput:
for (ix, col) in enumerate(lstoutput):
lstoutput[ix] += q_output[ix]
else:
lstoutput = q_output
ib = pd.DataFrame(
lstoutput,
index=[
"DAM",
"POS",
"NEG",
"regulation state",
"ib_inv",
"ib_afn",
"ib_rt",
"nv_op",
"nv_af",
"opgeregeld",
"afgeregeld",
],
).T
ib.index = inputdata.index
return ib
def apply_imbalance_logic_for_quarter_hour(q_data):
[nv_op, nv_af, opgeregeld, afgeregeld] = [False] * 4
lst_inv = [np.NaN] * 15
lst_afn = [np.NaN] * 15
lst_rt = [np.NaN] * 15
lst_nv_op = [np.NaN] * 15
lst_nv_af = [np.NaN] * 15
lst_afr = [np.NaN] * 15
lst_opr = [np.NaN] * 15
mins = iter(range(15))
for m in mins:
[
DAM,
POS,
NEG,
rt,
vol_op,
vol_af,
net_vol,
delta_vol,
nood_op,
nood_af,
prijs_hoog,
prijs_mid,
prijs_laag,
prikkelc,
] = [col[0 : m + 1] for col in q_data]
delta_vol[0] = 0
if nood_op.sum() > 0:
nv_op = True
if nood_af.sum() > 0:
nv_af = True
if pd.notna(prijs_hoog).any() > 0:
opgeregeld = True
if pd.notna(prijs_laag).any() > 0:
afgeregeld = True
if (opgeregeld == True) and (afgeregeld == False):
regeltoestand = 1
elif (opgeregeld == False) and (afgeregeld == True):
regeltoestand = -1
elif (opgeregeld == False) and (afgeregeld == False):
if nv_op == True:
regeltoestand = 1
if nv_af == True:
regeltoestand = -1
else:
regeltoestand = 0
else:
# Zowel opregeld als afregeld > kijk naar trend
# Continue niet-dalend: RT1
# Continue dalend: RT -1
# Geen continue trend: RT 2
if all(i >= 0 for i in delta_vol):
regeltoestand = 1
elif all(i <= 0 for i in delta_vol):
regeltoestand = -1
else:
regeltoestand = 2
# Bepaal de verwachte onbalansprijzen
dam = DAM[0]
pc = prikkelc[0]
with warnings.catch_warnings():
warnings.simplefilter("ignore")
hoogste_prijs = np.nanmax(prijs_hoog)
mid_prijs = prijs_mid[-1]
laagste_prijs = np.nanmin(prijs_laag)
if regeltoestand == 0:
prijs_inv = mid_prijs
prijs_afn = mid_prijs
elif regeltoestand == -1:
if nv_af:
prijs_afn = np.nanmin((dam - 200, laagste_prijs))
else:
prijs_afn = laagste_prijs
prijs_inv = prijs_afn
elif regeltoestand == 1:
if nv_op:
prijs_inv = np.nanmax((dam + 200, hoogste_prijs))
else:
prijs_inv = hoogste_prijs
prijs_afn = prijs_inv
elif regeltoestand == 2:
if nv_op:
prijs_afn = np.nanmax((dam + 200, hoogste_prijs, mid_prijs))
else:
prijs_afn = np.nanmax((mid_prijs, hoogste_prijs))
if nv_af:
prijs_inv = np.nanmin((dam - 200, laagste_prijs, mid_prijs))
else:
prijs_inv = np.nanmin((mid_prijs, laagste_prijs))
prijs_inv -= pc
prijs_afn += pc
lst_inv[m] = prijs_inv
lst_afn[m] = prijs_afn
lst_rt[m] = regeltoestand
lst_nv_op[m] = nv_op
lst_nv_af[m] = nv_af
lst_opr[m] = opgeregeld
lst_afr[m] = afgeregeld
return [
list(DAM),
list(POS),
list(NEG),
list(rt),
lst_inv,
lst_afn,
lst_rt,
lst_nv_op,
lst_nv_af,
lst_opr,
lst_afr,
]