Esempio n. 1
0
def mock_trade_6(fee):
    """
    Simulate prod entry with open sell order
    """
    trade = Trade(
        pair='LTC/BTC',
        stake_amount=0.001,
        amount=2.0,
        amount_requested=2.0,
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=5),
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        is_open=True,
        open_rate=0.15,
        exchange='binance',
        strategy='SampleStrategy',
        buy_tag='TEST2',
        open_order_id="prod_sell_6",
        timeframe=5,
    )
    o = Order.parse_from_ccxt_object(mock_order_6(), 'LTC/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_6_sell(), 'LTC/BTC', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 2
0
def mock_trade_2(fee):
    """
    Closed trade...
    """
    trade = Trade(
        pair='ETC/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=123.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.123,
        close_rate=0.128,
        close_profit=0.005,
        close_profit_abs=0.000584127,
        exchange='binance',
        is_open=False,
        open_order_id='dry_run_sell_12345',
        strategy='StrategyTestV2',
        timeframe=5,
        buy_tag='TEST1',
        sell_reason='sell_signal',
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
        close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=2),
    )
    o = Order.parse_from_ccxt_object(mock_order_2(), 'ETC/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_2_sell(), 'ETC/BTC', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 3
0
def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
                            limit_sell_order, mocker) -> None:
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        get_balances=MagicMock(return_value=ticker),
        fetch_ticker=ticker,
        get_fee=fee,
    )

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    patch_get_signal(freqtradebot)
    rpc = RPC(freqtradebot)

    # Create some test data
    freqtradebot.enter_positions()
    trade = Trade.query.first()
    assert trade

    # Simulate fulfilled LIMIT_BUY order for trade
    oobj = Order.parse_from_ccxt_object(limit_buy_order, limit_buy_order['symbol'], 'buy')
    trade.update_trade(oobj)

    # 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)

    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_pct'], 6.2)
Esempio n. 4
0
def mock_trade_5(fee):
    """
    Simulate prod entry with stoploss
    """
    trade = Trade(
        pair='XRP/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=124.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=12),
        is_open=True,
        open_rate=0.123,
        exchange='binance',
        strategy='SampleStrategy',
        buy_tag='TEST1',
        stoploss_order_id='prod_stoploss_3455',
        timeframe=5,
    )
    o = Order.parse_from_ccxt_object(mock_order_5(), 'XRP/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_5_stoploss(), 'XRP/BTC', 'stoploss')
    trade.orders.append(o)
    return trade
Esempio n. 5
0
def mock_trade_usdt_7(fee):
    """
    Simulate prod entry with open sell order
    """
    trade = Trade(
        pair='LTC/USDT',
        stake_amount=20.0,
        amount=2.0,
        amount_requested=2.0,
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
        close_date=datetime.now(tz=timezone.utc) - timedelta(minutes=5),
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        is_open=False,
        open_rate=10.0,
        close_rate=8.0,
        close_profit=-0.2,
        close_profit_abs=-4.0,
        exchange='binance',
        strategy='SampleStrategy',
        open_order_id="prod_sell_6",
        timeframe=5,
    )
    o = Order.parse_from_ccxt_object(mock_order_usdt_7(), 'LTC/USDT', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_usdt_7_sell(), 'LTC/USDT', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 6
0
def mock_trade_3(fee):
    """
    Closed trade
    """
    trade = Trade(
        pair='XRP/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=123.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.05,
        close_rate=0.06,
        close_profit=0.01,
        close_profit_abs=0.000155,
        exchange='binance',
        is_open=False,
        strategy='StrategyTestV2',
        timeframe=5,
        sell_reason='roi',
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=20),
        close_date=datetime.now(tz=timezone.utc),
    )
    o = Order.parse_from_ccxt_object(mock_order_3(), 'XRP/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_3_sell(), 'XRP/BTC', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 7
0
def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee,
                                     ticker_sell_up, limit_buy_order,
                                     limit_sell_order):
    mocker.patch.multiple(
        'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
        get_price=MagicMock(return_value={'bitcoin': {
            'usd': 15000.0
        }}),
    )
    mocker.patch(
        'freqtrade.rpc.fiat_convert.CryptoToFiatConverter._find_price',
        return_value=15000.0)
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        fetch_ticker=ticker,
        get_fee=fee,
    )

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    patch_get_signal(freqtradebot)
    stake_currency = default_conf['stake_currency']
    fiat_display_currency = default_conf['fiat_display_currency']

    rpc = RPC(freqtradebot)

    # Create some test data
    freqtradebot.enter_positions()
    trade = Trade.query.first()
    # Simulate fulfilled LIMIT_BUY order for trade
    oobj = Order.parse_from_ccxt_object(limit_buy_order,
                                        limit_buy_order['symbol'], 'buy')
    trade.update_trade(oobj)
    # Update the ticker with a market going up
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          fetch_ticker=ticker_sell_up,
                          get_fee=fee)
    oobj = Order.parse_from_ccxt_object(limit_sell_order,
                                        limit_sell_order['symbol'], 'sell')
    trade.update_trade(oobj)
    trade.close_date = datetime.utcnow()
    trade.is_open = False

    for trade in Trade.query.order_by(Trade.id).all():
        trade.open_rate = None

    stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
    assert prec_satoshi(stats['profit_closed_coin'], 0)
    assert prec_satoshi(stats['profit_closed_percent_mean'], 0)
    assert prec_satoshi(stats['profit_closed_fiat'], 0)
    assert prec_satoshi(stats['profit_all_coin'], 0)
    assert prec_satoshi(stats['profit_all_percent_mean'], 0)
    assert prec_satoshi(stats['profit_all_fiat'], 0)
    assert stats['trade_count'] == 1
    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)
Esempio n. 8
0
def test_rpc_daily_profit(default_conf, update, ticker, fee, limit_buy_order,
                          limit_sell_order, markets, mocker) -> None:
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          fetch_ticker=ticker,
                          get_fee=fee,
                          markets=PropertyMock(return_value=markets))

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    patch_get_signal(freqtradebot)
    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.enter_positions()
    trade = Trade.query.first()
    assert trade

    # Simulate buy & sell
    oobj = Order.parse_from_ccxt_object(limit_buy_order,
                                        limit_buy_order['symbol'], 'buy')
    trade.update_trade(oobj)
    oobj = Order.parse_from_ccxt_object(limit_sell_order,
                                        limit_sell_order['symbol'], 'sell')
    trade.update_trade(oobj)
    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['data']) == 7
    assert days['stake_currency'] == default_conf['stake_currency']
    assert days['fiat_display_currency'] == default_conf[
        'fiat_display_currency']
    for day in days['data']:
        # [datetime.date(2018, 1, 11), '0.00000000 BTC', '0.000 USD']
        assert (day['abs_profit'] == 0.0 or day['abs_profit'] == 0.00006217)

        assert (day['fiat_value'] == 0.0 or day['fiat_value'] == 0.76748865)
    # ensure first day is current date
    assert str(days['data'][0]['date']) == 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)
Esempio n. 9
0
def mock_trade_5(fee):
    """
    Simulate prod entry with stoploss
    """
    trade = Trade(pair='XRP/BTC',
                  stake_amount=0.001,
                  amount=123.0,
                  amount_requested=124.0,
                  fee_open=fee.return_value,
                  fee_close=fee.return_value,
                  open_rate=0.123,
                  exchange='bittrex',
                  strategy='SampleStrategy',
                  stoploss_order_id='prod_stoploss_3455')
    o = Order.parse_from_ccxt_object(mock_order_5(), 'XRP/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_5_stoploss(), 'XRP/BTC',
                                     'stoploss')
    trade.orders.append(o)
    return trade
Esempio n. 10
0
def mock_trade_6(fee):
    """
    Simulate prod entry with open sell order
    """
    trade = Trade(
        pair='LTC/BTC',
        stake_amount=0.001,
        amount=2.0,
        amount_requested=2.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.15,
        exchange='bittrex',
        strategy='SampleStrategy',
        open_order_id="prod_sell_6",
    )
    o = Order.parse_from_ccxt_object(mock_order_6(), 'LTC/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_6_sell(), 'LTC/BTC', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 11
0
def mock_trade_3(fee):
    """
    Closed trade
    """
    trade = Trade(
        pair='XRP/BTC',
        stake_amount=0.001,
        amount=123.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.05,
        close_rate=0.06,
        close_profit=0.01,
        exchange='bittrex',
        is_open=False,
    )
    o = Order.parse_from_ccxt_object(mock_order_3(), 'XRP/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_3_sell(), 'XRP/BTC', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 12
0
def mock_trade_2(fee):
    """
    Closed trade...
    """
    trade = Trade(
        pair='ETC/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=123.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.123,
        close_rate=0.128,
        close_profit=0.005,
        exchange='bittrex',
        is_open=False,
        open_order_id='dry_run_sell_12345',
        strategy='DefaultStrategy',
    )
    o = Order.parse_from_ccxt_object(mock_order_2(), 'ETC/BTC', 'buy')
    trade.orders.append(o)
    o = Order.parse_from_ccxt_object(mock_order_2_sell(), 'ETC/BTC', 'sell')
    trade.orders.append(o)
    return trade
Esempio n. 13
0
def mock_trade_1(fee):
    trade = Trade(
        pair='ETH/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=123.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.123,
        exchange='bittrex',
        open_order_id='dry_run_buy_12345',
        strategy='DefaultStrategy',
    )
    o = Order.parse_from_ccxt_object(mock_order_1(), 'ETH/BTC', 'buy')
    trade.orders.append(o)
    return trade
Esempio n. 14
0
def mock_trade_1(fee):
    trade = Trade(
        pair='ETH/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=123.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        is_open=True,
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17),
        open_rate=0.123,
        exchange='binance',
        open_order_id='dry_run_buy_12345',
        strategy='StrategyTestV2',
        timeframe=5,
    )
    o = Order.parse_from_ccxt_object(mock_order_1(), 'ETH/BTC', 'buy')
    trade.orders.append(o)
    return trade
Esempio n. 15
0
def mock_trade_4(fee):
    """
    Simulate prod entry
    """
    trade = Trade(
        pair='ETC/BTC',
        stake_amount=0.001,
        amount=123.0,
        amount_requested=124.0,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_rate=0.123,
        exchange='bittrex',
        open_order_id='prod_buy_12345',
        strategy='DefaultStrategy',
        timeframe=5,
    )
    o = Order.parse_from_ccxt_object(mock_order_4(), 'ETC/BTC', 'buy')
    trade.orders.append(o)
    return trade
Esempio n. 16
0
def mock_trade_usdt_4(fee):
    """
    Simulate prod entry
    """
    trade = Trade(
        pair='ETC/USDT',
        stake_amount=20.0,
        amount=10.0,
        amount_requested=10.01,
        fee_open=fee.return_value,
        fee_close=fee.return_value,
        open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=14),
        is_open=True,
        open_rate=2.0,
        exchange='binance',
        open_order_id='prod_buy_12345',
        strategy='StrategyTestV2',
        timeframe=5,
    )
    o = Order.parse_from_ccxt_object(mock_order_usdt_4(), 'ETC/USDT', 'buy')
    trade.orders.append(o)
    return trade
Esempio n. 17
0
def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
                                                     limit_buy_order, mocker) -> None:
    """
    Tests workflow of selling stoploss_on_exchange.
    Sells
    * first trade as stoploss
    * 2nd trade is kept
    * 3rd trade is sold via sell-signal
    """
    default_conf['max_open_trades'] = 3
    default_conf['exchange']['name'] = 'binance'

    stoploss = {
        'id': 123,
        'info': {}
    }
    stoploss_order_open = {
        "id": "123",
        "timestamp": 1542707426845,
        "datetime": "2018-11-20T09:50:26.845Z",
        "lastTradeTimestamp": None,
        "symbol": "BTC/USDT",
        "type": "stop_loss_limit",
        "side": "sell",
        "price": 1.08801,
        "amount": 90.99181074,
        "cost": 0.0,
        "average": 0.0,
        "filled": 0.0,
        "remaining": 0.0,
        "status": "open",
        "fee": None,
        "trades": None
    }
    stoploss_order_closed = stoploss_order_open.copy()
    stoploss_order_closed['status'] = 'closed'
    stoploss_order_closed['filled'] = stoploss_order_closed['amount']

    # Sell first trade based on stoploss, keep 2nd and 3rd trade open
    stoploss_order_mock = MagicMock(
        side_effect=[stoploss_order_closed, stoploss_order_open, stoploss_order_open])
    # Sell 3rd trade (not called for the first trade)
    should_sell_mock = MagicMock(side_effect=[
        ExitCheckTuple(exit_type=ExitType.NONE),
        ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]
    )
    cancel_order_mock = MagicMock()
    mocker.patch('freqtrade.exchange.Binance.stoploss', stoploss)
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        fetch_ticker=ticker,
        get_fee=fee,
        amount_to_precision=lambda s, x, y: y,
        price_to_precision=lambda s, x, y: y,
        fetch_stoploss_order=stoploss_order_mock,
        cancel_stoploss_order_with_result=cancel_order_mock,
    )

    mocker.patch.multiple(
        'freqtrade.freqtradebot.FreqtradeBot',
        create_stoploss_order=MagicMock(return_value=True),
        _notify_exit=MagicMock(),
    )
    mocker.patch("freqtrade.strategy.interface.IStrategy.should_exit", should_sell_mock)
    wallets_mock = mocker.patch("freqtrade.wallets.Wallets.update", MagicMock())
    mocker.patch("freqtrade.wallets.Wallets.get_free", MagicMock(return_value=1000))

    freqtrade = get_patched_freqtradebot(mocker, default_conf)
    freqtrade.strategy.order_types['stoploss_on_exchange'] = True
    # Switch ordertype to market to close trade immediately
    freqtrade.strategy.order_types['exit'] = 'market'
    freqtrade.strategy.confirm_trade_entry = MagicMock(return_value=True)
    freqtrade.strategy.confirm_trade_exit = MagicMock(return_value=True)
    patch_get_signal(freqtrade)

    # Create some test data
    freqtrade.enter_positions()
    assert freqtrade.strategy.confirm_trade_entry.call_count == 3
    freqtrade.strategy.confirm_trade_entry.reset_mock()
    assert freqtrade.strategy.confirm_trade_exit.call_count == 0
    wallets_mock.reset_mock()

    trades = Trade.query.all()
    # Make sure stoploss-order is open and trade is bought (since we mock update_trade_state)
    for trade in trades:
        stoploss_order_closed['id'] = '3'
        oobj = Order.parse_from_ccxt_object(stoploss_order_closed, trade.pair, 'stoploss')

        trade.orders.append(oobj)
        trade.stoploss_order_id = '3'
        trade.open_order_id = None

    n = freqtrade.exit_positions(trades)
    assert n == 2
    assert should_sell_mock.call_count == 2
    assert freqtrade.strategy.confirm_trade_entry.call_count == 0
    assert freqtrade.strategy.confirm_trade_exit.call_count == 1
    freqtrade.strategy.confirm_trade_exit.reset_mock()

    # Only order for 3rd trade needs to be cancelled
    assert cancel_order_mock.call_count == 1
    # Wallets must be updated between stoploss cancellation and selling, and will be updated again
    # during update_trade_state
    assert wallets_mock.call_count == 4

    trade = trades[0]
    assert trade.exit_reason == ExitType.STOPLOSS_ON_EXCHANGE.value
    assert not trade.is_open

    trade = trades[1]
    assert not trade.exit_reason
    assert trade.is_open

    trade = trades[2]
    assert trade.exit_reason == ExitType.EXIT_SIGNAL.value
    assert not trade.is_open
Esempio n. 18
0
def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
                              limit_buy_order, limit_sell_order,
                              mocker) -> None:
    mocker.patch.multiple(
        'freqtrade.rpc.fiat_convert.CoinGeckoAPI',
        get_price=MagicMock(return_value={'bitcoin': {
            'usd': 15000.0
        }}),
    )
    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',
        fetch_ticker=ticker,
        get_fee=fee,
    )

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    patch_get_signal(freqtradebot)
    stake_currency = default_conf['stake_currency']
    fiat_display_currency = default_conf['fiat_display_currency']

    rpc = RPC(freqtradebot)
    rpc._fiat_converter = CryptoToFiatConverter()

    res = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
    assert res['trade_count'] == 0
    assert res['first_trade_date'] == ''
    assert res['first_trade_timestamp'] == 0
    assert res['latest_trade_date'] == ''
    assert res['latest_trade_timestamp'] == 0

    # Create some test data
    freqtradebot.enter_positions()
    trade = Trade.query.first()
    # Simulate fulfilled LIMIT_BUY order for trade
    oobj = Order.parse_from_ccxt_object(limit_buy_order,
                                        limit_buy_order['symbol'], 'sell')
    trade.update_trade(oobj)

    # Update the ticker with a market going up
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          fetch_ticker=ticker_sell_up)
    oobj = Order.parse_from_ccxt_object(limit_sell_order,
                                        limit_sell_order['symbol'], 'sell')
    trade.update_trade(oobj)
    trade.close_date = datetime.utcnow()
    trade.is_open = False

    freqtradebot.enter_positions()
    trade = Trade.query.first()
    # Simulate fulfilled LIMIT_BUY order for trade
    oobj = Order.parse_from_ccxt_object(limit_buy_order,
                                        limit_buy_order['symbol'], 'buy')
    trade.update_trade(oobj)

    # Update the ticker with a market going up
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          fetch_ticker=ticker_sell_up)
    oobj = Order.parse_from_ccxt_object(limit_sell_order,
                                        limit_sell_order['symbol'], 'sell')
    trade.update_trade(oobj)
    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_mean'], 6.2)
    assert prec_satoshi(stats['profit_closed_fiat'], 0.93255)
    assert prec_satoshi(stats['profit_all_coin'], 5.802e-05)
    assert prec_satoshi(stats['profit_all_percent_mean'], 2.89)
    assert prec_satoshi(stats['profit_all_fiat'], 0.8703)
    assert stats['trade_count'] == 2
    assert stats['first_trade_date'] == 'just now'
    assert stats['latest_trade_date'] == 'just now'
    assert stats['avg_duration'] in ('0:00:00', '0:00:01', '0:00:02')
    assert stats['best_pair'] == 'ETH/BTC'
    assert prec_satoshi(stats['best_rate'], 6.2)

    # Test non-available pair
    mocker.patch(
        'freqtrade.exchange.Exchange.get_rate',
        MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))
    stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
    assert stats['trade_count'] == 2
    assert stats['first_trade_date'] == 'just now'
    assert stats['latest_trade_date'] == 'just now'
    assert stats['avg_duration'] in ('0:00:00', '0:00:01', '0:00:02')
    assert stats['best_pair'] == 'ETH/BTC'
    assert prec_satoshi(stats['best_rate'], 6.2)
    assert isnan(stats['profit_all_coin'])