Accept parameters to forceexit
This commit is contained in:
parent
78e129034e
commit
82aecc81f3
@ -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):
|
||||||
|
@ -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'])
|
||||||
|
@ -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}.'}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user