voly 0.0.60__tar.gz → 0.0.62__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.60
3
+ Version: 0.0.62
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.60"
7
+ version = "0.0.62"
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.60"
63
+ python_version = "0.0.62"
64
64
  warn_return_any = true
65
65
  warn_unused_configs = true
66
66
  disallow_untyped_defs = true
@@ -319,7 +319,7 @@ class VolyClient:
319
319
  # -------------------------------------------------------------------------
320
320
 
321
321
  @staticmethod
322
- def fit_model(market_data: pd.DataFrame,
322
+ def fit_model(option_chain: pd.DataFrame,
323
323
  model_name: str = 'svi',
324
324
  initial_params: Optional[List[float]] = None,
325
325
  param_bounds: Optional[Tuple] = None) -> Dict[str, Any]:
@@ -327,19 +327,19 @@ class VolyClient:
327
327
  Fit a volatility model to market data.
328
328
 
329
329
  Parameters:
330
- - market_data: DataFrame with market data
330
+ - option_chain: DataFrame with option market data
331
331
  - model_name: Name of model to fit (default: 'svi')
332
332
  - initial_params: Optional initial parameters for optimization
333
333
  - param_bounds: Optional parameter bounds for optimization
334
334
 
335
335
  Returns:
336
- - Dictionary with fitting results and optional plots
336
+ - Tuple of (fit_results, fit_performance)
337
337
  """
338
338
  logger.info(f"Fitting {model_name.upper()} model to market data")
339
339
 
340
340
  # Fit the model
341
341
  fit_results, fit_performance = fit_model(
342
- market_data=market_data,
342
+ option_chain=option_chain,
343
343
  model_name=model_name,
344
344
  initial_params=initial_params,
345
345
  param_bounds=param_bounds
@@ -377,7 +377,7 @@ class VolyClient:
377
377
 
378
378
  @staticmethod
379
379
  def plot_model(fit_results: Dict[str, Any],
380
- market_data: pd.DataFrame = None,
380
+ option_chain: pd.DataFrame = None,
381
381
  moneyness_params: Tuple[float, float, int] = (-2, 2, 500)
382
382
  ) -> Dict[str, go.Figure]:
383
383
  """
@@ -385,7 +385,7 @@ class VolyClient:
385
385
 
386
386
  Parameters:
387
387
  - fit_results: Dictionary with fitting results from fit_model()
388
- - market_data: Optional market data for comparison
388
+ - option_chain: Optional market data for comparison
389
389
  - moneyness_params: Grid of log-moneyness values
390
390
 
391
391
  Returns:
@@ -401,7 +401,7 @@ class VolyClient:
401
401
  fit_performance = fit_results['fit_performance']
402
402
 
403
403
  # Plot volatility smiles
404
- plots['smiles'] = plot_all_smiles(moneyness_array, iv_surface, market_data)
404
+ plots['smiles'] = plot_all_smiles(moneyness_array, iv_surface, option_chain)
405
405
 
406
406
  # Plot 3D surface
407
407
  plots['surface_3d'] = plot_3d_surface(moneyness_array, iv_surface)
@@ -21,7 +21,7 @@ pio.renderers.default = "browser"
21
21
  @catch_exception
22
22
  def plot_volatility_smile(moneyness_array: np.ndarray,
23
23
  iv_array: np.ndarray,
24
- market_data: pd.DataFrame = None,
24
+ option_chain: pd.DataFrame = None,
25
25
  maturity: Optional[str] = None) -> go.Figure:
26
26
  """Plot volatility smile for a single expiry."""
27
27
  fig = go.Figure()
@@ -38,8 +38,8 @@ def plot_volatility_smile(moneyness_array: np.ndarray,
38
38
  )
39
39
 
40
40
  # Add market data if provided
41
- if market_data is not None and maturity is not None:
42
- maturity_data = market_data[market_data['maturity_name'] == maturity]
41
+ if option_chain is not None and maturity is not None:
42
+ maturity_data = option_chain[option_chain['maturity_name'] == maturity]
43
43
 
44
44
  if not maturity_data.empty:
45
45
  # Add bid and ask IVs
@@ -72,13 +72,13 @@ def plot_volatility_smile(moneyness_array: np.ndarray,
72
72
  @catch_exception
73
73
  def plot_all_smiles(moneyness_array: np.ndarray,
74
74
  iv_surface: Dict[str, np.ndarray],
75
- market_data: Optional[pd.DataFrame] = None) -> List[go.Figure]:
75
+ option_chain: Optional[pd.DataFrame] = None) -> List[go.Figure]:
76
76
  """Plot volatility smiles for all expiries."""
77
77
  return [
78
78
  plot_volatility_smile(
79
79
  moneyness_array=moneyness_array,
80
80
  iv_array=iv_surface[maturity],
81
- market_data=market_data,
81
+ option_chain=option_chain,
82
82
  maturity=maturity
83
83
  )
84
84
  for maturity in iv_surface.keys()
@@ -19,17 +19,17 @@ warnings.filterwarnings("ignore")
19
19
 
20
20
 
21
21
  @catch_exception
22
- def calculate_residuals(params: List[float], ytm: float, market_data: pd.DataFrame,
22
+ def calculate_residuals(params: List[float], ytm: float, option_chain: pd.DataFrame,
23
23
  model: Any = SVIModel) -> np.ndarray:
24
24
  """Calculate residuals between market and model implied volatilities."""
25
- maturity_data = market_data[market_data['ytm'] == ytm]
25
+ maturity_data = option_chain[option_chain['ytm'] == ytm]
26
26
  w = np.array([model.svi(x, *params) for x in maturity_data['log_moneyness']])
27
27
  iv_actual = maturity_data['mark_iv'].values
28
28
  return iv_actual - np.sqrt(w / ytm)
29
29
 
30
30
 
31
31
  @catch_exception
32
- def fit_model(market_data: pd.DataFrame,
32
+ def fit_model(option_chain: pd.DataFrame,
33
33
  model_name: str = 'svi',
34
34
  initial_params: Optional[List[float]] = None,
35
35
  param_bounds: Optional[Tuple] = None) -> Tuple[pd.DataFrame, pd.DataFrame]:
@@ -56,8 +56,8 @@ def fit_model(market_data: pd.DataFrame,
56
56
  'rmse', 'mae', 'r2', 'max_error', 'n_points']
57
57
 
58
58
  # Get unique maturities and sort them
59
- unique_ytms = sorted(market_data['ytm'].unique())
60
- maturity_names = [market_data[market_data['ytm'] == ytm]['maturity_name'].iloc[0] for ytm in unique_ytms]
59
+ unique_ytms = sorted(option_chain['ytm'].unique())
60
+ maturity_names = [option_chain[option_chain['ytm'] == ytm]['maturity_name'].iloc[0] for ytm in unique_ytms]
61
61
 
62
62
  # Create empty DataFrames
63
63
  fit_results_df = pd.DataFrame(index=results_index, columns=maturity_names)
@@ -68,7 +68,7 @@ def fit_model(market_data: pd.DataFrame,
68
68
 
69
69
  for ytm in unique_ytms:
70
70
  # Get data for this maturity
71
- maturity_data = market_data[market_data['ytm'] == ytm]
71
+ maturity_data = option_chain[option_chain['ytm'] == ytm]
72
72
  maturity_name = maturity_data['maturity_name'].iloc[0]
73
73
  dtm = maturity_data['dtm'].iloc[0]
74
74
 
@@ -79,7 +79,7 @@ def fit_model(market_data: pd.DataFrame,
79
79
  result = least_squares(
80
80
  calculate_residuals,
81
81
  initial_params,
82
- args=(ytm, market_data, SVIModel),
82
+ args=(ytm, option_chain, SVIModel),
83
83
  bounds=param_bounds,
84
84
  max_nfev=1000
85
85
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voly
3
- Version: 0.0.60
3
+ Version: 0.0.62
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