voly 0.0.157__tar.gz → 0.0.158__tar.gz

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.
Files changed (26) hide show
  1. {voly-0.0.157/src/voly.egg-info → voly-0.0.158}/PKG-INFO +1 -1
  2. {voly-0.0.157 → voly-0.0.158}/pyproject.toml +2 -2
  3. {voly-0.0.157 → voly-0.0.158}/src/voly/core/data.py +103 -0
  4. {voly-0.0.157 → voly-0.0.158}/src/voly/core/hd.py +0 -2
  5. {voly-0.0.157 → voly-0.0.158}/src/voly/formulas.py +0 -1
  6. {voly-0.0.157 → voly-0.0.158/src/voly.egg-info}/PKG-INFO +1 -1
  7. {voly-0.0.157 → voly-0.0.158}/LICENSE +0 -0
  8. {voly-0.0.157 → voly-0.0.158}/README.md +0 -0
  9. {voly-0.0.157 → voly-0.0.158}/setup.cfg +0 -0
  10. {voly-0.0.157 → voly-0.0.158}/setup.py +0 -0
  11. {voly-0.0.157 → voly-0.0.158}/src/voly/__init__.py +0 -0
  12. {voly-0.0.157 → voly-0.0.158}/src/voly/client.py +0 -0
  13. {voly-0.0.157 → voly-0.0.158}/src/voly/core/__init__.py +0 -0
  14. {voly-0.0.157 → voly-0.0.158}/src/voly/core/charts.py +0 -0
  15. {voly-0.0.157 → voly-0.0.158}/src/voly/core/fit.py +0 -0
  16. {voly-0.0.157 → voly-0.0.158}/src/voly/core/interpolate.py +0 -0
  17. {voly-0.0.157 → voly-0.0.158}/src/voly/core/rnd.py +0 -0
  18. {voly-0.0.157 → voly-0.0.158}/src/voly/exceptions.py +0 -0
  19. {voly-0.0.157 → voly-0.0.158}/src/voly/models.py +0 -0
  20. {voly-0.0.157 → voly-0.0.158}/src/voly/utils/__init__.py +0 -0
  21. {voly-0.0.157 → voly-0.0.158}/src/voly/utils/density.py +0 -0
  22. {voly-0.0.157 → voly-0.0.158}/src/voly/utils/logger.py +0 -0
  23. {voly-0.0.157 → voly-0.0.158}/src/voly.egg-info/SOURCES.txt +0 -0
  24. {voly-0.0.157 → voly-0.0.158}/src/voly.egg-info/dependency_links.txt +0 -0
  25. {voly-0.0.157 → voly-0.0.158}/src/voly.egg-info/requires.txt +0 -0
  26. {voly-0.0.157 → voly-0.0.158}/src/voly.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voly
3
- Version: 0.0.157
3
+ Version: 0.0.158
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "voly"
7
- version = "0.0.157"
7
+ version = "0.0.158"
8
8
  description = "Options & volatility research package"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -60,7 +60,7 @@ line_length = 100
60
60
  multi_line_output = 3
61
61
 
62
62
  [tool.mypy]
63
- python_version = "0.0.157"
63
+ python_version = "0.0.158"
64
64
  warn_return_any = true
65
65
  warn_unused_configs = true
66
66
  disallow_untyped_defs = true
@@ -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',
@@ -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
@@ -251,7 +251,6 @@ def iv(option_price: float, s: float, K: float, r: float, t: float,
251
251
  K=K,
252
252
  t=t,
253
253
  r=r,
254
- q=0.0, # Assume zero dividend yield
255
254
  flag=flag
256
255
  )
257
256
  return iv_value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: voly
3
- Version: 0.0.157
3
+ Version: 0.0.158
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes