detquantlib 3.13.0__tar.gz → 3.14.1__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 (30) hide show
  1. {detquantlib-3.13.0 → detquantlib-3.14.1}/PKG-INFO +1 -2
  2. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/data/databases/detdatabase.py +35 -49
  3. {detquantlib-3.13.0 → detquantlib-3.14.1}/pyproject.toml +6 -2
  4. {detquantlib-3.13.0 → detquantlib-3.14.1}/LICENSE.txt +0 -0
  5. {detquantlib-3.13.0 → detquantlib-3.14.1}/README.md +0 -0
  6. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/__init__.py +0 -0
  7. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/converters/__init__.py +0 -0
  8. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/converters/definitions.py +0 -0
  9. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/converters/energy.py +0 -0
  10. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/converters/helpers.py +0 -0
  11. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/converters/price.py +0 -0
  12. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/data/__init__.py +0 -0
  13. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/data/databases/helpers.py +0 -0
  14. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/data/entsoe/entsoe.py +0 -0
  15. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/data/sftp/sftp.py +0 -0
  16. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/dates/__init__.py +0 -0
  17. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/dates/dates.py +0 -0
  18. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/figures/__init__.py +0 -0
  19. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/figures/plotly_figures.py +0 -0
  20. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/forecasting/__init__.py +0 -0
  21. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/forecasting/forecasting.py +0 -0
  22. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/outputs/__init__.py +0 -0
  23. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/outputs/outputs_interface.py +0 -0
  24. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/stats/__init__.py +0 -0
  25. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/stats/data_analysis.py +0 -0
  26. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/tradable_products/__init__.py +0 -0
  27. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/tradable_products/tradable_products.py +0 -0
  28. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/utils/__init__.py +0 -0
  29. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/utils/logging.py +0 -0
  30. {detquantlib-3.13.0 → detquantlib-3.14.1}/detquantlib/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: detquantlib
3
- Version: 3.13.0
3
+ Version: 3.14.1
4
4
  Summary: An internal library containing functions and classes that can be used across Quant models.
5
5
  License-File: LICENSE.txt
6
6
  Author: DET
@@ -21,7 +21,6 @@ Requires-Dist: pyodbc (>=5.2.0,<6.0.0)
21
21
  Requires-Dist: python-dotenv (>=1.1.0,<2.0.0)
22
22
  Requires-Dist: scipy (>=1.15.2,<2.0.0)
23
23
  Requires-Dist: sqlalchemy (>=2.0.43,<3.0.0)
24
- Project-URL: Repository, https://github.com/Dynamic-Energy-Trading/detquantlib
25
24
  Description-Content-Type: text/markdown
26
25
 
27
26
  # DET Quant Library
@@ -9,21 +9,36 @@ import pandas as pd
9
9
  from dateutil.relativedelta import *
10
10
  from sqlalchemy import Engine, create_engine, text
11
11
 
12
+ # Internal modules
13
+ from detquantlib.converters import convert_energy
14
+ from detquantlib.data.databases.helpers import list_to_sql_columns, list_to_sql_set
15
+ from detquantlib.utils import list_to_str
16
+
12
17
 
13
18
  class DetDatabase:
14
19
  """
15
20
  A class to easily interact with the DET database, including fetching and processing data.
16
21
  """
17
22
 
18
- def __init__(self, engine: Engine = None, driver: str = "ODBC Driver 18 for SQL Server"):
23
+ def __init__(
24
+ self,
25
+ db_name: str = None,
26
+ engine: Engine = None,
27
+ driver: str = "ODBC Driver 18 for SQL Server",
28
+ ):
19
29
  """
20
30
  Constructor method.
21
31
 
22
32
  Args:
33
+ db_name: Database name. If None, the name is fetched from environment variables.
23
34
  engine: Instance of SQLAlchemy engine. If None, the instance is automatically
24
35
  initialized.
25
36
  driver: ODBC driver
26
37
  """
38
+ # Store database name if it is provided
39
+ if db_name:
40
+ os.environ["DET_DB_NAME"] = db_name
41
+
27
42
  # Only allow object creation if mandatory environment variables exist
28
43
  DetDatabase.check_environment_variables()
29
44
 
@@ -48,7 +63,7 @@ class DetDatabase:
48
63
  for d in required_env_vars:
49
64
  if d["name"] not in available_env_vars:
50
65
  required_env_vars_names = [x["name"] for x in required_env_vars]
51
- required_env_vars_str = ", ".join(f"'{x}'" for x in required_env_vars_names)
66
+ required_env_vars_str = list_to_str(required_env_vars_names)
52
67
  raise EnvironmentError(
53
68
  f"The DetDatabase class requires the following environment variables: "
54
69
  f"{required_env_vars_str}. Environment variable '{d['name']}' "
@@ -93,7 +108,7 @@ class DetDatabase:
93
108
  """
94
109
  try:
95
110
  df = pd.read_sql_query(query, con=self.engine)
96
- except Exception as e:
111
+ except Exception:
97
112
  # If query fails, close connection before raising the error
98
113
  self.terminate_engine()
99
114
  raise
@@ -198,10 +213,7 @@ class DetDatabase:
198
213
  columns.append("DateTime(UTC)")
199
214
 
200
215
  # Convert columns from list to string
201
- if len(columns) == 1:
202
- columns_str = str(columns[0])
203
- else:
204
- columns_str = f"[{'], ['.join(columns)}]"
216
+ columns_str = list_to_sql_columns(columns)
205
217
 
206
218
  # Get commodity information (map code and local timezone)
207
219
  # Note: The local timezone is important because ENTSOE provides all prices in the UTC
@@ -415,10 +427,7 @@ class DetDatabase:
415
427
  columns.append("DateTime(UTC)")
416
428
 
417
429
  # Convert columns from list to string
418
- if len(columns) == 1:
419
- columns_str = str(columns[0])
420
- else:
421
- columns_str = f"[{'], ['.join(columns)}]"
430
+ columns_str = list_to_sql_columns(columns)
422
431
 
423
432
  # Get commodity information (map code and local timezone)
424
433
  # Note: The local timezone is important because ENTSOE provides all prices in the UTC
@@ -567,13 +576,10 @@ class DetDatabase:
567
576
  columns = ["*"]
568
577
 
569
578
  # Convert columns from list to string
570
- if len(columns) == 1:
571
- columns_str = str(columns[0])
572
- else:
573
- columns_str = f"[{'], ['.join(columns)}]"
579
+ columns_str = list_to_sql_columns(columns)
574
580
 
575
581
  # Convert tenors from list to string
576
- tenors_str = f"({' ,'.join([repr(item) for item in tenors])})"
582
+ tenors_str = list_to_sql_set(tenors)
577
583
 
578
584
  # Convert dates from datetime to string
579
585
  start_trading_date_str = start_trading_date.strftime("%Y-%m-%d")
@@ -639,10 +645,7 @@ class DetDatabase:
639
645
  columns = ["*"]
640
646
 
641
647
  # Convert columns from list to string
642
- if len(columns) == 1:
643
- columns_str = str(columns[0])
644
- else:
645
- columns_str = f"[{'], ['.join(columns)}]"
648
+ columns_str = list_to_sql_columns(columns)
646
649
 
647
650
  # Query db
648
651
  table = DetDatabase.get_table_name("commodity")
@@ -679,7 +682,7 @@ class DetDatabase:
679
682
 
680
683
  elif commodity_info.shape[0] == 0:
681
684
  available_values = self.load_commodities(columns=[filter_column])
682
- available_values_str = ", ".join(f"'{x}'" for x in available_values[filter_column])
685
+ available_values_str = list_to_str(available_values[filter_column])
683
686
  raise ValueError(
684
687
  f"Value {filter_value} not found in column '{filter_column}'. Available values: "
685
688
  f"{available_values_str}."
@@ -713,10 +716,7 @@ class DetDatabase:
713
716
  columns = ["*"]
714
717
 
715
718
  # Convert columns from list to string
716
- if len(columns) == 1:
717
- columns_str = str(columns[0])
718
- else:
719
- columns_str = f"[{'], ['.join(columns)}]"
719
+ columns_str = list_to_sql_columns(columns)
720
720
 
721
721
  # Convert dates from datetime to string
722
722
  end_trading_date = pd.Timestamp(end_trading_date).floor("D") + relativedelta(days=1)
@@ -769,13 +769,10 @@ class DetDatabase:
769
769
  columns = ["*"]
770
770
 
771
771
  # Convert columns from list to string
772
- if len(columns) == 1:
773
- columns_str = str(columns[0])
774
- else:
775
- columns_str = f"[{'], ['.join(columns)}]"
772
+ columns_str = list_to_sql_columns(columns)
776
773
 
777
774
  # Convert tenors from list to string
778
- identifiers_str = ", ".join(f"'{i}'" for i in identifiers)
775
+ identifiers_str = list_to_sql_set(identifiers)
779
776
 
780
777
  # Query db
781
778
  table = DetDatabase.get_table_name("instrument")
@@ -819,10 +816,7 @@ class DetDatabase:
819
816
  columns = ["*"]
820
817
 
821
818
  # Convert columns from list to string
822
- if len(columns) == 1:
823
- columns_str = f"[{columns[0]}]"
824
- else:
825
- columns_str = f"[{'], ['.join(columns)}]"
819
+ columns_str = list_to_sql_columns(columns)
826
820
 
827
821
  # Convert dates from datetime to string
828
822
  start_trading_date_str = start_trading_date.strftime("%Y-%m-%d")
@@ -922,10 +916,7 @@ class DetDatabase:
922
916
  columns = ["*"]
923
917
 
924
918
  # Convert columns from list to string
925
- if len(columns) == 1:
926
- columns_str = str(columns[0])
927
- else:
928
- columns_str = f"[{'], ['.join(columns)}]"
919
+ columns_str = list_to_sql_columns(columns)
929
920
 
930
921
  # Convert dates from datetime to string
931
922
  forecast_date_str = forecast_date.strftime("%Y-%m-%d")
@@ -975,10 +966,11 @@ class DetDatabase:
975
966
  df[c] = df[c].dt.tz_localize(None)
976
967
 
977
968
  # Rescale column values
978
- df["kWh"] = df["kWh"] / 1000
969
+ df["Volume(MWh)"] = convert_energy(df["kWh"], unit_in="kWh", unit_out="MWh")
970
+ df.drop(columns="kWh", inplace=True)
979
971
 
980
972
  # Rename columns
981
- df = df.rename(columns={"kWh": "Volume(MWh)", "Datetime": "DeliveryStart"})
973
+ df = df.rename(columns={"Datetime": "DeliveryStart"})
982
974
 
983
975
  return df
984
976
 
@@ -1026,10 +1018,7 @@ class DetDatabase:
1026
1018
  columns = ["*"]
1027
1019
 
1028
1020
  # Convert columns from list to string
1029
- if len(columns) == 1:
1030
- columns_str = str(columns[0])
1031
- else:
1032
- columns_str = f"[{'], ['.join(columns)}]"
1021
+ columns_str = list_to_sql_columns(columns)
1033
1022
 
1034
1023
  # Query db
1035
1024
  table = DetDatabase.get_table_name("client_day_ahead_auction_bids")
@@ -1093,10 +1082,7 @@ class DetDatabase:
1093
1082
  columns = ["*"]
1094
1083
 
1095
1084
  # Convert columns from list to string
1096
- if len(columns) == 1:
1097
- columns_str = str(columns[0])
1098
- else:
1099
- columns_str = f"[{'], ['.join(columns)}]"
1085
+ columns_str = list_to_sql_columns(columns)
1100
1086
 
1101
1087
  # Query db
1102
1088
  table = DetDatabase.get_table_name("client")
@@ -1131,7 +1117,7 @@ class DetDatabase:
1131
1117
 
1132
1118
  elif client_info.shape[0] == 0:
1133
1119
  available_values = self.load_clients(columns=[filter_column])
1134
- available_values_str = ", ".join(f"'{x}'" for x in available_values[filter_column])
1120
+ available_values_str = list_to_str(available_values[filter_column])
1135
1121
  raise ValueError(
1136
1122
  f"Value {filter_value} not found in column '{filter_column}'. Available values: "
1137
1123
  f"{available_values_str}."
@@ -1,10 +1,9 @@
1
1
  [tool.poetry]
2
2
  name = "detquantlib"
3
- version = "3.13.0"
3
+ version = "3.14.1"
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"
7
- repository = "https://github.com/Dynamic-Energy-Trading/detquantlib"
8
7
  packages = [
9
8
  { include = "detquantlib" }, # Specifies the location of the package
10
9
  ]
@@ -30,6 +29,7 @@ pytest-cov = "^7.0.0"
30
29
  black = "^25.9.0"
31
30
  darglint = "^1.8.1"
32
31
  isort = "^6.1.0"
32
+ ruff = "^0.15.4"
33
33
  colorama = "^0.4.6"
34
34
  pymarkdownlnt = "^0.9.32"
35
35
  md-toc = "^9.0.0"
@@ -53,6 +53,10 @@ known_third_party = ["invoke"]
53
53
  [tool.black]
54
54
  line-length = 99
55
55
 
56
+ [tool.ruff.lint]
57
+ select = ["B", "F"] # "B"=flake8-bugbear, "F"=Pyflakes
58
+ ignore = ["F403", "F405"]
59
+
56
60
  [tool.pymarkdown]
57
61
  plugins.md013.enabled = false # Disable line length requirements
58
62
  plugins.md040.enabled = false # Disable fenced code blocks language requirements
File without changes
File without changes