Add threading lock object for /forcesell

Protects against stoploss_on_exchange order recreation
in case of /forcesell (it's a timing issue, so may or may not happen).
This commit is contained in:
Matthias 2020-01-22 20:50:09 +01:00
parent 58ceda4b90
commit aad10ceee3
2 changed files with 30 additions and 23 deletions

View File

@ -7,6 +7,7 @@ import traceback
from datetime import datetime
from math import isclose
from os import getpid
from threading import Lock
from typing import Any, Dict, List, Optional, Tuple
import arrow
@ -27,7 +28,6 @@ from freqtrade.state import State
from freqtrade.strategy.interface import IStrategy, SellType
from freqtrade.wallets import Wallets
logger = logging.getLogger(__name__)
@ -92,6 +92,8 @@ class FreqtradeBot:
# the initial state of the bot.
# Keep this at the end of this initialization method.
self.rpc: RPCManager = RPCManager(self)
# Protect sell-logic from forcesell and viceversa
self._sell_lock = Lock()
def cleanup(self) -> None:
"""
@ -132,6 +134,10 @@ class FreqtradeBot:
self.dataprovider.refresh(self._create_pair_whitelist(self.active_pair_whitelist),
self.strategy.informative_pairs())
# Protect from collisions with forcesell.
# 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)

View File

@ -420,6 +420,7 @@ class RPC:
if self._freqtrade.state != State.RUNNING:
raise RPCException('trader is not running')
with self._freqtrade._sell_lock:
if trade_id == 'all':
# Execute sell for all open orders
for trade in Trade.get_open_trades():