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.
- {voly-0.0.39/src/voly.egg-info → voly-0.0.41}/PKG-INFO +1 -1
 - {voly-0.0.39 → voly-0.0.41}/pyproject.toml +2 -2
 - {voly-0.0.39 → voly-0.0.41}/src/voly/core/charts.py +39 -42
 - {voly-0.0.39 → voly-0.0.41}/src/voly/core/fit.py +1 -1
 - {voly-0.0.39 → voly-0.0.41}/src/voly/core/rnd.py +1 -4
 - {voly-0.0.39 → voly-0.0.41/src/voly.egg-info}/PKG-INFO +1 -1
 - {voly-0.0.39 → voly-0.0.41}/LICENSE +0 -0
 - {voly-0.0.39 → voly-0.0.41}/README.md +0 -0
 - {voly-0.0.39 → voly-0.0.41}/setup.cfg +0 -0
 - {voly-0.0.39 → voly-0.0.41}/setup.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/__init__.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/client.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/core/__init__.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/core/data.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/core/interpolate.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/exceptions.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/formulas.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/models.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/utils/__init__.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly/utils/logger.py +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly.egg-info/SOURCES.txt +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly.egg-info/dependency_links.txt +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly.egg-info/requires.txt +0 -0
 - {voly-0.0.39 → voly-0.0.41}/src/voly.egg-info/top_level.txt +0 -0
 - {voly-0.0.39 → voly-0.0.41}/tests/test_client.py +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.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. 
     | 
| 
      
 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( 
     | 
| 
       26 
     | 
    
         
            -
                                       
     | 
| 
       27 
     | 
    
         
            -
                                      market_data:  
     | 
| 
      
 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 
     | 
    
         
            -
                                       
     | 
| 
      
 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= 
     | 
| 
       49 
     | 
    
         
            -
                        y= 
     | 
| 
      
 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 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       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= 
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
       124 
     | 
    
         
            -
                         
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                -  
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 361 
     | 
    
         
            +
                maturities = list(iv_surface.keys())
         
     | 
| 
       365 
362 
     | 
    
         | 
| 
       366 
363 
     | 
    
         
             
                # Convert implied volatility surface to array
         
     | 
| 
       367 
     | 
    
         
            -
                z_array = np.array([iv_surface[ 
     | 
| 
      
 364 
     | 
    
         
            +
                z_array = np.array([iv_surface[m] for m in maturities])
         
     | 
| 
       368 
365 
     | 
    
         | 
| 
       369 
366 
     | 
    
         
             
                # Create mesh grid
         
     | 
| 
       370 
     | 
    
         
            -
                X, Y = np.meshgrid( 
     | 
| 
      
 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=' 
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                -  
     | 
| 
      
 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( 
     | 
| 
      
 413 
     | 
    
         
            +
                prices = spot_price * np.exp(moneyness_array)
         
     | 
| 
       417 
414 
     | 
    
         | 
| 
       418 
415 
     | 
    
         
             
                # Normalize the RND to integrate to 1
         
     | 
| 
       419 
     | 
    
         
            -
                dx =  
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                -  
     | 
| 
      
 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( 
     | 
| 
      
 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 =  
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                -  
     | 
| 
      
 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( 
     | 
| 
      
 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 =  
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                -  
     | 
| 
      
 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( 
     | 
| 
      
 787 
     | 
    
         
            +
                prices = spot_price * np.exp(moneyness_array)
         
     | 
| 
       791 
788 
     | 
    
         | 
| 
       792 
789 
     | 
    
         
             
                # Normalize the RND
         
     | 
| 
       793 
     | 
    
         
            -
                dx =  
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                -  
     | 
| 
      
 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( 
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
      
 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= 
     | 
| 
      
 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[ 
     | 
| 
      
 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  
     | 
| 
      
 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
         
     | 
| 
         
            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
         
     |