Skip to content

Commit 497b765

Browse files
TexasCodingclaude
andcommitted
feat(orderbook): add cleanup method for consistent resource management
- Adds cleanup() method to OrderBook class following the same pattern as OrderManager and PositionManager - Clears all orderbook data: bid/ask DataFrames, recent trades, callbacks, statistics, and metadata - Uses proper thread synchronization with orderbook_lock - Fixes missing cleanup method issue in examples/05_orderbook_analysis.py - Includes comprehensive docstring with usage examples - Maintains architectural consistency across all manager classes 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent e7ded77 commit 497b765

File tree

5 files changed

+220
-125
lines changed

5 files changed

+220
-125
lines changed

examples/04_realtime_data.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@
3333

3434
def display_current_prices(data_manager):
3535
"""Display current prices across all timeframes."""
36-
print(f"\n📊 Current Prices:")
36+
print("\n📊 Current Prices:")
3737

3838
current_price = data_manager.get_current_price()
3939
if current_price:
4040
print(f" Current Price: ${current_price:.2f}")
4141
else:
42-
print(f" Current Price: Not available")
42+
print(" Current Price: Not available")
4343

4444
# Get multi-timeframe data
4545
mtf_data = data_manager.get_mtf_data(bars=1) # Just latest bar from each timeframe
@@ -62,7 +62,7 @@ def display_memory_stats(data_manager):
6262
"""Display memory usage statistics."""
6363
try:
6464
stats = data_manager.get_memory_stats()
65-
print(f"\n💾 Memory Statistics:")
65+
print("\n💾 Memory Statistics:")
6666
print(f" Total Bars: {stats['total_bars']:,}")
6767
print(f" Ticks Processed: {stats['ticks_processed']:,}")
6868
print(f" Bars Cleaned: {stats['bars_cleaned']:,}")
@@ -71,7 +71,7 @@ def display_memory_stats(data_manager):
7171
# Show per-timeframe breakdown
7272
breakdown = stats.get("timeframe_breakdown", {})
7373
if breakdown:
74-
print(f" Timeframe Breakdown:")
74+
print(" Timeframe Breakdown:")
7575
for tf, count in breakdown.items():
7676
print(f" {tf}: {count:,} bars")
7777

@@ -83,7 +83,7 @@ def display_system_statistics(data_manager):
8383
"""Display comprehensive system statistics."""
8484
try:
8585
stats = data_manager.get_statistics()
86-
print(f"\n📈 System Statistics:")
86+
print("\n📈 System Statistics:")
8787
print(f" System Running: {stats['is_running']}")
8888
print(f" Instrument: {stats['instrument']}")
8989
print(f" Contract ID: {stats['contract_id']}")
@@ -94,7 +94,7 @@ def display_system_statistics(data_manager):
9494
# Show timeframe statistics
9595
tf_stats = stats.get("timeframes", {})
9696
if tf_stats:
97-
print(f" Timeframe Data:")
97+
print(" Timeframe Data:")
9898
for tf, tf_info in tf_stats.items():
9999
bars = tf_info.get("bars", 0)
100100
latest_price = tf_info.get("latest_price", 0)
@@ -107,7 +107,7 @@ def display_system_statistics(data_manager):
107107

108108
def setup_realtime_callbacks(data_manager):
109109
"""Setup callbacks for real-time data events."""
110-
print(f"\n🔔 Setting up real-time callbacks...")
110+
print("\n🔔 Setting up real-time callbacks...")
111111

112112
# Data update callback
113113
def on_data_update(data):
@@ -142,14 +142,14 @@ def on_connection_status(data):
142142
data_manager.add_callback("data_update", on_data_update)
143143
data_manager.add_callback("new_bar", on_new_bar)
144144
data_manager.add_callback("connection_status", on_connection_status)
145-
print(f" ✅ Callbacks registered successfully")
145+
print(" ✅ Callbacks registered successfully")
146146
except Exception as e:
147147
print(f" ❌ Callback setup error: {e}")
148148

149149

150150
def demonstrate_historical_analysis(data_manager):
151151
"""Demonstrate historical data analysis capabilities."""
152-
print(f"\n📚 Historical Data Analysis:")
152+
print("\n📚 Historical Data Analysis:")
153153

154154
# Get data for different timeframes
155155
timeframes_to_analyze = ["1min", "5min", "15min"]
@@ -203,8 +203,8 @@ def monitor_realtime_feed(data_manager, duration_seconds=60):
203203
price_updates = 0
204204
bar_updates = 0
205205

206-
print(f"Monitoring MNQ real-time data feed...")
207-
print(f"Press Ctrl+C to stop early")
206+
print("Monitoring MNQ real-time data feed...")
207+
print("Press Ctrl+C to stop early")
208208

209209
try:
210210
while time.time() - start_time < duration_seconds:
@@ -230,10 +230,10 @@ def monitor_realtime_feed(data_manager, duration_seconds=60):
230230
try:
231231
health = data_manager.health_check()
232232
if health.get("status") == "healthy":
233-
print(f" ✅ System Health: Good")
233+
print(" ✅ System Health: Good")
234234
else:
235235
issues = health.get("issues", [])
236-
print(f" ⚠️ System Health: Issues detected")
236+
print(" ⚠️ System Health: Issues detected")
237237
for issue in issues:
238238
print(f" • {issue}")
239239
except Exception as e:
@@ -251,9 +251,9 @@ def monitor_realtime_feed(data_manager, duration_seconds=60):
251251
bar_updates += 1
252252

253253
except KeyboardInterrupt:
254-
print(f"\n⏹️ Monitoring stopped by user")
254+
print("\n⏹️ Monitoring stopped by user")
255255

256-
print(f"\n📊 Monitoring Summary:")
256+
print("\n📊 Monitoring Summary:")
257257
print(f" Duration: {time.time() - start_time:.1f} seconds")
258258
print(f" Price Updates: {price_updates}")
259259
print(f" Bar Updates: {bar_updates}")
@@ -292,7 +292,7 @@ def main():
292292
realtime_client=realtime_client,
293293
timeframes=timeframes,
294294
)
295-
print(f"✅ Real-time data manager created for MNQ")
295+
print("✅ Real-time data manager created for MNQ")
296296
print(f" Timeframes: {', '.join(timeframes)}")
297297
except Exception as e:
298298
print(f"❌ Failed to create data manager: {e}")
@@ -416,7 +416,7 @@ def main():
416416

417417
try:
418418
stats = data_manager.get_statistics()
419-
print(f"\nFinal System State:")
419+
print("\nFinal System State:")
420420
print(f" Is Running: {stats['is_running']}")
421421
print(f" Total Timeframes: {len(stats.get('timeframes', {}))}")
422422
print(

examples/05_orderbook_analysis.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,14 @@ def display_best_prices(orderbook):
3636
"""Display current best bid/ask prices."""
3737
best_prices = orderbook.get_best_bid_ask()
3838

39-
print(f"📊 Best Bid/Ask:")
39+
print("📊 Best Bid/Ask:")
4040
if best_prices["bid"] and best_prices["ask"]:
4141
print(f" Bid: ${best_prices['bid']:.2f}")
4242
print(f" Ask: ${best_prices['ask']:.2f}")
4343
print(f" Spread: ${best_prices['spread']:.2f}")
4444
print(f" Mid: ${best_prices['mid']:.2f}")
4545
else:
46-
print(f" No bid/ask data available")
46+
print(" No bid/ask data available")
4747

4848

4949
def display_orderbook_levels(orderbook, levels=5):
@@ -86,15 +86,15 @@ def display_market_depth(orderbook):
8686
try:
8787
depth = orderbook.get_orderbook_depth(price_range=50.0) # 50 point range
8888

89-
print(f"\n🔍 Market Depth Analysis (±50 points):")
89+
print("\n🔍 Market Depth Analysis (±50 points):")
9090
print(
9191
f" Bid Volume: {depth['bid_volume']:,} contracts ({depth['bid_levels']} levels)"
9292
)
9393
print(
9494
f" Ask Volume: {depth['ask_volume']:,} contracts ({depth['ask_levels']} levels)"
9595
)
9696

97-
if "mid_price" in depth and depth["mid_price"]:
97+
if depth.get("mid_price"):
9898
print(f" Mid Price: ${depth['mid_price']:.2f}")
9999

100100
# Calculate and display imbalance
@@ -106,11 +106,11 @@ def display_market_depth(orderbook):
106106

107107
# Interpret imbalance
108108
if bid_ratio > 60:
109-
print(f" 📈 Strong buying pressure detected")
109+
print(" 📈 Strong buying pressure detected")
110110
elif ask_ratio > 60:
111-
print(f" 📉 Strong selling pressure detected")
111+
print(" 📉 Strong selling pressure detected")
112112
else:
113-
print(f" ⚖️ Balanced market")
113+
print(" ⚖️ Balanced market")
114114

115115
except Exception as e:
116116
print(f" ❌ Market depth error: {e}")
@@ -122,7 +122,7 @@ def display_trade_flow(orderbook):
122122
# Get trade summary for last 5 minutes
123123
trade_summary = orderbook.get_trade_flow_summary(minutes=5)
124124

125-
print(f"\n💹 Trade Flow Analysis (5 minutes):")
125+
print("\n💹 Trade Flow Analysis (5 minutes):")
126126
print(f" Total Volume: {trade_summary['total_volume']:,} contracts")
127127
print(f" Total Trades: {trade_summary['trade_count']}")
128128
print(
@@ -141,11 +141,11 @@ def display_trade_flow(orderbook):
141141

142142
# Interpret ratio
143143
if trade_summary["buy_sell_ratio"] > 1.5:
144-
print(f" 📈 Strong buying activity")
144+
print(" 📈 Strong buying activity")
145145
elif trade_summary["buy_sell_ratio"] < 0.67:
146-
print(f" 📉 Strong selling activity")
146+
print(" 📉 Strong selling activity")
147147
else:
148-
print(f" ⚖️ Balanced trading activity")
148+
print(" ⚖️ Balanced trading activity")
149149

150150
except Exception as e:
151151
print(f" ❌ Trade flow error: {e}")
@@ -156,7 +156,7 @@ def display_order_statistics(orderbook):
156156
try:
157157
order_stats = orderbook.get_order_type_statistics()
158158

159-
print(f"\n📊 Order Type Statistics:")
159+
print("\n📊 Order Type Statistics:")
160160
print(f" Type 1 (Ask Orders): {order_stats['type_1_count']:,}")
161161
print(f" Type 2 (Bid Orders): {order_stats['type_2_count']:,}")
162162
print(f" Type 5 (Trades): {order_stats['type_5_count']:,}")
@@ -208,23 +208,23 @@ def display_memory_stats(orderbook):
208208
try:
209209
stats = orderbook.get_memory_stats()
210210

211-
print(f"\n💾 Memory Statistics:")
211+
print("\n💾 Memory Statistics:")
212212
print(f" Total Trades: {stats['total_trades']:,}")
213213
print(f" Total Depth Entries: {stats['total_depth_entries']:,}")
214214
print(f" Bid Levels: {stats['bid_levels']:,}")
215215
print(f" Ask Levels: {stats['ask_levels']:,}")
216216
print(f" Memory Usage: {stats['memory_usage_mb']:.2f} MB")
217217

218218
if stats.get("cleanup_triggered", False):
219-
print(f" 🧹 Memory cleanup active")
219+
print(" 🧹 Memory cleanup active")
220220

221221
except Exception as e:
222222
print(f" ❌ Memory stats error: {e}")
223223

224224

225225
def setup_orderbook_callbacks(orderbook):
226226
"""Setup callbacks for orderbook events."""
227-
print(f"\n🔔 Setting up orderbook callbacks...")
227+
print("\n🔔 Setting up orderbook callbacks...")
228228

229229
# Price update callback
230230
def on_price_update(data):
@@ -257,7 +257,7 @@ def on_trade(data):
257257
orderbook.add_callback("price_update", on_price_update)
258258
orderbook.add_callback("depth_change", on_depth_change)
259259
orderbook.add_callback("trade", on_trade)
260-
print(f" ✅ Orderbook callbacks registered")
260+
print(" ✅ Orderbook callbacks registered")
261261
except Exception as e:
262262
print(f" ❌ Callback setup error: {e}")
263263

@@ -270,8 +270,8 @@ def monitor_orderbook_feed(orderbook, duration_seconds=60):
270270
start_time = time.time()
271271
update_count = 0
272272

273-
print(f"Monitoring MNQ Level 2 orderbook...")
274-
print(f"Press Ctrl+C to stop early")
273+
print("Monitoring MNQ Level 2 orderbook...")
274+
print("Press Ctrl+C to stop early")
275275

276276
try:
277277
while time.time() - start_time < duration_seconds:
@@ -288,17 +288,17 @@ def monitor_orderbook_feed(orderbook, duration_seconds=60):
288288
display_market_depth(orderbook)
289289

290290
# Show recent activity
291-
print(f"\n📈 Recent Activity:")
291+
print("\n📈 Recent Activity:")
292292
display_recent_trades(orderbook, count=5)
293293

294294
update_count += 1
295295

296296
time.sleep(1)
297297

298298
except KeyboardInterrupt:
299-
print(f"\n⏹️ Monitoring stopped by user")
299+
print("\n⏹️ Monitoring stopped by user")
300300

301-
print(f"\n📊 Monitoring Summary:")
301+
print("\n📊 Monitoring Summary:")
302302
print(f" Duration: {time.time() - start_time:.1f} seconds")
303303
print(f" Update Cycles: {update_count}")
304304

@@ -329,7 +329,7 @@ def main():
329329
orderbook = create_orderbook(
330330
instrument="MNQ", realtime_client=realtime_client
331331
)
332-
print(f"✅ Level 2 orderbook created for MNQ")
332+
print("✅ Level 2 orderbook created for MNQ")
333333
except Exception as e:
334334
print(f"❌ Failed to create orderbook: {e}")
335335
return False
@@ -404,7 +404,7 @@ def main():
404404
snapshot = orderbook.get_orderbook_snapshot(levels=20)
405405
metadata = snapshot["metadata"]
406406

407-
print(f"📸 Orderbook Snapshot:")
407+
print("📸 Orderbook Snapshot:")
408408
print(f" Best Bid: ${metadata.get('best_bid', 0):.2f}")
409409
print(f" Best Ask: ${metadata.get('best_ask', 0):.2f}")
410410
print(f" Spread: ${metadata.get('spread', 0):.2f}")
@@ -419,7 +419,7 @@ def main():
419419
bids_df = snapshot["bids"]
420420
asks_df = snapshot["asks"]
421421

422-
print(f"\n📊 Data Structure (Polars DataFrames):")
422+
print("\n📊 Data Structure (Polars DataFrames):")
423423
print(f" Bids DataFrame: {len(bids_df)} rows")
424424
if not bids_df.is_empty():
425425
print(" Bid Columns:", bids_df.columns)

0 commit comments

Comments
 (0)