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 +25 -2
- voly/core/hd.py +84 -0
- {voly-0.0.105.dist-info → voly-0.0.107.dist-info}/METADATA +3 -2
- {voly-0.0.105.dist-info → voly-0.0.107.dist-info}/RECORD +7 -6
- {voly-0.0.105.dist-info → voly-0.0.107.dist-info}/WHEEL +1 -1
- {voly-0.0.105.dist-info → voly-0.0.107.dist-info/licenses}/LICENSE +0 -0
- {voly-0.0.105.dist-info → voly-0.0.107.dist-info}/top_level.txt +0 -0
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
|
|
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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: voly
|
|
3
|
-
Version: 0.0.
|
|
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=
|
|
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.
|
|
15
|
-
voly-0.0.
|
|
16
|
-
voly-0.0.
|
|
17
|
-
voly-0.0.
|
|
18
|
-
voly-0.0.
|
|
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,,
|
|
File without changes
|
|
File without changes
|