Skip to content

Commit bac6219

Browse files
committed
feat: add price to force-exit
1 parent 0ed3bdc commit bac6219

File tree

3 files changed

+26
-8
lines changed

3 files changed

+26
-8
lines changed

freqtrade/rpc/api_server/api_schemas.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ class ForceExitPayload(BaseModel):
426426
tradeid: str | int
427427
ordertype: OrderTypeValues | None = None
428428
amount: float | None = None
429+
price: float | None = None
429430

430431

431432
class BlacklistPayload(BaseModel):

freqtrade/rpc/api_server/api_v1.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@
9292
# 2.42: Add /pair_history endpoint with live data
9393
# 2.43: Add /profit_all endpoint
9494
# 2.44: Add candle_types parameter to download-data endpoint
95-
API_VERSION = 2.44
95+
# 2.45: Add price to forceexit endpoint
96+
API_VERSION = 2.45
9697

9798
# Public API, requires no auth.
9899
router_public = APIRouter()
@@ -325,7 +326,9 @@ def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)):
325326
@router.post("/forcesell", response_model=ResultMsg, tags=["trading"])
326327
def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)):
327328
ordertype = payload.ordertype.value if payload.ordertype else None
328-
return rpc._rpc_force_exit(str(payload.tradeid), ordertype, amount=payload.amount)
329+
return rpc._rpc_force_exit(
330+
str(payload.tradeid), ordertype, amount=payload.amount, price=payload.price
331+
)
329332

330333

331334
@router.get("/blacklist", response_model=BlacklistResponse, tags=["info", "pairlist"])

freqtrade/rpc/rpc.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,11 @@ def _rpc_reload_trade_from_exchange(self, trade_id: int) -> dict[str, str]:
940940
return {"status": "Reloaded from orders from exchange"}
941941

942942
def __exec_force_exit(
943-
self, trade: Trade, ordertype: str | None, amount: float | None = None
943+
self,
944+
trade: Trade,
945+
ordertype: str | None,
946+
amount: float | None = None,
947+
price: float | None = None,
944948
) -> bool:
945949
# Check if there is there are open orders
946950
trade_entry_cancelation_registry = []
@@ -964,8 +968,13 @@ def __exec_force_exit(
964968
# Order cancellation failed, so we can't exit.
965969
return False
966970
# Get current rate and execute sell
967-
current_rate = self._freqtrade.exchange.get_rate(
968-
trade.pair, side="exit", is_short=trade.is_short, refresh=True
971+
972+
current_rate = (
973+
self._freqtrade.exchange.get_rate(
974+
trade.pair, side="exit", is_short=trade.is_short, refresh=True
975+
)
976+
if ordertype == "market" or price is None
977+
else price
969978
)
970979
exit_check = ExitCheckTuple(exit_type=ExitType.FORCE_EXIT)
971980
order_type = ordertype or self._freqtrade.strategy.order_types.get(
@@ -990,11 +999,16 @@ def __exec_force_exit(
990999
return False
9911000

9921001
def _rpc_force_exit(
993-
self, trade_id: str, ordertype: str | None = None, *, amount: float | None = None
1002+
self,
1003+
trade_id: str,
1004+
ordertype: str | None = None,
1005+
*,
1006+
amount: float | None = None,
1007+
price: float | None = None,
9941008
) -> dict[str, str]:
9951009
"""
9961010
Handler for forceexit <id>.
997-
Sells the given trade at current price
1011+
exts the given trade. Uses current price if price is None.
9981012
"""
9991013

10001014
if self._freqtrade.state == State.STOPPED:
@@ -1024,7 +1038,7 @@ def _rpc_force_exit(
10241038
logger.warning("force_exit: Invalid argument received")
10251039
raise RPCException("invalid argument")
10261040

1027-
result = self.__exec_force_exit(trade, ordertype, amount)
1041+
result = self.__exec_force_exit(trade, ordertype, amount, price)
10281042
Trade.commit()
10291043
self._freqtrade.wallets.update()
10301044
if not result:

0 commit comments

Comments
 (0)