voly 0.0.105__py3-none-any.whl → 0.0.107__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
@@ -15,11 +15,12 @@ from voly.utils.logger import logger, catch_exception, setup_file_logging
15
15
  from voly.exceptions import VolyError
16
16
  from voly.models import SVIModel
17
17
  from voly.formulas import (
18
- d1, d2, bs, delta, gamma, vega, theta, rho, vanna, volga, charm, greeks, iv
18
+ d1, d2, bs, delta, gamma, vega, theta, rho, vanna, volga, charm, greeks, iv, pdf_to_calls
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
22
  from voly.core.rnd import get_rnd_surface
23
+ from voly.core.hd import get_historical_data
23
24
  from voly.core.interpolate import interpolate_model
24
25
  from voly.core.charts import (
25
26
  plot_all_smiles, plot_raw_parameters, plot_jw_parameters, plot_fit_performance, plot_3d_surface,
@@ -271,7 +272,7 @@ class VolyClient:
271
272
 
272
273
  @staticmethod
273
274
  def interpolate_model(fit_results: pd.DataFrame,
274
- list_of_days: List[str] = ['7d', '30d', '90d', '150d', '240d'],
275
+ list_of_days=None,
275
276
  method: str = 'cubic') -> pd.DataFrame:
276
277
  """
277
278
  Interpolate a fitted model to specific days to expiry.
@@ -284,6 +285,8 @@ class VolyClient:
284
285
  Returns:
285
286
  - DataFrame with interpolated model parameters for the specified days
286
287
  """
288
+ if list_of_days is None:
289
+ list_of_days = ['7d', '30d', '90d', '150d', '240d']
287
290
  logger.info(f"Interpolating model with {method} method")
288
291
 
289
292
  # Interpolate the model
@@ -314,3 +317,23 @@ class VolyClient:
314
317
  )
315
318
 
316
319
  return pdf_surface, cdf_surface, x_surface, moments
320
+
321
+ # -------------------------------------------------------------------------
322
+ # Historical Density (HD)
323
+ # -------------------------------------------------------------------------
324
+
325
+ @staticmethod
326
+ def get_historical_data(currency: str = 'BTC',
327
+ lookback_days: str = '90d',
328
+ granularity: str = '15m',
329
+ exchange_name: str = 'binance'):
330
+
331
+ # Generate the surface
332
+ df_hist = get_historical_data(
333
+ currency=currency,
334
+ lookback_days=lookback_days,
335
+ granularity=granularity,
336
+ exchange_name=exchange_name
337
+ )
338
+
339
+ return df_hist
voly/core/hd.py ADDED
@@ -0,0 +1,84 @@
1
+ """
2
+ This module handles calculating historical densities from
3
+ time series of prices and converting them to implied volatility smiles.
4
+ """
5
+
6
+ import ccxt
7
+ import pandas as pd
8
+ import datetime as dt
9
+ from voly.utils.logger import logger, catch_exception
10
+ from voly.exceptions import VolyError
11
+
12
+
13
+ @catch_exception
14
+ def get_historical_data(currency='BTC', lookback_days='90d', granularity='15m', exchange_name='binance'):
15
+ """
16
+ Fetch historical OHLCV data for a cryptocurrency.
17
+
18
+ Parameters:
19
+ ----------
20
+ currency : str
21
+ The cryptocurrency to fetch data for (e.g., 'BTC', 'ETH').
22
+ lookback_days : str
23
+ The lookback period in days, formatted as '90d', '30d', etc.
24
+ granularity : str
25
+ The time interval for data points (e.g., '15m', '1h', '1d').
26
+ exchange_name : str
27
+ The exchange to fetch data from (default: 'binance').
28
+
29
+ Returns:
30
+ -------
31
+ df_hist : pandas.DataFrame containing the historical price data with OHLCV columns.
32
+ """
33
+
34
+ try:
35
+ # Get the exchange class from ccxt
36
+ exchange_class = getattr(ccxt, exchange_name.lower())
37
+ exchange = exchange_class({'enableRateLimit': True})
38
+ except (AttributeError, TypeError):
39
+ raise VolyError(f"Exchange '{exchange_name}' not found in ccxt. Please check the exchange name.")
40
+
41
+ # Form the trading pair symbol
42
+ symbol = currency + '/USDT'
43
+
44
+ # Convert lookback_days to timestamp
45
+ if lookback_days.endswith('d'):
46
+ days_ago = int(lookback_days[:-1])
47
+ date_start = (dt.datetime.now() - dt.timedelta(days=days_ago)).strftime('%Y-%m-%d %H:%M:%S')
48
+ else:
49
+ raise VolyError("lookback_days should be in format '90d', '30d', etc.")
50
+
51
+ # Convert start date to timestamp
52
+ from_ts = exchange.parse8601(date_start)
53
+
54
+ # Fetch OHLCV data in batches
55
+ ohlcv = []
56
+ last_timestamp = from_ts
57
+
58
+ while True:
59
+ batch = exchange.fetch_ohlcv(symbol, granularity, since=last_timestamp, limit=1000)
60
+
61
+ if len(batch) == 0:
62
+ break
63
+
64
+ if ohlcv and batch[0][0] == ohlcv[-1][0]:
65
+ batch = batch[1:] # Avoid duplicates
66
+
67
+ ohlcv.extend(batch)
68
+
69
+ # Update timestamp for next batch
70
+ last_timestamp = batch[-1][0]
71
+
72
+ # Break if we got less than the limit (reached the end)
73
+ if len(batch) < 1000:
74
+ break
75
+
76
+ # Convert to DataFrame
77
+ df_hist = pd.DataFrame(ohlcv, columns=['date', 'open', 'high', 'low', 'close', 'volume'])
78
+ df_hist['date'] = pd.to_datetime(df_hist['date'], unit='ms')
79
+ df_hist.set_index('date', inplace=True)
80
+ df_hist = df_hist.sort_index(ascending=True)
81
+
82
+ print(f"Data fetched successfully: {len(df_hist)} rows from {df_hist.index[0]} to {df_hist.index[-1]}")
83
+
84
+ return df_hist
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: voly
3
- Version: 0.0.105
3
+ Version: 0.0.107
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -33,6 +33,7 @@ Requires-Dist: mypy>=0.931; extra == "dev"
33
33
  Requires-Dist: flake8>=4.0.1; extra == "dev"
34
34
  Requires-Dist: twine>=4.0.0; extra == "dev"
35
35
  Requires-Dist: build>=0.8.0; extra == "dev"
36
+ Dynamic: license-file
36
37
 
37
38
  # Voly - Options & Volatility Research Package
38
39
 
@@ -1,5 +1,5 @@
1
1
  voly/__init__.py,sha256=8xyDk7rFCn_MOD5hxuv5cxxKZvBVRiSIM7TgaMPpwpw,211
2
- voly/client.py,sha256=sx7yL6FDKfH03I86EZgdcfiJOLVuBRjsWr1FBDJ-WXE,11627
2
+ voly/client.py,sha256=FOH1E_zTCnDZhGLab9dzpqMQ5-fkW0MFeV0o1dBMx0w,12424
3
3
  voly/exceptions.py,sha256=PBsbn1vNMvKcCJwwJ4lBO6glD85jo1h2qiEmD7ArAjs,92
4
4
  voly/formulas.py,sha256=1Kjo6j7dMzjyfym-Cfk67qP4sS-lKQpkj0YNAoBOGe0,13351
5
5
  voly/models.py,sha256=BF-O7BjGf0BLMpw4rCtfwW7s8_f4iyUZdUY6q1dVxLs,3363
@@ -7,12 +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=sKDg_W8saF24gb2USV1JYntdNpstD-os1ACsczmUV7Y,2736
10
11
  voly/core/interpolate.py,sha256=JkK172-FXyhesW3hY4pEeuJWG3Bugq7QZXbeKoRpLuo,5305
11
12
  voly/core/rnd.py,sha256=VKM8ojLBziB9nxOEsKO5z_9Z1BSOVNxg0OQPx-Sp80I,10094
12
13
  voly/utils/__init__.py,sha256=E05mWatyC-PDOsCxQV1p5Xi1IgpOomxrNURyCx_gB-w,200
13
14
  voly/utils/logger.py,sha256=4-_2bVJmq17Q0d7Rd2mPg1AeR8gxv6EPvcmBDMFWcSM,1744
14
- voly-0.0.105.dist-info/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
15
- voly-0.0.105.dist-info/METADATA,sha256=qyC14tF1gR3HqH35NNeJ-XDLjg1iQixH8R8RnwSVhY8,4093
16
- voly-0.0.105.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
17
- voly-0.0.105.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
18
- voly-0.0.105.dist-info/RECORD,,
15
+ voly-0.0.107.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
16
+ voly-0.0.107.dist-info/METADATA,sha256=85BF65TsY_sJhLiE94yb_77khaO3Vhm1qRd27s8PgQw,4115
17
+ voly-0.0.107.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
18
+ voly-0.0.107.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
19
+ voly-0.0.107.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.1.0)
2
+ Generator: setuptools (77.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5