voly 0.0.133__py3-none-any.whl → 0.0.135__py3-none-any.whl

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/core/hd.py CHANGED
@@ -449,7 +449,15 @@ def get_garch_hd_surface(model_results: pd.DataFrame,
449
449
  if missing_columns:
450
450
  raise VolyError(f"Required columns missing in model_results: {missing_columns}")
451
451
 
452
- # Calculate log returns from price history
452
+ # Determine granularity from df_hist
453
+ if len(df_hist) > 1:
454
+ # Calculate minutes between consecutive timestamps
455
+ minutes_diff = (df_hist.index[1] - df_hist.index[0]).total_seconds() / 60
456
+ minutes_per_period = int(minutes_diff)
457
+ else:
458
+ raise VolyError("Cannot determine granularity from df_hist.")
459
+
460
+ # Calculate log returns based on the determined granularity
453
461
  log_returns = np.log(df_hist['close'] / df_hist['close'].shift(1)) * 100
454
462
  log_returns = log_returns.dropna().values
455
463
 
@@ -469,6 +477,9 @@ def get_garch_hd_surface(model_results: pd.DataFrame,
469
477
 
470
478
  logger.info(f"Processing GARCH HD for maturity {i} (t={t:.4f} years, {tau_day} days)")
471
479
 
480
+ # Calculate the number of periods that match the time to expiry
481
+ n_periods = int(t * 365.25 * 24 * 60 / minutes_per_period)
482
+
472
483
  # Initialize GARCH model
473
484
  garch_model = GARCHModel(
474
485
  data=log_returns,
@@ -485,8 +496,26 @@ def get_garch_hd_surface(model_results: pd.DataFrame,
485
496
  variate_parameters=variate_parameters
486
497
  )
487
498
 
488
- # Convert to terminal prices
489
- simulated_prices = s * np.exp(simulated_log_returns / 100 + simulated_tau_mu / 100)
499
+ # Scale the simulated returns to match target time horizon
500
+ scaling_factor = np.sqrt(n_periods / tau_day)
501
+ scaled_log_returns = simulated_log_returns * scaling_factor
502
+
503
+ # Risk-neutral adjustment (Girsanov transformation)
504
+ # Calculate empirical mean and volatility of the scaled returns
505
+ mu_scaled = scaled_log_returns.mean()
506
+ sigma_scaled = scaled_log_returns.std()
507
+
508
+ # Expected risk-neutral drift
509
+ expected_risk_neutral_mean = (r - 0.5 * (sigma_scaled / 100) ** 2) * 100 * np.sqrt(t)
510
+
511
+ # Calculate adjustment to shift physical to risk-neutral measure
512
+ adjustment = mu_scaled - expected_risk_neutral_mean
513
+
514
+ # Adjust the returns to the risk-neutral measure
515
+ risk_neutral_log_returns = scaled_log_returns - adjustment
516
+
517
+ # Convert to terminal prices using the risk-neutral returns
518
+ simulated_prices = s * np.exp(risk_neutral_log_returns / 100)
490
519
 
491
520
  # Convert to moneyness domain
492
521
  simulated_moneyness = s / simulated_prices
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voly
3
- Version: 0.0.133
3
+ Version: 0.0.135
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -7,13 +7,13 @@ voly/core/__init__.py,sha256=bu6fS2I1Pj9fPPnl-zY3L7NqrZSY5Zy6NY2uMUvdhKs,183
7
7
  voly/core/charts.py,sha256=E21OZB5lTY4YL2flgaFJ6s5g3_ExtAQT2zryZZxLPyM,12735
8
8
  voly/core/data.py,sha256=pDeuYhP0GX4RbtlqByvsE3rfHcIkix0BU5MLW8sKIeI,8935
9
9
  voly/core/fit.py,sha256=Tb9eeG7e_2dQTcqt6aqEwFrZdy6jR9rSNqe6tzOdVhQ,9245
10
- voly/core/hd.py,sha256=mnQdLxWn9cBzTci6i_u3xKSDkH2uhjdpuRGXYpJydIk,19949
10
+ voly/core/hd.py,sha256=07tqWc9WtjHrOnIM3nj9JTaw3v2s5kaV2AcRLnL_p8M,21259
11
11
  voly/core/interpolate.py,sha256=JkK172-FXyhesW3hY4pEeuJWG3Bugq7QZXbeKoRpLuo,5305
12
12
  voly/core/rnd.py,sha256=0VE77lxesx_BPAO46QwKpcauZNaHnPTiDhmRbSURn3c,10022
13
13
  voly/utils/__init__.py,sha256=E05mWatyC-PDOsCxQV1p5Xi1IgpOomxrNURyCx_gB-w,200
14
14
  voly/utils/logger.py,sha256=4-_2bVJmq17Q0d7Rd2mPg1AeR8gxv6EPvcmBDMFWcSM,1744
15
- voly-0.0.133.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
16
- voly-0.0.133.dist-info/METADATA,sha256=Hb0WI6776ODVcmhuEDQdE4y2ZLxM8EAk8HAajlbbn5c,4115
17
- voly-0.0.133.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
18
- voly-0.0.133.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
19
- voly-0.0.133.dist-info/RECORD,,
15
+ voly-0.0.135.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
16
+ voly-0.0.135.dist-info/METADATA,sha256=ZMMRpocTA7buNWu_1F8esF2laQkezgNLejaUz4SSf58,4115
17
+ voly-0.0.135.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
18
+ voly-0.0.135.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
19
+ voly-0.0.135.dist-info/RECORD,,
File without changes