merge leverage/margin
This commit is contained in:
@@ -18,7 +18,7 @@ from telegram.error import BadRequest, NetworkError, TelegramError
|
||||
from freqtrade import __version__
|
||||
from freqtrade.constants import CANCEL_REASON
|
||||
from freqtrade.edge import PairInfo
|
||||
from freqtrade.enums import RPCMessageType, RunMode, SellType, State
|
||||
from freqtrade.enums import ExitType, RPCMessageType, RunMode, SignalDirection, State
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.freqtradebot import FreqtradeBot
|
||||
from freqtrade.loggers import setup_logging
|
||||
@@ -27,8 +27,8 @@ from freqtrade.persistence.models import Order
|
||||
from freqtrade.rpc import RPC
|
||||
from freqtrade.rpc.rpc import RPCException
|
||||
from freqtrade.rpc.telegram import Telegram, authorized_only
|
||||
from tests.conftest import (create_mock_trades, get_patched_freqtradebot, log_has, log_has_re,
|
||||
patch_exchange, patch_get_signal, patch_whitelist)
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, create_mock_trades, get_patched_freqtradebot,
|
||||
log_has, log_has_re, patch_exchange, patch_get_signal, patch_whitelist)
|
||||
|
||||
|
||||
class DummyCls(Telegram):
|
||||
@@ -94,8 +94,10 @@ def test_telegram_init(default_conf, mocker, caplog) -> None:
|
||||
assert start_polling.start_polling.call_count == 1
|
||||
|
||||
message_str = ("rpc.telegram is listening for following commands: [['status'], ['profit'], "
|
||||
"['balance'], ['start'], ['stop'], ['forcesell'], ['forcebuy'], ['trades'], "
|
||||
"['delete'], ['performance'], ['buys'], ['sells'], ['mix_tags'], "
|
||||
"['balance'], ['start'], ['stop'], "
|
||||
"['forcesell', 'forceexit'], ['forcebuy', 'forcelong'], ['forceshort'], "
|
||||
"['trades'], ['delete'], ['performance'], "
|
||||
"['buys', 'entries'], ['sells', 'exits'], ['mix_tags'], "
|
||||
"['stats'], ['daily'], ['weekly'], ['monthly'], "
|
||||
"['count'], ['locks'], ['unlock', 'delete_locks'], "
|
||||
"['reload_config', 'reload_conf'], ['show_config', 'show_conf'], "
|
||||
@@ -191,18 +193,21 @@ def test_telegram_status(default_conf, update, mocker) -> None:
|
||||
'amount': 90.99181074,
|
||||
'stake_amount': 90.99181074,
|
||||
'buy_tag': None,
|
||||
'enter_tag': None,
|
||||
'close_profit_ratio': None,
|
||||
'profit': -0.0059,
|
||||
'profit_ratio': -0.0059,
|
||||
'initial_stop_loss_abs': 1.098e-05,
|
||||
'stop_loss_abs': 1.099e-05,
|
||||
'sell_order_status': None,
|
||||
'exit_order_status': None,
|
||||
'initial_stop_loss_ratio': -0.0005,
|
||||
'stoploss_current_dist': 1e-08,
|
||||
'stoploss_current_dist_ratio': -0.0002,
|
||||
'stop_loss_ratio': -0.0001,
|
||||
'open_order': '(limit buy rem=0.00000000)',
|
||||
'is_open': True,
|
||||
'is_short': False,
|
||||
'filled_entry_orders': [],
|
||||
'orders': []
|
||||
}]),
|
||||
)
|
||||
@@ -393,7 +398,8 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
fields = re.sub('[ ]+', ' ', line[2].strip()).split(' ')
|
||||
|
||||
assert int(fields[0]) == 1
|
||||
assert 'ETH/BTC' in fields[1]
|
||||
assert 'L' in fields[1]
|
||||
assert 'ETH/BTC' in fields[2]
|
||||
assert msg_mock.call_count == 1
|
||||
|
||||
|
||||
@@ -629,7 +635,7 @@ def test_weekly_wrong_input(default_conf, update, ticker, mocker) -> None:
|
||||
context.args = ["this week"]
|
||||
telegram._weekly(update=update, context=context)
|
||||
assert str('Weekly Profit over the last 8 weeks (starting from Monday)</b>:') \
|
||||
in msg_mock.call_args_list[0][0][0]
|
||||
in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_monthly_handle(default_conf, update, ticker, limit_buy_order, fee,
|
||||
@@ -821,8 +827,9 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
|
||||
assert '*Best Performing:* `ETH/BTC: 6.20%`' in msg_mock.call_args_list[-1][0][0]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_telegram_stats(default_conf, update, ticker, ticker_sell_up, fee,
|
||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
limit_buy_order, limit_sell_order, mocker, is_short) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@@ -838,11 +845,11 @@ def test_telegram_stats(default_conf, update, ticker, ticker_sell_up, fee,
|
||||
msg_mock.reset_mock()
|
||||
|
||||
# Create some test data
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short=is_short)
|
||||
|
||||
telegram._stats(update=update, context=MagicMock())
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'Sell Reason' in msg_mock.call_args_list[-1][0][0]
|
||||
assert 'Exit Reason' in msg_mock.call_args_list[-1][0][0]
|
||||
assert 'ROI' in msg_mock.call_args_list[-1][0][0]
|
||||
assert 'Avg. Duration' in msg_mock.call_args_list[-1][0][0]
|
||||
msg_mock.reset_mock()
|
||||
@@ -912,6 +919,10 @@ def test_balance_handle_too_large_response(default_conf, update, mocker) -> None
|
||||
'balance': i,
|
||||
'est_stake': 1,
|
||||
'stake': 'BTC',
|
||||
'is_position': False,
|
||||
'leverage': 1.0,
|
||||
'position': 0.0,
|
||||
'side': 'long',
|
||||
})
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_balance', return_value={
|
||||
'currencies': balances,
|
||||
@@ -1036,7 +1047,7 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
|
||||
# /forcesell 1
|
||||
context = MagicMock()
|
||||
context.args = ["1"]
|
||||
telegram._forcesell(update=update, context=context)
|
||||
telegram._forceexit(update=update, context=context)
|
||||
|
||||
assert msg_mock.call_count == 4
|
||||
last_msg = msg_mock.call_args_list[-2][0][0]
|
||||
@@ -1046,18 +1057,22 @@ def test_telegram_forcesell_handle(default_conf, update, ticker, fee,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'gain': 'profit',
|
||||
'leverage': 1.0,
|
||||
'limit': 1.173e-05,
|
||||
'amount': 91.07468123,
|
||||
'order_type': 'limit',
|
||||
'open_rate': 1.098e-05,
|
||||
'current_rate': 1.173e-05,
|
||||
'direction': 'Long',
|
||||
'profit_amount': 6.314e-05,
|
||||
'profit_ratio': 0.0629778,
|
||||
'stake_currency': 'BTC',
|
||||
'base_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': ANY,
|
||||
'sell_reason': SellType.FORCE_SELL.value,
|
||||
'enter_tag': ANY,
|
||||
'sell_reason': ExitType.FORCE_SELL.value,
|
||||
'exit_reason': ExitType.FORCE_SELL.value,
|
||||
'open_date': ANY,
|
||||
'close_date': ANY,
|
||||
'close_rate': ANY,
|
||||
@@ -1102,7 +1117,7 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
|
||||
# /forcesell 1
|
||||
context = MagicMock()
|
||||
context.args = ["1"]
|
||||
telegram._forcesell(update=update, context=context)
|
||||
telegram._forceexit(update=update, context=context)
|
||||
|
||||
assert msg_mock.call_count == 4
|
||||
|
||||
@@ -1113,18 +1128,22 @@ def test_telegram_forcesell_down_handle(default_conf, update, ticker, fee,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'gain': 'loss',
|
||||
'leverage': 1.0,
|
||||
'limit': 1.043e-05,
|
||||
'amount': 91.07468123,
|
||||
'order_type': 'limit',
|
||||
'open_rate': 1.098e-05,
|
||||
'current_rate': 1.043e-05,
|
||||
'direction': 'Long',
|
||||
'profit_amount': -5.497e-05,
|
||||
'profit_ratio': -0.05482878,
|
||||
'stake_currency': 'BTC',
|
||||
'base_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': ANY,
|
||||
'sell_reason': SellType.FORCE_SELL.value,
|
||||
'enter_tag': ANY,
|
||||
'sell_reason': ExitType.FORCE_SELL.value,
|
||||
'exit_reason': ExitType.FORCE_SELL.value,
|
||||
'open_date': ANY,
|
||||
'close_date': ANY,
|
||||
'close_rate': ANY,
|
||||
@@ -1159,7 +1178,7 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
||||
# /forcesell all
|
||||
context = MagicMock()
|
||||
context.args = ["all"]
|
||||
telegram._forcesell(update=update, context=context)
|
||||
telegram._forceexit(update=update, context=context)
|
||||
|
||||
# Called for each trade 2 times
|
||||
assert msg_mock.call_count == 8
|
||||
@@ -1170,18 +1189,22 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'gain': 'loss',
|
||||
'leverage': 1.0,
|
||||
'limit': 1.099e-05,
|
||||
'amount': 91.07468123,
|
||||
'order_type': 'limit',
|
||||
'open_rate': 1.098e-05,
|
||||
'current_rate': 1.099e-05,
|
||||
'direction': 'Long',
|
||||
'profit_amount': -4.09e-06,
|
||||
'profit_ratio': -0.00408133,
|
||||
'stake_currency': 'BTC',
|
||||
'base_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': ANY,
|
||||
'sell_reason': SellType.FORCE_SELL.value,
|
||||
'enter_tag': ANY,
|
||||
'sell_reason': ExitType.FORCE_SELL.value,
|
||||
'exit_reason': ExitType.FORCE_SELL.value,
|
||||
'open_date': ANY,
|
||||
'close_date': ANY,
|
||||
'close_rate': ANY,
|
||||
@@ -1202,7 +1225,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
||||
# /forcesell 1
|
||||
context = MagicMock()
|
||||
context.args = ["1"]
|
||||
telegram._forcesell(update=update, context=context)
|
||||
telegram._forceexit(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'not running' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
@@ -1211,7 +1234,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
||||
freqtradebot.state = State.RUNNING
|
||||
context = MagicMock()
|
||||
context.args = []
|
||||
telegram._forcesell(update=update, context=context)
|
||||
telegram._forceexit(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert "You must specify a trade-id or 'all'." in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
@@ -1221,36 +1244,37 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
|
||||
# /forcesell 123456
|
||||
context = MagicMock()
|
||||
context.args = ["123456"]
|
||||
telegram._forcesell(update=update, context=context)
|
||||
telegram._forceexit(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'invalid argument' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_forcebuy_handle(default_conf, update, mocker) -> None:
|
||||
def test_forceenter_handle(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_forcebuy', fbuy_mock)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
|
||||
telegram, freqtradebot, _ = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
|
||||
# /forcebuy ETH/BTC
|
||||
# /forcelong ETH/BTC
|
||||
context = MagicMock()
|
||||
context.args = ["ETH/BTC"]
|
||||
telegram._forcebuy(update=update, context=context)
|
||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
|
||||
assert fbuy_mock.call_count == 1
|
||||
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
|
||||
assert fbuy_mock.call_args_list[0][0][1] is None
|
||||
assert fbuy_mock.call_args_list[0][1]['order_side'] == SignalDirection.LONG
|
||||
|
||||
# Reset and retry with specified price
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_forcebuy', fbuy_mock)
|
||||
# /forcebuy ETH/BTC 0.055
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
# /forcelong ETH/BTC 0.055
|
||||
context = MagicMock()
|
||||
context.args = ["ETH/BTC", "0.055"]
|
||||
telegram._forcebuy(update=update, context=context)
|
||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
|
||||
assert fbuy_mock.call_count == 1
|
||||
assert fbuy_mock.call_args_list[0][0][0] == 'ETH/BTC'
|
||||
@@ -1258,24 +1282,24 @@ def test_forcebuy_handle(default_conf, update, mocker) -> None:
|
||||
assert fbuy_mock.call_args_list[0][0][1] == 0.055
|
||||
|
||||
|
||||
def test_forcebuy_handle_exception(default_conf, update, mocker) -> None:
|
||||
def test_forceenter_handle_exception(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
|
||||
update.message.text = '/forcebuy ETH/Nonepair'
|
||||
telegram._forcebuy(update=update, context=MagicMock())
|
||||
telegram._forceenter(update=update, context=MagicMock(), order_side=SignalDirection.LONG)
|
||||
|
||||
assert msg_mock.call_count == 1
|
||||
assert msg_mock.call_args_list[0][0][0] == 'Forcebuy not enabled.'
|
||||
assert msg_mock.call_args_list[0][0][0] == 'Forceentry not enabled.'
|
||||
|
||||
|
||||
def test_forcebuy_no_pair(default_conf, update, mocker) -> None:
|
||||
def test_forceenter_no_pair(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_forcebuy', fbuy_mock)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
@@ -1283,7 +1307,7 @@ def test_forcebuy_no_pair(default_conf, update, mocker) -> None:
|
||||
|
||||
context = MagicMock()
|
||||
context.args = []
|
||||
telegram._forcebuy(update=update, context=context)
|
||||
telegram._forceenter(update=update, context=context, order_side=SignalDirection.LONG)
|
||||
|
||||
assert fbuy_mock.call_count == 0
|
||||
assert msg_mock.call_count == 1
|
||||
@@ -1294,8 +1318,8 @@ def test_forcebuy_no_pair(default_conf, update, mocker) -> None:
|
||||
assert reduce(lambda acc, x: acc + len(x), keyboard, 0) == 5
|
||||
update = MagicMock()
|
||||
update.callback_query = MagicMock()
|
||||
update.callback_query.data = 'XRP/USDT'
|
||||
telegram._forcebuy_inline(update, None)
|
||||
update.callback_query.data = 'XRP/USDT_||_long'
|
||||
telegram._forceenter_inline(update, None)
|
||||
assert fbuy_mock.call_count == 1
|
||||
|
||||
|
||||
@@ -1333,8 +1357,8 @@ def test_telegram_performance_handle(default_conf, update, ticker, fee,
|
||||
assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
def test_telegram_entry_tag_performance_handle(
|
||||
default_conf, update, ticker, fee, limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker,
|
||||
@@ -1347,7 +1371,6 @@ def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
freqtradebot.enter_positions()
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
trade.buy_tag = "TESTBUY"
|
||||
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
limit_buy_order['id'] = trade.orders[0].order_id
|
||||
@@ -1355,6 +1378,7 @@ def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
trade.update_order(limit_buy_order)
|
||||
trade.update_trade(oobj)
|
||||
|
||||
trade.enter_tag = "TESTBUY"
|
||||
# Simulate fulfilled LIMIT_SELL order for trade
|
||||
oobj = Order.parse_from_ccxt_object(limit_sell_order, limit_sell_order['symbol'], 'sell')
|
||||
trade.update_trade(oobj)
|
||||
@@ -1362,25 +1386,25 @@ def test_telegram_buy_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
trade.close_date = datetime.utcnow()
|
||||
trade.is_open = False
|
||||
context = MagicMock()
|
||||
telegram._buy_tag_performance(update=update, context=context)
|
||||
telegram._enter_tag_performance(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'Buy Tag Performance' in msg_mock.call_args_list[0][0][0]
|
||||
assert 'Entry Tag Performance' in msg_mock.call_args_list[0][0][0]
|
||||
assert '<code>TESTBUY\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
context.args = [trade.pair]
|
||||
telegram._buy_tag_performance(update=update, context=context)
|
||||
telegram._enter_tag_performance(update=update, context=context)
|
||||
assert msg_mock.call_count == 2
|
||||
|
||||
msg_mock.reset_mock()
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_buy_tag_performance',
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_enter_tag_performance',
|
||||
side_effect=RPCException('Error'))
|
||||
telegram._buy_tag_performance(update=update, context=MagicMock())
|
||||
telegram._enter_tag_performance(update=update, context=MagicMock())
|
||||
|
||||
assert msg_mock.call_count == 1
|
||||
assert "Error" in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_telegram_sell_reason_performance_handle(default_conf, update, ticker, fee,
|
||||
def test_telegram_exit_reason_performance_handle(default_conf, update, ticker, fee,
|
||||
limit_buy_order, limit_sell_order, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@@ -1394,7 +1418,7 @@ def test_telegram_sell_reason_performance_handle(default_conf, update, ticker, f
|
||||
freqtradebot.enter_positions()
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
trade.sell_reason = 'TESTSELL'
|
||||
trade.exit_reason = 'TESTSELL'
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
limit_buy_order['id'] = trade.orders[0].order_id
|
||||
oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy')
|
||||
@@ -1408,19 +1432,19 @@ def test_telegram_sell_reason_performance_handle(default_conf, update, ticker, f
|
||||
trade.close_date = datetime.utcnow()
|
||||
trade.is_open = False
|
||||
context = MagicMock()
|
||||
telegram._sell_reason_performance(update=update, context=context)
|
||||
telegram._exit_reason_performance(update=update, context=context)
|
||||
assert msg_mock.call_count == 1
|
||||
assert 'Sell Reason Performance' in msg_mock.call_args_list[0][0][0]
|
||||
assert 'Exit Reason Performance' in msg_mock.call_args_list[0][0][0]
|
||||
assert '<code>TESTSELL\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
|
||||
context.args = [trade.pair]
|
||||
|
||||
telegram._sell_reason_performance(update=update, context=context)
|
||||
telegram._exit_reason_performance(update=update, context=context)
|
||||
assert msg_mock.call_count == 2
|
||||
|
||||
msg_mock.reset_mock()
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_sell_reason_performance',
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_exit_reason_performance',
|
||||
side_effect=RPCException('Error'))
|
||||
telegram._sell_reason_performance(update=update, context=MagicMock())
|
||||
telegram._exit_reason_performance(update=update, context=MagicMock())
|
||||
|
||||
assert msg_mock.call_count == 1
|
||||
assert "Error" in msg_mock.call_args_list[0][0][0]
|
||||
@@ -1440,8 +1464,9 @@ def test_telegram_mix_tag_performance_handle(default_conf, update, ticker, fee,
|
||||
freqtradebot.enter_positions()
|
||||
trade = Trade.query.first()
|
||||
assert trade
|
||||
trade.buy_tag = "TESTBUY"
|
||||
trade.sell_reason = "TESTSELL"
|
||||
|
||||
trade.enter_tag = "TESTBUY"
|
||||
trade.exit_reason = "TESTSELL"
|
||||
|
||||
# Simulate fulfilled LIMIT_BUY order for trade
|
||||
limit_buy_order['id'] = trade.orders[0].order_id
|
||||
@@ -1668,7 +1693,10 @@ def test_edge_enabled(edge_conf, update, mocker) -> None:
|
||||
assert 'Winrate' not in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_telegram_trades(mocker, update, default_conf, fee):
|
||||
@pytest.mark.parametrize('is_short,regex_pattern',
|
||||
[(True, r"just now[ ]*XRP\/BTC \(#3\) -1.00% \("),
|
||||
(False, r"just now[ ]*XRP\/BTC \(#3\) 1.00% \(")])
|
||||
def test_telegram_trades(mocker, update, default_conf, fee, is_short, regex_pattern):
|
||||
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
@@ -1686,7 +1714,7 @@ def test_telegram_trades(mocker, update, default_conf, fee):
|
||||
assert "<pre>" not in msg_mock.call_args_list[0][0][0]
|
||||
msg_mock.reset_mock()
|
||||
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short=is_short)
|
||||
|
||||
context = MagicMock()
|
||||
context.args = [5]
|
||||
@@ -1696,11 +1724,11 @@ def test_telegram_trades(mocker, update, default_conf, fee):
|
||||
assert "Profit (" in msg_mock.call_args_list[0][0][0]
|
||||
assert "Close Date" in msg_mock.call_args_list[0][0][0]
|
||||
assert "<pre>" in msg_mock.call_args_list[0][0][0]
|
||||
assert bool(re.search(r"just now[ ]*XRP\/BTC \(#3\) 1.00% \(",
|
||||
msg_mock.call_args_list[0][0][0]))
|
||||
assert bool(re.search(regex_pattern, msg_mock.call_args_list[0][0][0]))
|
||||
|
||||
|
||||
def test_telegram_delete_trade(mocker, update, default_conf, fee):
|
||||
@pytest.mark.parametrize('is_short', [True, False])
|
||||
def test_telegram_delete_trade(mocker, update, default_conf, fee, is_short):
|
||||
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
context = MagicMock()
|
||||
@@ -1710,7 +1738,7 @@ def test_telegram_delete_trade(mocker, update, default_conf, fee):
|
||||
assert "Trade-id not set." in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
msg_mock.reset_mock()
|
||||
create_mock_trades(fee)
|
||||
create_mock_trades(fee, is_short=is_short)
|
||||
|
||||
context = MagicMock()
|
||||
context.args = [1]
|
||||
@@ -1755,7 +1783,7 @@ def test_show_config_handle(default_conf, update, mocker) -> None:
|
||||
assert msg_mock.call_count == 1
|
||||
assert '*Mode:* `{}`'.format('Dry-run') in msg_mock.call_args_list[0][0][0]
|
||||
assert '*Exchange:* `binance`' in msg_mock.call_args_list[0][0][0]
|
||||
assert '*Strategy:* `StrategyTestV2`' in msg_mock.call_args_list[0][0][0]
|
||||
assert f'*Strategy:* `{CURRENT_TEST_STRATEGY}`' in msg_mock.call_args_list[0][0][0]
|
||||
assert '*Stoploss:* `-0.1`' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
msg_mock.reset_mock()
|
||||
@@ -1764,18 +1792,25 @@ def test_show_config_handle(default_conf, update, mocker) -> None:
|
||||
assert msg_mock.call_count == 1
|
||||
assert '*Mode:* `{}`'.format('Dry-run') in msg_mock.call_args_list[0][0][0]
|
||||
assert '*Exchange:* `binance`' in msg_mock.call_args_list[0][0][0]
|
||||
assert '*Strategy:* `StrategyTestV2`' in msg_mock.call_args_list[0][0][0]
|
||||
assert f'*Strategy:* `{CURRENT_TEST_STRATEGY}`' in msg_mock.call_args_list[0][0][0]
|
||||
assert '*Initial Stoploss:* `-0.1`' in msg_mock.call_args_list[0][0][0]
|
||||
|
||||
|
||||
def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
|
||||
@pytest.mark.parametrize('message_type,enter,enter_signal,leverage', [
|
||||
(RPCMessageType.BUY, 'Long', 'long_signal_01', None),
|
||||
(RPCMessageType.BUY, 'Long', 'long_signal_01', 1.0),
|
||||
(RPCMessageType.BUY, 'Long', 'long_signal_01', 5.0),
|
||||
(RPCMessageType.SHORT, 'Short', 'short_signal_01', 2.0)])
|
||||
def test_send_msg_buy_notification(default_conf, mocker, caplog, message_type,
|
||||
enter, enter_signal, leverage) -> None:
|
||||
|
||||
msg = {
|
||||
'type': RPCMessageType.BUY,
|
||||
'type': message_type,
|
||||
'trade_id': 1,
|
||||
'buy_tag': 'buy_signal_01',
|
||||
'enter_tag': enter_signal,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'leverage': leverage,
|
||||
'limit': 1.099e-05,
|
||||
'order_type': 'limit',
|
||||
'stake_amount': 0.01465333,
|
||||
@@ -1789,13 +1824,17 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
telegram.send_msg(msg)
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== '\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n' \
|
||||
'*Buy Tag:* `buy_signal_01`\n' \
|
||||
'*Amount:* `1333.33333333`\n' \
|
||||
'*Open Rate:* `0.00001099`\n' \
|
||||
'*Current Rate:* `0.00001099`\n' \
|
||||
'*Total:* `(0.01465333 BTC, 180.895 USD)`'
|
||||
leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else ''
|
||||
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
f'\N{LARGE BLUE CIRCLE} *Binance:* {enter} ETH/BTC (#1)\n'
|
||||
f'*Enter Tag:* `{enter_signal}`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
f'{leverage_text}'
|
||||
'*Open Rate:* `0.00001099`\n'
|
||||
'*Current Rate:* `0.00001099`\n'
|
||||
'*Total:* `(0.01465333 BTC, 180.895 USD)`'
|
||||
)
|
||||
|
||||
freqtradebot.config['telegram']['notification_settings'] = {'buy': 'off'}
|
||||
caplog.clear()
|
||||
@@ -1813,20 +1852,23 @@ def test_send_msg_buy_notification(default_conf, mocker, caplog) -> None:
|
||||
msg_mock.call_args_list[0][1]['disable_notification'] is True
|
||||
|
||||
|
||||
def test_send_msg_buy_cancel_notification(default_conf, mocker) -> None:
|
||||
@pytest.mark.parametrize('message_type,enter_signal', [
|
||||
(RPCMessageType.BUY_CANCEL, 'long_signal_01'),
|
||||
(RPCMessageType.SHORT_CANCEL, 'short_signal_01')])
|
||||
def test_send_msg_buy_cancel_notification(default_conf, mocker, message_type, enter_signal) -> None:
|
||||
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.BUY_CANCEL,
|
||||
'buy_tag': 'buy_signal_01',
|
||||
'type': message_type,
|
||||
'enter_tag': enter_signal,
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'reason': CANCEL_REASON['TIMEOUT']
|
||||
})
|
||||
assert (msg_mock.call_args[0][0] == '\N{WARNING SIGN} *Binance:* '
|
||||
'Cancelling open buy Order for ETH/BTC (#1). '
|
||||
'Cancelling enter Order for ETH/BTC (#1). '
|
||||
'Reason: cancelled due to timeout.')
|
||||
|
||||
|
||||
@@ -1858,17 +1900,24 @@ def test_send_msg_protection_notification(default_conf, mocker, time_machine) ->
|
||||
"*All pairs* will be locked until `2021-09-01 06:45:00`.")
|
||||
|
||||
|
||||
def test_send_msg_buy_fill_notification(default_conf, mocker) -> None:
|
||||
@pytest.mark.parametrize('message_type,entered,enter_signal,leverage', [
|
||||
(RPCMessageType.BUY_FILL, 'Longed', 'long_signal_01', 1.0),
|
||||
(RPCMessageType.BUY_FILL, 'Longed', 'long_signal_02', 2.0),
|
||||
(RPCMessageType.SHORT_FILL, 'Shorted', 'short_signal_01', 2.0),
|
||||
])
|
||||
def test_send_msg_buy_fill_notification(default_conf, mocker, message_type, entered,
|
||||
enter_signal, leverage) -> None:
|
||||
|
||||
default_conf['telegram']['notification_settings']['buy_fill'] = 'on'
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.BUY_FILL,
|
||||
'type': message_type,
|
||||
'trade_id': 1,
|
||||
'buy_tag': 'buy_signal_01',
|
||||
'enter_tag': enter_signal,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'leverage': leverage,
|
||||
'stake_amount': 0.01465333,
|
||||
'stake_currency': 'BTC',
|
||||
'fiat_currency': 'USD',
|
||||
@@ -1876,13 +1925,15 @@ def test_send_msg_buy_fill_notification(default_conf, mocker) -> None:
|
||||
'amount': 1333.3333333333335,
|
||||
'open_date': arrow.utcnow().shift(hours=-1)
|
||||
})
|
||||
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== '\N{CHECK MARK} *Binance:* Bought ETH/BTC (#1)\n' \
|
||||
'*Buy Tag:* `buy_signal_01`\n' \
|
||||
'*Amount:* `1333.33333333`\n' \
|
||||
'*Open Rate:* `0.00001099`\n' \
|
||||
'*Total:* `(0.01465333 BTC, 180.895 USD)`'
|
||||
leverage_text = f'*Leverage:* `{leverage}`\n' if leverage != 1.0 else ''
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
f'\N{CHECK MARK} *Binance:* {entered} ETH/BTC (#1)\n'
|
||||
f'*Enter Tag:* `{enter_signal}`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
f"{leverage_text}"
|
||||
'*Open Rate:* `0.00001099`\n'
|
||||
'*Total:* `(0.01465333 BTC, 180.895 USD)`'
|
||||
)
|
||||
|
||||
msg_mock.reset_mock()
|
||||
telegram.send_msg({
|
||||
@@ -1922,6 +1973,8 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'leverage': 1.0,
|
||||
'direction': 'Long',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
@@ -1932,22 +1985,23 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'profit_ratio': -0.57405275,
|
||||
'stake_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': 'buy_signal1',
|
||||
'sell_reason': SellType.STOP_LOSS.value,
|
||||
'enter_tag': 'buy_signal1',
|
||||
'exit_reason': ExitType.STOP_LOSS.value,
|
||||
'open_date': arrow.utcnow().shift(hours=-1),
|
||||
'close_date': arrow.utcnow(),
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||
'*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH / -24.812 USD)`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `1:00:00 (60.0 min)`'
|
||||
)
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
'\N{WARNING SIGN} *Binance:* Exiting KEY/ETH (#1)\n'
|
||||
'*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH / -24.812 USD)`\n'
|
||||
'*Enter Tag:* `buy_signal1`\n'
|
||||
'*Exit Reason:* `stop_loss`\n'
|
||||
'*Direction:* `Long`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `1:00:00 (60.0 min)`'
|
||||
)
|
||||
|
||||
msg_mock.reset_mock()
|
||||
telegram.send_msg({
|
||||
@@ -1955,6 +2009,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'direction': 'Long',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
@@ -1966,8 +2021,8 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'profit_ratio': -0.57405275,
|
||||
'stake_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': 'buy_signal1',
|
||||
'sell_reason': SellType.STOP_LOSS.value,
|
||||
'enter_tag': 'buy_signal1',
|
||||
'exit_reason': ExitType.STOP_LOSS.value,
|
||||
'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30),
|
||||
'close_date': arrow.utcnow(),
|
||||
'stake_amount': 1234,
|
||||
@@ -1991,6 +2046,7 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'direction': 'Long',
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
@@ -2000,22 +2056,23 @@ def test_send_msg_sell_notification(default_conf, mocker) -> None:
|
||||
'profit_amount': -0.05746268,
|
||||
'profit_ratio': -0.57405275,
|
||||
'stake_currency': 'ETH',
|
||||
'buy_tag': 'buy_signal1',
|
||||
'sell_reason': SellType.STOP_LOSS.value,
|
||||
'enter_tag': 'buy_signal1',
|
||||
'exit_reason': SellType.STOP_LOSS.value,
|
||||
'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30),
|
||||
'close_date': arrow.utcnow(),
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||
== ('\N{WARNING SIGN} *Binance:* Exiting KEY/ETH (#1)\n'
|
||||
'*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH)`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Enter Tag:* `buy_signal1`\n'
|
||||
'*Exit Reason:* `stop_loss`\n'
|
||||
'*Direction:* `Long`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `1 day, 2:30:00 (1590.0 min)`'
|
||||
)
|
||||
)
|
||||
# Reset singleton function to avoid random breaks
|
||||
telegram._rpc._fiat_converter.convert_amount = old_convamount
|
||||
|
||||
@@ -2033,9 +2090,9 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
|
||||
'pair': 'KEY/ETH',
|
||||
'reason': 'Cancelled on exchange'
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Cancelling open sell Order for KEY/ETH (#1).'
|
||||
' Reason: Cancelled on exchange.')
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
'\N{WARNING SIGN} *Binance:* Cancelling exit Order for KEY/ETH (#1).'
|
||||
' Reason: Cancelled on exchange.')
|
||||
|
||||
msg_mock.reset_mock()
|
||||
telegram.send_msg({
|
||||
@@ -2045,14 +2102,19 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
|
||||
'pair': 'KEY/ETH',
|
||||
'reason': 'timeout'
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Cancelling open sell Order for KEY/ETH (#1).'
|
||||
' Reason: timeout.')
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
'\N{WARNING SIGN} *Binance:* Cancelling exit Order for KEY/ETH (#1). Reason: timeout.')
|
||||
# Reset singleton function to avoid random breaks
|
||||
telegram._rpc._fiat_converter.convert_amount = old_convamount
|
||||
|
||||
|
||||
def test_send_msg_sell_fill_notification(default_conf, mocker) -> None:
|
||||
@pytest.mark.parametrize('direction,enter_signal,leverage', [
|
||||
('Long', 'long_signal_01', None),
|
||||
('Long', 'long_signal_01', 1.0),
|
||||
('Long', 'long_signal_01', 5.0),
|
||||
('Short', 'short_signal_01', 2.0)])
|
||||
def test_send_msg_sell_fill_notification(default_conf, mocker, direction,
|
||||
enter_signal, leverage) -> None:
|
||||
|
||||
default_conf['telegram']['notification_settings']['sell_fill'] = 'on'
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
@@ -2062,6 +2124,8 @@ def test_send_msg_sell_fill_notification(default_conf, mocker) -> None:
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'leverage': leverage,
|
||||
'direction': direction,
|
||||
'gain': 'loss',
|
||||
'limit': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
@@ -2071,21 +2135,25 @@ def test_send_msg_sell_fill_notification(default_conf, mocker) -> None:
|
||||
'profit_amount': -0.05746268,
|
||||
'profit_ratio': -0.57405275,
|
||||
'stake_currency': 'ETH',
|
||||
'buy_tag': 'buy_signal1',
|
||||
'sell_reason': SellType.STOP_LOSS.value,
|
||||
'enter_tag': enter_signal,
|
||||
'exit_reason': ExitType.STOP_LOSS.value,
|
||||
'open_date': arrow.utcnow().shift(days=-1, hours=-2, minutes=-30),
|
||||
'close_date': arrow.utcnow(),
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('\N{WARNING SIGN} *Binance:* Sold KEY/ETH (#1)\n'
|
||||
'*Profit:* `-57.41% (loss: -0.05746268 ETH)`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `1 day, 2:30:00 (1590.0 min)`'
|
||||
)
|
||||
|
||||
leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else ''
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
'\N{WARNING SIGN} *Binance:* Exited KEY/ETH (#1)\n'
|
||||
'*Profit:* `-57.41% (loss: -0.05746268 ETH)`\`\n'
|
||||
f'*Enter Tag:* `{enter_signal}`\n'
|
||||
'*Exit Reason:* `stop_loss`\n'
|
||||
f"*Direction:* `{direction}`\n"
|
||||
f"{leverage_text}"
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `1 day, 2:30:00 (1590.0 min)`\n'
|
||||
)
|
||||
|
||||
|
||||
def test_send_msg_status_notification(default_conf, mocker) -> None:
|
||||
@@ -2124,16 +2192,22 @@ def test_send_msg_unknown_type(default_conf, mocker) -> None:
|
||||
})
|
||||
|
||||
|
||||
def test_send_msg_buy_notification_no_fiat(default_conf, mocker) -> None:
|
||||
@pytest.mark.parametrize('message_type,enter,enter_signal,leverage', [
|
||||
(RPCMessageType.BUY, 'Long', 'long_signal_01', None),
|
||||
(RPCMessageType.BUY, 'Long', 'long_signal_01', 2.0),
|
||||
(RPCMessageType.SHORT, 'Short', 'short_signal_01', 2.0)])
|
||||
def test_send_msg_buy_notification_no_fiat(
|
||||
default_conf, mocker, message_type, enter, enter_signal, leverage) -> None:
|
||||
del default_conf['fiat_display_currency']
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.BUY,
|
||||
'buy_tag': 'buy_signal_01',
|
||||
'type': message_type,
|
||||
'enter_tag': enter_signal,
|
||||
'trade_id': 1,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'ETH/BTC',
|
||||
'leverage': leverage,
|
||||
'limit': 1.099e-05,
|
||||
'order_type': 'limit',
|
||||
'stake_amount': 0.01465333,
|
||||
@@ -2144,15 +2218,27 @@ 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] == ('\N{LARGE BLUE CIRCLE} *Binance:* Buying ETH/BTC (#1)\n'
|
||||
'*Buy Tag:* `buy_signal_01`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00001099`\n'
|
||||
'*Current Rate:* `0.00001099`\n'
|
||||
'*Total:* `(0.01465333 BTC)`')
|
||||
|
||||
leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else ''
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
f'\N{LARGE BLUE CIRCLE} *Binance:* {enter} ETH/BTC (#1)\n'
|
||||
f'*Enter Tag:* `{enter_signal}`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
f'{leverage_text}'
|
||||
'*Open Rate:* `0.00001099`\n'
|
||||
'*Current Rate:* `0.00001099`\n'
|
||||
'*Total:* `(0.01465333 BTC)`'
|
||||
)
|
||||
|
||||
|
||||
def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
||||
@pytest.mark.parametrize('direction,enter_signal,leverage', [
|
||||
('Long', 'long_signal_01', None),
|
||||
('Long', 'long_signal_01', 1.0),
|
||||
('Long', 'long_signal_01', 5.0),
|
||||
('Short', 'short_signal_01', 2.0),
|
||||
])
|
||||
def test_send_msg_sell_notification_no_fiat(
|
||||
default_conf, mocker, direction, enter_signal, leverage) -> None:
|
||||
del default_conf['fiat_display_currency']
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
@@ -2162,6 +2248,8 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'gain': 'loss',
|
||||
'leverage': leverage,
|
||||
'direction': direction,
|
||||
'limit': 3.201e-05,
|
||||
'amount': 1333.3333333333335,
|
||||
'order_type': 'limit',
|
||||
@@ -2171,31 +2259,36 @@ def test_send_msg_sell_notification_no_fiat(default_conf, mocker) -> None:
|
||||
'profit_ratio': -0.57405275,
|
||||
'stake_currency': 'ETH',
|
||||
'fiat_currency': 'USD',
|
||||
'buy_tag': 'buy_signal1',
|
||||
'sell_reason': SellType.STOP_LOSS.value,
|
||||
'enter_tag': enter_signal,
|
||||
'exit_reason': ExitType.STOP_LOSS.value,
|
||||
'open_date': arrow.utcnow().shift(hours=-2, minutes=-35, seconds=-3),
|
||||
'close_date': arrow.utcnow(),
|
||||
})
|
||||
assert msg_mock.call_args[0][0] == ('\N{WARNING SIGN} *Binance:* Selling KEY/ETH (#1)\n'
|
||||
'*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH)`\n'
|
||||
'*Buy Tag:* `buy_signal1`\n'
|
||||
'*Sell Reason:* `stop_loss`\n'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `2:35:03 (155.1 min)`'
|
||||
)
|
||||
|
||||
leverage_text = f'*Leverage:* `{leverage}`\n' if leverage and leverage != 1.0 else ''
|
||||
assert msg_mock.call_args[0][0] == (
|
||||
'\N{WARNING SIGN} *Binance:* Exiting KEY/ETH (#1)\n'
|
||||
'*Unrealized Profit:* `-57.41% (loss: -0.05746268 ETH)`\n'
|
||||
f'*Enter Tag:* `{enter_signal}`\n'
|
||||
'*Exit Reason:* `stop_loss`\n'
|
||||
f'*Direction:* `{direction}`\n'
|
||||
f'{leverage_text}'
|
||||
'*Amount:* `1333.33333333`\n'
|
||||
'*Open Rate:* `0.00007500`\n'
|
||||
'*Current Rate:* `0.00003201`\n'
|
||||
'*Close Rate:* `0.00003201`\n'
|
||||
'*Duration:* `2:35:03 (155.1 min)`\n'
|
||||
)
|
||||
|
||||
|
||||
@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}"),
|
||||
({'profit_percent': 20.1, 'exit_reason': 'roi'}, "\N{ROCKET}"),
|
||||
({'profit_percent': 5.1, 'exit_reason': 'roi'}, "\N{ROCKET}"),
|
||||
({'profit_percent': 2.56, 'exit_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
|
||||
({'profit_percent': 1.0, 'exit_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
|
||||
({'profit_percent': 0.0, 'exit_reason': 'roi'}, "\N{EIGHT SPOKED ASTERISK}"),
|
||||
({'profit_percent': -5.0, 'exit_reason': 'stop_loss'}, "\N{WARNING SIGN}"),
|
||||
({'profit_percent': -2.0, 'exit_reason': 'sell_signal'}, "\N{CROSS MARK}"),
|
||||
])
|
||||
def test__sell_emoji(default_conf, mocker, msg, expected):
|
||||
del default_conf['fiat_display_currency']
|
||||
|
||||
Reference in New Issue
Block a user