voly 0.0.187__tar.gz → 0.0.190__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.
- {voly-0.0.187/src/voly.egg-info → voly-0.0.190}/PKG-INFO +1 -1
- {voly-0.0.187 → voly-0.0.190}/pyproject.toml +2 -2
- {voly-0.0.187 → voly-0.0.190}/src/voly/client.py +1 -1
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/fit.py +3 -16
- {voly-0.0.187 → voly-0.0.190/src/voly.egg-info}/PKG-INFO +1 -1
- {voly-0.0.187 → voly-0.0.190}/LICENSE +0 -0
- {voly-0.0.187 → voly-0.0.190}/README.md +0 -0
- {voly-0.0.187 → voly-0.0.190}/setup.cfg +0 -0
- {voly-0.0.187 → voly-0.0.190}/setup.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/__init__.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/__init__.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/charts.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/data.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/hd.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/interpolate.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/core/rnd.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/exceptions.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/formulas.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/models.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/utils/__init__.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/utils/density.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly/utils/logger.py +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly.egg-info/SOURCES.txt +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly.egg-info/dependency_links.txt +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly.egg-info/requires.txt +0 -0
- {voly-0.0.187 → voly-0.0.190}/src/voly.egg-info/top_level.txt +0 -0
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "voly"
|
7
|
-
version = "0.0.
|
7
|
+
version = "0.0.190"
|
8
8
|
description = "Options & volatility research package"
|
9
9
|
readme = "README.md"
|
10
10
|
authors = [
|
@@ -60,7 +60,7 @@ line_length = 100
|
|
60
60
|
multi_line_output = 3
|
61
61
|
|
62
62
|
[tool.mypy]
|
63
|
-
python_version = "0.0.
|
63
|
+
python_version = "0.0.190"
|
64
64
|
warn_return_any = true
|
65
65
|
warn_unused_configs = true
|
66
66
|
disallow_untyped_defs = true
|
@@ -175,7 +175,7 @@ class VolyClient:
|
|
175
175
|
Returns:
|
176
176
|
- DataFrame with fit results including arbitrage checks
|
177
177
|
"""
|
178
|
-
logger.info(f"Fitting
|
178
|
+
logger.info(f"Fitting model to market data")
|
179
179
|
|
180
180
|
# Fit the model
|
181
181
|
fit_results = fit_model(
|
@@ -37,11 +37,8 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
37
37
|
# Define column names and their data types
|
38
38
|
column_dtypes = {
|
39
39
|
's': float,
|
40
|
-
'u': float,
|
41
40
|
't': float,
|
42
41
|
'r': float,
|
43
|
-
'oi': float,
|
44
|
-
'volume': float,
|
45
42
|
'maturity_date': 'datetime64[ns]',
|
46
43
|
'a': float,
|
47
44
|
'b': float,
|
@@ -67,6 +64,7 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
67
64
|
}
|
68
65
|
|
69
66
|
s = option_chain['index_price'].iloc[0]
|
67
|
+
unique_ts = sorted(option_chain['t'].unique())
|
70
68
|
maturity_names = [option_chain[option_chain['t'] == t]['maturity_name'].iloc[0] for t in unique_ts]
|
71
69
|
groups = option_chain.groupby('maturity_date')
|
72
70
|
params_dict = {}
|
@@ -94,7 +92,6 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
94
92
|
|
95
93
|
# Combine cleaned duplicates and unique rows
|
96
94
|
maturity_data = pd.concat([unique_iv, cleaned_duplicated_iv])
|
97
|
-
#maturity_name = maturity_data['maturity_name'].iloc[0]
|
98
95
|
maturity_date = maturity_data['maturity_date'].iloc[0]
|
99
96
|
|
100
97
|
t = group['t'].iloc[0]
|
@@ -106,17 +103,12 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
106
103
|
mask = ~np.isnan(w) & ~np.isnan(vega) & ~np.isnan(k) & (iv >= 0)
|
107
104
|
k, w, vega, iv = k[mask], w[mask], vega[mask], iv[mask]
|
108
105
|
|
109
|
-
logger.info(f"Processing maturity {maturity}, points after filtering: {len(k)}")
|
110
|
-
|
111
106
|
params = [np.nan] * 5
|
112
107
|
loss = np.inf
|
113
108
|
nu = psi = p = c = nu_tilde = np.nan
|
114
109
|
rmse = mae = r2 = max_error = np.nan
|
115
110
|
butterfly_arbitrage_free = True
|
116
|
-
u = s # Assume underlying_price is index_price
|
117
111
|
r = maturity_data['interest_rate'].iloc[0] if 'interest_rate' in maturity_data.columns else 0
|
118
|
-
oi = maturity_data['open_interest'].sum() if 'open_interest' in maturity_data.columns else 0
|
119
|
-
volume = maturity_data['volume'].sum() if 'volume' in maturity_data.columns else 0
|
120
112
|
log_min_strike = usd_min_strike = np.nan
|
121
113
|
|
122
114
|
if len(k) > 5:
|
@@ -161,15 +153,11 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
161
153
|
GREEN, RED, RESET = '\033[32m', '\033[31m', '\033[0m'
|
162
154
|
status = f'{GREEN}SUCCESS{RESET}' if not np.isnan(params[0]) else f'{RED}FAILED{RESET}'
|
163
155
|
logger.info(f'Optimization for {maturity}: {status}')
|
164
|
-
logger.info("================================================")
|
165
156
|
|
166
157
|
# Store results
|
167
158
|
results_data['s'].append(float(s))
|
168
|
-
results_data['u'].append(float(u))
|
169
159
|
results_data['t'].append(float(t))
|
170
160
|
results_data['r'].append(float(r))
|
171
|
-
results_data['oi'].append(float(oi))
|
172
|
-
results_data['volume'].append(float(volume))
|
173
161
|
results_data['maturity_date'].append(maturity_date)
|
174
162
|
results_data['a'].append(float(a_scaled) if not np.isnan(params[0]) else np.nan)
|
175
163
|
results_data['b'].append(float(b_scaled) if not np.isnan(params[0]) else np.nan)
|
@@ -220,7 +208,6 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
220
208
|
results_df = results_df.sort_values(by='t')
|
221
209
|
|
222
210
|
# Calendar arbitrage check (pre-correction) with timer
|
223
|
-
logger.info("\nChecking calendar arbitrage (pre-correction)...")
|
224
211
|
k_grid = np.linspace(-2, 2, num_points)
|
225
212
|
sorted_maturities = sorted(params_dict.keys(), key=lambda x: params_dict[x][0])
|
226
213
|
calendar_arbitrage_free = True
|
@@ -254,7 +241,7 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
254
241
|
results_df.at[mat, 'calendar_arbitrage_free'] = calendar_arbitrage_free
|
255
242
|
|
256
243
|
# Calendar arbitrage correction with timer
|
257
|
-
logger.info("
|
244
|
+
logger.info("Performing calendar arbitrage correction...")
|
258
245
|
for i in range(1, len(sorted_maturities)):
|
259
246
|
mat2 = sorted_maturities[i]
|
260
247
|
mat1 = sorted_maturities[i - 1]
|
@@ -366,7 +353,7 @@ def fit_model(option_chain: pd.DataFrame) -> pd.DataFrame:
|
|
366
353
|
|
367
354
|
# End overall timer and print total time
|
368
355
|
end_total = time.time()
|
369
|
-
logger.info(f"
|
356
|
+
logger.info(f"Total execution time for model fit: {end_total - start_total:.4f} seconds")
|
370
357
|
|
371
358
|
logger.info("Model fitting complete.")
|
372
359
|
return results_df
|
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
|