PYield 0.7.5__tar.gz → 0.7.6__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.
- {pyield-0.7.5 → pyield-0.7.6}/PKG-INFO +1 -1
- pyield-0.7.6/pyield/__about__.py +1 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/futures/ddi.py +18 -14
- {pyield-0.7.5 → pyield-0.7.6}/pyield/futures/di.py +26 -32
- {pyield-0.7.5 → pyield-0.7.6}/pyproject.toml +1 -1
- pyield-0.7.5/pyield/__about__.py +0 -1
- {pyield-0.7.5 → pyield-0.7.6}/LICENSE +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/README.md +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/__init__.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/bday.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/data_access.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/data_analysis.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/futures/__init__.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/futures/common.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/futures/di_xml.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/futures/frc.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/holidays/__init__.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/holidays/br_holidays_new.txt +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/holidays/br_holidays_old.txt +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/holidays/core.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/indicators.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/projections.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/py.typed +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/treasuries.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/pyield/utils.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/tests/__init__.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/tests/test_bday.py +0 -0
- {pyield-0.7.5 → pyield-0.7.6}/tests/test_futures.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.7.6"
|
|
@@ -15,9 +15,8 @@ def _convert_prices_to_rates(prices: pd.Series, n_days: pd.Series) -> pd.Series:
|
|
|
15
15
|
pd.Series: A pd.Series containing DDI futures rates.
|
|
16
16
|
"""
|
|
17
17
|
rates = (100_000 / prices - 1) * (360 / n_days)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return 100 * rates
|
|
18
|
+
# Round to 5 (3 in %) dec. places (contract's current max. precision)
|
|
19
|
+
return rates.round(5)
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
def _process_raw_df(df: pd.DataFrame, trade_date: pd.Timestamp) -> pd.DataFrame:
|
|
@@ -70,29 +69,34 @@ def _process_raw_df(df: pd.DataFrame, trade_date: pd.Timestamp) -> pd.DataFrame:
|
|
|
70
69
|
else:
|
|
71
70
|
df["ExpirationDate"] = df["ExpirationCode"].apply(common.get_expiration_date)
|
|
72
71
|
|
|
73
|
-
df["
|
|
72
|
+
df["DaysToExp"] = (df["ExpirationDate"] - trade_date).dt.days
|
|
74
73
|
# Convert to nullable integer, since other columns use this data type
|
|
75
|
-
df["
|
|
76
|
-
# Remove expired contracts
|
|
77
|
-
df.query("DaysToExpiration > 0", inplace=True)
|
|
74
|
+
df["DaysToExp"] = df["DaysToExp"].astype(pd.Int64Dtype())
|
|
78
75
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
)
|
|
76
|
+
# Remove expired contracts
|
|
77
|
+
df.query("DaysToExp > 0", inplace=True)
|
|
82
78
|
|
|
79
|
+
# Columns where 0 means NaN
|
|
83
80
|
rate_cols = [col for col in df.columns if "Rate" in col]
|
|
84
81
|
cols_with_nan = rate_cols + ["SettlementPrice"]
|
|
85
|
-
#
|
|
82
|
+
# Replace 0 with NaN in these columns
|
|
86
83
|
df[cols_with_nan] = df[cols_with_nan].replace(0, pd.NA)
|
|
87
|
-
|
|
84
|
+
|
|
88
85
|
df[rate_cols] = df[rate_cols].div(100).round(5)
|
|
89
86
|
|
|
87
|
+
# Calculate SettlementRate
|
|
88
|
+
df["SettlementRate"] = _convert_prices_to_rates(
|
|
89
|
+
df["SettlementPrice"], df["DaysToExp"]
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
df["TickerSymbol"] = "DI1" + df["ExpirationCode"]
|
|
93
|
+
|
|
90
94
|
# Filter and order columns
|
|
91
95
|
ordered_cols = [
|
|
92
96
|
"TradeDate",
|
|
93
97
|
"ExpirationCode",
|
|
94
98
|
"ExpirationDate",
|
|
95
|
-
"
|
|
99
|
+
"DaysToExp",
|
|
96
100
|
"OpenContracts",
|
|
97
101
|
# "OpenContractsEndSession" since there is no OpenContracts at the end of the
|
|
98
102
|
# day in XML data, it will be removed to avoid confusion with XML data
|
|
@@ -132,7 +136,7 @@ def fetch_past_ddi(trade_date: pd.Timestamp, return_raw: bool = False) -> pd.Dat
|
|
|
132
136
|
>>> di.fetch_ddi(pd.Timestamp("2021-01-04"))
|
|
133
137
|
|
|
134
138
|
Notes:
|
|
135
|
-
-
|
|
139
|
+
- DaysToExp: number of business days to ExpirationDate.
|
|
136
140
|
- OpenContracts: number of open contracts at the start of the trading day.
|
|
137
141
|
"""
|
|
138
142
|
df_raw = common.fetch_past_raw_df(asset_code="DDI", trade_date=trade_date)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pandas as pd
|
|
2
2
|
|
|
3
|
-
from .. import bday
|
|
4
|
-
from . import common
|
|
3
|
+
from .. import bday as bd
|
|
4
|
+
from . import common as cm
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def _convert_prices_to_rates(prices: pd.Series, bd: pd.Series) -> pd.Series:
|
|
@@ -17,22 +17,12 @@ def _convert_prices_to_rates(prices: pd.Series, bd: pd.Series) -> pd.Series:
|
|
|
17
17
|
"""
|
|
18
18
|
rates = (100_000 / prices) ** (252 / bd) - 1
|
|
19
19
|
|
|
20
|
-
#
|
|
21
|
-
return
|
|
20
|
+
# Round to 5 (3 in %) dec. places (contract's current max. precision)
|
|
21
|
+
return rates.round(5)
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
def
|
|
25
|
-
|
|
26
|
-
convert_cols = [
|
|
27
|
-
"FirstRate",
|
|
28
|
-
"MinRate",
|
|
29
|
-
"MaxRate",
|
|
30
|
-
"AvgRate",
|
|
31
|
-
"CloseRate",
|
|
32
|
-
"CloseBidRate",
|
|
33
|
-
"CloseAskRate",
|
|
34
|
-
]
|
|
35
|
-
for col in convert_cols:
|
|
24
|
+
def _adjust_older_contracts_rates(df: pd.DataFrame, rate_cols: list) -> pd.DataFrame:
|
|
25
|
+
for col in rate_cols:
|
|
36
26
|
df[col] = _convert_prices_to_rates(df[col], df["BDaysToExp"])
|
|
37
27
|
|
|
38
28
|
# Invert low and high prices
|
|
@@ -82,30 +72,34 @@ def _process_past_raw_df(df: pd.DataFrame, trade_date: pd.Timestamp) -> pd.DataF
|
|
|
82
72
|
# Contract code format was changed in 22/05/2006
|
|
83
73
|
if trade_date < pd.Timestamp("2006-05-22"):
|
|
84
74
|
df["ExpirationDate"] = df["ExpirationCode"].apply(
|
|
85
|
-
|
|
75
|
+
cm.get_old_expiration_date, args=(trade_date,)
|
|
86
76
|
)
|
|
87
77
|
else:
|
|
88
|
-
df["ExpirationDate"] = df["ExpirationCode"].apply(
|
|
78
|
+
df["ExpirationDate"] = df["ExpirationCode"].apply(cm.get_expiration_date)
|
|
79
|
+
|
|
80
|
+
df["BDaysToExp"] = bd.count_bdays(trade_date, df["ExpirationDate"])
|
|
89
81
|
|
|
90
|
-
df["BDaysToExp"] = bday.count_bdays(trade_date, df["ExpirationDate"])
|
|
91
82
|
# Remove expired contracts
|
|
92
83
|
df.query("BDaysToExp > 0", inplace=True)
|
|
93
84
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
# Columns where 0 means NaN
|
|
86
|
+
rate_cols = [col for col in df.columns if "Rate" in col]
|
|
87
|
+
cols_with_nan = rate_cols + ["SettlementPrice"]
|
|
88
|
+
# Replace 0 with NaN in these columns
|
|
89
|
+
df[cols_with_nan] = df[cols_with_nan].replace(0, pd.NA)
|
|
90
|
+
|
|
91
|
+
# Prior to 17/01/2002 (inclusive), prices were not converted to rates
|
|
92
|
+
if trade_date > pd.Timestamp("2002-01-17"):
|
|
93
|
+
# Remove % and round to 5 (3 in %) dec. places in rate columns
|
|
94
|
+
df[rate_cols] = df[rate_cols].div(100).round(5)
|
|
95
|
+
else:
|
|
96
|
+
df = _adjust_older_contracts_rates(df, rate_cols)
|
|
97
97
|
|
|
98
|
+
# Calculate SettlementRate
|
|
98
99
|
df["SettlementRate"] = _convert_prices_to_rates(
|
|
99
100
|
df["SettlementPrice"], df["BDaysToExp"]
|
|
100
101
|
)
|
|
101
102
|
|
|
102
|
-
rate_cols = [col for col in df.columns if "Rate" in col]
|
|
103
|
-
cols_with_nan = rate_cols + ["SettlementPrice"]
|
|
104
|
-
# Columns where 0 means NaN
|
|
105
|
-
df[cols_with_nan] = df[cols_with_nan].replace(0, pd.NA)
|
|
106
|
-
# Remove % and round to 5 dec. places (3 in %) since it is the contract's precision
|
|
107
|
-
df[rate_cols] = df[rate_cols].div(100).round(5)
|
|
108
|
-
|
|
109
103
|
df["TickerSymbol"] = "DI1" + df["ExpirationCode"]
|
|
110
104
|
|
|
111
105
|
# Filter and order columns
|
|
@@ -161,7 +155,7 @@ def _process_last_raw_di_df(raw_df: pd.DataFrame) -> pd.DataFrame:
|
|
|
161
155
|
# Rename columns
|
|
162
156
|
df = df.rename(columns=rename_columns)
|
|
163
157
|
|
|
164
|
-
df["BDaysToExp"] =
|
|
158
|
+
df["BDaysToExp"] = bd.count_bdays(df["TradeTimestamp"], df["ExpirationDate"])
|
|
165
159
|
|
|
166
160
|
# Remove percentage in all rate columns
|
|
167
161
|
rate_cols = [col for col in df.columns if "Rate" in col]
|
|
@@ -178,7 +172,7 @@ def fetch_last_di() -> pd.DataFrame:
|
|
|
178
172
|
Returns:
|
|
179
173
|
pd.DataFrame: A Pandas pd.DataFrame containing the latest DI futures data.
|
|
180
174
|
"""
|
|
181
|
-
raw_df =
|
|
175
|
+
raw_df = cm.fetch_last_raw_df(future_code="DI1")
|
|
182
176
|
return _process_last_raw_di_df(raw_df)
|
|
183
177
|
|
|
184
178
|
|
|
@@ -202,7 +196,7 @@ def fetch_past_di(trade_date: pd.Timestamp, return_raw: bool = False) -> pd.Data
|
|
|
202
196
|
- BDaysToExp: number of business days to ExpirationDate.
|
|
203
197
|
- OpenContracts: number of open contracts at the start of the trading day.
|
|
204
198
|
"""
|
|
205
|
-
df_raw =
|
|
199
|
+
df_raw = cm.fetch_past_raw_df(asset_code="DI1", trade_date=trade_date)
|
|
206
200
|
if return_raw:
|
|
207
201
|
return df_raw
|
|
208
202
|
if df_raw.empty:
|
pyield-0.7.5/pyield/__about__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.7.5"
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|