Merge pull request #2796 from freqtrade/update_wallets_after_foresell

update wallets after forcesell
This commit is contained in:
hroff-1902 2020-01-23 00:10:47 +03:00 committed by GitHub
commit 82797e768f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 22 deletions

View File

@ -7,6 +7,7 @@ import traceback
from datetime import datetime from datetime import datetime
from math import isclose from math import isclose
from os import getpid from os import getpid
from threading import Lock
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
import arrow import arrow
@ -27,7 +28,6 @@ from freqtrade.state import State
from freqtrade.strategy.interface import IStrategy, SellType from freqtrade.strategy.interface import IStrategy, SellType
from freqtrade.wallets import Wallets from freqtrade.wallets import Wallets
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -92,6 +92,8 @@ class FreqtradeBot:
# the initial state of the bot. # the initial state of the bot.
# Keep this at the end of this initialization method. # Keep this at the end of this initialization method.
self.rpc: RPCManager = RPCManager(self) self.rpc: RPCManager = RPCManager(self)
# Protect sell-logic from forcesell and viceversa
self._sell_lock = Lock()
def cleanup(self) -> None: def cleanup(self) -> None:
""" """
@ -132,8 +134,12 @@ class FreqtradeBot:
self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist), self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist),
self.strategy.informative_pairs()) self.strategy.informative_pairs())
# First process current opened trades (positions) # Protect from collisions with forcesell.
self.exit_positions(trades) # Without this, freqtrade my try to recreate stoploss_on_exchange orders
# while selling is in process, since telegram messages arrive in an different thread.
with self._sell_lock:
# First process current opened trades (positions)
self.exit_positions(trades)
# Then looking for buy opportunities # Then looking for buy opportunities
if self.get_free_open_trades(): if self.get_free_open_trades():
@ -748,8 +754,8 @@ class FreqtradeBot:
Check and execute sell Check and execute sell
""" """
should_sell = self.strategy.should_sell( should_sell = self.strategy.should_sell(
trade, sell_rate, datetime.utcnow(), buy, sell, trade, sell_rate, datetime.utcnow(), buy, sell,
force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0 force_stoploss=self.edge.stoploss(trade.pair) if self.edge else 0
) )
if should_sell.sell_flag: if should_sell.sell_flag:

View File

@ -420,24 +420,27 @@ class RPC:
if self._freqtrade.state != State.RUNNING: if self._freqtrade.state != State.RUNNING:
raise RPCException('trader is not running') raise RPCException('trader is not running')
if trade_id == 'all': with self._freqtrade._sell_lock:
# Execute sell for all open orders if trade_id == 'all':
for trade in Trade.get_open_trades(): # Execute sell for all open orders
_exec_forcesell(trade) for trade in Trade.get_open_trades():
_exec_forcesell(trade)
Trade.session.flush()
self._freqtrade.wallets.update()
return {'result': 'Created sell orders for all open trades.'}
# Query for trade
trade = Trade.get_trades(
trade_filter=[Trade.id == trade_id, Trade.is_open.is_(True), ]
).first()
if not trade:
logger.warning('forcesell: Invalid argument received')
raise RPCException('invalid argument')
_exec_forcesell(trade)
Trade.session.flush() Trade.session.flush()
return {'result': 'Created sell orders for all open trades.'} self._freqtrade.wallets.update()
return {'result': f'Created sell order for trade {trade_id}.'}
# Query for trade
trade = Trade.get_trades(
trade_filter=[Trade.id == trade_id, Trade.is_open.is_(True), ]
).first()
if not trade:
logger.warning('forcesell: Invalid argument received')
raise RPCException('invalid argument')
_exec_forcesell(trade)
Trade.session.flush()
return {'result': f'Created sell order for trade {trade_id}.'}
def _rpc_forcebuy(self, pair: str, price: Optional[float]) -> Optional[Trade]: def _rpc_forcebuy(self, pair: str, price: Optional[float]) -> Optional[Trade]:
""" """