feat: add price to force-exit
This commit is contained in:
@@ -426,6 +426,7 @@ class ForceExitPayload(BaseModel):
|
|||||||
tradeid: str | int
|
tradeid: str | int
|
||||||
ordertype: OrderTypeValues | None = None
|
ordertype: OrderTypeValues | None = None
|
||||||
amount: float | None = None
|
amount: float | None = None
|
||||||
|
price: float | None = None
|
||||||
|
|
||||||
|
|
||||||
class BlacklistPayload(BaseModel):
|
class BlacklistPayload(BaseModel):
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ logger = logging.getLogger(__name__)
|
|||||||
# 2.42: Add /pair_history endpoint with live data
|
# 2.42: Add /pair_history endpoint with live data
|
||||||
# 2.43: Add /profit_all endpoint
|
# 2.43: Add /profit_all endpoint
|
||||||
# 2.44: Add candle_types parameter to download-data endpoint
|
# 2.44: Add candle_types parameter to download-data endpoint
|
||||||
API_VERSION = 2.44
|
# 2.45: Add price to forceexit endpoint
|
||||||
|
API_VERSION = 2.45
|
||||||
|
|
||||||
# Public API, requires no auth.
|
# Public API, requires no auth.
|
||||||
router_public = APIRouter()
|
router_public = APIRouter()
|
||||||
@@ -325,7 +326,9 @@ def force_entry(payload: ForceEnterPayload, rpc: RPC = Depends(get_rpc)):
|
|||||||
@router.post("/forcesell", response_model=ResultMsg, tags=["trading"])
|
@router.post("/forcesell", response_model=ResultMsg, tags=["trading"])
|
||||||
def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)):
|
def forceexit(payload: ForceExitPayload, rpc: RPC = Depends(get_rpc)):
|
||||||
ordertype = payload.ordertype.value if payload.ordertype else None
|
ordertype = payload.ordertype.value if payload.ordertype else None
|
||||||
return rpc._rpc_force_exit(str(payload.tradeid), ordertype, amount=payload.amount)
|
return rpc._rpc_force_exit(
|
||||||
|
str(payload.tradeid), ordertype, amount=payload.amount, price=payload.price
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.get("/blacklist", response_model=BlacklistResponse, tags=["info", "pairlist"])
|
@router.get("/blacklist", response_model=BlacklistResponse, tags=["info", "pairlist"])
|
||||||
|
|||||||
+20
-6
@@ -940,7 +940,11 @@ class RPC:
|
|||||||
return {"status": "Reloaded from orders from exchange"}
|
return {"status": "Reloaded from orders from exchange"}
|
||||||
|
|
||||||
def __exec_force_exit(
|
def __exec_force_exit(
|
||||||
self, trade: Trade, ordertype: str | None, amount: float | None = None
|
self,
|
||||||
|
trade: Trade,
|
||||||
|
ordertype: str | None,
|
||||||
|
amount: float | None = None,
|
||||||
|
price: float | None = None,
|
||||||
) -> bool:
|
) -> bool:
|
||||||
# Check if there is there are open orders
|
# Check if there is there are open orders
|
||||||
trade_entry_cancelation_registry = []
|
trade_entry_cancelation_registry = []
|
||||||
@@ -964,8 +968,13 @@ class RPC:
|
|||||||
# Order cancellation failed, so we can't exit.
|
# Order cancellation failed, so we can't exit.
|
||||||
return False
|
return False
|
||||||
# Get current rate and execute sell
|
# Get current rate and execute sell
|
||||||
current_rate = self._freqtrade.exchange.get_rate(
|
|
||||||
trade.pair, side="exit", is_short=trade.is_short, refresh=True
|
current_rate = (
|
||||||
|
self._freqtrade.exchange.get_rate(
|
||||||
|
trade.pair, side="exit", is_short=trade.is_short, refresh=True
|
||||||
|
)
|
||||||
|
if ordertype == "market" or price is None
|
||||||
|
else price
|
||||||
)
|
)
|
||||||
exit_check = ExitCheckTuple(exit_type=ExitType.FORCE_EXIT)
|
exit_check = ExitCheckTuple(exit_type=ExitType.FORCE_EXIT)
|
||||||
order_type = ordertype or self._freqtrade.strategy.order_types.get(
|
order_type = ordertype or self._freqtrade.strategy.order_types.get(
|
||||||
@@ -990,11 +999,16 @@ class RPC:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def _rpc_force_exit(
|
def _rpc_force_exit(
|
||||||
self, trade_id: str, ordertype: str | None = None, *, amount: float | None = None
|
self,
|
||||||
|
trade_id: str,
|
||||||
|
ordertype: str | None = None,
|
||||||
|
*,
|
||||||
|
amount: float | None = None,
|
||||||
|
price: float | None = None,
|
||||||
) -> dict[str, str]:
|
) -> dict[str, str]:
|
||||||
"""
|
"""
|
||||||
Handler for forceexit <id>.
|
Handler for forceexit <id>.
|
||||||
Sells the given trade at current price
|
exts the given trade. Uses current price if price is None.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if self._freqtrade.state == State.STOPPED:
|
if self._freqtrade.state == State.STOPPED:
|
||||||
@@ -1024,7 +1038,7 @@ class RPC:
|
|||||||
logger.warning("force_exit: Invalid argument received")
|
logger.warning("force_exit: Invalid argument received")
|
||||||
raise RPCException("invalid argument")
|
raise RPCException("invalid argument")
|
||||||
|
|
||||||
result = self.__exec_force_exit(trade, ordertype, amount)
|
result = self.__exec_force_exit(trade, ordertype, amount, price)
|
||||||
Trade.commit()
|
Trade.commit()
|
||||||
self._freqtrade.wallets.update()
|
self._freqtrade.wallets.update()
|
||||||
if not result:
|
if not result:
|
||||||
|
|||||||
Reference in New Issue
Block a user