Refactoring _process/throttle to let throttle handle cases when we need an extra sleep time due to poor exchange conditions
This commit is contained in:
parent
5f86c389b0
commit
10ef0874b5
@ -92,14 +92,17 @@ def process_maybe_execute_sell(trade, interval):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _process(interval: int, nb_assets: Optional[int] = 0) -> bool:
|
def _process(interval: int, nb_assets: Optional[int] = 0) -> (bool, int):
|
||||||
"""
|
"""
|
||||||
Queries the persistence layer for open trades and handles them,
|
Queries the persistence layer for open trades and handles them,
|
||||||
otherwise a new trade is created.
|
otherwise a new trade is created.
|
||||||
:param: nb_assets: the maximum number of pairs to be traded at the same time
|
:param: nb_assets: the maximum number of pairs to be traded at the same time
|
||||||
:return: True if one or more trades has been created or closed, False otherwise
|
:return: a pair, the first value is True if one or more trades has been created
|
||||||
|
or closed, False otherwise, the second argument is a requested sleep time in
|
||||||
|
seconds to be used when exchange is having problems
|
||||||
"""
|
"""
|
||||||
state_changed = False
|
state_changed = False
|
||||||
|
extra_time = 0
|
||||||
try:
|
try:
|
||||||
# Refresh whitelist based on wallet maintenance
|
# Refresh whitelist based on wallet maintenance
|
||||||
sanitized_list = refresh_whitelist(
|
sanitized_list = refresh_whitelist(
|
||||||
@ -130,7 +133,7 @@ def _process(interval: int, nb_assets: Optional[int] = 0) -> bool:
|
|||||||
'Got %s in _process(), retrying in 30 seconds...',
|
'Got %s in _process(), retrying in 30 seconds...',
|
||||||
error
|
error
|
||||||
)
|
)
|
||||||
time.sleep(30)
|
extra_time = 30
|
||||||
except OperationalException:
|
except OperationalException:
|
||||||
rpc.send_msg('*Status:* Got OperationalException:\n```\n{traceback}```{hint}'.format(
|
rpc.send_msg('*Status:* Got OperationalException:\n```\n{traceback}```{hint}'.format(
|
||||||
traceback=traceback.format_exc(),
|
traceback=traceback.format_exc(),
|
||||||
@ -138,7 +141,7 @@ def _process(interval: int, nb_assets: Optional[int] = 0) -> bool:
|
|||||||
))
|
))
|
||||||
logger.exception('Got OperationalException. Stopping trader ...')
|
logger.exception('Got OperationalException. Stopping trader ...')
|
||||||
update_state(State.STOPPED)
|
update_state(State.STOPPED)
|
||||||
return state_changed
|
return state_changed, extra_time
|
||||||
|
|
||||||
|
|
||||||
# FIX: 20180110, why is cancel.order unconditionally here, whereas
|
# FIX: 20180110, why is cancel.order unconditionally here, whereas
|
||||||
|
@ -115,9 +115,9 @@ def throttle(func: Callable[..., Any], min_secs: float, *args, **kwargs) -> Any:
|
|||||||
:return: Any
|
:return: Any
|
||||||
"""
|
"""
|
||||||
start = time.time()
|
start = time.time()
|
||||||
result = func(*args, **kwargs)
|
(result, extra_time) = func(*args, **kwargs)
|
||||||
end = time.time()
|
end = time.time()
|
||||||
duration = max(min_secs - (end - start), 0.0)
|
duration = max(max(min_secs - (end - start), 0.0), extra_time)
|
||||||
logger.debug('Throttling %s for %.2f seconds', func.__name__, duration)
|
logger.debug('Throttling %s for %.2f seconds', func.__name__, duration)
|
||||||
time.sleep(duration)
|
time.sleep(duration)
|
||||||
return result
|
return result
|
||||||
|
@ -91,7 +91,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order, health, m
|
|||||||
assert not trades
|
assert not trades
|
||||||
|
|
||||||
result = _process(interval=int(default_conf['ticker_interval']))
|
result = _process(interval=int(default_conf['ticker_interval']))
|
||||||
assert result is True
|
assert result == (True, 0)
|
||||||
|
|
||||||
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||||
assert len(trades) == 1
|
assert len(trades) == 1
|
||||||
@ -117,7 +117,7 @@ def test_process_exchange_failures(default_conf, ticker, health, mocker):
|
|||||||
buy=MagicMock(side_effect=requests.exceptions.RequestException))
|
buy=MagicMock(side_effect=requests.exceptions.RequestException))
|
||||||
init(default_conf, create_engine('sqlite://'))
|
init(default_conf, create_engine('sqlite://'))
|
||||||
result = _process(interval=int(default_conf['ticker_interval']))
|
result = _process(interval=int(default_conf['ticker_interval']))
|
||||||
assert result is False
|
assert result == (False, 30)
|
||||||
assert sleep_mock.has_calls()
|
assert sleep_mock.has_calls()
|
||||||
|
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ def test_process_operational_exception(default_conf, ticker, health, mocker):
|
|||||||
assert get_state() == State.RUNNING
|
assert get_state() == State.RUNNING
|
||||||
|
|
||||||
result = _process(interval=int(default_conf['ticker_interval']))
|
result = _process(interval=int(default_conf['ticker_interval']))
|
||||||
assert result is False
|
assert result == (False, 0)
|
||||||
assert get_state() == State.STOPPED
|
assert get_state() == State.STOPPED
|
||||||
assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]
|
assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]
|
||||||
|
|
||||||
@ -155,12 +155,12 @@ def test_process_trade_handling(default_conf, ticker, limit_buy_order, health, m
|
|||||||
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||||
assert not trades
|
assert not trades
|
||||||
result = _process(interval=int(default_conf['ticker_interval']))
|
result = _process(interval=int(default_conf['ticker_interval']))
|
||||||
assert result is True
|
assert result == (True, 0)
|
||||||
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
|
||||||
assert len(trades) == 1
|
assert len(trades) == 1
|
||||||
|
|
||||||
result = _process(interval=int(default_conf['ticker_interval']))
|
result = _process(interval=int(default_conf['ticker_interval']))
|
||||||
assert result is False
|
assert result == (False, 0)
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade(default_conf, ticker, limit_buy_order, mocker):
|
def test_create_trade(default_conf, ticker, limit_buy_order, mocker):
|
||||||
|
@ -16,7 +16,7 @@ from freqtrade.misc import (common_args_parser, file_dump_json, load_config,
|
|||||||
def test_throttle():
|
def test_throttle():
|
||||||
|
|
||||||
def func():
|
def func():
|
||||||
return 42
|
return (42, 1)
|
||||||
|
|
||||||
start = time.time()
|
start = time.time()
|
||||||
result = throttle(func, min_secs=0.1)
|
result = throttle(func, min_secs=0.1)
|
||||||
@ -32,7 +32,7 @@ def test_throttle():
|
|||||||
def test_throttle_with_assets():
|
def test_throttle_with_assets():
|
||||||
|
|
||||||
def func(nb_assets=-1):
|
def func(nb_assets=-1):
|
||||||
return nb_assets
|
return (nb_assets, 0)
|
||||||
|
|
||||||
result = throttle(func, min_secs=0.1, nb_assets=666)
|
result = throttle(func, min_secs=0.1, nb_assets=666)
|
||||||
assert result == 666
|
assert result == 666
|
||||||
|
Loading…
Reference in New Issue
Block a user