fix: handle 404 errors by checking portfolio for filled/closed positions
This commit is contained in:
+51
-10
@@ -53,6 +53,17 @@ class ExecutionManager:
|
|||||||
logger.error(f"Failed to place entry order: {e}")
|
logger.error(f"Failed to place entry order: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _is_ticker_in_portfolio(self, ticker: str) -> bool:
|
||||||
|
"""Helper to check if a ticker currently has an open position."""
|
||||||
|
try:
|
||||||
|
positions = self.client.get_all_open_positions()
|
||||||
|
for pos in positions:
|
||||||
|
if pos.get('ticker') == ticker:
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error checking portfolio: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
def monitor_and_bracket(self, params: Dict[str, Any]):
|
def monitor_and_bracket(self, params: Dict[str, Any]):
|
||||||
"""Polls the entry order and places SL/TP once filled."""
|
"""Polls the entry order and places SL/TP once filled."""
|
||||||
if not self.current_order_id:
|
if not self.current_order_id:
|
||||||
@@ -87,6 +98,15 @@ class ExecutionManager:
|
|||||||
logger.warning(f"Entry order was {status}. Aborting.")
|
logger.warning(f"Entry order was {status}. Aborting.")
|
||||||
return False
|
return False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
# Trading212 404s if an order is no longer active (filled or cancelled)
|
||||||
|
if "404" in str(e):
|
||||||
|
if self._is_ticker_in_portfolio(ticker):
|
||||||
|
self.is_in_position = True
|
||||||
|
logger.info(f"Order {self.current_order_id} disappeared but position detected. Assuming filled.")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
logger.warning(f"Order {self.current_order_id} disappeared and no position found. Assuming cancelled/rejected.")
|
||||||
|
return False
|
||||||
logger.error(f"Error checking order status: {e}")
|
logger.error(f"Error checking order status: {e}")
|
||||||
|
|
||||||
time.sleep(10) # Poll every 10 seconds
|
time.sleep(10) # Poll every 10 seconds
|
||||||
@@ -118,20 +138,41 @@ class ExecutionManager:
|
|||||||
if not self.is_in_position:
|
if not self.is_in_position:
|
||||||
return False, "", 0.0
|
return False, "", 0.0
|
||||||
|
|
||||||
|
ticker = self.params.get('ticker')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.tp_order_id:
|
if self.tp_order_id:
|
||||||
tp_info = self.client.get_order_status(self.tp_order_id)
|
try:
|
||||||
if tp_info.get('status') == "FILLED":
|
tp_info = self.client.get_order_status(self.tp_order_id)
|
||||||
fill_price = tp_info.get('filledPrice', tp_info.get('limitPrice', self.params.get('target_price')))
|
if tp_info.get('status') == "FILLED":
|
||||||
self.is_in_position = False
|
fill_price = tp_info.get('filledPrice', tp_info.get('limitPrice', self.params.get('target_price')))
|
||||||
return True, "TP Hit", float(fill_price)
|
self.is_in_position = False
|
||||||
|
return True, "TP Hit", float(fill_price)
|
||||||
|
except Exception as e:
|
||||||
|
if "404" in str(e):
|
||||||
|
if not self._is_ticker_in_portfolio(ticker):
|
||||||
|
self.is_in_position = False
|
||||||
|
logger.info(f"TP order {self.tp_order_id} disappeared and position closed. Assuming TP hit.")
|
||||||
|
return True, "TP Hit", float(self.params.get('target_price'))
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
if self.sl_order_id:
|
if self.sl_order_id:
|
||||||
sl_info = self.client.get_order_status(self.sl_order_id)
|
try:
|
||||||
if sl_info.get('status') == "FILLED":
|
sl_info = self.client.get_order_status(self.sl_order_id)
|
||||||
fill_price = sl_info.get('filledPrice', sl_info.get('stopPrice', self.params.get('stop_loss')))
|
if sl_info.get('status') == "FILLED":
|
||||||
self.is_in_position = False
|
fill_price = sl_info.get('filledPrice', sl_info.get('stopPrice', self.params.get('stop_loss')))
|
||||||
return True, "SL Hit", float(fill_price)
|
self.is_in_position = False
|
||||||
|
return True, "SL Hit", float(fill_price)
|
||||||
|
except Exception as e:
|
||||||
|
if "404" in str(e):
|
||||||
|
if not self._is_ticker_in_portfolio(ticker):
|
||||||
|
self.is_in_position = False
|
||||||
|
logger.info(f"SL order {self.sl_order_id} disappeared and position closed. Assuming SL hit.")
|
||||||
|
return True, "SL Hit", float(self.params.get('stop_loss'))
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error checking exit status: {e}")
|
logger.error(f"Error checking exit status: {e}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user