voly 0.0.157__py3-none-any.whl → 0.0.159__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 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
@@ -245,15 +245,19 @@ def iv(option_price: float, s: float, K: float, r: float, t: float,
245
245
  return np.inf # Price exceeds strike
246
246
 
247
247
  flag = 'c' if option_type.lower() in ["call", "c"] else 'p'
248
- iv_value = implied_volatility(
249
- price=option_price,
250
- S=s,
251
- K=K,
252
- t=t,
253
- r=r,
254
- q=0.0, # Assume zero dividend yield
255
- flag=flag
256
- )
248
+
249
+ try:
250
+ iv_value = implied_volatility(
251
+ price=option_price,
252
+ S=s,
253
+ K=K,
254
+ t=t,
255
+ r=r,
256
+ flag=flag
257
+ )
258
+ except:
259
+ iv_value = 5.0 # max iv allowed
260
+
257
261
  return iv_value
258
262
 
259
263
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voly
3
- Version: 0.0.157
3
+ Version: 0.0.159
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -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=G_soRiPwQlHy6milOAj6TdmBWr-fNZpMvm0joXAMZ90,10767
4
+ voly/formulas.py,sha256=QEwl3l8R0LJbktm9vflJeMhL8-UBdq8W8NzoPx71Ayg,10818
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=pDeuYhP0GX4RbtlqByvsE3rfHcIkix0BU5MLW8sKIeI,8935
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=kAQO2ft6vmobW60mokhoZbzVElYC_wy1OeBXhmeCtAg,14850
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.157.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
17
- voly-0.0.157.dist-info/METADATA,sha256=5RTJLbGrsh2EQQ4jTBqIGoYF6UDI4_4UnRHsSEDSMM8,4115
18
- voly-0.0.157.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
19
- voly-0.0.157.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
20
- voly-0.0.157.dist-info/RECORD,,
16
+ voly-0.0.159.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
17
+ voly-0.0.159.dist-info/METADATA,sha256=fZdgIs_6QxUT662ba0xHz8Z3_OgVLao65bgRa1eWynY,4115
18
+ voly-0.0.159.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
19
+ voly-0.0.159.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
20
+ voly-0.0.159.dist-info/RECORD,,
File without changes