diff --git a/services/trading/engine.py b/services/trading/engine.py index 6f91f9a..fdcec74 100644 --- a/services/trading/engine.py +++ b/services/trading/engine.py @@ -32,6 +32,7 @@ except ImportError: from services.shared.config import TradingConfig from services.shared.redis_keys import ( QUEUE_BROKER, + TRADING_DEDUPE_PREFIX, queue_key, trading_dedupe_key, ) @@ -735,6 +736,9 @@ class TradingEngine: if self.redis is not None: broker_queue = queue_key(QUEUE_BROKER) await self.redis.rpush(broker_queue, json.dumps(order_job)) + # Set 24h cooldown to prevent immediate re-entry + cooldown_key = f"{TRADING_DEDUPE_PREFIX}:sell_cooldown:{ticker}" + await self.redis.set(cooldown_key, "1", ex=86400) logger.info( "Pushed sell order for %s (%d shares, ~$%.2f) to broker queue", ticker, sell_qty, estimated_proceeds, @@ -779,6 +783,16 @@ class TradingEngine: continue # --- Buy path --- + # Check sell cooldown — don't re-enter a position we just sold + if self.redis is not None: + cooldown_key = f"{TRADING_DEDUPE_PREFIX}:sell_cooldown:{ticker}" + if await self.redis.get(cooldown_key): + logger.info( + "Decision for %s: skip (reason=sell_cooldown)", + ticker, + ) + continue + # Check if we already hold this ticker — don't double up try: existing_pos = await self.pool.fetchrow( @@ -1852,6 +1866,9 @@ class TradingEngine: try: broker_queue = queue_key(QUEUE_BROKER) await self.redis.rpush(broker_queue, json.dumps(order_job)) + # Set 24h cooldown to prevent immediate re-entry + cooldown_key = f"{TRADING_DEDUPE_PREFIX}:sell_cooldown:{ticker}" + await self.redis.set(cooldown_key, "1", ex=86400) logger.info("Submitted sell order for %s (%d shares): %s", ticker, quantity, reason) except Exception: logger.exception("Failed to push sell order for %s", ticker)