voly 0.0.78__tar.gz → 0.0.80__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voly
3
- Version: 0.0.78
3
+ Version: 0.0.80
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "voly"
7
- version = "0.0.78"
7
+ version = "0.0.80"
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.78"
63
+ python_version = "0.0.80"
64
64
  warn_return_any = true
65
65
  warn_unused_configs = true
66
66
  disallow_untyped_defs = true
@@ -7,6 +7,7 @@ risk-neutral densities, and model fitting results.
7
7
 
8
8
  import numpy as np
9
9
  import pandas as pd
10
+ from scipy import interpolate
10
11
  from typing import Dict, List, Tuple, Optional, Union, Any
11
12
  from voly.utils.logger import logger, catch_exception
12
13
  from voly.models import SVIModel
@@ -150,8 +151,7 @@ def plot_raw_parameters(fit_results: pd.DataFrame) -> go.Figure:
150
151
  maturity_names = fit_results.index
151
152
 
152
153
  # Create hover text with maturity info
153
- tick_labels = [f"{m} (DTM: {fit_results.loc[m, 'dtm']:.1f}"
154
- for m in maturity_names]
154
+ tick_labels = [f"{m} (DTM: {fit_results.loc[m, 'dtm']:.1f}" for m in maturity_names]
155
155
 
156
156
  # Plot each parameter
157
157
  for i, param in enumerate(param_names):
@@ -214,8 +214,7 @@ def plot_jw_parameters(fit_results: pd.DataFrame) -> go.Figure:
214
214
  maturity_names = fit_results.index
215
215
 
216
216
  # Create hover text with maturity info
217
- tick_labels = [f"{m} (DTE: {fit_results.loc[m, 'dtm']:.1f}, YTE: {fit_results.loc[m, 'ytm']:.4f})"
218
- for m in maturity_names]
217
+ tick_labels = [f"{m} (DTE: {fit_results.loc[m, 'dtm']:.1f})" for m in maturity_names]
219
218
 
220
219
  # Plot each parameter
221
220
  for i, param in enumerate(param_names):
@@ -227,7 +226,7 @@ def plot_jw_parameters(fit_results: pd.DataFrame) -> go.Figure:
227
226
  y=fit_results[param],
228
227
  mode='lines+markers',
229
228
  name=param,
230
- line=dict(width=2, color='rgb(0, 180, 180)'),
229
+ line=dict(width=2),
231
230
  marker=dict(size=8),
232
231
  text=tick_labels,
233
232
  hovertemplate="%{text}<br>%{y:.4f}"
@@ -328,7 +327,7 @@ def plot_fit_performance(fit_results: pd.DataFrame) -> go.Figure:
328
327
  def plot_3d_surface(x_surface: Dict[str, np.ndarray],
329
328
  iv_surface: Dict[str, np.ndarray],
330
329
  fit_results: pd.DataFrame = None,
331
- domain_type: str = 'log_moneyness') -> go.Figure:
330
+ return_domain: str = 'log_moneyness') -> go.Figure:
332
331
  """
333
332
  Plot 3D implied volatility surface.
334
333
 
@@ -336,69 +335,79 @@ def plot_3d_surface(x_surface: Dict[str, np.ndarray],
336
335
  - x_surface: Dictionary mapping maturity names to x-domain arrays
337
336
  - iv_surface: Dictionary mapping maturity names to IV arrays
338
337
  - fit_results: Optional DataFrame with maturity information
339
- - domain_type: Type of x-domain ('log_moneyness', 'moneyness', 'strikes', 'delta')
338
+ - return_domain: Type of x-domain ('log_moneyness', 'moneyness', 'strikes', 'delta')
340
339
 
341
340
  Returns:
342
341
  - Plotly figure
343
342
  """
343
+
344
344
  # Map domain types to axis labels
345
345
  domain_labels = {
346
346
  'log_moneyness': 'Log Moneyness',
347
- 'moneyness': 'Moneyness (S/K)',
347
+ 'moneyness': 'Moneyness',
348
348
  'strikes': 'Strike Price',
349
- 'delta': 'Call Delta'
349
+ 'delta': 'Delta'
350
350
  }
351
351
 
352
- # Define custom colorscale
353
- custom_blue_scale = [[0, '#60AEFC'], [1, '#002040']]
354
-
355
- # Get maturity names
352
+ # Get maturity names and sort by DTM
356
353
  maturity_names = list(iv_surface.keys())
357
-
358
- # Get z-axis values (days to expiry)
359
354
  if fit_results is not None:
360
- # Use DTM values from fit_results
361
355
  maturity_values = [fit_results.loc[name, 'dtm'] for name in maturity_names]
356
+ # Sort by maturity
357
+ sorted_indices = np.argsort(maturity_values)
358
+ maturity_names = [maturity_names[i] for i in sorted_indices]
359
+ maturity_values = [maturity_values[i] for i in sorted_indices]
362
360
  else:
363
- # Default to sequential values
364
361
  maturity_values = list(range(len(maturity_names)))
365
362
 
366
- # Create 3D surface using lines for each maturity
367
- fig = go.Figure()
363
+ # Create a common x-grid for all maturities
364
+ # Use 100 points between the min and max x-values across all maturities
365
+ all_x = np.concatenate([x_surface[m] for m in maturity_names])
366
+ x_min, x_max = np.min(all_x), np.max(all_x)
367
+ x_grid = np.linspace(x_min, x_max, 100)
368
+
369
+ # Create a matrix for the surface
370
+ z_matrix = np.zeros((len(maturity_names), len(x_grid)))
368
371
 
369
- # Add a line for each maturity
372
+ # Fill the matrix with interpolated IV values
370
373
  for i, maturity in enumerate(maturity_names):
371
374
  x_values = x_surface[maturity]
372
- z_values = iv_surface[maturity] * 100 # Convert to percentage
373
- y_values = np.full_like(x_values, maturity_values[i])
374
-
375
- # Color based on maturity (blue to light blue gradient)
376
- color_intensity = i / max(1, len(maturity_names) - 1)
377
- color = f'rgb({int(30 + 170*color_intensity)}, {int(120 + 80*color_intensity)}, {int(220 - 120*color_intensity)})'
378
-
379
- # Add trace
380
- fig.add_trace(go.Scatter3d(
381
- x=x_values,
382
- y=y_values,
383
- z=z_values,
384
- mode='lines',
385
- name=maturity,
386
- line=dict(
387
- color=color,
388
- width=5
389
- )
390
- ))
375
+ iv_values = iv_surface[maturity] * 100 # Convert to percentage
376
+
377
+ # Create interpolation function
378
+ f = interpolate.interp1d(x_values, iv_values, kind='cubic',
379
+ bounds_error=False, fill_value='extrapolate')
380
+
381
+ # Generate interpolated values for the common x-grid
382
+ z_matrix[i] = f(x_grid)
383
+
384
+ # Create figure with the surface
385
+ fig = go.Figure(data=[go.Surface(
386
+ z=z_matrix,
387
+ x=x_grid,
388
+ y=maturity_values,
389
+ colorscale='Plotly3'
390
+ )])
391
+
392
+ # Add contours
393
+ fig.update_traces(contours_z=dict(
394
+ show=True,
395
+ usecolormap=True,
396
+ highlightcolor="white",
397
+ project_z=True
398
+ ))
391
399
 
392
400
  # Update layout
393
401
  fig.update_layout(
394
- title='Implied Volatility 3D Surface',
402
+ title='Implied Volatility Surface',
395
403
  template='plotly_dark',
396
404
  scene=dict(
397
- xaxis_title=domain_labels.get(domain_type, 'X Domain'),
405
+ xaxis_title=domain_labels.get(return_domain, 'X Domain'),
398
406
  yaxis_title='Days to Expiry',
399
- zaxis_title='Implied Volatility (%)'
407
+ zaxis_title='Implied Volatility (%)',
408
+ aspectratio=dict(x=1, y=1, z=0.7)
400
409
  ),
401
- margin=dict(l=65, r=50, b=65, t=90)
410
+ scene_camera_eye=dict(x=1, y=-2, z=0.5)
402
411
  )
403
412
 
404
413
  return fig
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voly
3
- Version: 0.0.78
3
+ Version: 0.0.80
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
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