|
@@ -107,6 +107,7 @@ class ExternalEventMonitor:
|
|
|
|
|
|
# If no existing lifecycle, this is a position opening
|
|
# If no existing lifecycle, this is a position opening
|
|
if not existing_lc:
|
|
if not existing_lc:
|
|
|
|
+ logger.debug(f"🔍 Position analysis: {full_symbol} no existing lifecycle, current size: {current_size}")
|
|
if current_size > 1e-9: # Position exists on exchange
|
|
if current_size > 1e-9: # Position exists on exchange
|
|
return 'position_opened'
|
|
return 'position_opened'
|
|
else:
|
|
else:
|
|
@@ -116,6 +117,9 @@ class ExternalEventMonitor:
|
|
previous_size = existing_lc.get('current_position_size', 0)
|
|
previous_size = existing_lc.get('current_position_size', 0)
|
|
lc_position_side = existing_lc.get('position_side')
|
|
lc_position_side = existing_lc.get('position_side')
|
|
|
|
|
|
|
|
+ logger.debug(f"🔍 Position analysis: {full_symbol} {side_from_fill} {amount_from_fill}")
|
|
|
|
+ logger.debug(f" Lifecycle side: {lc_position_side}, previous size: {previous_size}, current size: {current_size}")
|
|
|
|
+
|
|
# Check if this is a closing trade (opposite side)
|
|
# Check if this is a closing trade (opposite side)
|
|
is_closing_trade = False
|
|
is_closing_trade = False
|
|
if lc_position_side == 'long' and side_from_fill.lower() == 'sell':
|
|
if lc_position_side == 'long' and side_from_fill.lower() == 'sell':
|
|
@@ -123,17 +127,26 @@ class ExternalEventMonitor:
|
|
elif lc_position_side == 'short' and side_from_fill.lower() == 'buy':
|
|
elif lc_position_side == 'short' and side_from_fill.lower() == 'buy':
|
|
is_closing_trade = True
|
|
is_closing_trade = True
|
|
|
|
|
|
|
|
+ logger.debug(f" Is closing trade: {is_closing_trade}")
|
|
|
|
+
|
|
if is_closing_trade:
|
|
if is_closing_trade:
|
|
if current_size < 1e-9: # Position is now closed
|
|
if current_size < 1e-9: # Position is now closed
|
|
|
|
+ logger.debug(f" → Position closed (current_size < 1e-9)")
|
|
return 'position_closed'
|
|
return 'position_closed'
|
|
elif current_size < previous_size - 1e-9: # Position reduced but not closed
|
|
elif current_size < previous_size - 1e-9: # Position reduced but not closed
|
|
|
|
+ logger.debug(f" → Position decreased (current_size {current_size} < previous_size - 1e-9 {previous_size - 1e-9})")
|
|
return 'position_decreased'
|
|
return 'position_decreased'
|
|
else:
|
|
else:
|
|
# Same side trade - position increase
|
|
# Same side trade - position increase
|
|
|
|
+ logger.debug(f" Same side trade check: current_size {current_size} > previous_size + 1e-9 {previous_size + 1e-9}?")
|
|
if current_size > previous_size + 1e-9:
|
|
if current_size > previous_size + 1e-9:
|
|
|
|
+ logger.debug(f" → Position increased")
|
|
return 'position_increased'
|
|
return 'position_increased'
|
|
|
|
+ else:
|
|
|
|
+ logger.debug(f" → Size check failed, not enough increase")
|
|
|
|
|
|
# Default fallback
|
|
# Default fallback
|
|
|
|
+ logger.debug(f" → Fallback to external_unmatched")
|
|
return 'external_unmatched'
|
|
return 'external_unmatched'
|
|
|
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
@@ -581,6 +594,35 @@ class ExternalEventMonitor:
|
|
|
|
|
|
logger.info(f"🔍 External fill analysis: {full_symbol} {side_from_fill} {amount_from_fill} -> {action_type}")
|
|
logger.info(f"🔍 External fill analysis: {full_symbol} {side_from_fill} {amount_from_fill} -> {action_type}")
|
|
|
|
|
|
|
|
+ # Additional debug logging for position changes
|
|
|
|
+ if existing_lc:
|
|
|
|
+ previous_size = existing_lc.get('current_position_size', 0)
|
|
|
|
+ current_positions = self.trading_engine.get_positions() or []
|
|
|
|
+ current_size = 0
|
|
|
|
+ for pos in current_positions:
|
|
|
|
+ if pos.get('symbol') == full_symbol:
|
|
|
|
+ current_size = abs(float(pos.get('contracts', 0)))
|
|
|
|
+ break
|
|
|
|
+ logger.info(f"📊 Position size change: {previous_size} -> {current_size} (diff: {current_size - previous_size})")
|
|
|
|
+ logger.info(f"🎯 Expected change based on fill: {'+' if side_from_fill.lower() == 'buy' else '-'}{amount_from_fill}")
|
|
|
|
+
|
|
|
|
+ # Check if this might be a position decrease that was misclassified
|
|
|
|
+ if (action_type == 'external_unmatched' and
|
|
|
|
+ existing_lc.get('position_side') == 'long' and
|
|
|
|
+ side_from_fill.lower() == 'sell' and
|
|
|
|
+ current_size < previous_size):
|
|
|
|
+ logger.warning(f"⚠️ Potential misclassification: {full_symbol} {side_from_fill} looks like position decrease but classified as external_unmatched")
|
|
|
|
+ # Force re-check with proper parameters
|
|
|
|
+ action_type = 'position_decreased'
|
|
|
|
+ logger.info(f"🔄 Corrected action_type to: {action_type}")
|
|
|
|
+ elif (action_type == 'external_unmatched' and
|
|
|
|
+ existing_lc.get('position_side') == 'long' and
|
|
|
|
+ side_from_fill.lower() == 'buy' and
|
|
|
|
+ current_size > previous_size):
|
|
|
|
+ logger.warning(f"⚠️ Potential misclassification: {full_symbol} {side_from_fill} looks like position increase but classified as external_unmatched")
|
|
|
|
+ action_type = 'position_increased'
|
|
|
|
+ logger.info(f"🔄 Corrected action_type to: {action_type}")
|
|
|
|
+
|
|
if action_type == 'position_opened':
|
|
if action_type == 'position_opened':
|
|
# Create new lifecycle for external position
|
|
# Create new lifecycle for external position
|
|
lifecycle_id = stats.create_trade_lifecycle(
|
|
lifecycle_id = stats.create_trade_lifecycle(
|