voly 0.0.39__tar.gz → 0.0.41__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.39
3
+ Version: 0.0.41
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.39"
7
+ version = "0.0.41"
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.39"
63
+ python_version = "0.0.41"
64
64
  warn_return_any = true
65
65
  warn_unused_configs = true
66
66
  disallow_untyped_defs = true
@@ -22,11 +22,11 @@ pio.renderers.default = "browser"
22
22
 
23
23
 
24
24
  @catch_exception
25
- def plot_volatility_smile(moneyness: np.ndarray,
26
- iv: np.ndarray,
27
- market_data: Optional[pd.DataFrame] = None,
25
+ def plot_volatility_smile(moneyness_array: np.ndarray,
26
+ iv_values: np.ndarray,
27
+ market_data: pd.DataFrame = None,
28
28
  expiry: Optional[float] = None,
29
- title: Optional[str] = None) -> go.Figure:
29
+ ) -> go.Figure:
30
30
  """
31
31
  Plot volatility smile for a single expiry.
32
32
 
@@ -45,8 +45,8 @@ def plot_volatility_smile(moneyness: np.ndarray,
45
45
  # Add model curve
46
46
  fig.add_trace(
47
47
  go.Scatter(
48
- x=moneyness,
49
- y=iv * 100, # Convert to percentage
48
+ x=moneyness_array,
49
+ y=iv_values * 100, # Convert to percentage
50
50
  mode='lines',
51
51
  name='Model',
52
52
  line=dict(color='#0080FF', width=2)
@@ -79,15 +79,12 @@ def plot_volatility_smile(moneyness: np.ndarray,
79
79
  )
80
80
  )
81
81
 
82
- # Get maturity name and DTE for title if not provided
83
- if title is None:
84
- maturity_name = expiry_data['maturity_name'].iloc[0]
85
- dte_value = expiry_data['dte'].iloc[0]
86
- title = f'Vol Smile for {maturity_name} (DTE: {dte_value:.1f})'
82
+ maturity_name = expiry_data['maturity_name'].iloc[0]
83
+ dte_value = expiry_data['dte'].iloc[0]
87
84
 
88
85
  # Update layout
89
86
  fig.update_layout(
90
- title=title,
87
+ title=f'Vol Smile for {maturity_name} (DTE: {dte_value:.1f})',
91
88
  xaxis_title='Log Moneyness',
92
89
  yaxis_title='Implied Volatility (%)',
93
90
  template='plotly_dark',
@@ -98,7 +95,7 @@ def plot_volatility_smile(moneyness: np.ndarray,
98
95
 
99
96
 
100
97
  @catch_exception
101
- def plot_all_smiles(moneyness: np.ndarray,
98
+ def plot_all_smiles(moneyness_array: np.ndarray,
102
99
  iv_surface: Dict[float, np.ndarray],
103
100
  market_data: Optional[pd.DataFrame] = None) -> List[go.Figure]:
104
101
  """
@@ -120,8 +117,8 @@ def plot_all_smiles(moneyness: np.ndarray,
120
117
  # Create a figure for each expiry
121
118
  for expiry in sorted_expiries:
122
119
  fig = plot_volatility_smile(
123
- moneyness=moneyness,
124
- iv=iv_surface[expiry],
120
+ moneyness_array=moneyness_array,
121
+ iv_values=iv_surface[expiry],
125
122
  market_data=market_data,
126
123
  expiry=expiry
127
124
  )
@@ -346,13 +343,13 @@ def plot_fit_performance(fit_performance: pd.DataFrame) -> go.Figure:
346
343
 
347
344
 
348
345
  @catch_exception
349
- def plot_3d_surface(moneyness_grid: np.ndarray,
346
+ def plot_3d_surface(moneyness_array: np.ndarray,
350
347
  iv_surface: dict[float, np.ndarray]) -> go.Figure:
351
348
  """
352
349
  Plot 3D implied volatility surface.
353
350
 
354
351
  Parameters:
355
- - moneyness_grid: grid of moneyness values
352
+ - moneyness_array: grid of moneyness values
356
353
  - iv_surface: Dictionary mapping expiry times to IV arrays
357
354
 
358
355
  Returns:
@@ -361,13 +358,13 @@ def plot_3d_surface(moneyness_grid: np.ndarray,
361
358
  start_color = '#60AEFC'
362
359
  end_color = '#002040' # Darker blue
363
360
  custom_blue_scale = [[0, start_color], [1, end_color]]
364
- yte_values = list(iv_surface.keys())
361
+ maturities = list(iv_surface.keys())
365
362
 
366
363
  # Convert implied volatility surface to array
367
- z_array = np.array([iv_surface[t] for t in yte_values])
364
+ z_array = np.array([iv_surface[m] for m in maturities])
368
365
 
369
366
  # Create mesh grid
370
- X, Y = np.meshgrid(moneyness_grid, yte_values)
367
+ X, Y = np.meshgrid(moneyness_array, maturities)
371
368
  Z = z_array * 100 # Convert to percentage
372
369
 
373
370
  # Create 3D surface plot with custom blue colorscale
@@ -383,7 +380,7 @@ def plot_3d_surface(moneyness_grid: np.ndarray,
383
380
  template='plotly_dark',
384
381
  scene=dict(
385
382
  xaxis_title='Log Moneyness',
386
- yaxis_title='Time to Expiry (years)',
383
+ yaxis_title='Maturities',
387
384
  zaxis_title='Implied Volatility (%)'
388
385
  ),
389
386
  margin=dict(l=65, r=50, b=65, t=90)
@@ -393,7 +390,7 @@ def plot_3d_surface(moneyness_grid: np.ndarray,
393
390
 
394
391
 
395
392
  @catch_exception
396
- def plot_rnd(moneyness_grid: np.ndarray,
393
+ def plot_rnd(moneyness_array: np.ndarray,
397
394
  rnd_values: np.ndarray,
398
395
  spot_price: float = 1.0,
399
396
  title: str = 'Risk-Neutral Density') -> go.Figure:
@@ -401,7 +398,7 @@ def plot_rnd(moneyness_grid: np.ndarray,
401
398
  Plot risk-neutral density (RND).
402
399
 
403
400
  Parameters:
404
- - moneyness_grid: Grid of log-moneyness values
401
+ - moneyness_array: Grid of log-moneyness values
405
402
  - rnd_values: RND values
406
403
  - spot_price: Spot price for converting to absolute prices
407
404
  - title: Plot title
@@ -413,10 +410,10 @@ def plot_rnd(moneyness_grid: np.ndarray,
413
410
  fig = go.Figure()
414
411
 
415
412
  # Convert to prices and normalize RND
416
- prices = spot_price * np.exp(moneyness_grid)
413
+ prices = spot_price * np.exp(moneyness_array)
417
414
 
418
415
  # Normalize the RND to integrate to 1
419
- dx = moneyness_grid[1] - moneyness_grid[0]
416
+ dx = moneyness_array[1] - moneyness_array[0]
420
417
  total_density = np.sum(rnd_values) * dx
421
418
  normalized_rnd = rnd_values / total_density if total_density > 0 else rnd_values
422
419
 
@@ -463,7 +460,7 @@ def plot_rnd(moneyness_grid: np.ndarray,
463
460
 
464
461
 
465
462
  @catch_exception
466
- def plot_rnd_all_expiries(moneyness_grid: np.ndarray,
463
+ def plot_rnd_all_expiries(moneyness_array: np.ndarray,
467
464
  rnd_surface: Dict[str, np.ndarray],
468
465
  param_matrix: pd.DataFrame,
469
466
  spot_price: float = 1.0) -> go.Figure:
@@ -471,7 +468,7 @@ def plot_rnd_all_expiries(moneyness_grid: np.ndarray,
471
468
  Plot risk-neutral densities for all expiries.
472
469
 
473
470
  Parameters:
474
- - moneyness_grid: Grid of log-moneyness values
471
+ - moneyness_array: Grid of log-moneyness values
475
472
  - rnd_surface: Dictionary mapping maturity names to RND arrays
476
473
  - param_matrix: Matrix containing model parameters with maturity info
477
474
  - spot_price: Spot price for converting to absolute prices
@@ -494,7 +491,7 @@ def plot_rnd_all_expiries(moneyness_grid: np.ndarray,
494
491
  for i in range(n_maturities)]
495
492
 
496
493
  # Convert to prices
497
- prices = spot_price * np.exp(moneyness_grid)
494
+ prices = spot_price * np.exp(moneyness_array)
498
495
 
499
496
  # Add traces for each expiry
500
497
  for i, maturity_name in enumerate(maturity_names):
@@ -502,7 +499,7 @@ def plot_rnd_all_expiries(moneyness_grid: np.ndarray,
502
499
  dte = dte_values[maturity_name]
503
500
 
504
501
  # Normalize the RND
505
- dx = moneyness_grid[1] - moneyness_grid[0]
502
+ dx = moneyness_array[1] - moneyness_array[0]
506
503
  total_density = np.sum(rnd) * dx
507
504
  normalized_rnd = rnd / total_density if total_density > 0 else rnd
508
505
 
@@ -543,7 +540,7 @@ def plot_rnd_all_expiries(moneyness_grid: np.ndarray,
543
540
 
544
541
 
545
542
  @catch_exception
546
- def plot_rnd_3d(moneyness_grid: np.ndarray,
543
+ def plot_rnd_3d(moneyness_array: np.ndarray,
547
544
  rnd_surface: Dict[str, np.ndarray],
548
545
  param_matrix: pd.DataFrame,
549
546
  spot_price: float = 1.0) -> go.Figure:
@@ -551,7 +548,7 @@ def plot_rnd_3d(moneyness_grid: np.ndarray,
551
548
  Plot 3D surface of risk-neutral densities.
552
549
 
553
550
  Parameters:
554
- - moneyness_grid: Grid of log-moneyness values
551
+ - moneyness_array: Grid of log-moneyness values
555
552
  - rnd_surface: Dictionary mapping maturity names to RND arrays
556
553
  - param_matrix: Matrix containing model parameters with maturity info
557
554
  - spot_price: Spot price for converting to absolute prices
@@ -569,7 +566,7 @@ def plot_rnd_3d(moneyness_grid: np.ndarray,
569
566
  dte_list = [dte_values[name] for name in maturity_names]
570
567
 
571
568
  # Convert to prices
572
- prices = spot_price * np.exp(moneyness_grid)
569
+ prices = spot_price * np.exp(moneyness_array)
573
570
 
574
571
  # Create z-data matrix and normalize RNDs
575
572
  z_data = np.zeros((len(maturity_names), len(prices)))
@@ -578,7 +575,7 @@ def plot_rnd_3d(moneyness_grid: np.ndarray,
578
575
  rnd = rnd_surface[name]
579
576
 
580
577
  # Normalize the RND
581
- dx = moneyness_grid[1] - moneyness_grid[0]
578
+ dx = moneyness_array[1] - moneyness_array[0]
582
579
  total_density = np.sum(rnd) * dx
583
580
  normalized_rnd = rnd / total_density if total_density > 0 else rnd
584
581
 
@@ -770,7 +767,7 @@ def plot_rnd_statistics(rnd_statistics: pd.DataFrame,
770
767
 
771
768
 
772
769
  @catch_exception
773
- def plot_cdf(moneyness_grid: np.ndarray,
770
+ def plot_cdf(moneyness_array: np.ndarray,
774
771
  rnd_values: np.ndarray,
775
772
  spot_price: float = 1.0,
776
773
  title: str = 'Cumulative Distribution Function') -> go.Figure:
@@ -778,7 +775,7 @@ def plot_cdf(moneyness_grid: np.ndarray,
778
775
  Plot the cumulative distribution function (CDF) from RND values.
779
776
 
780
777
  Parameters:
781
- - moneyness_grid: Grid of log-moneyness values
778
+ - moneyness_array: Grid of log-moneyness values
782
779
  - rnd_values: RND values
783
780
  - spot_price: Spot price for converting to absolute prices
784
781
  - title: Plot title
@@ -787,10 +784,10 @@ def plot_cdf(moneyness_grid: np.ndarray,
787
784
  - Plotly figure
788
785
  """
789
786
  # Convert to prices and normalize RND
790
- prices = spot_price * np.exp(moneyness_grid)
787
+ prices = spot_price * np.exp(moneyness_array)
791
788
 
792
789
  # Normalize the RND
793
- dx = moneyness_grid[1] - moneyness_grid[0]
790
+ dx = moneyness_array[1] - moneyness_array[0]
794
791
  total_density = np.sum(rnd_values) * dx
795
792
  normalized_rnd = rnd_values / total_density if total_density > 0 else rnd_values
796
793
 
@@ -850,7 +847,7 @@ def plot_cdf(moneyness_grid: np.ndarray,
850
847
 
851
848
 
852
849
  @catch_exception
853
- def plot_pdf(moneyness_grid: np.ndarray,
850
+ def plot_pdf(moneyness_array: np.ndarray,
854
851
  rnd_values: np.ndarray,
855
852
  spot_price: float = 1.0,
856
853
  title: str = 'Probability Density Function') -> go.Figure:
@@ -858,7 +855,7 @@ def plot_pdf(moneyness_grid: np.ndarray,
858
855
  Plot the probability density function (PDF) from RND values.
859
856
 
860
857
  Parameters:
861
- - moneyness_grid: Grid of log-moneyness values
858
+ - moneyness_array: Grid of log-moneyness values
862
859
  - rnd_values: RND values
863
860
  - spot_price: Spot price for converting to absolute prices
864
861
  - title: Plot title
@@ -867,7 +864,7 @@ def plot_pdf(moneyness_grid: np.ndarray,
867
864
  - Plotly figure
868
865
  """
869
866
  # This is essentially the same as plot_rnd but with a different title
870
- return plot_rnd(moneyness_grid, rnd_values, spot_price, title)
867
+ return plot_rnd(moneyness_array, rnd_values, spot_price, title)
871
868
 
872
869
 
873
870
  @catch_exception
@@ -886,13 +883,13 @@ def plot_interpolated_surface(
886
883
  - Plotly figure
887
884
  """
888
885
  # Extract data from interpolation results
889
- moneyness_grid = interp_results['moneyness_grid']
886
+ moneyness_array = interp_results['moneyness_array']
890
887
  target_expiries_years = interp_results['target_expiries_years']
891
888
  iv_surface = interp_results['iv_surface']
892
889
 
893
890
  # Create a 3D surface plot
894
891
  fig = plot_3d_surface(
895
- moneyness=moneyness_grid,
892
+ moneyness=moneyness_array,
896
893
  expiries=target_expiries_years,
897
894
  iv_surface=iv_surface,
898
895
  title=title
@@ -295,6 +295,6 @@ def get_iv_surface(fit_results: Dict[str, Any],
295
295
  for maturity, yte in zip(maturity_values, yte_values):
296
296
  svi_params = param_matrix[maturity].values
297
297
  w_svi = [SVIModel.svi(x, *svi_params) for x in moneyness_array]
298
- iv_surface[yte] = np.sqrt(np.array(w_svi) / yte)
298
+ iv_surface[maturity] = np.sqrt(np.array(w_svi) / yte)
299
299
 
300
300
  return moneyness_array, iv_surface
@@ -43,11 +43,9 @@ def get_rnd_surface(fit_results: Dict[str, Any],
43
43
  maturity_values = fit_results['fit_performance']['Maturity']
44
44
  param_matrix = fit_results['raw_param_matrix']
45
45
 
46
- # Generate implied volatility for each expiry
46
+ # Generate rnd for each expiry
47
47
  for maturity, yte in zip(maturity_values, yte_values):
48
48
  svi_params_list = list(param_matrix[maturity].values)
49
-
50
- # Adjust parameter order to match function signatures
51
49
  a, b, sigma, rho, m = svi_params_list
52
50
 
53
51
  # Calculate total variance
@@ -55,7 +53,6 @@ def get_rnd_surface(fit_results: Dict[str, Any],
55
53
 
56
54
  # Calculate risk-neutral density using the base RND function
57
55
  rnd_values = np.array([rnd(x, var) for x, var in zip(moneyness_array, total_var)])
58
-
59
56
  rnd_surface[maturity] = rnd_values
60
57
 
61
58
  return moneyness_array, rnd_surface
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voly
3
- Version: 0.0.39
3
+ Version: 0.0.41
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