|
@@ -927,6 +927,56 @@ class MarketMonitor:
|
|
|
|
|
|
# Original Fallback logic if still not processed
|
|
|
if not fill_processed_this_iteration:
|
|
|
+ # ---- START DIAGNOSTIC BLOCK ----
|
|
|
+ # Log details if this fill *should* have matched an open lifecycle but didn't.
|
|
|
+ # This condition checks if a position count recently changed, suggesting a closure.
|
|
|
+ # We access _update_cached_data's effect by checking self.last_known_positions vs current from cache.
|
|
|
+ # Note: This is an approximation. A more robust check might involve tracking position count changes more directly.
|
|
|
+
|
|
|
+ # Get current positions from cache (reflects state after _update_cached_data this cycle)
|
|
|
+ current_positions_from_cache_map = {
|
|
|
+ pos.get('symbol'): pos for pos in (self.cached_positions or [])
|
|
|
+ if pos.get('symbol') and abs(float(pos.get('contracts', 0))) > 1e-9
|
|
|
+ }
|
|
|
+ # Get DB's view of open positions
|
|
|
+ all_open_positions_in_db = stats.get_open_positions() # Fetches all with status='position_opened'
|
|
|
+ db_open_symbols = {pos_db.get('symbol') for pos_db in all_open_positions_in_db}
|
|
|
+
|
|
|
+ # Check if the fill's symbol *should* have been in the DB as open,
|
|
|
+ # but wasn't found by get_trade_by_symbol_and_status(full_symbol, 'position_opened')
|
|
|
+ if full_symbol in db_open_symbols:
|
|
|
+ # This is the critical contradiction: DB says it's open via get_open_positions,
|
|
|
+ # but get_trade_by_symbol_and_status(full_symbol, ...) failed.
|
|
|
+ # This should ideally not happen if queries are consistent.
|
|
|
+ logger.error(f"🚨 DIAGNOSTIC: Contradiction for {full_symbol}! get_open_positions() includes it, but get_trade_by_symbol_and_status('{full_symbol}', 'position_opened') failed to find it within _check_external_trades context for fill {trade_id}. This needs investigation into TradingStats symbol querying.")
|
|
|
+
|
|
|
+ # More general diagnostic: if a position disappeared from exchange but we couldn't match this fill
|
|
|
+ # This is a heuristic. A position count change was logged by _update_cached_data.
|
|
|
+ # If len(current_positions_from_cache_map) < len(self.last_known_positions_before_update_this_cycle)
|
|
|
+ # (hypothetical variable, self.last_known_positions is already updated)
|
|
|
+ # For now, we just log if get_trade_by_symbol_and_status failed.
|
|
|
+
|
|
|
+ potential_match_failure_logged = False
|
|
|
+ if not stats.get_trade_by_symbol_and_status(full_symbol, 'position_opened'): # Re-check to be sure
|
|
|
+ logger.warning(f"⚠️ DIAGNOSTIC for UNMATCHED FILL {trade_id} ({full_symbol}):")
|
|
|
+ logger.warning(f" Fill details: Side={side_from_fill}, Amount={amount_from_fill}, Price={price_from_fill}")
|
|
|
+ logger.warning(f" Attempted lookup with full_symbol='{full_symbol}' and status='position_opened' found NO active lifecycle.")
|
|
|
+ if all_open_positions_in_db:
|
|
|
+ logger.warning(f" However, DB currently has these 'position_opened' lifecycles (symbol - lifecycle_id):")
|
|
|
+ for db_pos in all_open_positions_in_db:
|
|
|
+ logger.warning(f" - '{db_pos.get('symbol')}' - ID: {db_pos.get('trade_lifecycle_id')}")
|
|
|
+ # Check for near matches (e.g. base token match)
|
|
|
+ base_token_fill = full_symbol.split('/')[0].split(':')[0]
|
|
|
+ near_matches = [db_s for db_s in db_open_symbols if base_token_fill in db_s]
|
|
|
+ if near_matches:
|
|
|
+ logger.warning(f" Possible near matches in DB for base token '{base_token_fill}': {near_matches}")
|
|
|
+ else:
|
|
|
+ logger.warning(f" No near matches found in DB for base token '{base_token_fill}'.")
|
|
|
+ else:
|
|
|
+ logger.warning(" DB has NO 'position_opened' lifecycles at all right now.")
|
|
|
+ potential_match_failure_logged = True
|
|
|
+ # ---- END DIAGNOSTIC BLOCK ----
|
|
|
+
|
|
|
linked_order_db_id = None
|
|
|
if exchange_order_id_from_fill:
|
|
|
order_in_db = stats.get_order_by_exchange_id(exchange_order_id_from_fill)
|