示例#1
0
def test_api_count(botclient, mocker, ticker, fee, markets):
    ftbot, client = botclient
    patch_get_signal(ftbot, (True, False))
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        get_balances=MagicMock(return_value=ticker),
        fetch_ticker=ticker,
        get_fee=fee,
        markets=PropertyMock(return_value=markets)
    )
    rc = client_get(client, f"{BASE_URI}/count")
    assert_response(rc)

    assert rc.json()["current"] == 0
    assert rc.json()["max"] == 1

    # Create some test data
    create_mock_trades(fee)
    rc = client_get(client, f"{BASE_URI}/count")
    assert_response(rc)
    assert rc.json()["current"] == 4
    assert rc.json()["max"] == 1

    ftbot.config['max_open_trades'] = float('inf')
    rc = client_get(client, f"{BASE_URI}/count")
    assert rc.json()["max"] == -1
示例#2
0
def test_api_stats(
    botclient,
    mocker,
    ticker,
    fee,
    markets,
):
    ftbot, client = botclient
    patch_get_signal(ftbot, (True, False, None))
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          get_balances=MagicMock(return_value=ticker),
                          fetch_ticker=ticker,
                          get_fee=fee,
                          markets=PropertyMock(return_value=markets))

    rc = client_get(client, f"{BASE_URI}/stats")
    assert_response(rc, 200)
    assert 'durations' in rc.json()
    assert 'sell_reasons' in rc.json()

    create_mock_trades(fee)

    rc = client_get(client, f"{BASE_URI}/stats")
    assert_response(rc, 200)
    assert 'durations' in rc.json()
    assert 'sell_reasons' in rc.json()

    assert 'wins' in rc.json()['durations']
    assert 'losses' in rc.json()['durations']
    assert 'draws' in rc.json()['durations']
示例#3
0
def test_total_open_trades_stakes(fee):

    res = Trade.total_open_trades_stakes()
    assert res == 0
    create_mock_trades(fee)
    res = Trade.total_open_trades_stakes()
    assert res == 0.004
示例#4
0
def test_sell_reason_performance_handle_2(mocker, default_conf, markets, fee):
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        markets=PropertyMock(return_value=markets)
    )

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    create_mock_trades(fee)
    rpc = RPC(freqtradebot)

    res = rpc._rpc_sell_reason_performance(None)

    assert len(res) == 2
    assert res[0]['sell_reason'] == 'sell_signal'
    assert res[0]['count'] == 1
    assert prec_satoshi(res[0]['profit_pct'], 0.5)
    assert res[1]['sell_reason'] == 'roi'
    assert res[1]['count'] == 1
    assert prec_satoshi(res[1]['profit_pct'], 1.0)

    # Test for a specific pair
    res = rpc._rpc_sell_reason_performance('ETC/BTC')
    assert len(res) == 1
    assert res[0]['count'] == 1
    assert res[0]['sell_reason'] == 'sell_signal'
    assert prec_satoshi(res[0]['profit_pct'], 0.5)
示例#5
0
def test_api_trades(botclient, mocker, fee, markets):
    ftbot, client = botclient
    patch_get_signal(ftbot)
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        markets=PropertyMock(return_value=markets)
    )
    rc = client_get(client, f"{BASE_URI}/trades")
    assert_response(rc)
    assert len(rc.json()) == 3
    assert rc.json()['trades_count'] == 0
    assert rc.json()['total_trades'] == 0

    create_mock_trades(fee)

    rc = client_get(client, f"{BASE_URI}/trades")
    assert_response(rc)
    assert len(rc.json()['trades']) == 2
    assert rc.json()['trades_count'] == 2
    assert rc.json()['total_trades'] == 2
    rc = client_get(client, f"{BASE_URI}/trades?limit=1")
    assert_response(rc)
    assert len(rc.json()['trades']) == 1
    assert rc.json()['trades_count'] == 1
    assert rc.json()['total_trades'] == 2
示例#6
0
def test_show_trades(mocker, fee, capsys, caplog):
    mocker.patch("freqtrade.persistence.init_db")
    create_mock_trades(fee, False)
    args = ["show-trades", "--db-url", "sqlite:///"]
    pargs = get_args(args)
    pargs['config'] = None
    start_show_trades(pargs)
    assert log_has(f"Printing {MOCK_TRADE_COUNT} Trades: ", caplog)
    captured = capsys.readouterr()
    assert "Trade(id=1" in captured.out
    assert "Trade(id=2" in captured.out
    assert "Trade(id=3" in captured.out
    args = [
        "show-trades", "--db-url", "sqlite:///", "--print-json", "--trade-ids",
        "1", "2"
    ]
    pargs = get_args(args)
    pargs['config'] = None
    start_show_trades(pargs)

    captured = capsys.readouterr()
    assert log_has("Printing 2 Trades: ", caplog)
    assert '"trade_id": 1' in captured.out
    assert '"trade_id": 2' in captured.out
    assert '"trade_id": 3' not in captured.out
    args = [
        "show-trades",
    ]
    pargs = get_args(args)
    pargs['config'] = None

    with pytest.raises(OperationalException,
                       match=r"--db-url is required for this command."):
        start_show_trades(pargs)
示例#7
0
def test_sync_wallet_futures_dry(mocker, default_conf, fee):
    default_conf['dry_run'] = True
    default_conf['trading_mode'] = 'futures'
    default_conf['margin_mode'] = 'isolated'
    freqtrade = get_patched_freqtradebot(mocker, default_conf)
    assert len(freqtrade.wallets._wallets) == 1
    assert len(freqtrade.wallets._positions) == 0

    create_mock_trades(fee, is_short=None)

    freqtrade.wallets.update()

    assert len(freqtrade.wallets._wallets) == 1
    assert len(freqtrade.wallets._positions) == 4
    positions = freqtrade.wallets.get_all_positions()
    positions['ETH/BTC'].side == 'short'
    positions['ETC/BTC'].side == 'long'
    positions['XRP/BTC'].side == 'long'
    positions['LTC/BTC'].side == 'short'

    assert freqtrade.wallets.get_starting_balance(
    ) == default_conf['dry_run_wallet']
    total = freqtrade.wallets.get_total('BTC')
    free = freqtrade.wallets.get_free('BTC')
    used = freqtrade.wallets.get_used('BTC')
    assert free + used == total
示例#8
0
def test_get_open(fee, use_db):
    Trade.use_db = use_db
    Trade.reset_trades()

    create_mock_trades(fee, use_db)
    assert len(Trade.get_open_trades()) == 4

    Trade.use_db = True
示例#9
0
def test_get_overall_performance(fee):

    create_mock_trades(fee)
    res = Trade.get_overall_performance()

    assert len(res) == 1
    assert 'pair' in res[0]
    assert 'profit' in res[0]
    assert 'count' in res[0]
示例#10
0
def test_get_best_pair(fee):

    res = Trade.get_best_pair()
    assert res is None

    create_mock_trades(fee)
    res = Trade.get_best_pair()
    assert len(res) == 2
    assert res[0] == 'ETC/BTC'
    assert res[1] == 0.005
示例#11
0
def test_total_open_trades_stakes(fee, use_db):

    Trade.use_db = use_db
    res = Trade.total_open_trades_stakes()
    assert res == 0
    create_mock_trades(fee, use_db)
    res = Trade.total_open_trades_stakes()
    assert res == 0.004

    Trade.use_db = True
示例#12
0
def test_get_total_closed_profit(fee, use_db):

    Trade.use_db = use_db
    Trade.reset_trades()
    res = Trade.get_total_closed_profit()
    assert res == 0
    create_mock_trades(fee, use_db)
    res = Trade.get_total_closed_profit()
    assert res == 0.000739127

    Trade.use_db = True
示例#13
0
def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog):
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    stoploss_mock = MagicMock()
    cancel_mock = MagicMock()
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        markets=PropertyMock(return_value=markets),
        cancel_order=cancel_mock,
        cancel_stoploss_order=stoploss_mock,
    )

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    freqtradebot.strategy.order_types['stoploss_on_exchange'] = True
    create_mock_trades(fee)
    rpc = RPC(freqtradebot)
    with pytest.raises(RPCException, match='invalid argument'):
        rpc._rpc_delete('200')

    create_mock_trades(fee)
    trades = Trade.query.all()
    trades[1].stoploss_order_id = '1234'
    trades[2].stoploss_order_id = '1234'
    assert len(trades) > 2

    res = rpc._rpc_delete('1')
    assert isinstance(res, dict)
    assert res['result'] == 'success'
    assert res['trade_id'] == '1'
    assert res['cancel_order_count'] == 1
    assert cancel_mock.call_count == 1
    assert stoploss_mock.call_count == 0
    cancel_mock.reset_mock()
    stoploss_mock.reset_mock()

    res = rpc._rpc_delete('2')
    assert isinstance(res, dict)
    assert cancel_mock.call_count == 1
    assert stoploss_mock.call_count == 1
    assert res['cancel_order_count'] == 2

    stoploss_mock = mocker.patch(
        'freqtrade.exchange.Exchange.cancel_stoploss_order',
        side_effect=InvalidOrderException)

    res = rpc._rpc_delete('3')
    assert stoploss_mock.call_count == 1
    stoploss_mock.reset_mock()

    cancel_mock = mocker.patch('freqtrade.exchange.Exchange.cancel_order',
                               side_effect=InvalidOrderException)

    res = rpc._rpc_delete('4')
    assert cancel_mock.call_count == 1
    assert stoploss_mock.call_count == 0
示例#14
0
def test_api_profit(botclient, mocker, ticker, fee, markets):
    ftbot, client = botclient
    patch_get_signal(ftbot)
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        get_balances=MagicMock(return_value=ticker),
        fetch_ticker=ticker,
        get_fee=fee,
        markets=PropertyMock(return_value=markets)
    )

    rc = client_get(client, f"{BASE_URI}/profit")
    assert_response(rc, 200)
    assert rc.json()['trade_count'] == 0

    create_mock_trades(fee)
    # Simulate fulfilled LIMIT_BUY order for trade

    rc = client_get(client, f"{BASE_URI}/profit")
    assert_response(rc)
    assert rc.json() == {'avg_duration': ANY,
                         'best_pair': 'XRP/BTC',
                         'best_rate': 1.0,
                         'best_pair_profit_ratio': 0.01,
                         'first_trade_date': ANY,
                         'first_trade_timestamp': ANY,
                         'latest_trade_date': '5 minutes ago',
                         'latest_trade_timestamp': ANY,
                         'profit_all_coin': -44.0631579,
                         'profit_all_fiat': -543959.6842755,
                         'profit_all_percent_mean': -66.41,
                         'profit_all_ratio_mean': -0.6641100666666667,
                         'profit_all_percent_sum': -398.47,
                         'profit_all_ratio_sum': -3.9846604,
                         'profit_all_percent': -4.41,
                         'profit_all_ratio': -0.044063014216106644,
                         'profit_closed_coin': 0.00073913,
                         'profit_closed_fiat': 9.124559849999999,
                         'profit_closed_ratio_mean': 0.0075,
                         'profit_closed_percent_mean': 0.75,
                         'profit_closed_ratio_sum': 0.015,
                         'profit_closed_percent_sum': 1.5,
                         'profit_closed_ratio': 7.391275897987988e-07,
                         'profit_closed_percent': 0.0,
                         'trade_count': 6,
                         'closed_trade_count': 2,
                         'winning_trades': 2,
                         'losing_trades': 0,
                         }
示例#15
0
def test_get_trades_proxy(fee, use_db):
    Trade.use_db = use_db
    Trade.reset_trades()
    create_mock_trades(fee, use_db)
    trades = Trade.get_trades_proxy()
    assert len(trades) == 6

    assert isinstance(trades[0], Trade)

    assert len(Trade.get_trades_proxy(is_open=True)) == 4
    assert len(Trade.get_trades_proxy(is_open=False)) == 2
    opendate = datetime.now(tz=timezone.utc) - timedelta(minutes=15)

    assert len(Trade.get_trades_proxy(open_date=opendate)) == 3

    Trade.use_db = True
示例#16
0
def test_api_trade_single(botclient, mocker, fee, ticker, markets):
    ftbot, client = botclient
    patch_get_signal(ftbot)
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        markets=PropertyMock(return_value=markets),
        fetch_ticker=ticker,
    )
    rc = client_get(client, f"{BASE_URI}/trade/3")
    assert_response(rc, 404)
    assert rc.json()['detail'] == 'Trade not found.'

    create_mock_trades(fee)

    rc = client_get(client, f"{BASE_URI}/trade/3")
    assert_response(rc)
    assert rc.json()['trade_id'] == 3
示例#17
0
def test_load_trades_from_db(default_conf, fee, mocker):

    create_mock_trades(fee)
    # remove init so it does not init again
    init_mock = mocker.patch('freqtrade.persistence.init', MagicMock())

    trades = load_trades_from_db(db_url=default_conf['db_url'])
    assert init_mock.call_count == 1
    assert len(trades) == 3
    assert isinstance(trades, DataFrame)
    assert "pair" in trades.columns
    assert "open_time" in trades.columns
    assert "profit_percent" in trades.columns

    for col in BT_DATA_COLUMNS:
        if col not in ['index', 'open_at_end']:
            assert col in trades.columns
示例#18
0
def test_select_order(fee):
    create_mock_trades(fee)

    trades = Trade.get_trades().all()

    # Open buy order, no sell order
    order = trades[0].select_order('buy', True)
    assert order is None
    order = trades[0].select_order('buy', False)
    assert order is not None
    order = trades[0].select_order('sell', None)
    assert order is None

    # closed buy order, and open sell order
    order = trades[1].select_order('buy', True)
    assert order is None
    order = trades[1].select_order('buy', False)
    assert order is not None
    order = trades[1].select_order('buy', None)
    assert order is not None
    order = trades[1].select_order('sell', True)
    assert order is None
    order = trades[1].select_order('sell', False)
    assert order is not None

    # Has open buy order
    order = trades[3].select_order('buy', True)
    assert order is not None
    order = trades[3].select_order('buy', False)
    assert order is None

    # Open sell order
    order = trades[4].select_order('buy', True)
    assert order is None
    order = trades[4].select_order('buy', False)
    assert order is not None

    order = trades[4].select_order('sell', True)
    assert order is not None
    assert order.ft_order_side == 'stoploss'
    order = trades[4].select_order('sell', False)
    assert order is None
示例#19
0
def test_api_delete_trade(botclient, mocker, fee, markets):
    ftbot, client = botclient
    patch_get_signal(ftbot)
    stoploss_mock = MagicMock()
    cancel_mock = MagicMock()
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        markets=PropertyMock(return_value=markets),
        cancel_order=cancel_mock,
        cancel_stoploss_order=stoploss_mock,
    )
    rc = client_delete(client, f"{BASE_URI}/trades/1")
    # Error - trade won't exist yet.
    assert_response(rc, 502)

    create_mock_trades(fee)

    ftbot.strategy.order_types['stoploss_on_exchange'] = True
    trades = Trade.query.all()
    trades[1].stoploss_order_id = '1234'
    Trade.commit()
    assert len(trades) > 2

    rc = client_delete(client, f"{BASE_URI}/trades/1")
    assert_response(rc)
    assert rc.json()['result_msg'] == 'Deleted trade 1. Closed 1 open orders.'
    assert len(trades) - 1 == len(Trade.query.all())
    assert cancel_mock.call_count == 1

    cancel_mock.reset_mock()
    rc = client_delete(client, f"{BASE_URI}/trades/1")
    # Trade is gone now.
    assert_response(rc, 502)
    assert cancel_mock.call_count == 0

    assert len(trades) - 1 == len(Trade.query.all())
    rc = client_delete(client, f"{BASE_URI}/trades/2")
    assert_response(rc)
    assert rc.json()['result_msg'] == 'Deleted trade 2. Closed 2 open orders.'
    assert len(trades) - 2 == len(Trade.query.all())
    assert stoploss_mock.call_count == 1
示例#20
0
def test_rpc_trade_history(mocker, default_conf, markets, fee):
    mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
    mocker.patch.multiple('freqtrade.exchange.Exchange',
                          markets=PropertyMock(return_value=markets))

    freqtradebot = get_patched_freqtradebot(mocker, default_conf)
    create_mock_trades(fee)
    rpc = RPC(freqtradebot)
    rpc._fiat_converter = CryptoToFiatConverter()
    trades = rpc._rpc_trade_history(2)
    assert len(trades['trades']) == 2
    assert trades['trades_count'] == 2
    assert isinstance(trades['trades'][0], dict)
    assert isinstance(trades['trades'][1], dict)

    trades = rpc._rpc_trade_history(0)
    assert len(trades['trades']) == 2
    assert trades['trades_count'] == 2
    # The first closed trade is for ETC ... sorting is descending
    assert trades['trades'][-1]['pair'] == 'ETC/BTC'
    assert trades['trades'][0]['pair'] == 'XRP/BTC'
示例#21
0
def test_load_trades_from_db(default_conf, fee, mocker):

    create_mock_trades(fee)
    # remove init so it does not init again
    init_mock = mocker.patch('freqtrade.data.btanalysis.init_db', MagicMock())

    trades = load_trades_from_db(db_url=default_conf['db_url'])
    assert init_mock.call_count == 1
    assert len(trades) == MOCK_TRADE_COUNT
    assert isinstance(trades, DataFrame)
    assert "pair" in trades.columns
    assert "open_date" in trades.columns
    assert "profit_ratio" in trades.columns

    for col in BT_DATA_COLUMNS:
        if col not in ['index', 'open_at_end']:
            assert col in trades.columns
    trades = load_trades_from_db(db_url=default_conf['db_url'],
                                 strategy='DefaultStrategy')
    assert len(trades) == 4
    trades = load_trades_from_db(db_url=default_conf['db_url'],
                                 strategy='NoneStrategy')
    assert len(trades) == 0
示例#22
0
def test_api_status(botclient, mocker, ticker, fee, markets):
    ftbot, client = botclient
    patch_get_signal(ftbot, (True, False))
    mocker.patch.multiple(
        'freqtrade.exchange.Exchange',
        get_balances=MagicMock(return_value=ticker),
        fetch_ticker=ticker,
        get_fee=fee,
        markets=PropertyMock(return_value=markets),
        fetch_order=MagicMock(return_value={}),
    )

    rc = client_get(client, f"{BASE_URI}/status")
    assert_response(rc, 200)
    assert rc.json() == []
    create_mock_trades(fee)

    rc = client_get(client, f"{BASE_URI}/status")
    assert_response(rc)
    assert len(rc.json()) == 4
    assert rc.json()[0] == {
        'amount': 123.0,
        'amount_requested': 123.0,
        'close_date': None,
        'close_timestamp': None,
        'close_profit': None,
        'close_profit_pct': None,
        'close_profit_abs': None,
        'close_rate': None,
        'current_profit': ANY,
        'current_profit_pct': ANY,
        'current_profit_abs': ANY,
        'profit_ratio': ANY,
        'profit_pct': ANY,
        'profit_abs': ANY,
        'profit_fiat': ANY,
        'current_rate': 1.099e-05,
        'open_date': ANY,
        'open_timestamp': ANY,
        'open_order': None,
        'open_rate': 0.123,
        'pair': 'ETH/BTC',
        'stake_amount': 0.001,
        'stop_loss_abs': ANY,
        'stop_loss_pct': ANY,
        'stop_loss_ratio': ANY,
        'stoploss_order_id': None,
        'stoploss_last_update': ANY,
        'stoploss_last_update_timestamp': ANY,
        'initial_stop_loss_abs': 0.0,
        'initial_stop_loss_pct': ANY,
        'initial_stop_loss_ratio': ANY,
        'stoploss_current_dist': ANY,
        'stoploss_current_dist_ratio': ANY,
        'stoploss_current_dist_pct': ANY,
        'stoploss_entry_dist': ANY,
        'stoploss_entry_dist_ratio': ANY,
        'trade_id': 1,
        'close_rate_requested': ANY,
        'fee_close': 0.0025,
        'fee_close_cost': None,
        'fee_close_currency': None,
        'fee_open': 0.0025,
        'fee_open_cost': None,
        'fee_open_currency': None,
        'is_open': True,
        'max_rate': ANY,
        'min_rate': ANY,
        'open_order_id': 'dry_run_buy_12345',
        'open_rate_requested': ANY,
        'open_trade_value': 15.1668225,
        'sell_reason': None,
        'sell_order_status': None,
        'strategy': 'DefaultStrategy',
        'timeframe': 5,
        'exchange': 'binance',
    }

    mocker.patch(
        'freqtrade.exchange.Exchange.get_sell_rate',
        MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))

    rc = client_get(client, f"{BASE_URI}/status")
    assert_response(rc)
    resp_values = rc.json()
    assert len(resp_values) == 4
    assert isnan(resp_values[0]['profit_abs'])
示例#23
0
def test_get_open(fee):

    create_mock_trades(fee)
    assert len(Trade.get_open_trades()) == 4
示例#24
0
def test_get_open(default_conf, fee):

    create_mock_trades(fee)
    assert len(Trade.get_open_trades()) == 2