detquantlib 3.6.0__tar.gz → 3.7.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.
- {detquantlib-3.6.0 → detquantlib-3.7.0}/PKG-INFO +1 -1
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/data/databases/detdatabase.py +185 -24
- {detquantlib-3.6.0 → detquantlib-3.7.0}/pyproject.toml +1 -1
- {detquantlib-3.6.0 → detquantlib-3.7.0}/LICENSE.txt +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/README.md +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/data/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/data/entsoe/entsoe.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/data/sftp/sftp.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/dates/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/dates/dates.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/figures/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/figures/plotly_figures.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/outputs/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/outputs/outputs_interface.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/stats/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/stats/data_analysis.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/tradable_products/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/tradable_products/tradable_products.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/utils/__init__.py +0 -0
- {detquantlib-3.6.0 → detquantlib-3.7.0}/detquantlib/utils/utils.py +0 -0
|
@@ -402,8 +402,7 @@ class DetDatabase:
|
|
|
402
402
|
|
|
403
403
|
# Convert end trading date to end delivery date
|
|
404
404
|
if end_trading_date is not None:
|
|
405
|
-
end_trading_date = pd.Timestamp(end_trading_date).floor("D")
|
|
406
|
-
end_delivery_date = end_trading_date + relativedelta(days=1)
|
|
405
|
+
end_trading_date = pd.Timestamp(end_trading_date).floor("D") + relativedelta(days=1)
|
|
407
406
|
|
|
408
407
|
# Convert end date to UTC and string
|
|
409
408
|
end_delivery_date = end_delivery_date.replace(tzinfo=ZoneInfo(timezone))
|
|
@@ -666,10 +665,7 @@ class DetDatabase:
|
|
|
666
665
|
return commodity_info
|
|
667
666
|
|
|
668
667
|
def load_account_positions(
|
|
669
|
-
self,
|
|
670
|
-
start_trading_date: datetime,
|
|
671
|
-
end_trading_date: datetime,
|
|
672
|
-
columns: list = None,
|
|
668
|
+
self, start_trading_date: datetime, end_trading_date: datetime, columns: list = None
|
|
673
669
|
) -> pd.DataFrame:
|
|
674
670
|
"""
|
|
675
671
|
Loads account positions from the database, over a user-defined range of trading dates.
|
|
@@ -697,6 +693,7 @@ class DetDatabase:
|
|
|
697
693
|
columns_str = f"[{'], ['.join(columns)}]"
|
|
698
694
|
|
|
699
695
|
# Convert dates from datetime to string
|
|
696
|
+
end_trading_date = pd.Timestamp(end_trading_date).floor("D") + relativedelta(days=1)
|
|
700
697
|
start_trading_date_str = start_trading_date.strftime("%Y-%m-%d")
|
|
701
698
|
end_trading_date_str = end_trading_date.strftime("%Y-%m-%d")
|
|
702
699
|
|
|
@@ -704,8 +701,8 @@ class DetDatabase:
|
|
|
704
701
|
table = DetDatabaseDefinitions.DEFINITIONS["table_name_account_position"]
|
|
705
702
|
query = (
|
|
706
703
|
f"SELECT {columns_str} FROM {table} "
|
|
707
|
-
f"WHERE
|
|
708
|
-
f"'{end_trading_date_str}'"
|
|
704
|
+
f"WHERE InsertionTimestamp>='{start_trading_date_str}' "
|
|
705
|
+
f"AND InsertionTimestamp<'{end_trading_date_str}'"
|
|
709
706
|
)
|
|
710
707
|
|
|
711
708
|
# Query db
|
|
@@ -730,11 +727,7 @@ class DetDatabase:
|
|
|
730
727
|
|
|
731
728
|
return df
|
|
732
729
|
|
|
733
|
-
def load_instruments(
|
|
734
|
-
self,
|
|
735
|
-
identifiers: list,
|
|
736
|
-
columns: list = None,
|
|
737
|
-
) -> pd.DataFrame:
|
|
730
|
+
def load_instruments(self, identifiers: list, columns: list = None) -> pd.DataFrame:
|
|
738
731
|
"""
|
|
739
732
|
Loads instrument data based on identifier (of account positions) from the database.
|
|
740
733
|
|
|
@@ -828,8 +821,8 @@ class DetDatabase:
|
|
|
828
821
|
query = (
|
|
829
822
|
f"SELECT {columns_str} FROM {table} "
|
|
830
823
|
f"WHERE Product LIKE '{product_code}' "
|
|
831
|
-
f"AND
|
|
832
|
-
f"'{end_trading_date_str}'"
|
|
824
|
+
f"AND TradingDate>='{start_trading_date_str}' "
|
|
825
|
+
f"AND TradingDate<='{end_trading_date_str}'"
|
|
833
826
|
)
|
|
834
827
|
|
|
835
828
|
# Query db
|
|
@@ -872,7 +865,7 @@ class DetDatabase:
|
|
|
872
865
|
columns: list = None,
|
|
873
866
|
) -> pd.DataFrame:
|
|
874
867
|
"""
|
|
875
|
-
Loads customer volume forecasts from
|
|
868
|
+
Loads customer volume forecasts from the database.
|
|
876
869
|
|
|
877
870
|
Args:
|
|
878
871
|
profile: Customer/profile name.
|
|
@@ -913,10 +906,8 @@ class DetDatabase:
|
|
|
913
906
|
start_delivery_date = start_delivery_date.astimezone(ZoneInfo("UTC"))
|
|
914
907
|
start_date_str = start_delivery_date.strftime("%Y-%m-%d %H:%M:%S")
|
|
915
908
|
|
|
916
|
-
# Set delivery end time
|
|
917
|
-
end_delivery_date = end_delivery_date.replace(hour=23, minute=59, second=59)
|
|
918
|
-
|
|
919
909
|
# Convert end delivery date form local timezone to UTC and string
|
|
910
|
+
end_delivery_date = pd.Timestamp(end_delivery_date).floor("D") + relativedelta(days=1)
|
|
920
911
|
end_delivery_date = end_delivery_date.replace(tzinfo=ZoneInfo(local_timezone))
|
|
921
912
|
end_delivery_date = end_delivery_date.astimezone(ZoneInfo("UTC"))
|
|
922
913
|
end_date_str = end_delivery_date.strftime("%Y-%m-%d %H:%M:%S")
|
|
@@ -932,16 +923,16 @@ class DetDatabase:
|
|
|
932
923
|
columns_str = f"[{'], ['.join(columns)}]"
|
|
933
924
|
|
|
934
925
|
# Convert dates from datetime to string
|
|
935
|
-
|
|
926
|
+
forecast_date_str = forecast_date.strftime("%Y-%m-%d")
|
|
936
927
|
|
|
937
928
|
# Create query
|
|
938
929
|
table = DetDatabaseDefinitions.DEFINITIONS["table_name_forecast_customer_volume"]
|
|
939
930
|
query = (
|
|
940
931
|
f"SELECT {columns_str} FROM {table} "
|
|
941
|
-
f"WHERE Profile
|
|
942
|
-
f"AND ForecastDate
|
|
943
|
-
f"AND
|
|
944
|
-
f"'{end_date_str}'"
|
|
932
|
+
f"WHERE Profile='{profile}' "
|
|
933
|
+
f"AND ForecastDate='{forecast_date_str}' "
|
|
934
|
+
f"AND Datetime>='{start_date_str}' "
|
|
935
|
+
f"AND Datetime<'{end_date_str}'"
|
|
945
936
|
)
|
|
946
937
|
|
|
947
938
|
# Query db
|
|
@@ -990,6 +981,174 @@ class DetDatabase:
|
|
|
990
981
|
|
|
991
982
|
return df
|
|
992
983
|
|
|
984
|
+
def load_customer_day_ahead_auction_bids(
|
|
985
|
+
self,
|
|
986
|
+
client_id: str,
|
|
987
|
+
start_delivery_date: datetime,
|
|
988
|
+
end_delivery_date: datetime,
|
|
989
|
+
local_timezone: str,
|
|
990
|
+
timezone_aware_dates: bool = False,
|
|
991
|
+
columns: list = None,
|
|
992
|
+
) -> pd.DataFrame:
|
|
993
|
+
"""
|
|
994
|
+
Loads customer day-ahead auction bids (volumes and limit prices) from the database.
|
|
995
|
+
|
|
996
|
+
Args:
|
|
997
|
+
client_id: Client ID
|
|
998
|
+
start_delivery_date: First delivery date included
|
|
999
|
+
end_delivery_date: Last delivery date included
|
|
1000
|
+
local_timezone: Local timezone (needed to account for DST switches)
|
|
1001
|
+
timezone_aware_dates: If true, returns all dates as timezone-aware. Otherwise, returns
|
|
1002
|
+
them as timezone-naive
|
|
1003
|
+
columns: Requested database table columns. Set columns=["*"] (i.e. as list) to get all
|
|
1004
|
+
columns
|
|
1005
|
+
|
|
1006
|
+
Returns:
|
|
1007
|
+
Dataframe containing customer day-ahead auction bids
|
|
1008
|
+
|
|
1009
|
+
Raises:
|
|
1010
|
+
ValueError: Raises an error if no data is found for user inputs
|
|
1011
|
+
"""
|
|
1012
|
+
# Convert start delivery date from local timezone to UTC and string
|
|
1013
|
+
start_delivery_date = start_delivery_date.replace(tzinfo=ZoneInfo(local_timezone))
|
|
1014
|
+
start_delivery_date = start_delivery_date.astimezone(ZoneInfo("UTC"))
|
|
1015
|
+
start_date_str = start_delivery_date.strftime("%Y-%m-%d %H:%M:%S")
|
|
1016
|
+
|
|
1017
|
+
# Convert end delivery date form local timezone to UTC and string
|
|
1018
|
+
end_delivery_date = pd.Timestamp(end_delivery_date).floor("D") + relativedelta(days=1)
|
|
1019
|
+
end_delivery_date = end_delivery_date.replace(tzinfo=ZoneInfo(local_timezone))
|
|
1020
|
+
end_delivery_date = end_delivery_date.astimezone(ZoneInfo("UTC"))
|
|
1021
|
+
end_date_str = end_delivery_date.strftime("%Y-%m-%d %H:%M:%S")
|
|
1022
|
+
|
|
1023
|
+
# Set default column values
|
|
1024
|
+
if columns is None:
|
|
1025
|
+
columns = ["*"]
|
|
1026
|
+
|
|
1027
|
+
# Convert columns from list to string
|
|
1028
|
+
if len(columns) == 1:
|
|
1029
|
+
columns_str = str(columns[0])
|
|
1030
|
+
else:
|
|
1031
|
+
columns_str = f"[{'], ['.join(columns)}]"
|
|
1032
|
+
|
|
1033
|
+
# Create query
|
|
1034
|
+
table = DetDatabaseDefinitions.DEFINITIONS["table_name_customer_day_ahead_auction_bids"]
|
|
1035
|
+
query = (
|
|
1036
|
+
f"SELECT {columns_str} FROM {table} "
|
|
1037
|
+
f"WHERE ClientId='{client_id}' "
|
|
1038
|
+
f"AND DeliveryStart>='{start_date_str}' "
|
|
1039
|
+
f"AND DeliveryStart<'{end_date_str}'"
|
|
1040
|
+
)
|
|
1041
|
+
|
|
1042
|
+
# Query db
|
|
1043
|
+
self.open_connection()
|
|
1044
|
+
df = self.query_db(query)
|
|
1045
|
+
self.close_connection()
|
|
1046
|
+
|
|
1047
|
+
# Assert data
|
|
1048
|
+
if df.empty:
|
|
1049
|
+
raise ValueError("No data found for user-defined inputs.")
|
|
1050
|
+
|
|
1051
|
+
# Sort data
|
|
1052
|
+
sort_cols = ["ClientId", "InsertionTimestamp", "DeliveryStart"]
|
|
1053
|
+
sort_cols = [c for c in sort_cols if c in df.columns]
|
|
1054
|
+
if len(sort_cols) > 0:
|
|
1055
|
+
df.sort_values(
|
|
1056
|
+
by=sort_cols,
|
|
1057
|
+
axis=0,
|
|
1058
|
+
ascending=True,
|
|
1059
|
+
inplace=True,
|
|
1060
|
+
ignore_index=True,
|
|
1061
|
+
)
|
|
1062
|
+
|
|
1063
|
+
# Localize, convert and set timezone-(un)aware datetimes
|
|
1064
|
+
cols_date = ["DeliveryStart", "DeliveryEnd", "InsertionTimestamp"]
|
|
1065
|
+
for c in cols_date:
|
|
1066
|
+
if c in df.columns:
|
|
1067
|
+
# Convert from datetime to pandas timestamp
|
|
1068
|
+
df[c] = pd.DatetimeIndex(df[c])
|
|
1069
|
+
|
|
1070
|
+
# Convert to timezone-aware dates
|
|
1071
|
+
if c == "InsertionTimestamp":
|
|
1072
|
+
df[c] = df[c].dt.tz_localize(local_timezone)
|
|
1073
|
+
else:
|
|
1074
|
+
df[c] = df[c].dt.tz_localize("UTC")
|
|
1075
|
+
df[c] = df[c].dt.tz_convert(local_timezone)
|
|
1076
|
+
|
|
1077
|
+
if not timezone_aware_dates:
|
|
1078
|
+
df[c] = df[c].dt.tz_localize(None)
|
|
1079
|
+
|
|
1080
|
+
return df
|
|
1081
|
+
|
|
1082
|
+
def load_clients(self, columns: list = None, conditions: str = None) -> pd.DataFrame:
|
|
1083
|
+
"""
|
|
1084
|
+
General method to load data from the database's client table.
|
|
1085
|
+
|
|
1086
|
+
Args:
|
|
1087
|
+
columns: Requested database table columns. Set columns=["*"] (i.e. as list) to get
|
|
1088
|
+
all columns.
|
|
1089
|
+
conditions: Optional conditions to add to SQL query. E.g. "WHERE Type='Supplier'".
|
|
1090
|
+
|
|
1091
|
+
Returns:
|
|
1092
|
+
Table data
|
|
1093
|
+
"""
|
|
1094
|
+
# Set default column values
|
|
1095
|
+
if columns is None:
|
|
1096
|
+
columns = ["*"]
|
|
1097
|
+
|
|
1098
|
+
# Convert columns from list to string
|
|
1099
|
+
if len(columns) == 1:
|
|
1100
|
+
columns_str = str(columns[0])
|
|
1101
|
+
else:
|
|
1102
|
+
columns_str = f"[{'], ['.join(columns)}]"
|
|
1103
|
+
|
|
1104
|
+
# Create query
|
|
1105
|
+
table = DetDatabaseDefinitions.DEFINITIONS["table_name_client"]
|
|
1106
|
+
query = f"SELECT {columns_str} FROM {table} {conditions}"
|
|
1107
|
+
|
|
1108
|
+
# Query db
|
|
1109
|
+
self.open_connection()
|
|
1110
|
+
df = self.query_db(query)
|
|
1111
|
+
self.close_connection()
|
|
1112
|
+
|
|
1113
|
+
return df
|
|
1114
|
+
|
|
1115
|
+
def get_client_info(self, filter_column: str, filter_value: str, info_columns: list) -> dict:
|
|
1116
|
+
"""
|
|
1117
|
+
Finds information related to a specific, user-defined client.
|
|
1118
|
+
|
|
1119
|
+
Args:
|
|
1120
|
+
filter_column: Column used to filter data for one specific client
|
|
1121
|
+
filter_value: Value used to filter data for one specific client
|
|
1122
|
+
info_columns: Columns containing the requested information
|
|
1123
|
+
|
|
1124
|
+
Returns:
|
|
1125
|
+
A dictionary containing the requested information
|
|
1126
|
+
|
|
1127
|
+
Raises:
|
|
1128
|
+
ValueError: Raises an error if match with input filter value is not unique
|
|
1129
|
+
ValueError: Raises an error if the input filter value is not found
|
|
1130
|
+
"""
|
|
1131
|
+
# Get client information for user-defined filtering criteria
|
|
1132
|
+
condition = f"WHERE {filter_column}='{filter_value}'"
|
|
1133
|
+
client_info = self.load_clients(columns=info_columns, conditions=condition)
|
|
1134
|
+
|
|
1135
|
+
# Validate response
|
|
1136
|
+
if client_info.shape[0] > 1:
|
|
1137
|
+
raise ValueError(f"More than one match found for {filter_column}={filter_value}.")
|
|
1138
|
+
|
|
1139
|
+
elif client_info.shape[0] == 0:
|
|
1140
|
+
available_values = self.load_clients(columns=[filter_column])
|
|
1141
|
+
available_values_str = ", ".join(f"'{x}'" for x in available_values[filter_column])
|
|
1142
|
+
raise ValueError(
|
|
1143
|
+
f"Value {filter_value} not found in column '{filter_column}'. Available values: "
|
|
1144
|
+
f"{available_values_str}."
|
|
1145
|
+
)
|
|
1146
|
+
|
|
1147
|
+
# Convert dataframe row to dict
|
|
1148
|
+
client_info = client_info.loc[0, :].to_dict()
|
|
1149
|
+
|
|
1150
|
+
return client_info
|
|
1151
|
+
|
|
993
1152
|
|
|
994
1153
|
class DetDatabaseDefinitions:
|
|
995
1154
|
"""A class containing some hard-coded definitions related to the DET database."""
|
|
@@ -1003,4 +1162,6 @@ class DetDatabaseDefinitions:
|
|
|
1003
1162
|
table_name_instruments="[TT].[Instrument]",
|
|
1004
1163
|
table_name_eex_eod_price="[EEX].[EODPrice]",
|
|
1005
1164
|
table_name_forecast_customer_volume="[DISP].[ForecastGold]",
|
|
1165
|
+
table_name_customer_day_ahead_auction_bids="[TRADE].[ClientBid]",
|
|
1166
|
+
table_name_client="[META].[Client]",
|
|
1006
1167
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|