@@ -269,6 +269,72 @@ def main():
269269
270270 setup_position_alerts (position_manager , contract_id )
271271
272+ # Open a small test position to demonstrate position management features
273+ print ("\n " + "=" * 50 )
274+ print ("📈 OPENING TEST POSITION" )
275+ print ("=" * 50 )
276+
277+ if order_manager :
278+ try :
279+ print ("Opening a small 1-contract LONG position for demonstration..." )
280+
281+ # Get current market price for order placement
282+ current_price = get_current_market_price (client )
283+
284+ # Place a small market buy order (1 contract)
285+ test_order = order_manager .place_order (
286+ contract_id = contract_id ,
287+ side = 0 , # Bid (buy)
288+ order_type = 2 , # Market order
289+ size = 1 , # Just 1 contract for safety
290+ custom_tag = f"test_pos_{ int (time .time ())} " ,
291+ )
292+
293+ if test_order .success :
294+ print (f"✅ Test position order placed: { test_order .orderId } " )
295+ print (" Waiting for order to fill and position to appear..." )
296+
297+ # Wait for order to fill and position to appear
298+ wait_time = 0
299+ max_wait = 30 # Maximum 30 seconds
300+
301+ while wait_time < max_wait :
302+ time .sleep (2 )
303+ wait_time += 2
304+
305+ # Check if we have a position now
306+ test_positions = position_manager .get_all_positions ()
307+ if test_positions :
308+ print (
309+ f"✅ Position opened successfully after { wait_time } s!"
310+ )
311+ for pos in test_positions :
312+ direction = "LONG" if pos .type == 1 else "SHORT"
313+ print (
314+ f" 📊 { pos .contractId } : { direction } { pos .size } contracts @ ${ pos .averagePrice :.2f} "
315+ )
316+ break
317+ else :
318+ print (f" ⏳ Waiting for position... ({ wait_time } s)" )
319+
320+ if wait_time >= max_wait :
321+ print (" ⚠️ Position didn't appear within 30 seconds" )
322+ print (
323+ " This may be normal if market is closed or order is still pending"
324+ )
325+
326+ else :
327+ print (f"❌ Test position order failed: { test_order .errorMessage } " )
328+ print (
329+ " Continuing with example using existing positions (if any)"
330+ )
331+
332+ except Exception as e :
333+ print (f"❌ Error opening test position: { e } " )
334+ print (" Continuing with example using existing positions (if any)" )
335+ else :
336+ print ("⚠️ No order manager available, skipping position opening" )
337+
272338 # If we have existing positions, demonstrate detailed analysis
273339 positions = position_manager .get_all_positions ()
274340 if positions :
@@ -476,8 +542,105 @@ def main():
476542 print (f"❌ Error: { e } " )
477543 return False
478544 finally :
479- # Cleanup
480- if "position_manager" in locals ():
545+ # Enhanced cleanup: Close all positions and cleanup
546+ if "position_manager" in locals () and "order_manager" in locals ():
547+ try :
548+ print ("\n 🧹 Enhanced cleanup: Closing all positions and orders..." )
549+
550+ # Get all open positions
551+ positions = position_manager .get_all_positions ()
552+ if positions :
553+ print (f" Found { len (positions )} open positions to close" )
554+
555+ for pos in positions :
556+ try :
557+ # Determine order side (opposite of position)
558+ if pos .type == 1 : # Long position
559+ side = 1 # Ask (sell)
560+ print (
561+ f" 📉 Closing LONG position: { pos .contractId } ({ pos .size } contracts)"
562+ )
563+ else : # Short position
564+ side = 0 # Bid (buy)
565+ print (
566+ f" 📈 Closing SHORT position: { pos .contractId } ({ pos .size } contracts)"
567+ )
568+
569+ # Place market order to close position
570+ if order_manager :
571+ close_order = order_manager .place_order (
572+ contract_id = pos .contractId ,
573+ side = side ,
574+ order_type = 2 , # Market order
575+ size = abs (pos .size ),
576+ custom_tag = f"close_pos_{ int (time .time ())} " ,
577+ )
578+
579+ if close_order .success :
580+ print (
581+ f" ✅ Close order placed: { close_order .orderId } "
582+ )
583+ else :
584+ print (
585+ f" ❌ Failed to place close order: { close_order .errorMessage } "
586+ )
587+
588+ except Exception as e :
589+ print (f" ❌ Error closing position { pos .contractId } : { e } " )
590+
591+ else :
592+ print (" ✅ No open positions to close" )
593+
594+ # Cancel any remaining open orders
595+ if order_manager :
596+ try :
597+ all_orders = order_manager .search_open_orders ()
598+ if all_orders :
599+ print (f" Found { len (all_orders )} open orders to cancel" )
600+ for order in all_orders :
601+ try :
602+ cancel_result = order_manager .cancel_order (order .id )
603+ if cancel_result :
604+ print (f" ✅ Cancelled order: { order .id } " )
605+ else :
606+ print (
607+ f" ❌ Failed to cancel order { order .id } "
608+ )
609+ except Exception as e :
610+ print (
611+ f" ❌ Error cancelling order { order .id } : { e } "
612+ )
613+ else :
614+ print (" ✅ No open orders to cancel" )
615+ except Exception as e :
616+ print (f" ⚠️ Error checking orders: { e } " )
617+
618+ # Wait a moment for orders to process
619+ time .sleep (2 )
620+
621+ # Final position check
622+ final_positions = position_manager .get_all_positions ()
623+ if final_positions :
624+ print (
625+ f" ⚠️ { len (final_positions )} positions still open after cleanup"
626+ )
627+ else :
628+ print (" ✅ All positions successfully closed" )
629+
630+ # Cleanup managers
631+ position_manager .cleanup ()
632+ print (" 🧹 Position manager cleaned up" )
633+
634+ except Exception as e :
635+ print (f" ⚠️ Enhanced cleanup error: { e } " )
636+ # Fallback to basic cleanup
637+ try :
638+ position_manager .cleanup ()
639+ print (" 🧹 Basic position manager cleanup completed" )
640+ except Exception as cleanup_e :
641+ print (f" ❌ Cleanup failed: { cleanup_e } " )
642+
643+ elif "position_manager" in locals ():
481644 try :
482645 position_manager .cleanup ()
483646 print ("🧹 Position manager cleaned up" )
0 commit comments