detquantlib 3.3.0__tar.gz → 3.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {detquantlib-3.3.0 → detquantlib-3.5.0}/PKG-INFO +1 -1
  2. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/data/databases/detdatabase.py +79 -49
  3. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/outputs/outputs_interface.py +12 -5
  4. {detquantlib-3.3.0 → detquantlib-3.5.0}/pyproject.toml +1 -1
  5. {detquantlib-3.3.0 → detquantlib-3.5.0}/LICENSE.txt +0 -0
  6. {detquantlib-3.3.0 → detquantlib-3.5.0}/README.md +0 -0
  7. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/__init__.py +0 -0
  8. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/data/__init__.py +0 -0
  9. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/data/entsoe/entsoe.py +0 -0
  10. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/data/sftp/sftp.py +0 -0
  11. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/dates/__init__.py +0 -0
  12. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/dates/dates.py +0 -0
  13. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/figures/__init__.py +0 -0
  14. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/figures/plotly_figures.py +0 -0
  15. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/outputs/__init__.py +0 -0
  16. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/stats/__init__.py +0 -0
  17. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/stats/data_analysis.py +0 -0
  18. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/tradable_products/__init__.py +0 -0
  19. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/tradable_products/tradable_products.py +0 -0
  20. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/utils/__init__.py +0 -0
  21. {detquantlib-3.3.0 → detquantlib-3.5.0}/detquantlib/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: detquantlib
3
- Version: 3.3.0
3
+ Version: 3.5.0
4
4
  Summary: An internal library containing functions and classes that can be used across Quant models.
5
5
  Author: DET
6
6
  Requires-Python: >=3.10,<4.0
@@ -109,6 +109,7 @@ class DetDatabase:
109
109
  end_delivery_date: datetime = None,
110
110
  columns: list = None,
111
111
  process_data: bool = True,
112
+ timezone_aware_dates: bool = False,
112
113
  ) -> pd.DataFrame:
113
114
  """
114
115
  Loads entsoe day-ahead spot prices from the database.
@@ -128,6 +129,8 @@ class DetDatabase:
128
129
  columns: Requested database table columns. Set columns=["*"] (i.e. as list) to get
129
130
  all columns.
130
131
  process_data: Indicates if data should be processed convert to standardized format
132
+ timezone_aware_dates: If true, returns all dates as timezone-aware. Otherwise,
133
+ returns them as timezone-naive.
131
134
 
132
135
  Returns:
133
136
  Dataframe containing day-ahead spot prices
@@ -137,8 +140,6 @@ class DetDatabase:
137
140
  compatible
138
141
  ValueError: Raises an error if the combination of trading dates and delivery dates
139
142
  is not valid.
140
- ValueError: Raises an error if match with input commodity name is not unique
141
- ValueError: Raises an error if input commodity is not supported
142
143
  ValueError: Raises an error if no price data is found for user inputs
143
144
  """
144
145
  # Input validation
@@ -181,21 +182,13 @@ class DetDatabase:
181
182
  # Note: The local timezone is important because ENTSOE provides all prices in the UTC
182
183
  # timezone. We first convert the dates from UTC to the local timezone, and then filter
183
184
  # for the requested delivery period.
184
- commodity_info = self.load_commodities(
185
- columns=["Timezone", "EntsoeMapCode"], conditions=f"WHERE Name='{commodity_name}'"
185
+ commodity_info = self.get_commodity_info(
186
+ filter_column="Name",
187
+ filter_value=commodity_name,
188
+ info_columns=["Timezone", "EntsoeMapCode"],
186
189
  )
187
- if commodity_info.shape[0] > 1:
188
- raise ValueError(f"More than one match found with commodity '{commodity_name}'.")
189
- elif commodity_info.shape[0] == 0:
190
- supported_commodities = self.load_commodities(columns=["Name"])
191
- supported_commodities_str = ", ".join(f"'{x}'" for x in supported_commodities["Name"])
192
- raise ValueError(
193
- f"Commodity '{commodity_name}' is not supported. Supported commodities: "
194
- f"{supported_commodities_str}."
195
- )
196
- else:
197
- map_code = commodity_info.loc[0, "EntsoeMapCode"]
198
- timezone = commodity_info.loc[0, "Timezone"]
190
+ map_code = commodity_info["EntsoeMapCode"]
191
+ timezone = commodity_info["Timezone"]
199
192
 
200
193
  # Convert start trading date to start delivery date
201
194
  if start_trading_date is not None:
@@ -239,11 +232,22 @@ class DetDatabase:
239
232
  by=["DateTime(UTC)"], axis=0, ascending=True, inplace=True, ignore_index=True
240
233
  )
241
234
 
235
+ # Convert date columns to timezone-aware dates
236
+ cols_date_utc = ["DateTime(UTC)", "UpdateTime(UTC)"]
237
+ for c in cols_date_utc:
238
+ if c in df.columns:
239
+ df[c] = df[c].dt.tz_localize("UTC")
240
+ if "InsertionTimestamp" in df.columns:
241
+ df["InsertionTimestamp"] = df["InsertionTimestamp"].dt.tz_localize(timezone)
242
+
242
243
  # Add column with delivery date expressed in local timezone
243
- datetime_column_name = f"DateTime({timezone})"
244
- df[datetime_column_name] = df["DateTime(UTC)"].dt.tz_localize("UTC")
245
- df[datetime_column_name] = df[datetime_column_name].dt.tz_convert(timezone)
246
- df[datetime_column_name] = df[datetime_column_name].dt.tz_localize(None)
244
+ df[f"DateTime({timezone})"] = df["DateTime(UTC)"].dt.tz_convert(timezone)
245
+
246
+ if not timezone_aware_dates:
247
+ cols_date_all = cols_date_utc + ["InsertionTimestamp", f"DateTime({timezone})"]
248
+ for c in cols_date_all:
249
+ if c in df.columns:
250
+ df[c] = df[c].dt.tz_localize(None)
247
251
 
248
252
  # Process raw data and convert it to standardized format
249
253
  if process_data:
@@ -266,6 +270,8 @@ class DetDatabase:
266
270
  Returns:
267
271
  Processed dataframe containing day-ahead spot prices
268
272
  """
273
+ df_in.reset_index(drop=True, inplace=True)
274
+
269
275
  # Initialize output dataframe
270
276
  df_out = pd.DataFrame()
271
277
 
@@ -277,7 +283,7 @@ class DetDatabase:
277
283
  df_out["TradingDate"] = trading_date
278
284
 
279
285
  # Set delivery start date
280
- df_out["DeliveryStart"] = df_in[f"DateTime({timezone})"].values
286
+ df_out["DeliveryStart"] = df_in[f"DateTime({timezone})"]
281
287
 
282
288
  # Set delivery end date
283
289
  delivery_end = [d + relativedelta(hours=1) for d in df_in[f"DateTime({timezone})"]]
@@ -300,6 +306,7 @@ class DetDatabase:
300
306
  end_delivery_date: datetime = None,
301
307
  columns: list = None,
302
308
  process_data: bool = True,
309
+ timezone_aware_dates: bool = False,
303
310
  ) -> pd.DataFrame:
304
311
  """
305
312
  Loads entsoe imbalance prices from the database.
@@ -319,6 +326,8 @@ class DetDatabase:
319
326
  columns: Requested database table columns. Set columns=["*"] (i.e. as list) to get
320
327
  all columns.
321
328
  process_data: Indicates if data should be processed convert to standardized format
329
+ timezone_aware_dates: If true, returns all dates as timezone-aware. Otherwise,
330
+ returns them as timezone-naive.
322
331
 
323
332
  Returns:
324
333
  Dataframe containing imbalance prices
@@ -328,8 +337,6 @@ class DetDatabase:
328
337
  compatible
329
338
  ValueError: Raises an error if the combination of trading dates and delivery dates
330
339
  is not valid.
331
- ValueError: Raises an error if match with input commodity name is not unique
332
- ValueError: Raises an error if input commodity is not supported
333
340
  ValueError: Raises an error if no price data is found for user inputs
334
341
  """
335
342
  # Input validation
@@ -378,21 +385,13 @@ class DetDatabase:
378
385
  # Note: The local timezone is important because ENTSOE provides all prices in the UTC
379
386
  # timezone. We first convert the dates from UTC to the local timezone, and then filter
380
387
  # for the requested delivery period.
381
- commodity_info = self.load_commodities(
382
- columns=["Timezone", "EntsoeMapCode"], conditions=f"WHERE Name='{commodity_name}'"
388
+ commodity_info = self.get_commodity_info(
389
+ filter_column="Name",
390
+ filter_value=commodity_name,
391
+ info_columns=["Timezone", "EntsoeMapCode"],
383
392
  )
384
- if commodity_info.shape[0] > 1:
385
- raise ValueError(f"More than one match found with commodity '{commodity_name}'.")
386
- elif commodity_info.shape[0] == 0:
387
- supported_commodities = self.load_commodities(columns=["Name"])
388
- supported_commodities_str = ", ".join(f"'{x}'" for x in supported_commodities["Name"])
389
- raise ValueError(
390
- f"Commodity '{commodity_name}' is not supported. Supported commodities: "
391
- f"{supported_commodities_str}."
392
- )
393
- else:
394
- map_code = commodity_info.loc[0, "EntsoeMapCode"]
395
- timezone = commodity_info.loc[0, "Timezone"]
393
+ map_code = commodity_info["EntsoeMapCode"]
394
+ timezone = commodity_info["Timezone"]
396
395
 
397
396
  # Convert start trading date to start delivery date
398
397
  if start_trading_date is not None:
@@ -435,11 +434,22 @@ class DetDatabase:
435
434
  by=["DateTime(UTC)"], axis=0, ascending=True, inplace=True, ignore_index=True
436
435
  )
437
436
 
437
+ # Convert date columns to timezone-aware dates
438
+ cols_date_utc = ["DateTime(UTC)", "UpdateTime(UTC)"]
439
+ for c in cols_date_utc:
440
+ if c in df.columns:
441
+ df[c] = df[c].dt.tz_localize("UTC")
442
+ if "InsertionTimestamp" in df.columns:
443
+ df["InsertionTimestamp"] = df["InsertionTimestamp"].dt.tz_localize(timezone)
444
+
438
445
  # Add column with delivery date expressed in local timezone
439
- datetime_column_name = f"DateTime({timezone})"
440
- df[datetime_column_name] = df["DateTime(UTC)"].dt.tz_localize("UTC")
441
- df[datetime_column_name] = df[datetime_column_name].dt.tz_convert(timezone)
442
- df[datetime_column_name] = df[datetime_column_name].dt.tz_localize(None)
446
+ df[f"DateTime({timezone})"] = df["DateTime(UTC)"].dt.tz_convert(timezone)
447
+
448
+ if not timezone_aware_dates:
449
+ cols_date_all = cols_date_utc + ["InsertionTimestamp", f"DateTime({timezone})"]
450
+ for c in cols_date_all:
451
+ if c in df.columns:
452
+ df[c] = df[c].dt.tz_localize(None)
443
453
 
444
454
  # Process raw data and convert it to standardized format
445
455
  if process_data:
@@ -462,6 +472,8 @@ class DetDatabase:
462
472
  Returns:
463
473
  Processed dataframe containing imbalance prices
464
474
  """
475
+ df_in.reset_index(drop=True, inplace=True)
476
+
465
477
  # Initialize output dataframe
466
478
  df_out = pd.DataFrame()
467
479
 
@@ -469,10 +481,10 @@ class DetDatabase:
469
481
  df_out["CommodityName"] = [commodity_name] * df_in.shape[0]
470
482
 
471
483
  # Set trading date
472
- df_out["TradingDate"] = df_in[f"DateTime({timezone})"].dt.floor("D").values
484
+ df_out["TradingDate"] = df_in[f"DateTime({timezone})"].dt.floor("D")
473
485
 
474
486
  # Set delivery start date
475
- df_out["DeliveryStart"] = df_in[f"DateTime({timezone})"].values
487
+ df_out["DeliveryStart"] = df_in[f"DateTime({timezone})"]
476
488
 
477
489
  # Set delivery end date
478
490
  delivery_end = [d + relativedelta(minutes=15) for d in df_in[f"DateTime({timezone})"]]
@@ -495,6 +507,7 @@ class DetDatabase:
495
507
  tenors: list,
496
508
  delivery_type: str,
497
509
  columns: list = None,
510
+ timezone_aware_dates: bool = False,
498
511
  ) -> pd.DataFrame:
499
512
  """
500
513
  Loads futures end-of-day settlement prices from the database, over a user-defined range
@@ -508,6 +521,8 @@ class DetDatabase:
508
521
  delivery_type: Delivery type ("Base", "Peak", "Offpeak")
509
522
  columns: Requested database table columns. Set columns=["*"] (i.e. as list) to get
510
523
  all columns.
524
+ timezone_aware_dates: If true, returns all dates as timezone-aware. Otherwise,
525
+ returns them as timezone-naive.
511
526
 
512
527
  Returns:
513
528
  Dataframe containing futures end-of-day settlement prices
@@ -561,9 +576,23 @@ class DetDatabase:
561
576
  )
562
577
 
563
578
  # Convert dates from datetime.date to pd.Timestamp
564
- df["TradingDate"] = pd.DatetimeIndex(df["TradingDate"])
565
- df["DeliveryStart"] = pd.DatetimeIndex(df["DeliveryStart"])
566
- df["DeliveryEnd"] = pd.DatetimeIndex(df["DeliveryEnd"])
579
+ cols_date = ["TradingDate", "DeliveryStart", "DeliveryEnd"]
580
+ for c in cols_date:
581
+ if c in df.columns:
582
+ df[c] = pd.DatetimeIndex(df[c])
583
+
584
+ if timezone_aware_dates:
585
+ # Get local timezone
586
+ commodity_info = self.get_commodity_info(
587
+ filter_column="Name", filter_value=commodity_name, info_columns=["Timezone"]
588
+ )
589
+ timezone = commodity_info["Timezone"]
590
+
591
+ # Convert timezone-naive to timezone-aware dates
592
+ cols_datetime = ["TradingDate", "DeliveryStart", "DeliveryEnd", "InsertionTimestamp"]
593
+ for c in cols_datetime:
594
+ if c in df.columns:
595
+ df[c] = df[c].dt.tz_localize(timezone)
567
596
 
568
597
  return df
569
598
 
@@ -826,9 +855,10 @@ class DetDatabase:
826
855
  )
827
856
 
828
857
  # Convert dates from datetime.date to pd.Timestamp
829
- df["TradingDate"] = pd.DatetimeIndex(df["TradingDate"])
830
- df["Delivery Start"] = pd.DatetimeIndex(df["Delivery Start"])
831
- df["Delivery End"] = pd.DatetimeIndex(df["Delivery End"])
858
+ cols_date = ["TradingDate", "Delivery Start", "Delivery End"]
859
+ for c in cols_date:
860
+ if c in df.columns:
861
+ df[c] = pd.DatetimeIndex(df[c])
832
862
 
833
863
  # Drop duplicates
834
864
  df = df.drop_duplicates()
@@ -12,7 +12,12 @@ class OutputItem:
12
12
  """A class to easily manage, store and export a model output."""
13
13
 
14
14
  def __init__(
15
- self, data=None, filename: str = None, extension: str = None, sub_path: str = None
15
+ self,
16
+ data=None,
17
+ filename: str = None,
18
+ extension: str = None,
19
+ sub_path: str = None,
20
+ export_options: dict = None,
16
21
  ):
17
22
  """
18
23
  Constructor method.
@@ -23,11 +28,13 @@ class OutputItem:
23
28
  extension: File extension to be used when exporting the output data
24
29
  sub_path: Within the output base directory, indicates the sub-path (if any) of the
25
30
  folder where the output data should be exported
31
+ export_options: Additional options for the function exporting the output data to a file
26
32
  """
27
33
  self.data = data
28
34
  self.filename = filename
29
35
  self.extension = extension
30
36
  self.sub_path = sub_path
37
+ self.export_options = dict() if export_options is None else export_options
31
38
 
32
39
  def export_to_file(self, folder_dir: Path = None):
33
40
  """
@@ -74,7 +81,7 @@ class OutputItem:
74
81
  """
75
82
  data_type = type(self.data)
76
83
  if data_type is pd.DataFrame:
77
- self.data.to_csv(file_dir, sep=",", index=False)
84
+ self.data.to_csv(file_dir, **self.export_options)
78
85
  else:
79
86
  raise TypeError(f"Exporting data type {data_type} to csv file is not supported.")
80
87
 
@@ -91,7 +98,7 @@ class OutputItem:
91
98
  data_type = type(self.data)
92
99
  if data_type is dict:
93
100
  with open(file_dir, "w") as f:
94
- json.dump(self.data, f, indent=4)
101
+ json.dump(self.data, f, indent=4, **self.export_options)
95
102
  else:
96
103
  raise TypeError(f"Exporting data type {data_type} to json file is not supported.")
97
104
 
@@ -107,7 +114,7 @@ class OutputItem:
107
114
  """
108
115
  data_type = type(self.data)
109
116
  if data_type is go.Figure:
110
- self.data.write_html(file_dir)
117
+ self.data.write_html(file_dir, **self.export_options)
111
118
  else:
112
119
  raise TypeError(f"Exporting data type {data_type} to html file is not supported.")
113
120
 
@@ -123,7 +130,7 @@ class OutputItem:
123
130
  """
124
131
  data_type = type(self.data)
125
132
  if data_type is np.ndarray:
126
- np.savez_compressed(file_dir, data=self.data)
133
+ np.savez_compressed(file_dir, data=self.data, **self.export_options)
127
134
  else:
128
135
  raise TypeError(f"Exporting data type {data_type} to npz file is not supported.")
129
136
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "detquantlib"
3
- version = "3.3.0"
3
+ version = "3.5.0"
4
4
  description = "An internal library containing functions and classes that can be used across Quant models."
5
5
  authors = ["DET"]
6
6
  readme = "README.md"
File without changes
File without changes