voly 0.0.86__tar.gz → 0.0.89__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.
Files changed (27) hide show
  1. {voly-0.0.86/src/voly.egg-info → voly-0.0.89}/PKG-INFO +1 -1
  2. {voly-0.0.86 → voly-0.0.89}/pyproject.toml +2 -2
  3. {voly-0.0.86 → voly-0.0.89}/src/voly/client.py +20 -204
  4. voly-0.0.89/src/voly/core/charts.py +415 -0
  5. {voly-0.0.86 → voly-0.0.89}/src/voly/core/data.py +1 -4
  6. {voly-0.0.86 → voly-0.0.89}/src/voly/core/fit.py +35 -43
  7. {voly-0.0.86 → voly-0.0.89}/src/voly/core/interpolate.py +5 -6
  8. voly-0.0.89/src/voly/core/rnd.py +288 -0
  9. {voly-0.0.86 → voly-0.0.89}/src/voly/formulas.py +27 -29
  10. {voly-0.0.86 → voly-0.0.89}/src/voly/models.py +0 -6
  11. {voly-0.0.86 → voly-0.0.89/src/voly.egg-info}/PKG-INFO +1 -1
  12. {voly-0.0.86 → voly-0.0.89}/src/voly.egg-info/SOURCES.txt +1 -2
  13. voly-0.0.86/src/voly/core/charts.py +0 -922
  14. voly-0.0.86/src/voly/core/rnd.py +0 -367
  15. voly-0.0.86/tests/test_client.py +0 -244
  16. {voly-0.0.86 → voly-0.0.89}/LICENSE +0 -0
  17. {voly-0.0.86 → voly-0.0.89}/README.md +0 -0
  18. {voly-0.0.86 → voly-0.0.89}/setup.cfg +0 -0
  19. {voly-0.0.86 → voly-0.0.89}/setup.py +0 -0
  20. {voly-0.0.86 → voly-0.0.89}/src/voly/__init__.py +0 -0
  21. {voly-0.0.86 → voly-0.0.89}/src/voly/core/__init__.py +0 -0
  22. {voly-0.0.86 → voly-0.0.89}/src/voly/exceptions.py +0 -0
  23. {voly-0.0.86 → voly-0.0.89}/src/voly/utils/__init__.py +0 -0
  24. {voly-0.0.86 → voly-0.0.89}/src/voly/utils/logger.py +0 -0
  25. {voly-0.0.86 → voly-0.0.89}/src/voly.egg-info/dependency_links.txt +0 -0
  26. {voly-0.0.86 → voly-0.0.89}/src/voly.egg-info/requires.txt +0 -0
  27. {voly-0.0.86 → voly-0.0.89}/src/voly.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voly
3
- Version: 0.0.86
3
+ Version: 0.0.89
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.86"
7
+ version = "0.0.89"
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.86"
63
+ python_version = "0.0.89"
64
64
  warn_return_any = true
65
65
  warn_unused_configs = true
66
66
  disallow_untyped_defs = true
@@ -19,12 +19,11 @@ from voly.formulas import (
19
19
  )
20
20
  from voly.core.data import fetch_option_chain, process_option_chain
21
21
  from voly.core.fit import fit_model, get_iv_surface
22
- from voly.core.rnd import get_rnd_surface, calculate_pdf, calculate_cdf, calculate_strike_probability
22
+ from voly.core.rnd import get_rnd_surface
23
23
  from voly.core.interpolate import interpolate_model
24
24
  from voly.core.charts import (
25
25
  plot_all_smiles, plot_raw_parameters, plot_jw_parameters, plot_fit_performance, plot_3d_surface,
26
- plot_fit_performance, plot_rnd, plot_pdf, plot_cdf, plot_rnd_all_expiries,
27
- plot_rnd_3d, plot_rnd_statistics, plot_interpolated_surface
26
+ plot_fit_performance
28
27
  )
29
28
 
30
29
 
@@ -349,7 +348,7 @@ class VolyClient:
349
348
 
350
349
  @staticmethod
351
350
  def get_iv_surface(model_results: pd.DataFrame,
352
- log_moneyness_params: Tuple[float, float, int] = (-2, 2, 500),
351
+ domain_params: Tuple[float, float, int] = (-2, 2, 500),
353
352
  return_domain: str = 'log_moneyness',
354
353
  ) -> Dict[str, Any]:
355
354
  """
@@ -357,7 +356,7 @@ class VolyClient:
357
356
 
358
357
  Parameters:
359
358
  - model_results: DataFrame from fit_model() or interpolate_model()
360
- - log_moneyness_params: Tuple of (min, max, num_points) for the moneyness grid
359
+ - domain_params: Tuple of (min, max, num_points) for the moneyness grid
361
360
  - return_domain: str Domain for x-axis values ('log_moneyness', 'moneyness', 'strikes', 'delta')
362
361
 
363
362
  Returns:
@@ -366,7 +365,7 @@ class VolyClient:
366
365
  # Generate the surface
367
366
  iv_surface, x_surface = get_iv_surface(
368
367
  model_results=model_results,
369
- log_moneyness_params=log_moneyness_params,
368
+ domain_params=domain_params,
370
369
  return_domain=return_domain
371
370
  )
372
371
 
@@ -375,7 +374,7 @@ class VolyClient:
375
374
  @staticmethod
376
375
  def plot_model(fit_results: pd.DataFrame,
377
376
  option_chain: pd.DataFrame = None,
378
- log_moneyness_params: Tuple[float, float, int] = (-2, 2, 500),
377
+ domain_params: Tuple[float, float, int] = (-2, 2, 500),
379
378
  return_domain: str = 'log_moneyness',
380
379
  ) -> Dict[str, Any]:
381
380
  """
@@ -384,8 +383,8 @@ class VolyClient:
384
383
  Parameters:
385
384
  - fit_results: DataFrame with fitting results from fit_model()
386
385
  - option_chain: Optional market data for comparison
387
- - log_moneyness_params: Grid of log-moneyness values
388
- - return_domain: Domain for x-axis values ('log_moneyness', 'moneyness', 'strikes', 'delta')
386
+ - domain_params: Grid of log-moneyness values
387
+ - return_domain: Domain for x-axis values ('log_moneyness', 'moneyness', 'strikes', 'returns', 'delta')
389
388
 
390
389
  Returns:
391
390
  - Dictionary of plot figures
@@ -393,7 +392,7 @@ class VolyClient:
393
392
  plots = {}
394
393
 
395
394
  # Generate IV surface and domain
396
- iv_surface, x_surface = get_iv_surface(fit_results, log_moneyness_params, return_domain)
395
+ iv_surface, x_surface = get_iv_surface(fit_results, domain_params, return_domain)
397
396
 
398
397
  # Plot volatility smiles
399
398
  plots['smiles'] = plot_all_smiles(
@@ -453,202 +452,19 @@ class VolyClient:
453
452
  # -------------------------------------------------------------------------
454
453
 
455
454
  @staticmethod
456
- def get_rnd_surface(fit_results: Dict[str, Any],
457
- moneyness_params: Tuple[float, float, int] = (-2, 2, 500)
458
- ) -> Dict[str, np.ndarray]:
459
- """
460
- Calculate risk-neutral density from fitted model.
461
-
462
- Parameters:
455
+ def get_rnd_surface(model_results: pd.DataFrame,
456
+ domain_params: Tuple[float, float, int] = (-1.5, 1.5, 1000),
457
+ return_domain: str = 'log_moneyness',
458
+ method: str = 'rookley') -> Tuple[Dict[str, np.ndarray], Dict[str, np.ndarray], Dict[str, np.ndarray], pd.DataFrame]:
463
459
 
464
- Returns:
465
- - Array with RND results over moneyness
466
- """
467
- logger.info("Calculating risk-neutral density")
460
+ logger.info("Calculating RND surface")
468
461
 
469
462
  # Generate the surface
470
- moneyness_array, rnd_surface = get_rnd_surface(
471
- fit_results=fit_results,
472
- moneyness_params=moneyness_params
473
- )
474
-
475
- return {
476
- 'moneyness_array': moneyness_array,
477
- 'rnd_surface': rnd_surface
478
- }
479
-
480
- @staticmethod
481
- def pdf(rnd_results: Dict[str, Any],
482
- maturity: Optional[str] = None,
483
- plot: bool = False) -> Tuple[np.ndarray, np.ndarray]:
484
- """
485
- Calculate probability density function (PDF) from RND results.
486
-
487
- Parameters:
488
- - rnd_results: Dictionary with RND results from rnd()
489
- - maturity: Optional maturity name for a specific expiry
490
- - plot: Whether to generate and return a plot
491
-
492
- Returns:
493
- - Tuple of (prices, pdf_values) and optional plot
494
- """
495
- logger.info("Calculating PDF from RND")
496
-
497
- # Extract required data
498
- moneyness_grid = rnd_results['moneyness_grid']
499
- rnd_surface = rnd_results['rnd_surface']
500
- spot_price = rnd_results['spot_price']
501
-
502
- # Select maturity
503
- if maturity is None:
504
- # Use first maturity if not specified
505
- maturity = list(rnd_surface.keys())[0]
506
- elif maturity not in rnd_surface:
507
- raise VolyError(f"Maturity '{maturity}' not found in RND results")
508
-
509
- # Get RND values for the selected maturity
510
- rnd_values = rnd_surface[maturity]
511
-
512
- # Calculate PDF
513
- prices, pdf_values = calculate_pdf(moneyness_grid, rnd_values, spot_price)
514
-
515
- result = (prices, pdf_values)
516
-
517
- # Generate plot if requested
518
- if plot:
519
- logger.info(f"Generating PDF plot for {maturity}")
520
- pdf_plot = plot_pdf(
521
- moneyness_grid, rnd_values, spot_price,
522
- title=f"Probability Density Function - {maturity}"
523
- )
524
- result = (prices, pdf_values, pdf_plot)
525
-
526
- return result
527
-
528
- @staticmethod
529
- def cdf(rnd_results: Dict[str, Any],
530
- maturity: Optional[str] = None,
531
- plot: bool = False) -> Tuple[np.ndarray, np.ndarray]:
532
- """
533
- Calculate cumulative distribution function (CDF) from RND results.
534
-
535
- Parameters:
536
- - rnd_results: Dictionary with RND results from rnd()
537
- - maturity: Optional maturity name for a specific expiry
538
- - plot: Whether to generate and return a plot
539
-
540
- Returns:
541
- - Tuple of (prices, cdf_values) and optional plot
542
- """
543
- logger.info("Calculating CDF from RND")
544
-
545
- # Extract required data
546
- moneyness_grid = rnd_results['moneyness_grid']
547
- rnd_surface = rnd_results['rnd_surface']
548
- spot_price = rnd_results['spot_price']
549
-
550
- # Select maturity
551
- if maturity is None:
552
- # Use first maturity if not specified
553
- maturity = list(rnd_surface.keys())[0]
554
- elif maturity not in rnd_surface:
555
- raise VolyError(f"Maturity '{maturity}' not found in RND results")
556
-
557
- # Get RND values for the selected maturity
558
- rnd_values = rnd_surface[maturity]
559
-
560
- # Calculate CDF
561
- prices, cdf_values = calculate_cdf(moneyness_grid, rnd_values, spot_price)
562
-
563
- result = (prices, cdf_values)
564
-
565
- # Generate plot if requested
566
- if plot:
567
- logger.info(f"Generating CDF plot for {maturity}")
568
- cdf_plot = plot_cdf(
569
- moneyness_grid, rnd_values, spot_price,
570
- title=f"Cumulative Distribution Function - {maturity}"
571
- )
572
- result = (prices, cdf_values, cdf_plot)
573
-
574
- return result
575
-
576
- @staticmethod
577
- def probability(rnd_results: Dict[str, Any],
578
- target_price: float,
579
- maturity: Optional[str] = None,
580
- direction: str = 'above') -> float:
581
- """
582
- Calculate the probability of price being above or below a target price.
583
-
584
- Parameters:
585
- - rnd_results: Dictionary with RND results from rnd()
586
- - target_price: Target price level
587
- - maturity: Optional maturity name for a specific expiry
588
- - direction: 'above' or 'below'
589
-
590
- Returns:
591
- - Probability (0 to 1)
592
- """
593
- if direction not in ['above', 'below']:
594
- raise VolyError("Direction must be 'above' or 'below'")
595
-
596
- # Extract required data
597
- moneyness_grid = rnd_results['moneyness_grid']
598
- rnd_surface = rnd_results['rnd_surface']
599
- spot_price = rnd_results['spot_price']
600
-
601
- # Select maturity
602
- if maturity is None:
603
- # Use first maturity if not specified
604
- maturity = list(rnd_surface.keys())[0]
605
- elif maturity not in rnd_surface:
606
- raise VolyError(f"Maturity '{maturity}' not found in RND results")
607
-
608
- # Get RND values for the selected maturity
609
- rnd_values = rnd_surface[maturity]
610
-
611
- # Calculate probability
612
- prob = calculate_strike_probability(
613
- target_price, moneyness_grid, rnd_values, spot_price, direction
614
- )
615
-
616
- return prob
617
-
618
- # -------------------------------------------------------------------------
619
- # Interpolation
620
- # -------------------------------------------------------------------------
621
-
622
- @staticmethod
623
- def interpolate(fit_results: Dict[str, Any],
624
- specific_days: Optional[List[int]] = None,
625
- num_points: int = 10,
626
- method: str = 'cubic',
627
- plot: bool = False) -> Dict[str, Any]:
628
- """
629
- Interpolate a fitted model to specific days to expiry.
630
-
631
- Parameters:
632
- - fit_results: Dictionary with fitting results from fit_model()
633
- - specific_days: Optional list of specific days to include (e.g., [7, 30, 90, 180])
634
- - num_points: Number of points for regular grid if specific_days is None
635
- - method: Interpolation method ('linear', 'cubic', 'pchip', etc.)
636
- - plot: Whether to generate and return a plot
637
-
638
- Returns:
639
- - Dictionary with interpolation results and optional plot
640
- """
641
- logger.info(f"Interpolating model with {method} method")
642
-
643
- # Interpolate the model
644
- interp_results = interpolate_model(
645
- fit_results, specific_days, num_points, method
463
+ pdf_surface, cdf_surface, x_surface, moments = get_rnd_surface(
464
+ model_results=model_results,
465
+ domain_params=domain_params,
466
+ return_domain=return_domain,
467
+ method=method
646
468
  )
647
469
 
648
- # Generate plot if requested
649
- if plot:
650
- logger.info("Generating interpolated surface plot")
651
- interp_plot = plot_interpolated_surface(interp_results)
652
- interp_results['plot'] = interp_plot
653
-
654
- return interp_results
470
+ return pdf_surface, cdf_surface, x_surface, moments