detquantlib 5.1.0__tar.gz → 5.1.2__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 (33) hide show
  1. {detquantlib-5.1.0 → detquantlib-5.1.2}/PKG-INFO +1 -1
  2. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/data/databases/detdatabase.py +47 -26
  3. {detquantlib-5.1.0 → detquantlib-5.1.2}/pyproject.toml +1 -1
  4. {detquantlib-5.1.0 → detquantlib-5.1.2}/LICENSE.txt +0 -0
  5. {detquantlib-5.1.0 → detquantlib-5.1.2}/README.md +0 -0
  6. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/__init__.py +0 -0
  7. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/assets/__init__.py +0 -0
  8. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/assets/battery.py +0 -0
  9. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/assets/wind_turbine.py +0 -0
  10. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/converters/__init__.py +0 -0
  11. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/converters/definitions.py +0 -0
  12. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/converters/energy.py +0 -0
  13. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/converters/helpers.py +0 -0
  14. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/converters/price.py +0 -0
  15. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/data/__init__.py +0 -0
  16. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/data/databases/helpers.py +0 -0
  17. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/data/entsoe/entsoe.py +0 -0
  18. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/data/sftp/sftp.py +0 -0
  19. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/dates/__init__.py +0 -0
  20. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/dates/dates.py +0 -0
  21. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/figures/__init__.py +0 -0
  22. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/figures/plotly_figures.py +0 -0
  23. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/forecasting/__init__.py +0 -0
  24. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/forecasting/forecasting.py +0 -0
  25. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/outputs/__init__.py +0 -0
  26. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/outputs/outputs_interface.py +0 -0
  27. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/stats/__init__.py +0 -0
  28. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/stats/data_analysis.py +0 -0
  29. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/tradable_products/__init__.py +0 -0
  30. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/tradable_products/tradable_products.py +0 -0
  31. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/utils/__init__.py +0 -0
  32. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/utils/logging.py +0 -0
  33. {detquantlib-5.1.0 → detquantlib-5.1.2}/detquantlib/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: detquantlib
3
- Version: 5.1.0
3
+ Version: 5.1.2
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: Dynamic Energy Trading
@@ -35,26 +35,32 @@ class DetDatabase:
35
35
  initialized.
36
36
  driver: ODBC driver
37
37
  """
38
- # Store database name if it is provided
39
- if db_name:
40
- os.environ["DET_DB_NAME"] = db_name
41
-
42
38
  # Only allow object creation if mandatory environment variables exist
43
- DetDatabase.check_environment_variables()
39
+ skip_db_name = db_name is not None
40
+ DetDatabase.check_environment_variables(skip_db_name)
44
41
 
42
+ self.db_name = db_name if db_name else os.environ["DET_DB_NAME"]
45
43
  self.driver = driver
46
44
  self.engine = engine if engine is not None else self.initialize_engine()
47
45
 
48
46
  @staticmethod
49
- def check_environment_variables():
47
+ def check_environment_variables(skip_db_name: bool):
50
48
  """
51
49
  Checks if environment variables needed by the class are defined.
52
50
 
51
+ Args:
52
+ skip_db_name: If true, does not check if the environment variable containing the
53
+ database name is defined
54
+
53
55
  Raises:
54
56
  ConnectionError: Raises an error if environment variables are not defined.
55
57
  """
56
- required_env_vars = [
57
- dict(name="DET_DB_NAME", value=None, description="Database name"),
58
+ required_env_vars = (
59
+ []
60
+ if skip_db_name
61
+ else [dict(name="DET_DB_NAME", value=None, description="Database name")]
62
+ )
63
+ required_env_vars += [
58
64
  dict(name="DET_DB_SERVER", value=None, description="Server name"),
59
65
  dict(name="DET_DB_USERNAME", value=None, description="Username"),
60
66
  dict(name="DET_DB_PASSWORD", value=None, description="Password"),
@@ -81,7 +87,7 @@ class DetDatabase:
81
87
  connection_str = (
82
88
  f"DRIVER={self.driver};"
83
89
  f"SERVER={os.getenv('DET_DB_SERVER')};"
84
- f"DATABASE={os.getenv('DET_DB_NAME')};"
90
+ f"DATABASE={self.db_name};"
85
91
  f"UID={os.getenv('DET_DB_USERNAME')};"
86
92
  f"PWD={quote_plus(os.getenv('DET_DB_PASSWORD'))}"
87
93
  )
@@ -872,15 +878,20 @@ class DetDatabase:
872
878
  Args:
873
879
  profile: Customer/profile name.
874
880
  Note on the 'Portfolio' and 'Portfolioweekend' profiles:
875
- - Profile names 'Portfolio' and 'Portfolioweekend' refer to the same set of
876
- connection points.
877
- - In the database, the profile name is set to 'Portfolio' when the forecast date
878
- is between Monday and Friday.
879
- - In the database, the profile name is set to 'Portfolioweekend' when the forecast
880
- date is Saturday or Sunday.
881
- - When calling this method, the input argument 'profile' can be set to
882
- 'PortfolioAll' to automatically let the method switch between 'Portfolio' and
883
- 'Portfolioweekend', based on the used-input forecast date.
881
+ - [Legacy data until March 2026]:
882
+ - Profile names 'Portfolio' and 'Portfolioweekend' refer to the same set
883
+ of connection points.
884
+ - In the database, the profile name is set to 'Portfolio' when the
885
+ forecast date is between Monday and Friday.
886
+ - In the database, the profile name is set to 'Portfolioweekend' when
887
+ the forecast date is Saturday or Sunday.
888
+ - [Data since March 2026]:
889
+ - The 'Portfolioweekend' name is deprecated. Day-ahead forecasts are
890
+ now stored under the 'Portfolio' profile only.
891
+ - When calling this method, set the input argument 'profile' to
892
+ 'PortfolioAll' to automatically switch between 'Portfolio' and
893
+ 'Portfolioweekend', based on the used-input forecast date.
894
+ 'PortfolioAll' supports both the legacy and new data structure.
884
895
  forecast_date: Date on which customer volume forecast is generated.
885
896
  start_delivery_date: First delivery date included.
886
897
  end_delivery_date: Last delivery date included.
@@ -896,13 +907,6 @@ class DetDatabase:
896
907
  Raises:
897
908
  ValueError: Raises an error if no volume forecast data is found for user inputs.
898
909
  """
899
- # Convert profile if set to "PortfolioAll"
900
- if profile == "PortfolioAll":
901
- if forecast_date.weekday() > 4:
902
- profile = "Portfolioweekend"
903
- else:
904
- profile = "Portfolio"
905
-
906
910
  # Convert start delivery date from local timezone to UTC and string
907
911
  start_delivery_date = start_delivery_date.replace(tzinfo=ZoneInfo(local_timezone))
908
912
  start_delivery_date = start_delivery_date.astimezone(ZoneInfo("UTC"))
@@ -924,17 +928,34 @@ class DetDatabase:
924
928
  # Convert dates from datetime to string
925
929
  forecast_date_str = forecast_date.strftime("%Y-%m-%d")
926
930
 
931
+ # Define query profile name. If 'PortfolioAll', first try with 'Portfolio' (compatibility
932
+ # with new data).
933
+ query_profile = "Portfolio" if profile == "PortfolioAll" else profile
934
+
927
935
  # Query db
928
936
  table = DetDatabase.get_table_name("client_volume_forecast")
929
937
  query = (
930
938
  f"SELECT {columns_str} FROM {table} "
931
- f"WHERE Profile='{profile}' "
939
+ f"WHERE Profile='{query_profile}' "
932
940
  f"AND ForecastDate='{forecast_date_str}' "
933
941
  f"AND Datetime>='{start_date_str}' "
934
942
  f"AND Datetime<'{end_date_str}'"
935
943
  )
936
944
  df = self.query_db(query)
937
945
 
946
+ if profile == "PortfolioAll" and df.empty and forecast_date.weekday() > 4:
947
+ # If 'Portfolio' not found, try with 'Portfolioweekend' (backward compatibility with
948
+ # legacy data)
949
+ query_profile = "Portfolioweekend"
950
+ query = (
951
+ f"SELECT {columns_str} FROM {table} "
952
+ f"WHERE Profile='{query_profile}' "
953
+ f"AND ForecastDate='{forecast_date_str}' "
954
+ f"AND Datetime>='{start_date_str}' "
955
+ f"AND Datetime<'{end_date_str}'"
956
+ )
957
+ df = self.query_db(query)
958
+
938
959
  # Assert data
939
960
  if df.empty:
940
961
  raise ValueError("No volume forecast data found for user-defined inputs.")
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "detquantlib"
3
- version = "5.1.0"
3
+ version = "5.1.2"
4
4
  description = "An internal library containing functions and classes that can be used across Quant models."
5
5
  authors = ["Dynamic Energy Trading"]
6
6
  readme = "README.md"
File without changes
File without changes