示例#1
0
def set_up():
    reset_config()
    config['app']['trading_exchanges'] = [
        exchanges.SANDBOX, exchanges.BITFINEX
    ]
    config['app']['trading_symbols'] = ['BTCUSD', 'ETHUSD']
    store.reset()
示例#2
0
def test_backtesting_three_routes():
    reset_config()
    router.set_routes([
        (exchanges.SANDBOX, 'BTCUSD', timeframes.MINUTE_5, 'Test19'),
        (exchanges.SANDBOX, 'ETHUSD', timeframes.MINUTE_5, 'Test19'),
        (exchanges.SANDBOX, 'XRPUSD', timeframes.MINUTE_15, 'Test19'),
    ])
    store.reset(True)
    candles = {}
    routes = router.routes
    for r in routes:
        key = jh.key(r.exchange, r.symbol)
        candles[key] = {
            'exchange': r.exchange,
            'symbol': r.symbol,
            'candles': fake_range_candle(5 * 3 * 20)
        }

        # assert that strategy hasn't been initiated before running backtest_mode()
        assert r.strategy is None

    # run backtest (dates are fake just to pass)
    backtest_mode.run('2019-04-01', '2019-04-02', candles)

    # there must be three positions present with the updated current_price
    assert len(store.positions.storage) == 3

    for r in routes:
        # r3's '15m' timeframe makes r1 and r2 to support
        # '15' timeframe as well. r1 and r2 also make r3
        # to support '5m' timeframe also.
        r_one_min = store.candles.get_candles(r.exchange, r.symbol, '1m')
        r_five_min = store.candles.get_candles(r.exchange, r.symbol, '5m')
        r_fifteen_min = store.candles.get_candles(r.exchange, r.symbol, '15m')

        # assert the count of present candles
        assert len(r_one_min) == (5 * 3) * 20
        assert len(r_five_min) == 20 * 3
        assert len(r_fifteen_min) == 20

        r_first_1 = r_one_min[0]
        r_last_1 = r_one_min[-1]
        r_first_5 = r_five_min[0]
        r_last_5 = r_five_min[-1]
        r_first_15 = r_fifteen_min[0]
        r_last_15 = r_fifteen_min[-1]

        # assert timestamps
        assert r_first_1[0] == r_first_5[0]
        assert r_last_1[0] == (r_last_5[0] + 60000 * 4)
        assert r_last_5[0] == (r_last_15[0] + 60000 * 10)

        # assert positions
        p = selectors.get_position(r.exchange, r.symbol)
        assert p.is_close is True
        last_candle = store.candles.get_candles(r.exchange, r.symbol, '1m')[-1]
        assert p.current_price == last_candle[2]

        # assert that the strategy has been initiated
        assert r.strategy is not None
示例#3
0
def set_up(count=2):
    reset_config()
    config['app']['considering_timeframes'] = ['1m', '5m']
    config['app']['considering_symbols'] = ['BTCUSD']
    config['app']['considering_exchanges'] = ['Sandbox']
    store.reset()
    store.candles.init_storage(count)
示例#4
0
def test_forming_candles():
    reset_config()
    router.set_routes([(exchanges.SANDBOX, 'BTC-USDT', timeframes.MINUTE_5,
                        'Test19')])
    router.set_extra_candles([(exchanges.SANDBOX, 'BTC-USDT',
                               timeframes.MINUTE_15)])
    store.reset(True)

    candles = {}
    key = jh.key(exchanges.SANDBOX, 'BTC-USDT')
    candles[key] = {
        'exchange': exchanges.SANDBOX,
        'symbol': 'BTC-USDT',
        'candles': test_candles_0
    }

    backtest_mode.run('2019-04-01', '2019-04-02', candles)

    # use math.ceil because it must include forming candle too
    assert len(
        store.candles.get_candles(exchanges.SANDBOX, 'BTC-USDT',
                                  timeframes.MINUTE_5)) == math.ceil(1382 / 5)
    assert len(
        store.candles.get_candles(exchanges.SANDBOX, 'BTC-USDT',
                                  timeframes.MINUTE_15)) == math.ceil(1382 /
                                                                      15)
示例#5
0
def set_up():
    reset_config()
    config['app']['considering_exchanges'] = [exchanges.SANDBOX]
    config['app']['trading_exchanges'] = [exchanges.SANDBOX]
    config['app']['trading_symbols'] = ['BTC-USD']
    config['app']['trading_timeframes'] = ['5m']
    store.reset()
示例#6
0
def set_up_without_fee(is_margin_trading=False):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'margin'
    config['env']['exchanges'][exchanges.SANDBOX]['fee'] = 0
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
        {
            'asset': 'USDT',
            'balance': 1000
        },
        {
            'asset': 'BTC',
            'balance': 0
        },
    ]
    if is_margin_trading:
        # used only in margin trading
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'margin'
        config['env']['exchanges'][
            exchanges.SANDBOX]['settlement_currency'] = 'USDT'
    config['app']['trading_mode'] = 'backtest'
    config['app']['considering_exchanges'] = ['Sandbox']
    router.set_routes([(exchanges.SANDBOX, 'BTC-USDT', '5m', 'Test19')])
    store.reset(True)

    global position
    global exchange
    position = selectors.get_position(exchanges.SANDBOX, 'BTC-USDT')
    position.current_price = 50
    exchange = selectors.get_exchange(exchanges.SANDBOX)
示例#7
0
def set_up_with_fee(is_futures_trading=False):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['fee'] = 0.002
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
        {
            'asset': 'USDT',
            'balance': 1000
        },
        {
            'asset': 'BTC',
            'balance': 0
        },
    ]
    if is_futures_trading:
        # used only in futures trading
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'futures'
    else:
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'spot'
    config['env']['exchanges'][
        exchanges.SANDBOX]['settlement_currency'] = 'USDT'
    config['app']['trading_mode'] = 'backtest'
    config['app']['considering_exchanges'] = ['Sandbox']
    router.set_routes([(exchanges.SANDBOX, 'BTC-USDT', '5m', 'Test19')])
    store.reset(True)

    global position
    global exchange
    global broker
    position = selectors.get_position(exchanges.SANDBOX, 'BTC-USDT')
    position.current_price = 50
    exchange = selectors.get_exchange(exchanges.SANDBOX)
    broker = Broker(position, exchanges.SANDBOX, 'BTC-USDT',
                    timeframes.MINUTE_5)
示例#8
0
def set_up(routes, fee=0):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['starting_balance'] = 10000
    config['env']['exchanges'][exchanges.SANDBOX]['fee'] = fee
    router.set_routes(routes)
    router.set_extra_candles([])
    store.reset(True)
示例#9
0
def test_forming_candles():
    reset_config()
    routes = [{
        'exchange': exchanges.SANDBOX,
        'symbol': 'BTC-USDT',
        'timeframe': timeframes.MINUTE_5,
        'strategy': 'Test19'
    }]
    extra_routes = [{
        'exchange': exchanges.SANDBOX,
        'symbol': 'BTC-USDT',
        'timeframe': timeframes.MINUTE_15
    }]

    candles = {}
    key = jh.key(exchanges.SANDBOX, 'BTC-USDT')
    candles[key] = {
        'exchange': exchanges.SANDBOX,
        'symbol': 'BTC-USDT',
        'candles': test_candles_0
    }

    backtest_mode.run(False, {}, routes, extra_routes, '2019-04-01',
                      '2019-04-02', candles)

    # use math.ceil because it must include forming candle too
    assert len(
        store.candles.get_candles(exchanges.SANDBOX, 'BTC-USDT',
                                  timeframes.MINUTE_5)) == math.ceil(1382 / 5)
    assert len(
        store.candles.get_candles(exchanges.SANDBOX, 'BTC-USDT',
                                  timeframes.MINUTE_15)) == math.ceil(1382 /
                                                                      15)
示例#10
0
def set_up(is_futures_trading=True,
           leverage=1,
           leverage_mode='cross',
           zero_fee=False):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
        {
            'asset': 'USDT',
            'balance': 10_000
        },
        {
            'asset': 'BTC',
            'balance': 0
        },
        {
            'asset': 'ETH',
            'balance': 0
        },
    ]

    if zero_fee:
        config['env']['exchanges']['Sandbox']['fee'] = 0

    if is_futures_trading:
        # used only in futures trading
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'futures'
        config['env']['exchanges'][
            exchanges.SANDBOX]['futures_leverage_mode'] = leverage_mode
        config['env']['exchanges'][
            exchanges.SANDBOX]['futures_leverage'] = leverage
    else:
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'spot'
示例#11
0
def set_up(routes=None,
           is_futures_trading=True,
           leverage=1,
           leverage_mode='cross'):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
        {
            'asset': 'USDT',
            'balance': 10_000
        },
        {
            'asset': 'BTC',
            'balance': 0
        },
        {
            'asset': 'ETH',
            'balance': 0
        },
    ]

    if is_futures_trading:
        # used only in futures trading
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'futures'
        config['env']['exchanges'][
            exchanges.SANDBOX]['futures_leverage_mode'] = leverage_mode
        config['env']['exchanges'][
            exchanges.SANDBOX]['futures_leverage'] = leverage
    else:
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'spot'

    if routes:
        router.set_routes(routes)

    store.reset(True)
示例#12
0
def set_up():
    """

    """
    reset_config()
    config['app']['considering_candles'] = [('Sandbox', 'BTCUSD')]
    store.reset()
    store.trades.init_storage()
示例#13
0
def set_up(routes):
    """

    :param routes:
    """
    reset_config()
    router.set_routes(routes)
    store.reset(True)
示例#14
0
def set_up(routes, is_margin_trading=True):
    reset_config()
    if is_margin_trading:
        # used only in margin trading
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'margin'
    else:
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'spot'
    router.set_routes(routes)
    store.reset(True)
示例#15
0
def set_up():
    """

    """
    reset_config()
    config['app']['considering_exchanges'] = [exchanges.SANDBOX]
    config['app']['trading_exchanges'] = [exchanges.SANDBOX]
    config['env']['exchanges'][exchanges.SANDBOX]['starting_balance'] = 2000
    store.reset()
示例#16
0
def set_up():
    reset_config()
    config['app']['considering_exchanges'] = [exchanges.SANDBOX]
    config['env']['exchanges'][exchanges.SANDBOX]['fee'] = 0
    config['env']['exchanges'][exchanges.SANDBOX]['starting_balance'] = 1000
    config['app']['trading_exchanges'] = [exchanges.SANDBOX]
    config['app']['trading_symbols'] = ['BTCUSD']
    config['app']['trading_timeframes'] = ['5m']
    store.reset()
示例#17
0
def test_backtesting_one_route():
    reset_config()
    router.set_routes([
        (exchanges.SANDBOX, 'BTC-USDT', timeframes.MINUTE_5, 'Test19')
    ])
    config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'margin'
    store.reset(True)

    candles = {}
    key = jh.key(exchanges.SANDBOX, 'BTC-USDT')
    candles[key] = {
        'exchange': exchanges.SANDBOX,
        'symbol': 'BTC-USDT',
        'candles': fake_range_candle(5 * 20)
    }
    routes = router.routes

    # assert that strategy hasn't been initiated before running backtest_mode()
    assert routes[0].strategy is None

    # run backtest (dates are fake just to pass)
    backtest_mode.run('2019-04-01', '2019-04-02', candles)

    one_min = store.candles.get_candles(exchanges.SANDBOX, 'BTC-USDT', '1m')
    five_min = store.candles.get_candles(exchanges.SANDBOX, 'BTC-USDT', '5m')

    # assert the count of present candles
    assert len(five_min) == 20
    assert len(one_min) == 20 * 5

    first_1 = one_min[0]
    last_1 = one_min[-1]
    first_5 = five_min[0]
    last_5 = five_min[-1]

    # assert time in store
    assert store.app.time == last_1[0] + 60000

    # assert timestamps
    assert first_1[0] == first_5[0]
    assert last_1[0] == (last_5[0] + 60000 * 4)

    # there must be only one positions present
    assert len(store.positions.storage) == 1
    p = selectors.get_position(exchanges.SANDBOX, 'BTC-USDT')
    assert p.is_close
    assert p.current_price == last_1[2]
    assert p.current_price == last_5[2]

    # assert routes
    assert len(routes) == 1
    assert routes[0].exchange == exchanges.SANDBOX
    assert routes[0].symbol == 'BTC-USDT'
    assert routes[0].timeframe == '5m'
    assert routes[0].strategy_name == 'Test19'
    # assert that the strategy has been initiated
    assert routes[0].strategy is not None
示例#18
0
def set_up():
    reset_config()
    config['app']['considering_exchanges'] = [exchanges.SANDBOX]
    config['app']['trading_exchanges'] = [exchanges.SANDBOX]
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [{
        'asset': 'USDT',
        'balance': 2000
    }]
    store.reset()
示例#19
0
def test_must_not_be_able_to_set_two_similar_routes():
    reset_config()
    router.set_routes([
        (exchanges.SANDBOX, 'ETH-USDT', timeframes.MINUTE_5, 'Test01'),
        (exchanges.SANDBOX, 'ETH-USDT', timeframes.MINUTE_30, 'Test02'),
    ])
    with pytest.raises(Exception) as err:
        store.reset(True)
    assert str(err.value).startswith(
        'each exchange-symbol pair can be traded only once')
示例#20
0
def set_up(routes, fee=0):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
        {'asset': 'USDT', 'balance': 1000},
        {'asset': 'BTC', 'balance': 0},
    ]
    config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'margin'
    config['env']['exchanges'][exchanges.SANDBOX]['fee'] = fee
    router.set_routes(routes)
    router.set_extra_candles([])
    store.reset(True)
示例#21
0
def set_up(routes, is_margin_trading=True):
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['assets'] = [
        {'asset': 'USDT', 'balance': 10000},
        {'asset': 'BTC', 'balance': 0},
        {'asset': 'ETH', 'balance': 0},
    ]
    if is_margin_trading:
        # used only in margin trading
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'margin'
    else:
        config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'spot'
    router.set_routes(routes)
    store.reset(True)
示例#22
0
def set_up_with_fee():
    reset_config()
    config['env']['exchanges'][exchanges.SANDBOX]['fee'] = 0.002
    config['env']['exchanges'][exchanges.SANDBOX]['starting_balance'] = 1000
    config['app']['trading_mode'] = 'backtest'
    config['app']['considering_exchanges'] = ['Sandbox']
    router.set_routes([(exchanges.SANDBOX, 'BTCUSD', '5m', 'Test19')])
    store.reset(True)

    global position
    global exchange
    global broker
    position = selectors.get_position(exchanges.SANDBOX, 'BTCUSD')
    position.current_price = 50
    exchange = selectors.get_exchange(exchanges.SANDBOX)
    broker = Broker(position, exchanges.SANDBOX, 'BTCUSD', timeframes.MINUTE_5)
示例#23
0
def set_up():
    reset_config()
    from jesse.routes import router
    router.set_routes([{
        'exchange': 'Sandbox',
        'symbol': 'BTC-USD',
        'timeframe': '1m',
        'strategy': 'Test01'
    }])
    router.set_extra_candles([{
        'exchange': 'Sandbox',
        'symbol': 'BTC-USD',
        'timeframe': '5m'
    }])
    config['app']['considering_timeframes'] = ['1m', '5m']
    config['app']['considering_symbols'] = ['BTC-USD']
    config['app']['considering_exchanges'] = ['Sandbox']
    store.reset(True)
    store.candles.init_storage()
示例#24
0
def set_up(routes):
    reset_config()
    router.set_routes(routes)
    store.reset(True)
示例#25
0
def _isolated_backtest(config: dict,
                       routes: List[Dict[str, str]],
                       extra_routes: List[Dict[str, str]],
                       candles: dict,
                       run_silently: bool = True,
                       hyperparameters: dict = None) -> dict:
    from jesse.services.validators import validate_routes
    from jesse.modes.backtest_mode import simulator
    from jesse.config import config as jesse_config, reset_config
    from jesse.routes import router
    from jesse.store import store
    from jesse.config import set_config
    from jesse.services import metrics
    from jesse.services import required_candles
    import jesse.helpers as jh

    jesse_config['app']['trading_mode'] = 'backtest'

    # inject (formatted) configuration values
    set_config(_format_config(config))

    # set routes
    router.initiate(routes, extra_routes)

    # register_custom_exception_handler()

    validate_routes(router)
    # TODO: further validate routes and allow only one exchange
    # TODO: validate the name of the exchange in the config and the route? or maybe to make sure it's a supported exchange

    # initiate candle store
    store.candles.init_storage(5000)

    # divide candles into warm_up_candles and trading_candles and then inject warm_up_candles

    max_timeframe = jh.max_timeframe(
        jesse_config['app']['considering_timeframes'])
    warm_up_num = config['warm_up_candles'] * jh.timeframe_to_one_minutes(
        max_timeframe)
    trading_candles = candles
    if warm_up_num != 0:
        for c in jesse_config['app']['considering_candles']:
            key = jh.key(c[0], c[1])
            # update trading_candles
            trading_candles[key]['candles'] = candles[key]['candles'][
                warm_up_num:]
            # inject warm-up candles
            required_candles.inject_required_candles_to_store(
                candles[key]['candles'][:warm_up_num], c[0], c[1])

    # run backtest simulation
    simulator(trading_candles, run_silently, hyperparameters)

    result = {
        'metrics': {
            'total': 0,
            'win_rate': 0,
            'net_profit_percentage': 0
        },
        'charts': None,
        'logs': None,
    }
    if store.completed_trades.count > 0:
        # add metrics
        result['metrics'] = metrics.trades(store.completed_trades.trades,
                                           store.app.daily_balance)
        # add charts
        result['charts'] = charts.portfolio_vs_asset_returns()
        # add logs
        result['logs'] = store.logs.info

    # reset store and config so rerunning would be flawlessly possible
    reset_config()
    store.reset()

    return result
示例#26
0
def set_up():
    """

    """
    reset_config()
    store.reset(True)
示例#27
0
def set_up():
    reset_config()
    config['app']['considering_candles'] = [('Sandbox', 'BTC-USD')]
    store.reset()
    store.tickers.init_storage()
示例#28
0
def test_backtesting_three_routes():
    reset_config()
    routes = [{
        'exchange': exchanges.SANDBOX,
        'symbol': 'BTC-USDT',
        'timeframe': timeframes.MINUTE_5,
        'strategy': 'Test19'
    }, {
        'exchange': exchanges.SANDBOX,
        'symbol': 'ETH-USDT',
        'timeframe': timeframes.MINUTE_5,
        'strategy': 'Test19'
    }, {
        'exchange': exchanges.SANDBOX,
        'symbol': 'XRP-USDT',
        'timeframe': timeframes.MINUTE_15,
        'strategy': 'Test19'
    }]
    config['env']['exchanges'][exchanges.SANDBOX]['type'] = 'futures'

    candles = {}
    for r in routes:
        key = jh.key(r['exchange'], r['symbol'])
        candles[key] = {
            'exchange': r['exchange'],
            'symbol': r['symbol'],
            'candles': range_candles(5 * 3 * 20)
        }

    # run backtest (dates are fake just to pass)
    backtest_mode.run(False, {}, routes, [], '2019-04-01', '2019-04-02',
                      candles)

    # there must be three positions present with the updated current_price
    assert len(store.positions.storage) == 3

    for r in router.routes:
        # r3's '15m' timeframe makes r1 and r2 to support
        # '15' timeframe as well. r1 and r2 also make r3
        # to support '5m' timeframe also.
        r_one_min = store.candles.get_candles(r.exchange, r.symbol, '1m')
        r_five_min = store.candles.get_candles(r.exchange, r.symbol, '5m')
        r_fifteen_min = store.candles.get_candles(r.exchange, r.symbol, '15m')

        # assert the count of present candles
        assert len(r_one_min) == (5 * 3) * 20
        assert len(r_five_min) == 20 * 3
        assert len(r_fifteen_min) == 20

        r_first_1 = r_one_min[0]
        r_last_1 = r_one_min[-1]
        r_first_5 = r_five_min[0]
        r_last_5 = r_five_min[-1]
        r_last_15 = r_fifteen_min[-1]

        # assert timestamps
        assert r_first_1[0] == r_first_5[0]
        assert r_last_1[0] == (r_last_5[0] + 60000 * 4)
        assert r_last_5[0] == (r_last_15[0] + 60000 * 10)

        # assert positions
        p = selectors.get_position(r.exchange, r.symbol)
        assert p.is_close is True
        last_candle = store.candles.get_candles(r.exchange, r.symbol, '1m')[-1]
        assert p.current_price == last_candle[2]

        # assert that the strategy has been initiated
        assert r.strategy is not None