Skip to content

Commit

Permalink
query_dayahead_prices can now handle dual time frequencies such as fo…
Browse files Browse the repository at this point in the history
…r DE_LU since 2022-08-19

fixed #204
  • Loading branch information
fboerman committed Aug 21, 2022
1 parent 0b9a38c commit 7c745d9
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 10 deletions.
19 changes: 13 additions & 6 deletions entsoe/entsoe.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from typing import Union, Optional, Dict
from typing import Union, Optional, Dict, List, Literal

import pandas as pd
from pandas.tseries.offsets import YearBegin, YearEnd
Expand All @@ -8,7 +8,7 @@
from bs4 import BeautifulSoup
from bs4.builder import XMLParsedAsHTMLWarning

from entsoe.exceptions import InvalidPSRTypeError, InvalidBusinessParameterError
from entsoe.exceptions import InvalidPSRTypeError, InvalidBusinessParameterError, InvalidParameterError
from .exceptions import NoMatchingDataError, PaginationError
from .mappings import Area, NEIGHBOURS, lookup_area
from .parsers import parse_prices, parse_loads, parse_generation, \
Expand All @@ -22,7 +22,7 @@
warnings.filterwarnings('ignore', category=XMLParsedAsHTMLWarning)

__title__ = "entsoe-py"
__version__ = "0.5.7"
__version__ = "0.5.8"
__author__ = "EnergieID.be, Frank Boerman"
__license__ = "MIT"

Expand Down Expand Up @@ -1049,11 +1049,14 @@ def query_net_position(self, country_code: Union[Area, str],

@year_limited
def query_day_ahead_prices(
self, country_code: Union[Area, str], start: pd.Timestamp,
end: pd.Timestamp) -> pd.Series:
self, country_code: Union[Area, str],
start: pd.Timestamp,
end: pd.Timestamp,
resolution: List[Literal['60T', '15T']] = '60T') -> pd.Series:
"""
Parameters
----------
resolution: either 60T for hourly values or 15T for quarterly values, throws error if type is not available
country_code : Area|str
start : pd.Timestamp
end : pd.Timestamp
Expand All @@ -1062,14 +1065,18 @@ def query_day_ahead_prices(
-------
pd.Series
"""
if resolution not in ['60T', '15T']:
raise InvalidParameterError('Please choose either 60T or 15T')
area = lookup_area(country_code)
# we do here extra days at start and end to fix issue 187
text = super(EntsoePandasClient, self).query_day_ahead_prices(
country_code=area,
start=start-pd.Timedelta(days=1),
end=end+pd.Timedelta(days=1)
)
series = parse_prices(text)
series = parse_prices(text)[resolution]
if len(series) == 0:
raise NoMatchingDataError
series = series.tz_convert(area.tz)
series = series.truncate(before=start, after=end)
# because of the above fix we need to check again if any valid data exists after truncating
Expand Down
4 changes: 4 additions & 0 deletions entsoe/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ class InvalidPSRTypeError(Exception):

class InvalidBusinessParameterError(Exception):
pass


class InvalidParameterError(Exception):
pass
14 changes: 10 additions & 4 deletions entsoe/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,17 @@ def parse_prices(xml_text):
-------
pd.Series
"""
series = []
series = {
'15T': [],
'60T': []
}
for soup in _extract_timeseries(xml_text):
series.append(_parse_price_timeseries(soup))
series = pd.concat(series)
series = series.sort_index()
soup_series = _parse_price_timeseries(soup)
series[soup_series.index.freqstr].append(soup_series)

for freq, freq_series in series.items():
if len(freq_series) > 0:
series[freq] = pd.concat(freq_series).sort_index()
return series


Expand Down

0 comments on commit 7c745d9

Please sign in to comment.