Esempio n. 1
0
def blacklist_post(payload: BlacklistPayload, rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_blacklist(payload.blacklist)
Esempio n. 2
0
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]
Esempio n. 3
0
def test_rpcforcebuy(mocker, default_conf, ticker, fee, markets,
                     limit_buy_order) -> None:
    default_conf['forcebuy_enable'] = True
    patch_exchange(mocker)
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    buy_mm = MagicMock(return_value={'id': limit_buy_order['id']})
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          get_balances=MagicMock(return_value=ticker),
                          get_ticker=ticker,
                          get_fee=fee,
                          markets=PropertyMock(return_value=markets),
                          buy=buy_mm)

    freqtradebot = FreqtradeBot(default_conf)
    patch_get_signal(freqtradebot, (True, False))
    rpc = RPC(freqtradebot)
    pair = 'ETH/BTC'
    trade = rpc._rpc_forcebuy(pair, None)
    assert isinstance(trade, Trade)
    assert trade.pair == pair
    assert trade.open_rate == ticker()['ask']

    # Test buy duplicate
    with pytest.raises(RPCException,
                       match=r'position for ETH/BTC already open - id: 1'):
        rpc._rpc_forcebuy(pair, 0.0001)
    pair = 'XRP/BTC'
    trade = rpc._rpc_forcebuy(pair, 0.0001)
    assert isinstance(trade, Trade)
    assert trade.pair == pair
    assert trade.open_rate == 0.0001

    # Test buy pair not with stakes
    with pytest.raises(
            RPCException,
            match=r'Wrong pair selected. Please pairs with stake.*'):
        rpc._rpc_forcebuy('XRP/ETH', 0.0001)
    pair = 'XRP/BTC'

    # Test not buying
    default_conf['stake_amount'] = 0.0000001
    freqtradebot = FreqtradeBot(default_conf)
    patch_get_signal(freqtradebot, (True, False))
    rpc = RPC(freqtradebot)
    pair = 'TKN/BTC'
    trade = rpc._rpc_forcebuy(pair, None)
    assert trade is None
Esempio n. 4
0
def test_send_msg_webhook(default_conf, mocker):
    default_conf["webhook"] = get_webhook_dict()
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
    # Test buy
    msg_mock = MagicMock()
    mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
    msg = {
        'type': RPCMessageType.BUY,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] ==
            default_conf["webhook"]["webhookbuy"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] ==
            default_conf["webhook"]["webhookbuy"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] ==
            default_conf["webhook"]["webhookbuy"]["value3"].format(**msg))
    # Test buy cancel
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.BUY_CANCEL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'limit': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] ==
            default_conf["webhook"]["webhookbuycancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] ==
            default_conf["webhook"]["webhookbuycancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] ==
            default_conf["webhook"]["webhookbuycancel"]["value3"].format(**msg))
    # Test buy fill
    msg_mock.reset_mock()

    msg = {
        'type': RPCMessageType.BUY_FILL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'open_rate': 0.005,
        'stake_amount': 0.8,
        'stake_amount_fiat': 500,
        'stake_currency': 'BTC',
        'fiat_currency': 'EUR'
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] ==
            default_conf["webhook"]["webhookbuyfill"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] ==
            default_conf["webhook"]["webhookbuyfill"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] ==
            default_conf["webhook"]["webhookbuyfill"]["value3"].format(**msg))
    # Test sell
    msg_mock.reset_mock()
    msg = {
        'type': RPCMessageType.SELL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'limit': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': SellType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] ==
            default_conf["webhook"]["webhooksell"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] ==
            default_conf["webhook"]["webhooksell"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] ==
            default_conf["webhook"]["webhooksell"]["value3"].format(**msg))
    # Test sell cancel
    msg_mock.reset_mock()
    msg = {
        'type': RPCMessageType.SELL_CANCEL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'limit': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': SellType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] ==
            default_conf["webhook"]["webhooksellcancel"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] ==
            default_conf["webhook"]["webhooksellcancel"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] ==
            default_conf["webhook"]["webhooksellcancel"]["value3"].format(**msg))
    # Test Sell fill
    msg_mock.reset_mock()
    msg = {
        'type': RPCMessageType.SELL_FILL,
        'exchange': 'Binance',
        'pair': 'ETH/BTC',
        'gain': "profit",
        'close_rate': 0.005,
        'amount': 0.8,
        'order_type': 'limit',
        'open_rate': 0.004,
        'current_rate': 0.005,
        'profit_amount': 0.001,
        'profit_ratio': 0.20,
        'stake_currency': 'BTC',
        'sell_reason': SellType.STOP_LOSS.value
    }
    webhook.send_msg(msg=msg)
    assert msg_mock.call_count == 1
    assert (msg_mock.call_args[0][0]["value1"] ==
            default_conf["webhook"]["webhooksellfill"]["value1"].format(**msg))
    assert (msg_mock.call_args[0][0]["value2"] ==
            default_conf["webhook"]["webhooksellfill"]["value2"].format(**msg))
    assert (msg_mock.call_args[0][0]["value3"] ==
            default_conf["webhook"]["webhooksellfill"]["value3"].format(**msg))

    for msgtype in [RPCMessageType.STATUS,
                    RPCMessageType.WARNING,
                    RPCMessageType.STARTUP]:
        # Test notification
        msg = {
            'type': msgtype,
            'status': 'Unfilled sell order for BTC cancelled due to timeout'
        }
        msg_mock = MagicMock()
        mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
        webhook.send_msg(msg)
        assert msg_mock.call_count == 1
        assert (msg_mock.call_args[0][0]["value1"] ==
                default_conf["webhook"]["webhookstatus"]["value1"].format(**msg))
        assert (msg_mock.call_args[0][0]["value2"] ==
                default_conf["webhook"]["webhookstatus"]["value2"].format(**msg))
        assert (msg_mock.call_args[0][0]["value3"] ==
                default_conf["webhook"]["webhookstatus"]["value3"].format(**msg))
Esempio n. 5
0
def test_rpc_edge_disabled(mocker, default_conf) -> None:
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    rpc = RPC(freqtradebot)
    with pytest.raises(RPCException, match=r'Edge is not enabled.'):
        rpc._rpc_edge()
Esempio n. 6
0
def daily(timescale: int = 7,
          rpc: RPC = Depends(get_rpc),
          config=Depends(get_config)):
    return rpc._rpc_daily_profit(timescale, config['stake_currency'],
                                 config.get('fiat_display_currency', ''))
Esempio n. 7
0
def trades(limit: int = 500, offset: int = 0, rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_trade_history(limit, offset=offset, order_by_id=True)
Esempio n. 8
0
def stop(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_stop()
Esempio n. 9
0
def stop_buy(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_stopbuy()
Esempio n. 10
0
def delete_lock_pair(payload: DeleteLockRequest, rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_delete_lock(lockid=payload.lockid, pair=payload.pair)
Esempio n. 11
0
def logs(limit: Optional[int] = None):
    return RPC._rpc_get_logs(limit)
Esempio n. 12
0
def delete_lock(lockid: int, rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_delete_lock(lockid=lockid)
Esempio n. 13
0
def locks(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_locks()
Esempio n. 14
0
def whitelist(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_whitelist()
Esempio n. 15
0
def profit(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
    return rpc._rpc_trade_statistics(config['stake_currency'],
                                     config.get('fiat_display_currency'))
Esempio n. 16
0
def reload_config(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_reload_config()
Esempio n. 17
0
def stats(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_stats()
Esempio n. 18
0
def pair_candles(pair: str,
                 timeframe: str,
                 limit: Optional[int],
                 rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_analysed_dataframe(pair, timeframe, limit)
Esempio n. 19
0
def status(rpc: RPC = Depends(get_rpc)):
    try:
        return rpc._rpc_trade_status()
    except RPCException:
        return []
Esempio n. 20
0
def plot_config(rpc: RPC = Depends(get_rpc)):
    return PlotConfig.parse_obj(rpc._rpc_plot_config())
Esempio n. 21
0
def test__init__(mocker, default_conf):
    default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
    webhook = Webhook(RPC(get_patched_freqtradebot(mocker, default_conf)), default_conf)
    assert webhook._config == default_conf
Esempio n. 22
0
def sysinfo():
    return RPC._rpc_sysinfo()
Esempio n. 23
0
def test_rpc_balance_handle(default_conf, mocker, tickers):
    mock_balance = {
        'BTC': {
            'free': 10.0,
            'total': 12.0,
            'used': 2.0,
        },
        'ETH': {
            'free': 1.0,
            'total': 5.0,
            'used': 4.0,
        },
        'USDT': {
            'free': 5.0,
            'total': 10.0,
            'used': 5.0,
        }
    }

    mocker.patch.multiple(
        'freqtrade.rpc.fiat_convert.Market',
        ticker=MagicMock(return_value={'price_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',
        get_balances=MagicMock(return_value=mock_balance),
        get_tickers=tickers,
        get_valid_pair_combination=MagicMock(
            side_effect=lambda a, b: f"{b}/{a}" if a == "USDT" else f"{a}/{b}")
    )
    default_conf['dry_run'] = False
    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    patch_get_signal(freqtradebot, (True, False))
    rpc = RPC(freqtradebot)
    rpc._fiat_converter = CryptoToFiatConverter()

    result = rpc._rpc_balance(default_conf['stake_currency'], default_conf['fiat_display_currency'])
    assert prec_satoshi(result['total'], 12.309096315)
    assert prec_satoshi(result['value'], 184636.44472997)
    assert 'USD' == result['symbol']
    assert result['currencies'] == [
        {'currency': 'BTC',
         'free': 10.0,
         'balance': 12.0,
         'used': 2.0,
         'est_stake': 12.0,
         'stake': 'BTC',
         },
        {'free': 1.0,
         'balance': 5.0,
         'currency': 'ETH',
         'est_stake': 0.30794,
         'used': 4.0,
         'stake': 'BTC',

         },
        {'free': 5.0,
         'balance': 10.0,
         'currency': 'USDT',
         'est_stake': 0.0011563153318162476,
         'used': 5.0,
         'stake': 'BTC',
         }
    ]
    assert result['total'] == 12.309096315331816
Esempio n. 24
0
def balance(rpc: RPC = Depends(get_rpc), config=Depends(get_config)):
    """Account Balances"""
    return rpc._rpc_balance(
        config['stake_currency'],
        config.get('fiat_display_currency', ''),
    )
Esempio n. 25
0
def test_api_run(default_conf, mocker, caplog):
    default_conf.update({
        "api_server": {
            "enabled": True,
            "listen_ip_address": "127.0.0.1",
            "listen_port": 8080,
            "username": "******",
            "password": "******",
        }
    })
    mocker.patch('freqtrade.rpc.telegram.Updater', MagicMock())

    server_mock = MagicMock()
    mocker.patch('freqtrade.rpc.api_server.webserver.UvicornServer',
                 server_mock)

    apiserver = ApiServer(RPC(get_patched_freqtradebot(mocker, default_conf)),
                          default_conf)

    assert server_mock.call_count == 1
    assert apiserver._config == default_conf
    apiserver.start_api()
    assert server_mock.call_count == 2
    assert server_mock.call_args_list[0][0][0].host == "127.0.0.1"
    assert server_mock.call_args_list[0][0][0].port == 8080
    assert isinstance(server_mock.call_args_list[0][0][0].app, FastAPI)

    assert log_has("Starting HTTP Server at 127.0.0.1:8080", caplog)
    assert log_has("Starting Local Rest Server.", caplog)

    # Test binding to public
    caplog.clear()
    server_mock.reset_mock()
    apiserver._config.update({
        "api_server": {
            "enabled": True,
            "listen_ip_address": "0.0.0.0",
            "listen_port": 8089,
            "password": "",
        }
    })
    apiserver.start_api()

    assert server_mock.call_count == 1
    assert server_mock.call_args_list[0][0][0].host == "0.0.0.0"
    assert server_mock.call_args_list[0][0][0].port == 8089
    assert isinstance(server_mock.call_args_list[0][0][0].app, FastAPI)
    assert log_has("Starting HTTP Server at 0.0.0.0:8089", caplog)
    assert log_has("Starting Local Rest Server.", caplog)
    assert log_has(
        "SECURITY WARNING - Local Rest Server listening to external connections",
        caplog)
    assert log_has(
        "SECURITY WARNING - This is insecure please set to your loopback,"
        "e.g 127.0.0.1 in config.json", caplog)
    assert log_has(
        "SECURITY WARNING - No password for local REST Server defined. "
        "Please make sure that this is intentional!", caplog)
    assert log_has_re(
        "SECURITY WARNING - `jwt_secret_key` seems to be default.*", caplog)

    # Test crashing API server
    caplog.clear()
    mocker.patch('freqtrade.rpc.api_server.webserver.UvicornServer',
                 MagicMock(side_effect=Exception))
    apiserver.start_api()
    assert log_has("Api server failed to start.", caplog)
Esempio n. 26
0
def count(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_count()
Esempio n. 27
0
def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
    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,
                          markets=PropertyMock(return_value=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)

    msg = rpc._rpc_forcesell('all')
    assert msg == {'result': 'Created sell orders for all open trades.'}

    freqtradebot.create_trade()
    msg = rpc._rpc_forcesell('all')
    assert msg == {'result': 'Created sell orders for all open trades.'}

    msg = rpc._rpc_forcesell('1')
    assert msg == {'result': 'Created sell order for trade 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
    msg = rpc._rpc_forcesell('2')
    assert msg == {'result': 'Created sell order for trade 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'
                 })
    msg = rpc._rpc_forcesell('3')
    assert msg == {'result': 'Created sell order for trade 3.'}
    # status quo, no exchange calls
    assert cancel_order_mock.call_count == 2
Esempio n. 28
0
def performance(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_performance()
Esempio n. 29
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, (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.enter_positions()
    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',
                          fetch_ticker=ticker_sell_up)
    trade.update(limit_sell_order)
    trade.close_date = datetime.utcnow()
    trade.is_open = False

    freqtradebot.enter_positions()
    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',
                          fetch_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.802e-05)
    assert prec_satoshi(stats['profit_all_percent'], 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'] == '0:00:00'
    assert stats['best_pair'] == 'ETH/BTC'
    assert prec_satoshi(stats['best_rate'], 6.2)

    # Test non-available pair
    mocker.patch(
        'freqtrade.freqtradebot.FreqtradeBot.get_sell_rate',
        MagicMock(
            side_effect=DependencyException("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'] == '0:00:00'
    assert stats['best_pair'] == 'ETH/BTC'
    assert prec_satoshi(stats['best_rate'], 6.2)
    assert isnan(stats['profit_all_coin'])
Esempio n. 30
0
def blacklist(rpc: RPC = Depends(get_rpc)):
    return rpc._rpc_blacklist()