refactor: unify fetch_stoploss_order

This commit is contained in:
Matthias
2025-12-16 20:43:02 +01:00
parent d4aee7e433
commit c8d74baaa1
4 changed files with 24 additions and 43 deletions

View File

@@ -17,7 +17,7 @@ from freqtrade.exchange.binance_public_data import (
download_archive_trades,
)
from freqtrade.exchange.common import retrier
from freqtrade.exchange.exchange_types import CcxtOrder, FtHas, Tickers
from freqtrade.exchange.exchange_types import FtHas, Tickers
from freqtrade.exchange.exchange_utils_timeframe import timeframe_to_msecs
from freqtrade.misc import deep_merge_dicts, json_load
from freqtrade.util import FtTTLCache
@@ -52,6 +52,7 @@ class Binance(Exchange):
"stoploss_order_types": {"limit": "stop", "market": "stop_market"},
"stoploss_blocks_assets": False, # Stoploss orders do not block assets
"stoploss_fetch_requires_stop_param": True,
"stoploss_algo_order_info_id": "actualOrderId",
"tickers_have_price": False,
"floor_leverage": True,
"fetch_orders_limit_minutes": 7 * 1440, # "fetch_orders" is limited to 7 days
@@ -146,28 +147,6 @@ class Binance(Exchange):
except ccxt.BaseError as e:
raise OperationalException(e) from e
def fetch_stoploss_order(
self, order_id: str, pair: str, params: dict | None = None
) -> CcxtOrder:
if self.trading_mode == TradingMode.FUTURES:
params = params or {}
params.update({"stop": True})
order = self.fetch_order(order_id, pair, params)
if self.trading_mode == TradingMode.FUTURES and order.get("status", "open") == "closed":
# Places a real order - which we need to fetch explicitly.
if new_orderid := order.get("info", {}).get("actualOrderId"):
order1 = self.fetch_order(order_id=new_orderid, pair=pair, params={})
order1["id_stop"] = order1["id"]
order1["id"] = order_id
order1["type"] = "stoploss"
order1["stopPrice"] = order.get("stopPrice")
order1["status_stop"] = "triggered"
return order1
return order
def get_historic_ohlcv(
self,
pair: str,

View File

@@ -1688,7 +1688,25 @@ class Exchange:
def fetch_stoploss_order(
self, order_id: str, pair: str, params: dict | None = None
) -> CcxtOrder:
return self.fetch_order(order_id, pair, params)
if self.get_option("stoploss_fetch_requires_stop_param"):
params = params or {}
params["stop"] = True
order = self.fetch_order(order_id, pair, params)
if (val := self.get_option("stoploss_algo_order_info_id")) and order.get(
"status", "open"
) == "closed":
if new_orderid := order.get("info", {}).get(val):
# Fetch real order, which was placed by the algo order.
order1 = self.fetch_order(order_id=new_orderid, pair=pair, params=None)
order1["id_stop"] = order1["id"]
order1["id"] = order_id
order1["type"] = "stoploss"
order1["stopPrice"] = order.get("stopPrice")
order1["status_stop"] = "triggered"
return order1
return order
def fetch_order_or_stoploss_order(
self, order_id: str, pair: str, stoploss_order: bool = False

View File

@@ -20,6 +20,7 @@ class FtHas(TypedDict, total=False):
stoploss_order_types: dict[str, str]
stoploss_blocks_assets: bool
stoploss_fetch_requires_stop_param: bool
stoploss_algo_order_info_id: str
# ohlcv
ohlcv_params: dict
ohlcv_candle_limit: int

View File

@@ -31,6 +31,7 @@ class Gate(Exchange):
"stop_price_param": "stopPrice",
"stop_price_prop": "stopPrice",
"stoploss_fetch_requires_stop_param": True,
"stoploss_algo_order_info_id": "fired_order_id",
"l2_limit_upper": 1000,
"marketOrderRequiresPrice": True,
"trades_has_history": False, # Endpoint would support this - but ccxt doesn't.
@@ -43,6 +44,7 @@ class Gate(Exchange):
"stop_price_type_field": "price_type",
"l2_limit_upper": 300,
"stoploss_blocks_assets": False,
"stoploss_algo_order_info_id": "trade_id",
"stop_price_type_value_mapping": {
PriceType.LAST: 0,
PriceType.MARK: 1,
@@ -133,22 +135,3 @@ class Gate(Exchange):
def get_order_id_conditional(self, order: CcxtOrder) -> str:
return safe_value_fallback2(order, order, "id_stop", "id")
def fetch_stoploss_order(
self, order_id: str, pair: str, params: dict | None = None
) -> CcxtOrder:
order = self.fetch_order(order_id=order_id, pair=pair, params={"stop": True})
if order.get("status", "open") == "closed":
# Places a real order - which we need to fetch explicitly.
val = "trade_id" if self.trading_mode == TradingMode.FUTURES else "fired_order_id"
if new_orderid := order.get("info", {}).get(val):
order1 = self.fetch_order(order_id=new_orderid, pair=pair, params=params)
order1["id_stop"] = order1["id"]
order1["id"] = order_id
order1["type"] = "stoploss"
order1["stopPrice"] = order.get("stopPrice")
order1["status_stop"] = "triggered"
return order1
return order