diff --git a/config.json.example b/config.json.example index 37980447d..0f4271001 100644 --- a/config.json.example +++ b/config.json.example @@ -4,7 +4,7 @@ "stake_amount": 0.05, "fiat_display_currency": "USD", "dry_run": false, - "ticker_interval": 5, + "ticker_interval": "5", "minimal_roi": { "40": 0.0, "30": 0.01, diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index d41c78921..dc85bfedb 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -139,7 +139,7 @@ def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict: @cached(TTLCache(maxsize=100, ttl=30)) -def get_ticker_history(pair: str, tick_interval: Optional[int] = 5) -> List[Dict]: +def get_ticker_history(pair: str, tick_interval) -> List[Dict]: return _API.get_ticker_history(pair, tick_interval) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index e35f006d2..c97e4635f 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -223,7 +223,7 @@ CONF_SCHEMA = { 'type': 'object', 'properties': { 'max_open_trades': {'type': 'integer', 'minimum': 1}, - 'ticker_interval': {'type': 'integer', 'minimum': 1, 'maximum': 1440}, + 'ticker_interval': {'type': 'string', 'enum': ['1', '5', '30', '60', '1440']}, 'stake_currency': {'type': 'string', 'enum': ['BTC', 'ETH', 'USDT']}, 'stake_amount': {'type': 'number', 'minimum': 0.0005}, 'fiat_display_currency': {'type': 'string', 'enum': ['AUD', 'BRL', 'CAD', 'CHF', diff --git a/freqtrade/tests/conftest.py b/freqtrade/tests/conftest.py index 188cc0c68..37dc3e894 100644 --- a/freqtrade/tests/conftest.py +++ b/freqtrade/tests/conftest.py @@ -18,7 +18,7 @@ def default_conf(): "stake_currency": "BTC", "stake_amount": 0.001, "fiat_display_currency": "USD", - "ticker_interval": 5, + "ticker_interval": "5", "dry_run": True, "minimal_roi": { "40": 0.0, diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index c567ecc6f..2e77d6c90 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -102,7 +102,7 @@ def test_status_handle(default_conf, update, ticker, mocker): msg_mock.reset_mock() # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) # Trigger status while we have a fulfilled order for the open trade _status(bot=MagicMock(), update=update) @@ -138,7 +138,7 @@ def test_status_table_handle(default_conf, update, ticker, mocker): msg_mock.reset_mock() # Create some test data - create_trade(15.0, default_conf['ticker_interval']) + create_trade(15.0, int(default_conf['ticker_interval'])) _status_table(bot=MagicMock(), update=update) @@ -176,7 +176,7 @@ def test_profit_handle( msg_mock.reset_mock() # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade @@ -225,7 +225,7 @@ def test_forcesell_handle(default_conf, update, ticker, ticker_sell_up, mocker): init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -262,7 +262,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, ticker_sell_down, m init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) # Decrease the price and sell it mocker.patch.multiple('freqtrade.main.exchange', @@ -324,7 +324,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, mocker): # Create some test data for _ in range(4): - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) rpc_mock.reset_mock() update.message.text = '/forcesell all' @@ -389,7 +389,7 @@ def test_performance_handle( init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -427,7 +427,7 @@ def test_daily_handle( init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -480,7 +480,7 @@ def test_count_handle(default_conf, update, ticker, mocker): update_state(State.RUNNING) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) msg_mock.reset_mock() _count(bot=MagicMock(), update=update) diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index 691ec5f35..19ac8d1b5 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -64,7 +64,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order, health, m trades = Trade.query.filter(Trade.is_open.is_(True)).all() assert not trades - result = _process(interval=default_conf['ticker_interval']) + result = _process(interval=int(default_conf['ticker_interval'])) assert result is True trades = Trade.query.filter(Trade.is_open.is_(True)).all() @@ -90,7 +90,7 @@ def test_process_exchange_failures(default_conf, ticker, health, mocker): get_wallet_health=health, buy=MagicMock(side_effect=requests.exceptions.RequestException)) init(default_conf, create_engine('sqlite://')) - result = _process(interval=default_conf['ticker_interval']) + result = _process(interval=int(default_conf['ticker_interval'])) assert result is False assert sleep_mock.has_calls() @@ -108,7 +108,7 @@ def test_process_operational_exception(default_conf, ticker, health, mocker): init(default_conf, create_engine('sqlite://')) assert get_state() == State.RUNNING - result = _process(interval=default_conf['ticker_interval']) + result = _process(interval=int(default_conf['ticker_interval'])) assert result is False assert get_state() == State.STOPPED assert 'OperationalException' in msg_mock.call_args_list[-1][0][0] @@ -129,12 +129,12 @@ def test_process_trade_handling(default_conf, ticker, limit_buy_order, health, m trades = Trade.query.filter(Trade.is_open.is_(True)).all() assert not trades - result = _process(interval=default_conf['ticker_interval']) + result = _process(interval=int(default_conf['ticker_interval'])) assert result is True trades = Trade.query.filter(Trade.is_open.is_(True)).all() assert len(trades) == 1 - result = _process(interval=default_conf['ticker_interval']) + result = _process(interval=int(default_conf['ticker_interval'])) assert result is False @@ -150,7 +150,7 @@ def test_create_trade(default_conf, ticker, limit_buy_order, mocker): whitelist = copy.deepcopy(default_conf['exchange']['pair_whitelist']) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade is not None @@ -180,7 +180,7 @@ def test_create_trade_minimal_amount(default_conf, ticker, mocker): get_ticker=ticker) init(default_conf, create_engine('sqlite://')) min_stake_amount = 0.0005 - create_trade(min_stake_amount, default_conf['ticker_interval']) + create_trade(min_stake_amount, int(default_conf['ticker_interval'])) rate, amount = buy_mock.call_args[0][1], buy_mock.call_args[0][2] assert rate * amount >= min_stake_amount @@ -195,7 +195,7 @@ def test_create_trade_no_stake_amount(default_conf, ticker, mocker): buy=MagicMock(return_value='mocked_limit_buy'), get_balance=MagicMock(return_value=default_conf['stake_amount'] * 0.5)) with pytest.raises(DependencyException, match=r'.*stake amount.*'): - create_trade(default_conf['stake_amount'], default_conf['ticker_interval']) + create_trade(default_conf['stake_amount'], int(default_conf['ticker_interval'])) def test_create_trade_no_pairs(default_conf, ticker, mocker): @@ -211,7 +211,7 @@ def test_create_trade_no_pairs(default_conf, ticker, mocker): conf = copy.deepcopy(default_conf) conf['exchange']['pair_whitelist'] = [] mocker.patch.dict('freqtrade.main._CONF', conf) - create_trade(default_conf['stake_amount'], default_conf['ticker_interval']) + create_trade(default_conf['stake_amount'], int(default_conf['ticker_interval'])) def test_create_trade_no_pairs_after_blacklist(default_conf, ticker, mocker): @@ -228,7 +228,7 @@ def test_create_trade_no_pairs_after_blacklist(default_conf, ticker, mocker): conf['exchange']['pair_whitelist'] = ["BTC_ETH"] conf['exchange']['pair_blacklist'] = ["BTC_ETH"] mocker.patch.dict('freqtrade.main._CONF', conf) - create_trade(default_conf['stake_amount'], default_conf['ticker_interval']) + create_trade(default_conf['stake_amount'], int(default_conf['ticker_interval'])) def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker): @@ -248,7 +248,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker): ticker=MagicMock(return_value={'price_usd': 15000.0}), _cache_symbols=MagicMock(return_value={'BTC': 1})) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -256,7 +256,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker): trade.update(limit_buy_order) assert trade.is_open is True - assert handle_trade(trade, default_conf['ticker_interval']) is True + assert handle_trade(trade, int(default_conf['ticker_interval'])) is True assert trade.open_order_id == 'mocked_limit_sell' # Simulate fulfilled LIMIT_SELL order for trade @@ -281,7 +281,7 @@ def test_handle_trade_roi(default_conf, ticker, mocker, caplog): mocker.patch('freqtrade.main.min_roi_reached', return_value=True) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() trade.is_open = True @@ -292,11 +292,11 @@ def test_handle_trade_roi(default_conf, ticker, mocker, caplog): # executing # if ROI is reached we must sell mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t, i: False) - assert handle_trade(trade, interval=default_conf['ticker_interval']) + assert handle_trade(trade, interval=int(default_conf['ticker_interval'])) assert ('freqtrade', logging.DEBUG, 'Executing sell due to ROI ...') in caplog.record_tuples # if ROI is reached we must sell even if sell-signal is not signalled mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t, i: True) - assert handle_trade(trade, interval=default_conf['ticker_interval']) + assert handle_trade(trade, interval=int(default_conf['ticker_interval'])) assert ('freqtrade', logging.DEBUG, 'Executing sell due to ROI ...') in caplog.record_tuples @@ -314,17 +314,17 @@ def test_handle_trade_experimental(default_conf, ticker, mocker, caplog): mocker.patch('freqtrade.main.min_roi_reached', return_value=False) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() trade.is_open = True mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t, i: False) - value_returned = handle_trade(trade, default_conf['ticker_interval']) + value_returned = handle_trade(trade, int(default_conf['ticker_interval'])) assert ('freqtrade', logging.DEBUG, 'Checking sell_signal ...') in caplog.record_tuples assert value_returned is False mocker.patch('freqtrade.main.get_signal', side_effect=lambda s, t, i: True) - assert handle_trade(trade, default_conf['ticker_interval']) + assert handle_trade(trade, int(default_conf['ticker_interval'])) s = 'Executing sell due to sell signal ...' assert ('freqtrade', logging.DEBUG, s) in caplog.record_tuples @@ -340,7 +340,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mo # Create trade and sell it init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -350,7 +350,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mo assert trade.is_open is False with pytest.raises(ValueError, match=r'.*closed trade.*'): - handle_trade(trade, default_conf['ticker_interval']) + handle_trade(trade, int(default_conf['ticker_interval'])) def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, mocker): @@ -482,7 +482,7 @@ def test_execute_sell_up(default_conf, ticker, ticker_sell_up, mocker): init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -519,7 +519,7 @@ def test_execute_sell_down(default_conf, ticker, ticker_sell_down, mocker): init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -549,7 +549,7 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, ticker_sell_d init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -581,7 +581,7 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, ticker_sell_up, init(default_conf, create_engine('sqlite://')) # Create some test data - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() assert trade @@ -621,11 +621,11 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order, mocker): buy=MagicMock(return_value='mocked_limit_buy')) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() trade.update(limit_buy_order) - assert handle_trade(trade, default_conf['ticker_interval']) is True + assert handle_trade(trade, int(default_conf['ticker_interval'])) is True def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, mocker): @@ -648,11 +648,11 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order, mocker): buy=MagicMock(return_value='mocked_limit_buy')) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() trade.update(limit_buy_order) - assert handle_trade(trade, default_conf['ticker_interval']) is True + assert handle_trade(trade, int(default_conf['ticker_interval'])) is True def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, mocker): @@ -675,11 +675,11 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, mocker): buy=MagicMock(return_value='mocked_limit_buy')) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() trade.update(limit_buy_order) - assert handle_trade(trade, default_conf['ticker_interval']) is False + assert handle_trade(trade, int(default_conf['ticker_interval'])) is False def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, mocker): @@ -702,8 +702,8 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, mocker): buy=MagicMock(return_value='mocked_limit_buy')) init(default_conf, create_engine('sqlite://')) - create_trade(0.001, default_conf['ticker_interval']) + create_trade(0.001, int(default_conf['ticker_interval'])) trade = Trade.query.first() trade.update(limit_buy_order) - assert handle_trade(trade, default_conf['ticker_interval']) is True + assert handle_trade(trade, int(default_conf['ticker_interval'])) is True