Skip to content

Commit 27b1ee6

Browse files
TexasCodingclaude
andcommitted
fix(orderbook): comprehensive fixes for Level 2 orderbook functionality
Fixed critical issues with orderbook data processing and examples: ## Core Fixes - Fixed DataFrame update issue in realtime.py where new DataFrames weren't properly reassigned - Fixed contract ID matching by using instrument.id instead of symbol in TradingSuite - Added volume tracking to memory stats in trade processing - Added parameter acknowledgment for API compatibility ## Analytics Enhancements - Enhanced get_orderbook_depth to return total bid/ask volumes - Completely rewrote get_statistics method with comprehensive metrics: - Added proper volume calculations for bid/ask sides - Added trade statistics (buy/sell trades, avg trade size) - Added VWAP calculation from tracked numerator/denominator - Added session high/low tracking from trade history - Fixed mid price calculation fallback - Added market_depth_score calculation ## Example Fixes - Fixed examples to only use methods that actually exist - Corrected parameter names (time_window_minutes vs window_minutes) - Removed calls to non-existent methods: - get_order_flow_imbalance (replaced with get_cumulative_delta) - estimate_market_impact (replaced with get_orderbook_depth) - Fixed detect_order_clusters parameters - Added new comprehensive example (06_advanced_orderbook.py) ## Results All orderbook methods now work correctly with proper data: - Market imbalance and depth analysis - Volume profile with Point of Control - Iceberg and cluster detection - Trade flow and cumulative delta - Support/resistance levels - Comprehensive statistics with VWAP 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e980229 commit 27b1ee6

File tree

5 files changed

+622
-54
lines changed

5 files changed

+622
-54
lines changed

examples/05_orderbook_analysis.py

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -192,25 +192,39 @@ async def display_market_microstructure(orderbook: OrderBook) -> None:
192192
async def display_iceberg_detection(orderbook: OrderBook) -> None:
193193
"""Display potential iceberg orders."""
194194
# Use detect_iceberg_orders instead of detect_icebergs
195-
icebergs = await orderbook.detect_iceberg_orders()
195+
icebergs = await orderbook.detect_iceberg_orders(
196+
min_refreshes=5,
197+
volume_threshold=50,
198+
time_window_minutes=10,
199+
)
196200

197201
print("\n🧊 Iceberg Detection:", flush=True)
198202
if icebergs and "iceberg_levels" in icebergs:
199203
iceberg_list = icebergs["iceberg_levels"]
200-
for iceberg in iceberg_list[:3]: # Show top 3
201-
side = "BID" if iceberg["side"] == "bid" else "ASK"
202-
print(
203-
f" Potential {side} iceberg at ${iceberg['price']:,.2f}",
204-
flush=True,
205-
)
206-
print(f" - Visible: {iceberg.get('visible_size', 'N/A')}", flush=True)
207-
print(
208-
f" - Refill Count: {iceberg.get('refill_count', 'N/A')}", flush=True
209-
)
210-
print(
211-
f" - Total Volume: {iceberg.get('total_volume', 'N/A')}", flush=True
212-
)
213-
print(f" - Confidence: {iceberg.get('confidence', 0):.1%}", flush=True)
204+
if iceberg_list:
205+
for iceberg in iceberg_list[:3]: # Show top 3
206+
side = "BID" if iceberg["side"] == "bid" else "ASK"
207+
print(
208+
f" Potential {side} iceberg at ${iceberg['price']:,.2f}",
209+
flush=True,
210+
)
211+
print(
212+
f" - Avg Volume: {iceberg.get('avg_volume', 'N/A'):.1f}",
213+
flush=True,
214+
)
215+
print(
216+
f" - Refresh Count: {iceberg.get('refresh_count', 'N/A')}",
217+
flush=True,
218+
)
219+
print(
220+
f" - Replenishments: {iceberg.get('replenishment_count', 'N/A')}",
221+
flush=True,
222+
)
223+
print(
224+
f" - Confidence: {iceberg.get('confidence', 0):.1%}", flush=True
225+
)
226+
else:
227+
print(" No iceberg orders detected", flush=True)
214228
else:
215229
print(" No iceberg orders detected", flush=True)
216230

@@ -295,18 +309,24 @@ async def demonstrate_comprehensive_methods(orderbook: OrderBook) -> None:
295309
try:
296310
order_stats = await orderbook.get_order_type_statistics()
297311
if order_stats:
298-
print(
299-
f" Market Orders: {order_stats.get('market_orders', 0):,}", flush=True
312+
# The stats are tracked by DomType numbers
313+
total_events = sum(
314+
v for k, v in order_stats.items() if k.startswith("type_")
300315
)
301-
print(
302-
f" Limit Orders: {order_stats.get('limit_orders', 0):,}", flush=True
303-
)
304-
print(f" Stop Orders: {order_stats.get('stop_orders', 0):,}", flush=True)
305-
if order_stats.get("avg_order_size"):
306-
print(
307-
f" Avg Order Size: {order_stats['avg_order_size']:.1f}",
308-
flush=True,
309-
)
316+
if total_events > 0:
317+
print(f" Total Events: {total_events:,}", flush=True)
318+
# Show top event types
319+
top_types = sorted(
320+
[(k, v) for k, v in order_stats.items() if k.startswith("type_")],
321+
key=lambda x: x[1],
322+
reverse=True,
323+
)[:5]
324+
for type_key, count in top_types:
325+
if count > 0:
326+
type_num = type_key.replace("type_", "").replace("_count", "")
327+
print(f" Type {type_num}: {count:,} events", flush=True)
328+
else:
329+
print(" No order statistics available", flush=True)
310330
else:
311331
print(" No order statistics available", flush=True)
312332
except Exception as e:
@@ -412,19 +432,6 @@ async def main() -> bool:
412432
print(" - 30 seconds: Comprehensive method demonstrations", flush=True)
413433
print("\nPress Ctrl+C at any time to stop early.", flush=True)
414434

415-
# Ask for confirmation
416-
print("\n❓ Continue with the full demonstration? (y/N): ", end="", flush=True)
417-
try:
418-
response = await asyncio.get_event_loop().run_in_executor(
419-
None, lambda: input().strip().lower()
420-
)
421-
if response != "y":
422-
print("❌ Orderbook analysis cancelled", flush=True)
423-
return False
424-
except (EOFError, KeyboardInterrupt):
425-
print("\n❌ Orderbook analysis cancelled", flush=True)
426-
return False
427-
428435
try:
429436
# Initialize TradingSuite v3 with orderbook feature
430437
print("\n🔑 Initializing TradingSuite v3 with orderbook...", flush=True)
@@ -492,11 +499,14 @@ async def main() -> bool:
492499
# Memory stats
493500
memory_stats = await orderbook.get_memory_stats()
494501
print("\n💾 Memory Usage:", flush=True)
495-
print(f" Bid Entries: {memory_stats.get('bid_entries', 0):,}", flush=True)
496-
print(f" Ask Entries: {memory_stats.get('ask_entries', 0):,}", flush=True)
497-
print(f" Trades Stored: {memory_stats.get('trades_stored', 0):,}", flush=True)
502+
print(f" Bid Depth: {memory_stats.get('avg_bid_depth', 0):,}", flush=True)
503+
print(f" Ask Depth: {memory_stats.get('avg_ask_depth', 0):,}", flush=True)
504+
print(
505+
f" Trades Processed: {memory_stats.get('trades_processed', 0):,}",
506+
flush=True,
507+
)
498508
print(
499-
f" Memory Cleaned: {memory_stats.get('memory_cleanups', 0)} times",
509+
f" Total Volume: {memory_stats.get('total_volume', 0):,}",
500510
flush=True,
501511
)
502512

0 commit comments

Comments
 (0)