Merge branch 'develop' into timeframe

This commit is contained in:
Matthias
2020-06-15 06:35:55 +02:00
47 changed files with 893 additions and 367 deletions

View File

@@ -42,8 +42,12 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
rpc._rpc_trade_status()
freqtradebot.enter_positions()
trades = Trade.get_open_trades()
trades[0].open_order_id = None
freqtradebot.exit_positions(trades)
results = rpc._rpc_trade_status()
assert {
assert results[0] == {
'trade_id': 1,
'pair': 'ETH/BTC',
'base_currency': 'BTC',
@@ -54,11 +58,11 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'fee_open': ANY,
'fee_open_cost': ANY,
'fee_open_currency': ANY,
'fee_close': ANY,
'fee_close': fee.return_value,
'fee_close_cost': ANY,
'fee_close_currency': ANY,
'open_rate_requested': ANY,
'open_trade_price': ANY,
'open_trade_price': 0.0010025,
'close_rate_requested': ANY,
'sell_reason': ANY,
'sell_order_status': ANY,
@@ -81,28 +85,32 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'close_profit_abs': None,
'current_profit': -0.00408133,
'current_profit_pct': -0.41,
'stop_loss': 0.0,
'stop_loss_abs': 0.0,
'stop_loss_pct': None,
'stop_loss_ratio': None,
'current_profit_abs': -4.09e-06,
'stop_loss': 9.882e-06,
'stop_loss_abs': 9.882e-06,
'stop_loss_pct': -10.0,
'stop_loss_ratio': -0.1,
'stoploss_order_id': None,
'stoploss_last_update': None,
'stoploss_last_update_timestamp': None,
'initial_stop_loss': 0.0,
'initial_stop_loss_abs': 0.0,
'initial_stop_loss_pct': None,
'initial_stop_loss_ratio': None,
'open_order': '(limit buy rem=0.00000000)',
'stoploss_last_update': ANY,
'stoploss_last_update_timestamp': ANY,
'initial_stop_loss': 9.882e-06,
'initial_stop_loss_abs': 9.882e-06,
'initial_stop_loss_pct': -10.0,
'initial_stop_loss_ratio': -0.1,
'stoploss_current_dist': -1.1080000000000002e-06,
'stoploss_current_dist_ratio': -0.10081893,
'stoploss_entry_dist': -0.00010475,
'stoploss_entry_dist_ratio': -0.10448878,
'open_order': None,
'exchange': 'bittrex',
} == results[0]
}
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_sell_rate',
MagicMock(side_effect=DependencyException("Pair 'ETH/BTC' not available")))
results = rpc._rpc_trade_status()
assert isnan(results[0]['current_profit'])
assert isnan(results[0]['current_rate'])
assert {
assert results[0] == {
'trade_id': 1,
'pair': 'ETH/BTC',
'base_currency': 'BTC',
@@ -113,7 +121,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'fee_open': ANY,
'fee_open_cost': ANY,
'fee_open_currency': ANY,
'fee_close': ANY,
'fee_close': fee.return_value,
'fee_close_cost': ANY,
'fee_close_currency': ANY,
'open_rate_requested': ANY,
@@ -140,20 +148,25 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'close_profit_abs': None,
'current_profit': ANY,
'current_profit_pct': ANY,
'stop_loss': 0.0,
'stop_loss_abs': 0.0,
'stop_loss_pct': None,
'stop_loss_ratio': None,
'current_profit_abs': ANY,
'stop_loss': 9.882e-06,
'stop_loss_abs': 9.882e-06,
'stop_loss_pct': -10.0,
'stop_loss_ratio': -0.1,
'stoploss_order_id': None,
'stoploss_last_update': None,
'stoploss_last_update_timestamp': None,
'initial_stop_loss': 0.0,
'initial_stop_loss_abs': 0.0,
'initial_stop_loss_pct': None,
'initial_stop_loss_ratio': None,
'open_order': '(limit buy rem=0.00000000)',
'stoploss_last_update': ANY,
'stoploss_last_update_timestamp': ANY,
'initial_stop_loss': 9.882e-06,
'initial_stop_loss_abs': 9.882e-06,
'initial_stop_loss_pct': -10.0,
'initial_stop_loss_ratio': -0.1,
'stoploss_current_dist': ANY,
'stoploss_current_dist_ratio': ANY,
'stoploss_entry_dist': -0.00010475,
'stoploss_entry_dist_ratio': -0.10448878,
'open_order': None,
'exchange': 'bittrex',
} == results[0]
}
def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
@@ -581,7 +594,7 @@ def test_rpc_stopbuy(mocker, default_conf) -> None:
assert freqtradebot.config['max_open_trades'] != 0
result = rpc._rpc_stopbuy()
assert {'status': 'No more buy will occur from now. Run /reload_conf to reset.'} == result
assert {'status': 'No more buy will occur from now. Run /reload_config to reset.'} == result
assert freqtradebot.config['max_open_trades'] == 0

View File

@@ -251,10 +251,10 @@ def test_api_cleanup(default_conf, mocker, caplog):
def test_api_reloadconf(botclient):
ftbot, client = botclient
rc = client_post(client, f"{BASE_URI}/reload_conf")
rc = client_post(client, f"{BASE_URI}/reload_config")
assert_response(rc)
assert rc.json == {'status': 'reloading config ...'}
assert ftbot.state == State.RELOAD_CONF
assert ftbot.state == State.RELOAD_CONFIG
def test_api_stopbuy(botclient):
@@ -263,7 +263,7 @@ def test_api_stopbuy(botclient):
rc = client_post(client, f"{BASE_URI}/stopbuy")
assert_response(rc)
assert rc.json == {'status': 'No more buy will occur from now. Run /reload_conf to reset.'}
assert rc.json == {'status': 'No more buy will occur from now. Run /reload_config to reset.'}
assert ftbot.config['max_open_trades'] == 0
@@ -326,6 +326,8 @@ def test_api_show_config(botclient, mocker):
assert rc.json['timeframe'] == '5m'
assert rc.json['state'] == 'running'
assert not rc.json['trailing_stop']
assert 'bid_strategy' in rc.json
assert 'ask_strategy' in rc.json
def test_api_daily(botclient, mocker, ticker, fee, markets):
@@ -429,9 +431,17 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, limit_buy_order, li
'profit_all_coin': 6.217e-05,
'profit_all_fiat': 0,
'profit_all_percent': 6.2,
'profit_all_percent_mean': 6.2,
'profit_all_ratio_mean': 0.06201058,
'profit_all_percent_sum': 6.2,
'profit_all_ratio_sum': 0.06201058,
'profit_closed_coin': 6.217e-05,
'profit_closed_fiat': 0,
'profit_closed_percent': 6.2,
'profit_closed_ratio_mean': 0.06201058,
'profit_closed_percent_mean': 6.2,
'profit_closed_ratio_sum': 0.06201058,
'profit_closed_percent_sum': 6.2,
'trade_count': 1,
'closed_trade_count': 1,
}
@@ -496,6 +506,10 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
assert rc.json == []
ftbot.enter_positions()
trades = Trade.get_open_trades()
trades[0].open_order_id = None
ftbot.exit_positions(trades)
rc = client_get(client, f"{BASE_URI}/status")
assert_response(rc)
assert len(rc.json) == 1
@@ -510,25 +524,30 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
'close_rate': None,
'current_profit': -0.00408133,
'current_profit_pct': -0.41,
'current_profit_abs': -4.09e-06,
'current_rate': 1.099e-05,
'open_date': ANY,
'open_date_hum': 'just now',
'open_timestamp': ANY,
'open_order': '(limit buy rem=0.00000000)',
'open_order': None,
'open_rate': 1.098e-05,
'pair': 'ETH/BTC',
'stake_amount': 0.001,
'stop_loss': 0.0,
'stop_loss_abs': 0.0,
'stop_loss_pct': None,
'stop_loss_ratio': None,
'stop_loss': 9.882e-06,
'stop_loss_abs': 9.882e-06,
'stop_loss_pct': -10.0,
'stop_loss_ratio': -0.1,
'stoploss_order_id': None,
'stoploss_last_update': None,
'stoploss_last_update_timestamp': None,
'initial_stop_loss': 0.0,
'initial_stop_loss_abs': 0.0,
'initial_stop_loss_pct': None,
'initial_stop_loss_ratio': None,
'stoploss_last_update': ANY,
'stoploss_last_update_timestamp': ANY,
'initial_stop_loss': 9.882e-06,
'initial_stop_loss_abs': 9.882e-06,
'initial_stop_loss_pct': -10.0,
'initial_stop_loss_ratio': -0.1,
'stoploss_current_dist': -1.1080000000000002e-06,
'stoploss_current_dist_ratio': -0.10081893,
'stoploss_entry_dist': -0.00010475,
'stoploss_entry_dist_ratio': -0.10448878,
'trade_id': 1,
'close_rate_requested': None,
'current_rate': 1.099e-05,
@@ -540,9 +559,9 @@ def test_api_status(botclient, mocker, ticker, fee, markets):
'fee_open_currency': None,
'open_date': ANY,
'is_open': True,
'max_rate': 0.0,
'min_rate': None,
'open_order_id': ANY,
'max_rate': 1.099e-05,
'min_rate': 1.098e-05,
'open_order_id': None,
'open_rate_requested': 1.098e-05,
'open_trade_price': 0.0010025,
'sell_reason': None,

View File

@@ -71,10 +71,11 @@ def test_init(default_conf, mocker, caplog) -> None:
assert start_polling.dispatcher.add_handler.call_count > 0
assert start_polling.start_polling.call_count == 1
message_str = "rpc.telegram is listening for following commands: [['status'], ['profit'], " \
"['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], " \
"['performance'], ['daily'], ['count'], ['reload_conf'], ['show_config'], " \
"['stopbuy'], ['whitelist'], ['blacklist'], ['edge'], ['help'], ['version']]"
message_str = ("rpc.telegram is listening for following commands: [['status'], ['profit'], "
"['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], "
"['performance'], ['daily'], ['count'], ['reload_config', 'reload_conf'], "
"['show_config', 'show_conf'], ['stopbuy'], ['whitelist'], ['blacklist'], "
"['edge'], ['help'], ['version']]")
assert log_has(message_str, caplog)
@@ -434,7 +435,8 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
assert msg_mock.call_count == 1
assert 'No closed trade' in msg_mock.call_args_list[-1][0][0]
assert '*ROI:* All trades' in msg_mock.call_args_list[-1][0][0]
assert '∙ `-0.00000500 BTC (-0.50%)`' in msg_mock.call_args_list[-1][0][0]
assert ('∙ `-0.00000500 BTC (-0.50%) (-0.5 \N{GREEK CAPITAL LETTER SIGMA}%)`'
in msg_mock.call_args_list[-1][0][0])
msg_mock.reset_mock()
# Update the ticker with a market going up
@@ -447,10 +449,12 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
telegram._profit(update=update, context=MagicMock())
assert msg_mock.call_count == 1
assert '*ROI:* Closed trades' in msg_mock.call_args_list[-1][0][0]
assert '∙ `0.00006217 BTC (6.20%)`' in msg_mock.call_args_list[-1][0][0]
assert ('∙ `0.00006217 BTC (6.20%) (6.2 \N{GREEK CAPITAL LETTER SIGMA}%)`'
in msg_mock.call_args_list[-1][0][0])
assert '∙ `0.933 USD`' in msg_mock.call_args_list[-1][0][0]
assert '*ROI:* All trades' in msg_mock.call_args_list[-1][0][0]
assert '∙ `0.00006217 BTC (6.20%)`' in msg_mock.call_args_list[-1][0][0]
assert ('∙ `0.00006217 BTC (6.20%) (6.2 \N{GREEK CAPITAL LETTER SIGMA}%)`'
in msg_mock.call_args_list[-1][0][0])
assert '∙ `0.933 USD`' in msg_mock.call_args_list[-1][0][0]
assert '*Best Performing:* `ETH/BTC: 6.20%`' in msg_mock.call_args_list[-1][0][0]
@@ -663,11 +667,11 @@ def test_stopbuy_handle(default_conf, update, mocker) -> None:
telegram._stopbuy(update=update, context=MagicMock())
assert freqtradebot.config['max_open_trades'] == 0
assert msg_mock.call_count == 1
assert 'No more buy will occur from now. Run /reload_conf to reset.' \
assert 'No more buy will occur from now. Run /reload_config to reset.' \
in msg_mock.call_args_list[0][0][0]
def test_reload_conf_handle(default_conf, update, mocker) -> None:
def test_reload_config_handle(default_conf, update, mocker) -> None:
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
@@ -680,8 +684,8 @@ def test_reload_conf_handle(default_conf, update, mocker) -> None:
freqtradebot.state = State.RUNNING
assert freqtradebot.state == State.RUNNING
telegram._reload_conf(update=update, context=MagicMock())
assert freqtradebot.state == State.RELOAD_CONF
telegram._reload_config(update=update, context=MagicMock())
assert freqtradebot.state == State.RELOAD_CONFIG
assert msg_mock.call_count == 1
assert 'reloading config' in msg_mock.call_args_list[0][0][0]
@@ -1013,9 +1017,8 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
msg_mock.reset_mock()
telegram._count(update=update, context=MagicMock())
msg = '<pre> current max total stake\n--------- ----- -------------\n' \
' 1 {} {}</pre>'\
.format(
msg = ('<pre> current max total stake\n--------- ----- -------------\n'
' 1 {} {}</pre>').format(
default_conf['max_open_trades'],
default_conf['stake_amount']
)
@@ -1222,7 +1225,7 @@ def test_send_msg_buy_notification(default_conf, mocker) -> None:
'open_date': arrow.utcnow().shift(hours=-1)
})
assert msg_mock.call_args[0][0] \
== '*Bittrex:* Buying ETH/BTC\n' \
== '\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC\n' \
'*Amount:* `1333.33333333`\n' \
'*Open Rate:* `0.00001099`\n' \
'*Current Rate:* `0.00001099`\n' \
@@ -1244,7 +1247,7 @@ def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None:
'pair': 'ETH/BTC',
})
assert msg_mock.call_args[0][0] \
== ('*Bittrex:* Cancelling Open Buy Order for ETH/BTC')
== ('\N{WARNING SIGN} *Bittrex:* Cancelling Open Buy Order for ETH/BTC')
def test_send_msg_sell_notification(default_conf, mocker) -> None:
@@ -1277,7 +1280,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
'close_date': arrow.utcnow(),
})
assert msg_mock.call_args[0][0] \
== ('*Binance:* Selling KEY/ETH\n'
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
'*Amount:* `1333.33333333`\n'
'*Open Rate:* `0.00007500`\n'
'*Current Rate:* `0.00003201`\n'
@@ -1305,7 +1308,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
'close_date': arrow.utcnow(),
})
assert msg_mock.call_args[0][0] \
== ('*Binance:* Selling KEY/ETH\n'
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
'*Amount:* `1333.33333333`\n'
'*Open Rate:* `0.00007500`\n'
'*Current Rate:* `0.00003201`\n'
@@ -1335,7 +1338,8 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
'reason': 'Cancelled on exchange'
})
assert msg_mock.call_args[0][0] \
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: Cancelled on exchange')
== ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH. '
'Reason: Cancelled on exchange')
msg_mock.reset_mock()
telegram.send_msg({
@@ -1345,7 +1349,7 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
'reason': 'timeout'
})
assert msg_mock.call_args[0][0] \
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout')
== ('\N{WARNING SIGN} *Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout')
# Reset singleton function to avoid random breaks
telegram._fiat_converter.convert_amount = old_convamount
@@ -1379,7 +1383,7 @@ def test_warning_notification(default_conf, mocker) -> None:
'type': RPCMessageType.WARNING_NOTIFICATION,
'status': 'message'
})
assert msg_mock.call_args[0][0] == '*Warning:* `message`'
assert msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Warning:* `message`'
def test_custom_notification(default_conf, mocker) -> None:
@@ -1437,12 +1441,11 @@ def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
'amount': 1333.3333333333335,
'open_date': arrow.utcnow().shift(hours=-1)
})
assert msg_mock.call_args[0][0] \
== '*Bittrex:* Buying ETH/BTC\n' \
'*Amount:* `1333.33333333`\n' \
'*Open Rate:* `0.00001099`\n' \
'*Current Rate:* `0.00001099`\n' \
'*Total:* `(0.001000 BTC)`'
assert msg_mock.call_args[0][0] == ('\N{LARGE BLUE CIRCLE} *Bittrex:* Buying ETH/BTC\n'
'*Amount:* `1333.33333333`\n'
'*Open Rate:* `0.00001099`\n'
'*Current Rate:* `0.00001099`\n'
'*Total:* `(0.001000 BTC)`')
def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
@@ -1473,15 +1476,37 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
'open_date': arrow.utcnow().shift(hours=-2, minutes=-35, seconds=-3),
'close_date': arrow.utcnow(),
})
assert msg_mock.call_args[0][0] \
== '*Binance:* Selling KEY/ETH\n' \
'*Amount:* `1333.33333333`\n' \
'*Open Rate:* `0.00007500`\n' \
'*Current Rate:* `0.00003201`\n' \
'*Close Rate:* `0.00003201`\n' \
'*Sell Reason:* `stop_loss`\n' \
'*Duration:* `2:35:03 (155.1 min)`\n' \
'*Profit:* `-57.41%`'
assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH\n'
'*Amount:* `1333.33333333`\n'
'*Open Rate:* `0.00007500`\n'
'*Current Rate:* `0.00003201`\n'
'*Close Rate:* `0.00003201`\n'
'*Sell Reason:* `stop_loss`\n'
'*Duration:* `2:35:03 (155.1 min)`\n'
'*Profit:* `-57.41%`')
@pytest.mark.parametrize('msg,expected', [
({'profit_percent': 20.1, 'sell_reason': 'roi'}, "\N{ROCKET}"),
({'profit_percent': 5.1, 'sell_reason': 'roi'}, "\N{ROCKET}"),
({'profit_percent': 2.56, 'sell_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
({'profit_percent': 1.0, 'sell_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
({'profit_percent': 0.0, 'sell_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
({'profit_percent': -5.0, 'sell_reason': 'stop_loss'}, "\N{WARNING SIGN}"),
({'profit_percent': -2.0, 'sell_reason': 'sell_signal'}, "\N{CROSS MARK}"),
])
def test__sell_emoji(default_conf, mocker, msg, expected):
del default_conf['fiat_display_currency']
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
assert telegram._get_sell_emoji(msg) == expected
def test__send_msg(default_conf, mocker) -> None: