Accept parameters to forceexit

This commit is contained in:
Matthias 2022-08-02 19:53:10 +02:00
parent 78e129034e
commit 82aecc81f3
4 changed files with 27 additions and 8 deletions

View File

@ -330,6 +330,7 @@ class ForceEnterPayload(BaseModel):
class ForceExitPayload(BaseModel): class ForceExitPayload(BaseModel):
tradeid: str tradeid: str
ordertype: Optional[OrderTypeValues] ordertype: Optional[OrderTypeValues]
amount: Optional[float]
class BlacklistPayload(BaseModel): class BlacklistPayload(BaseModel):

View File

@ -161,7 +161,7 @@ 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(payload.tradeid, ordertype) return rpc._rpc_force_exit(payload.tradeid, ordertype, amount=payload.amount)
@router.get('/blacklist', response_model=BlacklistResponse, tags=['info', 'pairlist']) @router.get('/blacklist', response_model=BlacklistResponse, tags=['info', 'pairlist'])

View File

@ -660,12 +660,15 @@ class RPC:
return {'status': 'No more buy will occur from now. Run /reload_config to reset.'} return {'status': 'No more buy will occur from now. Run /reload_config to reset.'}
def _rpc_force_exit(self, trade_id: str, ordertype: Optional[str] = None) -> Dict[str, str]: def _rpc_force_exit(self, trade_id: str, ordertype: Optional[str] = None, *,
amount: Optional[float]) -> Dict[str, str]:
""" """
Handler for forceexit <id>. Handler for forceexit <id>.
Sells the given trade at current price Sells the given trade at current price
""" """
def _exec_force_exit(trade: Trade) -> None:
def _exec_force_exit(trade: Trade, ordertype: Optional[str],
_amount: Optional[float] = None) -> None:
# Check if there is there is an open order # Check if there is there is an open order
fully_canceled = False fully_canceled = False
if trade.open_order_id: if trade.open_order_id:
@ -686,10 +689,19 @@ class RPC:
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(
"force_exit", self._freqtrade.strategy.order_types["exit"]) "force_exit", self._freqtrade.strategy.order_types["exit"])
sub_amount: float = None
if _amount and _amount < trade.amount:
# Partial exit ...
min_exit_stake = self._freqtrade.exchange.get_min_pair_stake_amount(
trade.pair, current_rate, trade.stop_loss_pct)
remaining = (trade.amount - _amount) * current_rate
if remaining < min_exit_stake:
raise RPCException(f'Remaining amount of {remaining} would be too small.')
sub_amount = _amount
self._freqtrade.execute_trade_exit( self._freqtrade.execute_trade_exit(
trade, current_rate, exit_check, ordertype=order_type) trade, current_rate, exit_check, ordertype=order_type,
# ---- EOF def _exec_forcesell ---- sub_trade_amt=sub_amount)
if self._freqtrade.state != State.RUNNING: if self._freqtrade.state != State.RUNNING:
raise RPCException('trader is not running') raise RPCException('trader is not running')
@ -711,7 +723,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')
_exec_force_exit(trade) _exec_force_exit(trade, ordertype, amount)
Trade.commit() Trade.commit()
self._freqtrade.wallets.update() self._freqtrade.wallets.update()
return {'result': f'Created sell order for trade {trade_id}.'} return {'result': f'Created sell order for trade {trade_id}.'}

View File

@ -275,14 +275,20 @@ class FtRestClient():
} }
return self._post("forceenter", data=data) return self._post("forceenter", data=data)
def forceexit(self, tradeid): def forceexit(self, tradeid, ordertype=None, amount=None):
"""Force-exit a trade. """Force-exit a trade.
:param tradeid: Id of the trade (can be received via status command) :param tradeid: Id of the trade (can be received via status command)
:param ordertype: Order type to use (must be market or limit)
:param amount: Amount to sell. Full sell if not given
:return: json object :return: json object
""" """
return self._post("forceexit", data={"tradeid": tradeid}) return self._post("forceexit", data={
"tradeid": tradeid,
"ordertype": ordertype,
"amount": amount,
})
def strategies(self): def strategies(self):
"""Lists available strategies """Lists available strategies