mirror of
https://github.com/freqtrade/freqtrade.git
synced 2026-01-20 14:00:38 +00:00
refactor: unify fetch_stoploss_order
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user