Skip to content

Commit 5c13483

Browse files
committed
fix(examples): improve join_orders example with better error handling and position cleanup
- Add graceful error handling for order cancellations that may fail due to fills - Implement automatic position cleanup to close any positions opened by filled orders - Fix Position model field references (use correct field names: size, type, contractId, averagePrice) - Add informative messages explaining why orders might not be cancellable - Ensure no positions are left open when the script completes
1 parent 27b1ee6 commit 5c13483

File tree

1 file changed

+65
-11
lines changed

1 file changed

+65
-11
lines changed

examples/16_join_orders.py

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,19 +134,73 @@ async def main() -> None:
134134
# Cancel orders to clean up
135135
if order_ids:
136136
print("\n4. Cancelling orders...")
137-
if join_bid_response and join_bid_response.success:
138-
cancel_result = await suite.orders.cancel_order(
137+
for order_id, order_type in [
138+
(
139139
join_bid_response.orderId
140-
)
141-
if cancel_result:
142-
print(f"✅ JoinBid order {join_bid_response.orderId} cancelled")
143-
144-
if join_ask_response and join_ask_response.success:
145-
cancel_result = await suite.orders.cancel_order(
140+
if join_bid_response and join_bid_response.success
141+
else None,
142+
"JoinBid",
143+
),
144+
(
146145
join_ask_response.orderId
147-
)
148-
if cancel_result:
149-
print(f"✅ JoinAsk order {join_ask_response.orderId} cancelled")
146+
if join_ask_response and join_ask_response.success
147+
else None,
148+
"JoinAsk",
149+
),
150+
]:
151+
if order_id:
152+
try:
153+
cancel_result = await suite.orders.cancel_order(order_id)
154+
if cancel_result:
155+
print(f"✅ {order_type} order {order_id} cancelled")
156+
except Exception as e:
157+
# Order might have been filled or already cancelled
158+
print(
159+
f"ℹ️ {order_type} order {order_id} could not be cancelled: {str(e).split(':')[-1].strip()}"
160+
)
161+
print(
162+
f" (Order may have been filled or already cancelled)"
163+
)
164+
165+
# Check for any open positions that need to be closed
166+
print("\n5. Checking for open positions...")
167+
await asyncio.sleep(1) # Allow time for position updates
168+
169+
positions = await suite.positions.get_all_positions()
170+
if positions:
171+
print(f"Found {len(positions)} open position(s)")
172+
for position in positions:
173+
if position.size != 0:
174+
# Determine if position is long or short based on type
175+
position_type = "LONG" if position.type == 1 else "SHORT"
176+
print(
177+
f" - {position.contractId}: {position_type} {position.size} contracts @ ${position.averagePrice:,.2f}"
178+
)
179+
180+
# Close the position with a market order
181+
# If LONG (type=1), we need to SELL (side=1) to close
182+
# If SHORT (type=2), we need to BUY (side=0) to close
183+
side = 1 if position.type == 1 else 0
184+
185+
print(f" Closing position with market order...")
186+
try:
187+
close_order = await suite.orders.place_market_order(
188+
contract_id=position.contractId,
189+
side=side,
190+
size=position.size,
191+
)
192+
if close_order and close_order.success:
193+
print(
194+
f" ✅ Position closed with order {close_order.orderId}"
195+
)
196+
else:
197+
print(
198+
f" ⚠️ Failed to close position: {close_order.errorMessage if close_order else 'Unknown error'}"
199+
)
200+
except Exception as e:
201+
print(f" ⚠️ Error closing position: {e}")
202+
else:
203+
print("✅ No open positions found")
150204

151205
except Exception as e:
152206
print(f"❌ Error: {e}")

0 commit comments

Comments
 (0)