voly 0.0.157__py3-none-any.whl → 0.0.158__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/data.py +103 -0
- voly/core/hd.py +0 -2
- voly/formulas.py +0 -1
- {voly-0.0.157.dist-info → voly-0.0.158.dist-info}/METADATA +1 -1
- {voly-0.0.157.dist-info → voly-0.0.158.dist-info}/RECORD +8 -8
- {voly-0.0.157.dist-info → voly-0.0.158.dist-info}/WHEEL +0 -0
- {voly-0.0.157.dist-info → voly-0.0.158.dist-info}/licenses/LICENSE +0 -0
- {voly-0.0.157.dist-info → voly-0.0.158.dist-info}/top_level.txt +0 -0
voly/core/data.py
CHANGED
@@ -232,6 +232,109 @@ def process_option_chain(df: pd.DataFrame, currency: str) -> pd.DataFrame:
|
|
232
232
|
return df
|
233
233
|
|
234
234
|
|
235
|
+
@catch_exception
|
236
|
+
def process_order_book_depth(option_chain, max_depth=5):
|
237
|
+
"""
|
238
|
+
Process the order book depth data to enhance option pricing and weighting.
|
239
|
+
|
240
|
+
Args:
|
241
|
+
option_chain: DataFrame containing option data with 'bids' and 'asks' columns
|
242
|
+
max_depth: Maximum number of levels to consider from the order book
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
Enhanced option_chain with additional columns for depth analysis
|
246
|
+
"""
|
247
|
+
# Create new columns for depth analysis
|
248
|
+
option_chain['vwap_bid'] = float('nan')
|
249
|
+
option_chain['vwap_ask'] = float('nan')
|
250
|
+
option_chain['vwap_mid'] = float('nan')
|
251
|
+
option_chain['depth_bid_qty'] = float('nan')
|
252
|
+
option_chain['depth_ask_qty'] = float('nan')
|
253
|
+
option_chain['vwap_bid_iv'] = float('nan')
|
254
|
+
option_chain['vwap_ask_iv'] = float('nan')
|
255
|
+
option_chain['vwap_mid_iv'] = float('nan')
|
256
|
+
option_chain['depth_liquidity'] = float('nan')
|
257
|
+
|
258
|
+
for idx, row in option_chain.iterrows():
|
259
|
+
s = row['underlying_price']
|
260
|
+
k = row['strikes']
|
261
|
+
t = row['t']
|
262
|
+
r = row['interest_rate'] if 'interest_rate' in row else 0.0
|
263
|
+
option_type = 'C' if row['option_type'] == 'call' else 'P'
|
264
|
+
|
265
|
+
# Process bid side
|
266
|
+
if 'bids' in row and isinstance(row['bids'], list) and len(row['bids']) > 0:
|
267
|
+
# Clean up the bid data
|
268
|
+
clean_bids = []
|
269
|
+
for bid in row['bids'][:max_depth]: # Limit to max_depth levels
|
270
|
+
if len(bid) >= 3:
|
271
|
+
# Extract price and quantity, removing 'new' if present
|
272
|
+
price = float(bid[1]) if bid[0] == 'new' else float(bid[0])
|
273
|
+
qty = float(bid[2]) if bid[0] == 'new' else float(bid[1])
|
274
|
+
clean_bids.append((price, qty))
|
275
|
+
|
276
|
+
if clean_bids:
|
277
|
+
# Calculate volume-weighted average price
|
278
|
+
total_qty = sum(qty for _, qty in clean_bids)
|
279
|
+
vwap_bid = sum(price * qty for price, qty in clean_bids) / total_qty if total_qty > 0 else float('nan')
|
280
|
+
|
281
|
+
# Calculate IV for VWAP
|
282
|
+
try:
|
283
|
+
vwap_bid_iv = voly.iv(vwap_bid * s, s, k, r, t, option_type)
|
284
|
+
except:
|
285
|
+
vwap_bid_iv = float('nan')
|
286
|
+
|
287
|
+
option_chain.at[idx, 'vwap_bid'] = vwap_bid
|
288
|
+
option_chain.at[idx, 'depth_bid_qty'] = total_qty
|
289
|
+
option_chain.at[idx, 'vwap_bid_iv'] = vwap_bid_iv
|
290
|
+
|
291
|
+
# Process ask side
|
292
|
+
if 'asks' in row and isinstance(row['asks'], list) and len(row['asks']) > 0:
|
293
|
+
# Clean up the ask data
|
294
|
+
clean_asks = []
|
295
|
+
for ask in row['asks'][:max_depth]: # Limit to max_depth levels
|
296
|
+
if len(ask) >= 3:
|
297
|
+
# Extract price and quantity, removing 'new' if present
|
298
|
+
price = float(ask[1]) if ask[0] == 'new' else float(ask[0])
|
299
|
+
qty = float(ask[2]) if ask[0] == 'new' else float(ask[1])
|
300
|
+
clean_asks.append((price, qty))
|
301
|
+
|
302
|
+
if clean_asks:
|
303
|
+
# Calculate volume-weighted average price
|
304
|
+
total_qty = sum(qty for _, qty in clean_asks)
|
305
|
+
vwap_ask = sum(price * qty for price, qty in clean_asks) / total_qty if total_qty > 0 else float('nan')
|
306
|
+
|
307
|
+
# Calculate IV for VWAP
|
308
|
+
try:
|
309
|
+
vwap_ask_iv = voly.iv(vwap_ask * s, s, k, r, t, option_type)
|
310
|
+
except:
|
311
|
+
vwap_ask_iv = float('nan')
|
312
|
+
|
313
|
+
option_chain.at[idx, 'vwap_ask'] = vwap_ask
|
314
|
+
option_chain.at[idx, 'depth_ask_qty'] = total_qty
|
315
|
+
option_chain.at[idx, 'vwap_ask_iv'] = vwap_ask_iv
|
316
|
+
|
317
|
+
# Calculate mid VWAP if both bid and ask are available
|
318
|
+
if not np.isnan(option_chain.at[idx, 'vwap_bid']) and not np.isnan(option_chain.at[idx, 'vwap_ask']):
|
319
|
+
vwap_mid = (option_chain.at[idx, 'vwap_bid'] + option_chain.at[idx, 'vwap_ask']) / 2
|
320
|
+
|
321
|
+
# Calculate IV for mid VWAP
|
322
|
+
try:
|
323
|
+
vwap_mid_iv = voly.iv(vwap_mid * s, s, k, r, t, option_type)
|
324
|
+
except:
|
325
|
+
vwap_mid_iv = float('nan')
|
326
|
+
|
327
|
+
option_chain.at[idx, 'vwap_mid'] = vwap_mid
|
328
|
+
option_chain.at[idx, 'vwap_mid_iv'] = vwap_mid_iv
|
329
|
+
|
330
|
+
# Calculate depth liquidity (sum of bid and ask quantities)
|
331
|
+
bid_qty = option_chain.at[idx, 'depth_bid_qty'] if not np.isnan(option_chain.at[idx, 'depth_bid_qty']) else 0
|
332
|
+
ask_qty = option_chain.at[idx, 'depth_ask_qty'] if not np.isnan(option_chain.at[idx, 'depth_ask_qty']) else 0
|
333
|
+
option_chain.at[idx, 'depth_liquidity'] = bid_qty + ask_qty
|
334
|
+
|
335
|
+
return option_chain
|
336
|
+
|
337
|
+
|
235
338
|
@catch_exception
|
236
339
|
async def fetch_option_chain(exchange: str = 'deribit',
|
237
340
|
currency: str = 'BTC',
|
voly/core/hd.py
CHANGED
@@ -230,8 +230,6 @@ def calculate_student_t_hd(df_hist: pd.DataFrame,
|
|
230
230
|
else:
|
231
231
|
df = 5 # Default value if kurtosis calculation fails
|
232
232
|
|
233
|
-
logger.info(f"Estimated degrees of freedom for t-distribution: {df:.2f}")
|
234
|
-
|
235
233
|
# Apply Girsanov adjustment to shift to risk-neutral measure
|
236
234
|
expected_risk_neutral_mean = (r - 0.5 * sigma_scaled ** 2) * np.sqrt(t)
|
237
235
|
adjustment = mu_scaled - expected_risk_neutral_mean
|
voly/formulas.py
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
voly/__init__.py,sha256=8xyDk7rFCn_MOD5hxuv5cxxKZvBVRiSIM7TgaMPpwpw,211
|
2
2
|
voly/client.py,sha256=-yE1_cBvjkK-BO_kKCYtn4WPbNOhAzT0hsfykU5LvQQ,14761
|
3
3
|
voly/exceptions.py,sha256=PBsbn1vNMvKcCJwwJ4lBO6glD85jo1h2qiEmD7ArAjs,92
|
4
|
-
voly/formulas.py,sha256=
|
4
|
+
voly/formulas.py,sha256=oXttz6cnn1a_WXBVIl4n38XdGUsd4ZSM4Dg6hM1tUG8,10722
|
5
5
|
voly/models.py,sha256=o-pHujGfr5Gn8ItckMzLI4Q8yaX9FQaV8UjCxv2zgTY,3364
|
6
6
|
voly/core/__init__.py,sha256=bu6fS2I1Pj9fPPnl-zY3L7NqrZSY5Zy6NY2uMUvdhKs,183
|
7
7
|
voly/core/charts.py,sha256=E21OZB5lTY4YL2flgaFJ6s5g3_ExtAQT2zryZZxLPyM,12735
|
8
|
-
voly/core/data.py,sha256=
|
8
|
+
voly/core/data.py,sha256=_iXiZ7N08J9V3EUG538QPX3lW_Yo8mEsk4VH9E9GtwQ,13581
|
9
9
|
voly/core/fit.py,sha256=Tb9eeG7e_2dQTcqt6aqEwFrZdy6jR9rSNqe6tzOdVhQ,9245
|
10
|
-
voly/core/hd.py,sha256=
|
10
|
+
voly/core/hd.py,sha256=UFAyLncNUHivpPAcko6IK1bC55mudVtdlRFfXp63HXE,14771
|
11
11
|
voly/core/interpolate.py,sha256=JkK172-FXyhesW3hY4pEeuJWG3Bugq7QZXbeKoRpLuo,5305
|
12
12
|
voly/core/rnd.py,sha256=GoC3m1Q46Wnk5tV_mstr-3_aktHeue6BBLh4DQTciW0,13307
|
13
13
|
voly/utils/__init__.py,sha256=E05mWatyC-PDOsCxQV1p5Xi1IgpOomxrNURyCx_gB-w,200
|
14
14
|
voly/utils/density.py,sha256=q0fX4im9TGwMCZ32Hzdv8CNh56KnJo8bmG5w0gVWZH8,5879
|
15
15
|
voly/utils/logger.py,sha256=4-_2bVJmq17Q0d7Rd2mPg1AeR8gxv6EPvcmBDMFWcSM,1744
|
16
|
-
voly-0.0.
|
17
|
-
voly-0.0.
|
18
|
-
voly-0.0.
|
19
|
-
voly-0.0.
|
20
|
-
voly-0.0.
|
16
|
+
voly-0.0.158.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
|
17
|
+
voly-0.0.158.dist-info/METADATA,sha256=GkUeHlcZ1_2FLecO_vu1FX5_aGC5HqzTwwLQ1BnK_Cc,4115
|
18
|
+
voly-0.0.158.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
19
|
+
voly-0.0.158.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
|
20
|
+
voly-0.0.158.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|