|
@@ -190,17 +190,38 @@ class SimplePositionTracker:
|
|
|
|
|
|
async def _handle_position_size_change(self, symbol: str, exchange_pos: Dict,
|
|
|
db_pos: Dict, stats, timestamp: datetime):
|
|
|
- """Handle position size changes."""
|
|
|
+ """Handle position size changes and position flips."""
|
|
|
try:
|
|
|
exchange_size = abs(float(exchange_pos.get('contracts', 0)))
|
|
|
db_size = db_pos.get('current_position_size', 0)
|
|
|
+ db_position_side = db_pos.get('position_side')
|
|
|
+
|
|
|
+ # Determine current exchange position side
|
|
|
+ ccxt_side = exchange_pos.get('side', '').lower()
|
|
|
+ if ccxt_side == 'long':
|
|
|
+ exchange_position_side = 'long'
|
|
|
+ elif ccxt_side == 'short':
|
|
|
+ exchange_position_side = 'short'
|
|
|
+ else:
|
|
|
+ # Fallback to contract sign
|
|
|
+ contracts = float(exchange_pos.get('contracts', 0))
|
|
|
+ exchange_position_side = 'long' if contracts > 0 else 'short'
|
|
|
+ logger.warning(f"⚠️ Using contract sign fallback for side detection: {symbol}")
|
|
|
+
|
|
|
+ # Check for POSITION FLIP (LONG ↔ SHORT)
|
|
|
+ if db_position_side != exchange_position_side:
|
|
|
+ logger.info(f"🔄 POSITION FLIP DETECTED: {symbol} {db_position_side.upper()} → {exchange_position_side.upper()}")
|
|
|
+
|
|
|
+ # Handle as: close old position + open new position
|
|
|
+ await self._handle_position_closed(symbol, db_pos, stats, timestamp)
|
|
|
+ await self._handle_position_opened(symbol, exchange_pos, stats, timestamp)
|
|
|
+ return
|
|
|
|
|
|
# Check if size actually changed (with small tolerance)
|
|
|
if abs(exchange_size - db_size) < 1e-6:
|
|
|
return # No meaningful change
|
|
|
|
|
|
lifecycle_id = db_pos['trade_lifecycle_id']
|
|
|
- position_side = db_pos.get('position_side')
|
|
|
entry_price = db_pos.get('entry_price', 0)
|
|
|
|
|
|
# Update position size using existing manager
|
|
@@ -216,7 +237,7 @@ class SimplePositionTracker:
|
|
|
|
|
|
# Send notification
|
|
|
await self._send_position_notification(change_type, symbol, {
|
|
|
- 'side': position_side,
|
|
|
+ 'side': db_position_side,
|
|
|
'old_size': db_size,
|
|
|
'new_size': exchange_size,
|
|
|
'size_diff': size_diff,
|