voly 0.0.135__py3-none-any.whl → 0.0.137__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/client.py CHANGED
@@ -311,21 +311,13 @@ class VolyClient:
311
311
 
312
312
  logger.info("Calculating RND surface")
313
313
 
314
- # Generate the surface
315
- pdf_surface, cdf_surface, x_surface, moments = get_rnd_surface(
314
+ return get_rnd_surface(
316
315
  model_results=model_results,
317
316
  domain_params=domain_params,
318
317
  return_domain=return_domain,
319
318
  method=method
320
319
  )
321
320
 
322
- return {
323
- 'pdf_surface': pdf_surface,
324
- 'cdf_surface': cdf_surface,
325
- 'x_surface': x_surface,
326
- 'moments': moments
327
- }
328
-
329
321
  # -------------------------------------------------------------------------
330
322
  # Historical Density (HD)
331
323
  # -------------------------------------------------------------------------
@@ -354,21 +346,13 @@ class VolyClient:
354
346
 
355
347
  logger.info("Calculating historical density surface")
356
348
 
357
- # Generate the surface
358
- pdf_surface, cdf_surface, x_surface, moments = get_hd_surface(
349
+ return get_hd_surface(
359
350
  model_results=model_results,
360
351
  df_hist=df_hist,
361
352
  domain_params=domain_params,
362
353
  return_domain=return_domain
363
354
  )
364
355
 
365
- return {
366
- 'pdf_surface': pdf_surface,
367
- 'cdf_surface': cdf_surface,
368
- 'x_surface': x_surface,
369
- 'moments': moments
370
- }
371
-
372
356
  @staticmethod
373
357
  def get_garch_hd_surface(model_results: pd.DataFrame,
374
358
  df_hist: pd.DataFrame,
voly/core/hd.py CHANGED
@@ -78,22 +78,6 @@ def get_historical_data(currency, lookback_days, granularity, exchange_name):
78
78
  return df_hist
79
79
 
80
80
 
81
- def generate_lm_points(min_lm, max_lm):
82
- if min_lm >= max_lm:
83
- raise ValueError("min_lm must be less than max_lm")
84
-
85
- max_transformed = np.sqrt(max_lm) if max_lm > 0 else 0
86
- min_transformed = -np.sqrt(-min_lm) if min_lm < 0 else 0
87
-
88
- transformed_points = np.arange(min_transformed, max_transformed + 0.05, 0.05)
89
- lm_points = np.sign(transformed_points) * transformed_points ** 2
90
-
91
- lm_points = np.unique(np.round(lm_points, decimals=2))
92
- lm_points = sorted(lm_points)
93
-
94
- return lm_points
95
-
96
-
97
81
  @catch_exception
98
82
  def get_hd_surface(model_results: pd.DataFrame,
99
83
  df_hist: pd.DataFrame,
@@ -205,16 +189,12 @@ def get_hd_surface(model_results: pd.DataFrame,
205
189
  # Create a DataFrame with moments using the same index as model_results
206
190
  moments = pd.DataFrame(all_moments).T
207
191
 
208
- return pdf_surface, cdf_surface, x_surface, moments
209
-
210
-
211
-
212
- import numpy as np
213
- import pandas as pd
214
- from scipy import stats
215
- from typing import Dict, List, Tuple, Optional, Union, Any
216
- from voly.utils.logger import logger, catch_exception
217
- from voly.exceptions import VolyError
192
+ return {
193
+ 'pdf_surface': pdf_surface,
194
+ 'cdf_surface': cdf_surface,
195
+ 'x_surface': x_surface,
196
+ 'moments': moments
197
+ }
218
198
 
219
199
 
220
200
  class GARCHModel:
@@ -473,18 +453,20 @@ def get_garch_hd_surface(model_results: pd.DataFrame,
473
453
  r = model_results.loc[i, 'r'] # Risk-free rate
474
454
  t = model_results.loc[i, 't'] # Time to maturity in years
475
455
 
476
- tau_day = int(t * 365.25) # Convert years to days
456
+ # Fix for very short-term maturities - use floating-point days
457
+ tau_days_float = t * 365.25 # Exact number of days (as float)
458
+ tau_day = max(1, int(tau_days_float)) # Ensure minimum of 1 day for simulation
477
459
 
478
- logger.info(f"Processing GARCH HD for maturity {i} (t={t:.4f} years, {tau_day} days)")
460
+ logger.info(f"Processing GARCH HD for maturity {i} (t={t:.4f} years, {tau_days_float:.2f} days)")
479
461
 
480
462
  # Calculate the number of periods that match the time to expiry
481
- n_periods = int(t * 365.25 * 24 * 60 / minutes_per_period)
463
+ n_periods = max(1, int(t * 365.25 * 24 * 60 / minutes_per_period))
482
464
 
483
465
  # Initialize GARCH model
484
466
  garch_model = GARCHModel(
485
467
  data=log_returns,
486
468
  data_name=str(i),
487
- n_fits=min(n_fits, len(log_returns) // 3), # Ensure we have enough data
469
+ n_fits=min(n_fits, len(log_returns) // 3),
488
470
  window_length=min(window_length, len(log_returns) // 3),
489
471
  z_h=0.1
490
472
  )
@@ -497,7 +479,8 @@ def get_garch_hd_surface(model_results: pd.DataFrame,
497
479
  )
498
480
 
499
481
  # Scale the simulated returns to match target time horizon
500
- scaling_factor = np.sqrt(n_periods / tau_day)
482
+ # Use floating-point days to avoid division by zero
483
+ scaling_factor = np.sqrt(n_periods / tau_days_float)
501
484
  scaled_log_returns = simulated_log_returns * scaling_factor
502
485
 
503
486
  # Risk-neutral adjustment (Girsanov transformation)
voly/core/rnd.py CHANGED
@@ -285,4 +285,9 @@ def get_rnd_surface(model_results: pd.DataFrame,
285
285
  # Ensure the index matches the model_results index
286
286
  moments.index = model_results.index
287
287
 
288
- return pdf_surface, cdf_surface, x_surface, moments
288
+ return {
289
+ 'pdf_surface': pdf_surface,
290
+ 'cdf_surface': cdf_surface,
291
+ 'x_surface': x_surface,
292
+ 'moments': moments
293
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voly
3
- Version: 0.0.135
3
+ Version: 0.0.137
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  voly/__init__.py,sha256=8xyDk7rFCn_MOD5hxuv5cxxKZvBVRiSIM7TgaMPpwpw,211
2
- voly/client.py,sha256=z9pRicD8XYAl1erpGHkNtxuRR50JTgoxlnXKRsnNibk,15581
2
+ voly/client.py,sha256=9Q_j4F72laro5OnA2IqAZhD2Vr-6QSaaz-vKRxk8KGs,15089
3
3
  voly/exceptions.py,sha256=PBsbn1vNMvKcCJwwJ4lBO6glD85jo1h2qiEmD7ArAjs,92
4
4
  voly/formulas.py,sha256=G_soRiPwQlHy6milOAj6TdmBWr-fNZpMvm0joXAMZ90,10767
5
5
  voly/models.py,sha256=o-pHujGfr5Gn8ItckMzLI4Q8yaX9FQaV8UjCxv2zgTY,3364
@@ -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=07tqWc9WtjHrOnIM3nj9JTaw3v2s5kaV2AcRLnL_p8M,21259
10
+ voly/core/hd.py,sha256=l0EyjZCC9hzupyEe1c4TMRSBZfp5P-KvsuRcGDXHwpc,20846
11
11
  voly/core/interpolate.py,sha256=JkK172-FXyhesW3hY4pEeuJWG3Bugq7QZXbeKoRpLuo,5305
12
- voly/core/rnd.py,sha256=0VE77lxesx_BPAO46QwKpcauZNaHnPTiDhmRbSURn3c,10022
12
+ voly/core/rnd.py,sha256=Bs44AzbAYn1Z8e-Og026BKN9Bu-7A4yH3i639uxXc_A,10116
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.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,,
15
+ voly-0.0.137.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
16
+ voly-0.0.137.dist-info/METADATA,sha256=rpzdcVFWIIe1Idzyhh6ly4ASVA4HqBCgbzRWyPV4t3k,4115
17
+ voly-0.0.137.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
18
+ voly-0.0.137.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
19
+ voly-0.0.137.dist-info/RECORD,,
File without changes