def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker) -> None: patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) patch_exchange(mocker) mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.get_pair_detail_url', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) telegram = Telegram(freqtradebot) # Create some test data for _ in range(4): freqtradebot.create_trade() rpc_mock.reset_mock() update.message.text = '/forcesell all' telegram._forcesell(bot=MagicMock(), update=update) assert rpc_mock.call_count == 4 msg = rpc_mock.call_args_list[0][0][0] assert { 'type': RPCMessageType.SELL_NOTIFICATION, 'exchange': 'Bittrex', 'pair': 'ETH/BTC', 'gain': 'loss', 'market_url': ANY, 'limit': 1.098e-05, 'amount': 90.99181073703367, 'open_rate': 1.099e-05, 'current_rate': 1.098e-05, 'profit_amount': -5.91e-06, 'profit_percent': -0.00589291, 'stake_currency': 'BTC', 'fiat_currency': 'USD', 'sell_reason': SellType.FORCE_SELL.value } == msg
def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: """ Test rpc_trade_status() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*trader is not running*'): rpc._rpc_trade_status() freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_trade_status() freqtradebot.create_trade() trades = rpc._rpc_trade_status() trade = trades[0] result_message = [ '*Trade ID:* `1`\n' '*Current Pair:* ' '[ETH/BTC](https://bittrex.com/Market/Index?MarketName=BTC-ETH)\n' '*Open Since:* `just now`\n' '*Amount:* `90.99181074`\n' '*Open Rate:* `0.00001099`\n' '*Close Rate:* `None`\n' '*Current Rate:* `0.00001098`\n' '*Close Profit:* `None`\n' '*Current Profit:* `-0.59%`\n' '*Open Order:* `(limit buy rem=0.00000000)`' ] assert trades == result_message assert trade.find('[ETH/BTC]') >= 0
def test_rpc_daily_profit(default_conf, update, ticker, fee, limit_buy_order, limit_sell_order, markets, mocker) -> None: patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) patch_exchange(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple('freqtrade.exchange.Exchange', get_ticker=ticker, get_fee=fee, get_markets=markets) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) stake_currency = default_conf['stake_currency'] fiat_display_currency = default_conf['fiat_display_currency'] rpc = RPC(freqtradebot) rpc._fiat_converter = CryptoToFiatConverter() # Create some test data freqtradebot.create_trade() trade = Trade.query.first() assert trade # Simulate buy & sell trade.update(limit_buy_order) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False # Try valid data update.message.text = '/daily 2' days = rpc._rpc_daily_profit(7, stake_currency, fiat_display_currency) assert len(days) == 7 for day in days: # [datetime.date(2018, 1, 11), '0.00000000 BTC', '0.000 USD'] assert (day[1] == '0.00000000 BTC' or day[1] == '0.00006217 BTC') assert (day[2] == '0.000 USD' or day[2] == '0.933 USD') # ensure first day is current date assert str(days[0][0]) == str(datetime.utcnow().date()) # Try invalid data with pytest.raises(RPCException, match=r'.*must be an integer greater than 0*'): rpc._rpc_daily_profit(0, stake_currency, fiat_display_currency)
def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> None: patch_coinmarketcap(mocker) patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_ticker=ticker, get_fee=fee, get_markets=markets ) msg_mock = MagicMock() status_table = MagicMock() mocker.patch.multiple( 'freqtrade.rpc.telegram.Telegram', _init=MagicMock(), _status_table=status_table, _send_msg=msg_mock ) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) telegram = Telegram(freqtradebot) freqtradebot.state = State.STOPPED # Status is also enabled when stopped telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'no active trade' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() freqtradebot.state = State.RUNNING telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'no active trade' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() # Create some test data freqtradebot.create_trade() # Trigger status while we have a fulfilled order for the open trade telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert '[ETH/BTC]' in msg_mock.call_args_list[0][0][0]
def test_status_handle(default_conf, update, ticker, mocker) -> None: """ Test _status() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) msg_mock = MagicMock() status_table = MagicMock() mocker.patch.multiple( 'freqtrade.rpc.telegram.Telegram', _init=MagicMock(), _status_table=status_table, send_msg=msg_mock ) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) telegram = Telegram(freqtradebot) freqtradebot.state = State.STOPPED telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'trader is not running' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() freqtradebot.state = State.RUNNING telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'no active trade' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() # Create some test data freqtradebot.create_trade() # Trigger status while we have a fulfilled order for the open trade telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert '[BTC_ETH]' in msg_mock.call_args_list[0][0][0]
def test_forcesell_down_handle(default_conf, update, ticker, fee, ticker_sell_down, markets, mocker) -> None: """ Test _forcesell() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock()) mocker.patch.multiple('freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets) freqtradebot = FreqtradeBot(default_conf) telegram = Telegram(freqtradebot) # Create some test data freqtradebot.create_trade() # Decrease the price and sell it mocker.patch.multiple('freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker_sell_down) trade = Trade.query.first() assert trade update.message.text = '/forcesell 1' telegram._forcesell(bot=MagicMock(), update=update) assert rpc_mock.call_count == 2 assert 'Selling' in rpc_mock.call_args_list[-1][0][0] assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0] assert 'Amount' in rpc_mock.call_args_list[-1][0][0] assert '0.00001044' in rpc_mock.call_args_list[-1][0][0] assert 'loss: -5.48%, -0.00005492' in rpc_mock.call_args_list[-1][0][0] assert '-0.824 USD' in rpc_mock.call_args_list[-1][0][0]
def test_create_trade_minimal_amount(default_conf, ticker, mocker) -> None: """ Test create_trade() method """ patch_get_signal(mocker) patch_RPCManager(mocker) patch_coinmarketcap(mocker) buy_mock = MagicMock(return_value='mocked_limit_buy') mocker.patch.multiple('freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker, buy=buy_mock) conf = deepcopy(default_conf) conf['stake_amount'] = 0.0005 freqtrade = FreqtradeBot(conf, create_engine('sqlite://')) freqtrade.create_trade() rate, amount = buy_mock.call_args[0][1], buy_mock.call_args[0][2] assert rate * amount >= conf['stake_amount']
def test_rpc_count(mocker, default_conf, ticker, fee, markets) -> None: patch_exchange(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple('freqtrade.exchange.Exchange', get_balances=MagicMock(return_value=ticker), get_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets)) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) rpc = RPC(freqtradebot) counts = rpc._rpc_count() assert counts["current"] == 0 # Create some test data freqtradebot.create_trade() counts = rpc._rpc_count() assert counts["current"] == 1
def test_status(default_conf, update, mocker, ticker) -> None: """ Test _status() method """ update.message.chat.id = 123 conf = deepcopy(default_conf) conf['telegram']['enabled'] = False conf['telegram']['chat_id'] = 123 patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) msg_mock = MagicMock() status_table = MagicMock() mocker.patch.multiple( 'freqtrade.rpc.telegram.Telegram', _init=MagicMock(), rpc_trade_status=MagicMock(return_value=(False, [1, 2, 3])), _status_table=status_table, send_msg=msg_mock ) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) freqtradebot = FreqtradeBot(conf, create_engine('sqlite://')) telegram = Telegram(freqtradebot) # Create some test data for _ in range(3): freqtradebot.create_trade() telegram._status(bot=MagicMock(), update=update) assert msg_mock.call_count == 3 update.message.text = MagicMock() update.message.text.replace = MagicMock(return_value='table 2 3') telegram._status(bot=MagicMock(), update=update) assert status_table.call_count == 1
def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> None: """ Test _count() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) msg_mock = MagicMock() mocker.patch.multiple('freqtrade.rpc.telegram.Telegram', _init=MagicMock(), _send_msg=msg_mock) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, buy=MagicMock(return_value={'id': 'mocked_order_id'}), get_markets=markets) mocker.patch('freqtrade.exchange.Exchange.get_fee', fee) freqtradebot = FreqtradeBot(default_conf) telegram = Telegram(freqtradebot) freqtradebot.state = State.STOPPED telegram._count(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'not running' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() freqtradebot.state = State.RUNNING # Create some test data freqtradebot.create_trade() msg_mock.reset_mock() telegram._count(bot=MagicMock(), update=update) msg = '<pre> current max total stake\n--------- ----- -------------\n' \ ' 1 {} {}</pre>'\ .format( default_conf['max_open_trades'], default_conf['stake_amount'] ) assert msg in msg_mock.call_args_list[0][0][0]
def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker) -> None: """ Test check_handle() method """ patch_get_signal(mocker) patch_RPCManager(mocker) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=MagicMock(return_value={ 'bid': 0.00001172, 'ask': 0.00001173, 'last': 0.00001172 }), buy=MagicMock(return_value='mocked_limit_buy'), sell=MagicMock(return_value='mocked_limit_sell')) patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://')) freqtrade.create_trade() trade = Trade.query.first() assert trade trade.update(limit_buy_order) assert trade.is_open is True patch_get_signal(mocker, value=(False, True)) assert freqtrade.handle_trade(trade) is True assert trade.open_order_id == 'mocked_limit_sell' # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) assert trade.close_rate == 0.00001173 assert trade.close_profit == 0.06201057 assert trade.calc_profit() == 0.00006217 assert trade.close_date is not None
def test_performance_handle(default_conf, update, ticker, limit_buy_order, limit_sell_order, mocker) -> None: """ Test _performance() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) msg_mock = MagicMock() mocker.patch.multiple( 'freqtrade.rpc.telegram.Telegram', _init=MagicMock(), send_msg=msg_mock ) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) telegram = Telegram(freqtradebot) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() assert trade # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False telegram._performance(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'Performance' in msg_mock.call_args_list[0][0][0] assert '<code>BTC_ETH\t6.20% (1)</code>' in msg_mock.call_args_list[0][0][0]
def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*trader is not running*'): rpc._rpc_trade_status() freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_trade_status() freqtradebot.create_trade() results = rpc._rpc_trade_status() assert { 'trade_id': 1, 'pair': 'ETH/BTC', 'market_url': 'https://bittrex.com/Market/Index?MarketName=BTC-ETH', 'date': ANY, 'open_rate': 1.099e-05, 'close_rate': None, 'current_rate': 1.098e-05, 'amount': 90.99181074, 'close_profit': None, 'current_profit': -0.59, 'open_order': '(limit buy rem=0.00000000)' } == results[0]
def test_create_trade_no_pairs(default_conf, ticker, mocker) -> None: """ Test create_trade() method """ patch_get_signal(mocker) patch_RPCManager(mocker) patch_coinmarketcap(mocker) mocker.patch.multiple('freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker, buy=MagicMock(return_value='mocked_limit_buy')) conf = deepcopy(default_conf) conf['exchange']['pair_whitelist'] = ["BTC_ETH"] conf['exchange']['pair_blacklist'] = ["BTC_ETH"] freqtrade = FreqtradeBot(conf, create_engine('sqlite://')) freqtrade.create_trade() with pytest.raises(DependencyException, match=r'.*No currency pairs in whitelist.*'): freqtrade.create_trade()
def test_performance_handle(default_conf, ticker, limit_buy_order, fee, limit_sell_order, markets, mocker) -> None: """ Test rpc_performance() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple( 'freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_balances=MagicMock(return_value=ticker), get_ticker=ticker, get_fee=fee, get_markets=markets ) freqtradebot = FreqtradeBot(default_conf) rpc = RPC(freqtradebot) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() assert trade # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False res = rpc._rpc_performance() assert len(res) == 1 assert res[0]['pair'] == 'ETH/BTC' assert res[0]['count'] == 1 assert prec_satoshi(res[0]['profit'], 6.2)
def test_forcesell_handle(default_conf, update, ticker, ticker_sell_up, mocker) -> None: """ Test _forcesell() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock()) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) telegram = Telegram(freqtradebot) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() assert trade # Increase the price and sell it mocker.patch('freqtrade.freqtradebot.exchange.get_ticker', ticker_sell_up) update.message.text = '/forcesell 1' telegram._forcesell(bot=MagicMock(), update=update) assert rpc_mock.call_count == 2 assert 'Selling' in rpc_mock.call_args_list[-1][0][0] assert '[BTC_ETH]' in rpc_mock.call_args_list[-1][0][0] assert 'Amount' in rpc_mock.call_args_list[-1][0][0] assert '0.00001172' in rpc_mock.call_args_list[-1][0][0] assert 'profit: 6.11%, 0.00006126' in rpc_mock.call_args_list[-1][0][0] assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
def test_count_handle(default_conf, update, ticker, mocker) -> None: """ Test _count() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) msg_mock = MagicMock() mocker.patch.multiple( 'freqtrade.rpc.telegram.Telegram', _init=MagicMock(), send_msg=msg_mock ) mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker, buy=MagicMock(return_value='mocked_order_id') ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) telegram = Telegram(freqtradebot) freqtradebot.state = State.STOPPED telegram._count(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'not running' in msg_mock.call_args_list[0][0][0] msg_mock.reset_mock() freqtradebot.state = State.RUNNING # Create some test data freqtradebot.create_trade() msg_mock.reset_mock() telegram._count(bot=MagicMock(), update=update) msg = '<pre> current max\n--------- -----\n 1 {}</pre>'.format( default_conf['max_open_trades'] ) assert msg in msg_mock.call_args_list[0][0][0]
def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker) -> None: """ Test _forcesell() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker, value={'price_usd': 15000.0}) mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0) rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock()) mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.get_pair_detail_url', MagicMock()) mocker.patch.multiple('freqtrade.exchange.Exchange', validate_pairs=MagicMock(), get_ticker=ticker, get_fee=fee, get_markets=markets) freqtradebot = FreqtradeBot(default_conf) telegram = Telegram(freqtradebot) # Create some test data for _ in range(4): freqtradebot.create_trade() rpc_mock.reset_mock() update.message.text = '/forcesell all' telegram._forcesell(bot=MagicMock(), update=update) assert rpc_mock.call_count == 4 for args in rpc_mock.call_args_list: assert '0.00001098' in args[0][0] assert 'loss: -0.59%, -0.00000591 BTC' in args[0][0] assert '-0.089 USD' in args[0][0]
def test_create_trade_no_signal(default_conf, mocker) -> None: """ Test create_trade() method """ conf = deepcopy(default_conf) conf['dry_run'] = True patch_get_signal(mocker, value=(False, False)) patch_RPCManager(mocker) patch_coinmarketcap(mocker) mocker.patch.multiple('freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker_history=MagicMock(return_value=20), get_balance=MagicMock(return_value=20)) conf = deepcopy(default_conf) conf['stake_amount'] = 10 freqtrade = FreqtradeBot(conf, create_engine('sqlite://')) Trade.query = MagicMock() Trade.query.filter = MagicMock() assert not freqtrade.create_trade()
def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee, limit_sell_order, markets, mocker) -> None: patch_exchange(mocker) mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch.multiple('freqtrade.exchange.Exchange', get_ticker=ticker, get_fee=fee, markets=PropertyMock(markets)) msg_mock = MagicMock() mocker.patch.multiple('freqtrade.rpc.telegram.Telegram', _init=MagicMock(), _send_msg=msg_mock) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) telegram = Telegram(freqtradebot) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() assert trade # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False # Try valid data update.message.text = '/daily 2' telegram._daily(bot=MagicMock(), update=update) assert msg_mock.call_count == 1 assert 'Daily' in msg_mock.call_args_list[0][0][0] assert str(datetime.utcnow().date()) in msg_mock.call_args_list[0][0][0] assert str(' 0.00006217 BTC') in msg_mock.call_args_list[0][0][0] assert str(' 0.933 USD') in msg_mock.call_args_list[0][0][0] assert str(' 1 trade') in msg_mock.call_args_list[0][0][0] assert str(' 0 trade') in msg_mock.call_args_list[0][0][0] # Reset msg_mock msg_mock.reset_mock() # Add two other trades freqtradebot.create_trade() freqtradebot.create_trade() trades = Trade.query.all() for trade in trades: trade.update(limit_buy_order) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False update.message.text = '/daily 1' telegram._daily(bot=MagicMock(), update=update) assert str(' 0.00018651 BTC') in msg_mock.call_args_list[0][0][0] assert str(' 2.798 USD') in msg_mock.call_args_list[0][0][0] assert str(' 3 trades') in msg_mock.call_args_list[0][0][0]
def test_rpc_forcesell(default_conf, ticker, mocker) -> None: """ Test rpc_forcesell() method """ patch_get_signal(mocker, (True, False)) patch_coinmarketcap(mocker) mocker.patch('freqtrade.rpc.rpc_manager.Telegram', MagicMock()) cancel_order_mock = MagicMock() mocker.patch.multiple( 'freqtrade.freqtradebot.exchange', validate_pairs=MagicMock(), get_ticker=ticker, cancel_order=cancel_order_mock, get_order=MagicMock( return_value={ 'closed': True, 'type': 'LIMIT_BUY', } ) ) freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://')) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED (error, res) = rpc.rpc_forcesell(None) assert error assert res == '`trader is not running`' freqtradebot.state = State.RUNNING (error, res) = rpc.rpc_forcesell(None) assert error assert res == 'Invalid argument.' (error, res) = rpc.rpc_forcesell('all') assert not error assert res == '' freqtradebot.create_trade() (error, res) = rpc.rpc_forcesell('all') assert not error assert res == '' (error, res) = rpc.rpc_forcesell('1') assert not error assert res == '' freqtradebot.state = State.STOPPED (error, res) = rpc.rpc_forcesell(None) assert error assert res == '`trader is not running`' (error, res) = rpc.rpc_forcesell('all') assert error assert res == '`trader is not running`' freqtradebot.state = State.RUNNING assert cancel_order_mock.call_count == 0 # make an limit-buy open trade mocker.patch( 'freqtrade.freqtradebot.exchange.get_order', return_value={ 'closed': None, 'type': 'LIMIT_BUY' } ) # check that the trade is called, which is done # by ensuring exchange.cancel_order is called (error, res) = rpc.rpc_forcesell('1') assert not error assert res == '' assert cancel_order_mock.call_count == 1 freqtradebot.create_trade() # make an limit-sell open trade mocker.patch( 'freqtrade.freqtradebot.exchange.get_order', return_value={ 'closed': None, 'type': 'LIMIT_SELL' } ) (error, res) = rpc.rpc_forcesell('2') assert not error assert res == '' # status quo, no exchange calls assert cancel_order_mock.call_count == 1
def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple('freqtrade.exchange.Exchange', _load_markets=MagicMock(return_value={}), get_ticker=ticker, get_fee=fee, markets=PropertyMock(return_value=markets)) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) rpc = RPC(freqtradebot) freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*no active trade*'): rpc._rpc_trade_status() freqtradebot.create_trade() results = rpc._rpc_trade_status() assert { 'trade_id': 1, 'pair': 'ETH/BTC', 'base_currency': 'BTC', 'open_date': ANY, 'open_date_hum': ANY, 'close_date': None, 'close_date_hum': None, 'open_rate': 1.099e-05, 'close_rate': None, 'current_rate': 1.098e-05, 'amount': 90.99181074, 'stake_amount': 0.001, 'close_profit': None, 'current_profit': -0.59, 'stop_loss': 0.0, 'initial_stop_loss': 0.0, 'initial_stop_loss_pct': None, 'stop_loss_pct': None, 'open_order': '(limit buy rem=0.00000000)' } == results[0] mocker.patch( 'freqtrade.exchange.Exchange.get_ticker', MagicMock( side_effect=DependencyException(f"Pair 'ETH/BTC' not available"))) # invalidate ticker cache rpc._freqtrade.exchange._cached_ticker = {} results = rpc._rpc_trade_status() assert isnan(results[0]['current_profit']) assert isnan(results[0]['current_rate']) assert { 'trade_id': 1, 'pair': 'ETH/BTC', 'base_currency': 'BTC', 'open_date': ANY, 'open_date_hum': ANY, 'close_date': None, 'close_date_hum': None, 'open_rate': 1.099e-05, 'close_rate': None, 'current_rate': ANY, 'amount': 90.99181074, 'stake_amount': 0.001, 'close_profit': None, 'current_profit': ANY, 'stop_loss': 0.0, 'initial_stop_loss': 0.0, 'initial_stop_loss_pct': None, 'stop_loss_pct': None, 'open_order': '(limit buy rem=0.00000000)' } == results[0]
def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None: patch_coinmarketcap(mocker) patch_exchange(mocker) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) cancel_order_mock = MagicMock() mocker.patch.multiple('freqtrade.exchange.Exchange', get_ticker=ticker, cancel_order=cancel_order_mock, get_order=MagicMock(return_value={ 'status': 'closed', 'type': 'limit', 'side': 'buy' }), get_fee=fee, get_markets=markets) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) rpc = RPC(freqtradebot) freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*trader is not running*'): rpc._rpc_forcesell(None) freqtradebot.state = State.RUNNING with pytest.raises(RPCException, match=r'.*invalid argument*'): rpc._rpc_forcesell(None) rpc._rpc_forcesell('all') freqtradebot.create_trade() rpc._rpc_forcesell('all') rpc._rpc_forcesell('1') freqtradebot.state = State.STOPPED with pytest.raises(RPCException, match=r'.*trader is not running*'): rpc._rpc_forcesell(None) with pytest.raises(RPCException, match=r'.*trader is not running*'): rpc._rpc_forcesell('all') freqtradebot.state = State.RUNNING assert cancel_order_mock.call_count == 0 # make an limit-buy open trade trade = Trade.query.filter(Trade.id == '1').first() filled_amount = trade.amount / 2 mocker.patch('freqtrade.exchange.Exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', 'side': 'buy', 'filled': filled_amount }) # check that the trade is called, which is done by ensuring exchange.cancel_order is called # and trade amount is updated rpc._rpc_forcesell('1') assert cancel_order_mock.call_count == 1 assert trade.amount == filled_amount freqtradebot.create_trade() trade = Trade.query.filter(Trade.id == '2').first() amount = trade.amount # make an limit-buy open trade, if there is no 'filled', don't sell it mocker.patch('freqtrade.exchange.Exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', 'side': 'buy', 'filled': None }) # check that the trade is called, which is done by ensuring exchange.cancel_order is called rpc._rpc_forcesell('2') assert cancel_order_mock.call_count == 2 assert trade.amount == amount freqtradebot.create_trade() # make an limit-sell open trade mocker.patch('freqtrade.exchange.Exchange.get_order', return_value={ 'status': 'open', 'type': 'limit', 'side': 'sell' }) rpc._rpc_forcesell('3') # status quo, no exchange calls assert cancel_order_mock.call_count == 2
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee, limit_buy_order, limit_sell_order, markets, mocker) -> None: mocker.patch.multiple( 'freqtrade.fiat_convert.Market', ticker=MagicMock(return_value={'price_usd': 15000.0}), ) patch_coinmarketcap(mocker) patch_exchange(mocker) mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock()) mocker.patch.multiple('freqtrade.exchange.Exchange', get_ticker=ticker, get_fee=fee, get_markets=markets) freqtradebot = FreqtradeBot(default_conf) patch_get_signal(freqtradebot, (True, False)) stake_currency = default_conf['stake_currency'] fiat_display_currency = default_conf['fiat_display_currency'] rpc = RPC(freqtradebot) rpc._fiat_converter = CryptoToFiatConverter() with pytest.raises(RPCException, match=r'.*no closed trade*'): rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) # Create some test data freqtradebot.create_trade() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Update the ticker with a market going up mocker.patch.multiple('freqtrade.exchange.Exchange', get_ticker=ticker_sell_up) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False freqtradebot.create_trade() trade = Trade.query.first() # Simulate fulfilled LIMIT_BUY order for trade trade.update(limit_buy_order) # Update the ticker with a market going up mocker.patch.multiple('freqtrade.exchange.Exchange', get_ticker=ticker_sell_up) trade.update(limit_sell_order) trade.close_date = datetime.utcnow() trade.is_open = False stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency) assert prec_satoshi(stats['profit_closed_coin'], 6.217e-05) assert prec_satoshi(stats['profit_closed_percent'], 6.2) assert prec_satoshi(stats['profit_closed_fiat'], 0.93255) assert prec_satoshi(stats['profit_all_coin'], 5.632e-05) assert prec_satoshi(stats['profit_all_percent'], 2.81) assert prec_satoshi(stats['profit_all_fiat'], 0.8448) assert stats['trade_count'] == 2 assert stats['first_trade_date'] == 'just now' assert stats['latest_trade_date'] == 'just now' assert stats['avg_duration'] == '0:00:00' assert stats['best_pair'] == 'ETH/BTC' assert prec_satoshi(stats['best_rate'], 6.2)