voly 0.0.250__tar.gz → 0.0.252__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.250/src/voly.egg-info → voly-0.0.252}/PKG-INFO +1 -1
- {voly-0.0.250 → voly-0.0.252}/pyproject.toml +2 -2
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/fit.py +10 -12
- {voly-0.0.250 → voly-0.0.252/src/voly.egg-info}/PKG-INFO +1 -1
- {voly-0.0.250 → voly-0.0.252}/LICENSE +0 -0
- {voly-0.0.250 → voly-0.0.252}/README.md +0 -0
- {voly-0.0.250 → voly-0.0.252}/setup.cfg +0 -0
- {voly-0.0.250 → voly-0.0.252}/setup.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/__init__.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/client.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/__init__.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/charts.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/data.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/hd.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/interpolate.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/core/rnd.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/exceptions.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/formulas.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/models.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/utils/__init__.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/utils/density.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly/utils/logger.py +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly.egg-info/SOURCES.txt +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly.egg-info/dependency_links.txt +0 -0
- {voly-0.0.250 → voly-0.0.252}/src/voly.egg-info/requires.txt +0 -0
- {voly-0.0.250 → voly-0.0.252}/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.252"
|
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.252"
|
64
64
|
warn_return_any = true
|
65
65
|
warn_unused_configs = true
|
66
66
|
disallow_untyped_defs = true
|
@@ -68,7 +68,6 @@ class SVICalibrator:
|
|
68
68
|
"""Filter and prepare market data"""
|
69
69
|
# Filter for call options only
|
70
70
|
group = group[group['flag'] == 'C']
|
71
|
-
group['log_moneyness'] = np.log(group['strikes'] / group['spot_price'].iloc[0])
|
72
71
|
|
73
72
|
# Handle duplicated IVs by keeping the row closest to log_moneyness=0
|
74
73
|
duplicated_iv = group[group.duplicated('mark_iv', keep=False)]
|
@@ -150,7 +149,7 @@ class SVICalibrator:
|
|
150
149
|
result = self.failed_calibration(expiry, maturity, t, len(k))
|
151
150
|
logger.error(f'\033[31mFAILED\033[0m for {maturity} (insufficient data points)')
|
152
151
|
self.update_results(result)
|
153
|
-
return
|
152
|
+
return expiry
|
154
153
|
|
155
154
|
# Perform SVI fitting
|
156
155
|
params, loss = SVIModel.fit(tiv=w, vega=vega, k=k, tau=t)
|
@@ -160,10 +159,10 @@ class SVICalibrator:
|
|
160
159
|
result = self.failed_calibration(expiry, maturity, t, len(k))
|
161
160
|
logger.error(f'\033[31mFAILED\033[0m for {maturity}')
|
162
161
|
self.update_results(result)
|
163
|
-
return
|
162
|
+
return expiry
|
164
163
|
|
165
164
|
# Successful fitting
|
166
|
-
self.params_dict[
|
165
|
+
self.params_dict[expiry] = (t, params)
|
167
166
|
|
168
167
|
# Calculate all model statistics
|
169
168
|
stats = self.calculate_model_stats(params, t, k, iv)
|
@@ -185,7 +184,7 @@ class SVICalibrator:
|
|
185
184
|
logger.info(f'\033[32mSUCCESS\033[0m for {maturity}')
|
186
185
|
|
187
186
|
self.update_results(result)
|
188
|
-
return
|
187
|
+
return expiry
|
189
188
|
|
190
189
|
def update_results(self, result_row):
|
191
190
|
"""Update results data dictionary"""
|
@@ -211,22 +210,21 @@ class SVICalibrator:
|
|
211
210
|
# Create results DataFrame and mapping for updates
|
212
211
|
fit_results = pd.DataFrame(self.results_data, index=self.results_data['maturity'])
|
213
212
|
fit_results = fit_results.sort_values(by='t')
|
214
|
-
|
213
|
+
maturities_dict = {row['expiry']: idx for idx, row in fit_results.iterrows()}
|
215
214
|
|
216
215
|
# Check for calendar arbitrage
|
217
216
|
sorted_maturities = sorted(self.params_dict.keys(), key=lambda x: self.params_dict[x][0])
|
218
|
-
print(sorted_maturities)
|
219
217
|
calendar_arbitrage_free = SVIModel.check_calendar_arbitrage(
|
220
218
|
sorted_maturities, self.params_dict, self.groups, self.s, self.num_points
|
221
219
|
)
|
222
220
|
|
223
221
|
# Update calendar arbitrage status
|
224
222
|
for mat in sorted_maturities:
|
225
|
-
mat_name =
|
223
|
+
mat_name = maturities_dict[mat]
|
226
224
|
fit_results.at[mat_name, 'calendar_arbitrage_free'] = calendar_arbitrage_free
|
227
225
|
|
228
226
|
# Correct calendar arbitrage violations
|
229
|
-
self.correct_calendar_arbitrage(sorted_maturities, fit_results,
|
227
|
+
self.correct_calendar_arbitrage(sorted_maturities, fit_results, maturities_dict)
|
230
228
|
|
231
229
|
# Clean up results and report execution time
|
232
230
|
fit_results = fit_results.drop(columns='maturity')
|
@@ -235,7 +233,7 @@ class SVICalibrator:
|
|
235
233
|
|
236
234
|
return fit_results
|
237
235
|
|
238
|
-
def correct_calendar_arbitrage(self, sorted_maturities, fit_results,
|
236
|
+
def correct_calendar_arbitrage(self, sorted_maturities, fit_results, maturities_dict):
|
239
237
|
"""Handle calendar arbitrage corrections"""
|
240
238
|
for i in range(1, len(sorted_maturities)):
|
241
239
|
mat2 = sorted_maturities[i]
|
@@ -261,7 +259,7 @@ class SVICalibrator:
|
|
261
259
|
|
262
260
|
# Calculate new stats and update results
|
263
261
|
stats = self.calculate_model_stats(new_params, t2, k, iv)
|
264
|
-
mat2_name =
|
262
|
+
mat2_name = maturities_dict[mat2]
|
265
263
|
|
266
264
|
# Update all stats at once
|
267
265
|
for key, value in stats.items():
|
@@ -275,7 +273,7 @@ class SVICalibrator:
|
|
275
273
|
|
276
274
|
# Update final status
|
277
275
|
for mat in sorted_maturities:
|
278
|
-
mat_name =
|
276
|
+
mat_name = maturities_dict[mat]
|
279
277
|
fit_results.at[mat_name, 'calendar_arbitrage_free'] = calendar_arbitrage_free
|
280
278
|
|
281
279
|
|
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
|