示例#1
0
def list_strategies(config=Depends(get_config)):
    directory = Path(config.get(
        'strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES))
    from freqtrade.resolvers.strategy_resolver import StrategyResolver
    strategies = StrategyResolver.search_all_objects(directory, False)
    strategies = sorted(strategies, key=lambda x: x['name'])

    return {'strategies': [x['name'] for x in strategies]}
    def _list_strategies(self):
        directory = Path(
            self._config.get(
                'strategy_path',
                self._config['user_data_dir'] / USERPATH_STRATEGIES))
        from freqtrade.resolvers.strategy_resolver import StrategyResolver
        strategy_objs = StrategyResolver.search_all_objects(directory, False)
        strategy_objs = sorted(strategy_objs, key=lambda x: x['name'])

        return jsonify({'strategies': [x['name'] for x in strategy_objs]})
示例#3
0
    def get_strategy_filename(config: Dict, strategy_name: str) -> Optional[Path]:
        """
        Get Strategy-location (filename) from strategy_name
        """
        from freqtrade.resolvers.strategy_resolver import StrategyResolver
        directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES))
        strategy_objs = StrategyResolver.search_all_objects(directory, False)
        strategies = [s for s in strategy_objs if s['name'] == strategy_name]
        if strategies:
            strategy = strategies[0]

            return Path(strategy['location'])
        return None
示例#4
0
def get_strategy(strategy: str, config=Depends(get_config)):

    config = deepcopy(config)
    from freqtrade.resolvers.strategy_resolver import StrategyResolver
    try:
        strategy_obj = StrategyResolver._load_strategy(
            strategy, config, extra_dir=config.get('strategy_path'))
    except OperationalException:
        raise HTTPException(status_code=404, detail='Strategy not found')

    return {
        'strategy': strategy_obj.get_strategy_name(),
        'code': strategy_obj.__source__,
    }
示例#5
0
    def _rpc_analysed_history_full(config, pair: str, timeframe: str,
                                   timerange: str) -> Dict[str, Any]:
        timerange_parsed = TimeRange.parse_timerange(timerange)

        _data = load_data(
            datadir=config.get("datadir"),
            pairs=[pair],
            timeframe=timeframe,
            timerange=timerange_parsed,
            data_format=config.get('dataformat_ohlcv', 'json'),
        )
        from freqtrade.resolvers.strategy_resolver import StrategyResolver
        strategy = StrategyResolver.load_strategy(config)
        df_analyzed = strategy.analyze_ticker(_data[pair], {'pair': pair})

        return RPC._convert_dataframe_to_dict(strategy.get_strategy_name(), pair, timeframe,
                                              df_analyzed, arrow.Arrow.utcnow().datetime)
    def _get_strategy(self, strategy: str):
        """
        Get a single strategy
        get:
          parameters:
            - strategy: Only get this strategy
        """
        config = deepcopy(self._config)
        from freqtrade.resolvers.strategy_resolver import StrategyResolver
        try:
            strategy_obj = StrategyResolver._load_strategy(
                strategy, config, extra_dir=config.get('strategy_path'))
        except OperationalException:
            return self.rest_error("Strategy not found.", 404)

        return jsonify({
            'strategy': strategy_obj.get_strategy_name(),
            'code': strategy_obj.__source__,
        })
示例#7
0
    def _rpc_analysed_history_full(config, pair: str, timeframe: str,
                                   timerange: str) -> Dict[str, Any]:
        timerange_parsed = TimeRange.parse_timerange(timerange)

        _data = load_data(
            datadir=config.get("datadir"),
            pairs=[pair],
            timeframe=timeframe,
            timerange=timerange_parsed,
            data_format=config.get('dataformat_ohlcv', 'json'),
        )
        if pair not in _data:
            raise RPCException(f"No data for {pair}, {timeframe} in {timerange} found.")
        from freqtrade.data.dataprovider import DataProvider
        from freqtrade.resolvers.strategy_resolver import StrategyResolver
        strategy = StrategyResolver.load_strategy(config)
        strategy.dp = DataProvider(config, exchange=None, pairlists=None)

        df_analyzed = strategy.analyze_ticker(_data[pair], {'pair': pair})

        return RPC._convert_dataframe_to_dict(strategy.get_strategy_name(), pair, timeframe,
                                              df_analyzed, arrow.Arrow.utcnow().datetime)
def test_generate_backtest_stats(default_conf, testdatadir):
    default_conf.update({'strategy': 'DefaultStrategy'})
    StrategyResolver.load_strategy(default_conf)

    results = {
        'DefStrat': {
            'results':
            pd.DataFrame({
                "pair": [
                    "UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC",
                    "UNITTEST/BTC"
                ],
                "profit_ratio": [0.003312, 0.010801, 0.013803, 0.002780],
                "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003],
                "open_date": [
                    Arrow(2017, 11, 14, 19, 32, 00).datetime,
                    Arrow(2017, 11, 14, 21, 36, 00).datetime,
                    Arrow(2017, 11, 14, 22, 12, 00).datetime,
                    Arrow(2017, 11, 14, 22, 44, 00).datetime
                ],
                "close_date": [
                    Arrow(2017, 11, 14, 21, 35, 00).datetime,
                    Arrow(2017, 11, 14, 22, 10, 00).datetime,
                    Arrow(2017, 11, 14, 22, 43, 00).datetime,
                    Arrow(2017, 11, 14, 22, 58, 00).datetime
                ],
                "open_rate": [0.002543, 0.003003, 0.003089, 0.003214],
                "close_rate": [0.002546, 0.003014, 0.003103, 0.003217],
                "trade_duration": [123, 34, 31, 14],
                "is_open": [False, False, False, True],
                "sell_reason": [
                    SellType.ROI, SellType.STOP_LOSS, SellType.ROI,
                    SellType.FORCE_SELL
                ]
            }),
            'config':
            default_conf,
            'locks': [],
            'backtest_start_time':
            Arrow.utcnow().int_timestamp,
            'backtest_end_time':
            Arrow.utcnow().int_timestamp,
        }
    }
    timerange = TimeRange.parse_timerange('1510688220-1510700340')
    min_date = Arrow.fromtimestamp(1510688220)
    max_date = Arrow.fromtimestamp(1510700340)
    btdata = history.load_data(testdatadir,
                               '1m', ['UNITTEST/BTC'],
                               timerange=timerange,
                               fill_up_missing=True)

    stats = generate_backtest_stats(btdata, results, min_date, max_date)
    assert isinstance(stats, dict)
    assert 'strategy' in stats
    assert 'DefStrat' in stats['strategy']
    assert 'strategy_comparison' in stats
    strat_stats = stats['strategy']['DefStrat']
    assert strat_stats['backtest_start'] == min_date.datetime
    assert strat_stats['backtest_end'] == max_date.datetime
    assert strat_stats['total_trades'] == len(results['DefStrat']['results'])
    # Above sample had no loosing trade
    assert strat_stats['max_drawdown'] == 0.0

    results = {
        'DefStrat': {
            'results':
            pd.DataFrame({
                "pair": [
                    "UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC",
                    "UNITTEST/BTC"
                ],
                "profit_ratio": [0.003312, 0.010801, -0.013803, 0.002780],
                "profit_abs": [0.000003, 0.000011, -0.000014, 0.000003],
                "open_date": [
                    Arrow(2017, 11, 14, 19, 32, 00).datetime,
                    Arrow(2017, 11, 14, 21, 36, 00).datetime,
                    Arrow(2017, 11, 14, 22, 12, 00).datetime,
                    Arrow(2017, 11, 14, 22, 44, 00).datetime
                ],
                "close_date": [
                    Arrow(2017, 11, 14, 21, 35, 00).datetime,
                    Arrow(2017, 11, 14, 22, 10, 00).datetime,
                    Arrow(2017, 11, 14, 22, 43, 00).datetime,
                    Arrow(2017, 11, 14, 22, 58, 00).datetime
                ],
                "open_rate": [0.002543, 0.003003, 0.003089, 0.003214],
                "close_rate": [0.002546, 0.003014, 0.0032903, 0.003217],
                "trade_duration": [123, 34, 31, 14],
                "open_at_end": [False, False, False, True],
                "sell_reason": [
                    SellType.ROI, SellType.STOP_LOSS, SellType.ROI,
                    SellType.FORCE_SELL
                ]
            }),
            'config':
            default_conf
        }
    }

    assert strat_stats['max_drawdown'] == 0.0
    assert strat_stats['drawdown_start'] == datetime(1970,
                                                     1,
                                                     1,
                                                     tzinfo=timezone.utc)
    assert strat_stats['drawdown_end'] == datetime(1970,
                                                   1,
                                                   1,
                                                   tzinfo=timezone.utc)
    assert strat_stats['drawdown_end_ts'] == 0
    assert strat_stats['drawdown_start_ts'] == 0
    assert strat_stats['pairlist'] == ['UNITTEST/BTC']

    # Test storing stats
    filename = Path(testdatadir / 'btresult.json')
    filename_last = Path(testdatadir / LAST_BT_RESULT_FN)
    _backup_file(filename_last, copy_file=True)
    assert not filename.is_file()

    store_backtest_stats(filename, stats)

    # get real Filename (it's btresult-<date>.json)
    last_fn = get_latest_backtest_filename(filename_last.parent)
    assert re.match(r"btresult-.*\.json", last_fn)

    filename1 = (testdatadir / last_fn)
    assert filename1.is_file()
    content = filename1.read_text()
    assert 'max_drawdown' in content
    assert 'strategy' in content
    assert 'pairlist' in content

    assert filename_last.is_file()

    _clean_test_file(filename_last)
    filename1.unlink()
示例#9
0
def test_generate_backtest_stats(default_conf, testdatadir, tmpdir):
    default_conf.update({'strategy': CURRENT_TEST_STRATEGY})
    StrategyResolver.load_strategy(default_conf)

    results = {
        'DefStrat': {
            'results':
            pd.DataFrame({
                "pair": [
                    "UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC",
                    "UNITTEST/BTC"
                ],
                "profit_ratio": [0.003312, 0.010801, 0.013803, 0.002780],
                "profit_abs": [0.000003, 0.000011, 0.000014, 0.000003],
                "open_date": [
                    Arrow(2017, 11, 14, 19, 32, 00).datetime,
                    Arrow(2017, 11, 14, 21, 36, 00).datetime,
                    Arrow(2017, 11, 14, 22, 12, 00).datetime,
                    Arrow(2017, 11, 14, 22, 44, 00).datetime
                ],
                "close_date": [
                    Arrow(2017, 11, 14, 21, 35, 00).datetime,
                    Arrow(2017, 11, 14, 22, 10, 00).datetime,
                    Arrow(2017, 11, 14, 22, 43, 00).datetime,
                    Arrow(2017, 11, 14, 22, 58, 00).datetime
                ],
                "open_rate": [0.002543, 0.003003, 0.003089, 0.003214],
                "close_rate": [0.002546, 0.003014, 0.003103, 0.003217],
                "trade_duration": [123, 34, 31, 14],
                "is_open": [False, False, False, True],
                "is_short": [False, False, False, False],
                "stake_amount": [0.01, 0.01, 0.01, 0.01],
                "exit_reason": [
                    ExitType.ROI, ExitType.STOP_LOSS, ExitType.ROI,
                    ExitType.FORCE_EXIT
                ]
            }),
            'config':
            default_conf,
            'locks': [],
            'final_balance':
            1000.02,
            'rejected_signals':
            20,
            'timedout_entry_orders':
            0,
            'timedout_exit_orders':
            0,
            'backtest_start_time':
            Arrow.utcnow().int_timestamp,
            'backtest_end_time':
            Arrow.utcnow().int_timestamp,
            'run_id':
            '123',
        }
    }
    timerange = TimeRange.parse_timerange('1510688220-1510700340')
    min_date = Arrow.fromtimestamp(1510688220)
    max_date = Arrow.fromtimestamp(1510700340)
    btdata = history.load_data(testdatadir,
                               '1m', ['UNITTEST/BTC'],
                               timerange=timerange,
                               fill_up_missing=True)

    stats = generate_backtest_stats(btdata, results, min_date, max_date)
    assert isinstance(stats, dict)
    assert 'strategy' in stats
    assert 'DefStrat' in stats['strategy']
    assert 'strategy_comparison' in stats
    strat_stats = stats['strategy']['DefStrat']
    assert strat_stats['backtest_start'] == min_date.strftime(
        DATETIME_PRINT_FORMAT)
    assert strat_stats['backtest_end'] == max_date.strftime(
        DATETIME_PRINT_FORMAT)
    assert strat_stats['total_trades'] == len(results['DefStrat']['results'])
    # Above sample had no loosing trade
    assert strat_stats['max_drawdown_account'] == 0.0

    # Retry with losing trade
    results = {
        'DefStrat': {
            'results':
            pd.DataFrame({
                "pair": [
                    "UNITTEST/BTC", "UNITTEST/BTC", "UNITTEST/BTC",
                    "UNITTEST/BTC"
                ],
                "profit_ratio": [0.003312, 0.010801, -0.013803, 0.002780],
                "profit_abs": [0.000003, 0.000011, -0.000014, 0.000003],
                "open_date": [
                    Arrow(2017, 11, 14, 19, 32, 00).datetime,
                    Arrow(2017, 11, 14, 21, 36, 00).datetime,
                    Arrow(2017, 11, 14, 22, 12, 00).datetime,
                    Arrow(2017, 11, 14, 22, 44, 00).datetime
                ],
                "close_date": [
                    Arrow(2017, 11, 14, 21, 35, 00).datetime,
                    Arrow(2017, 11, 14, 22, 10, 00).datetime,
                    Arrow(2017, 11, 14, 22, 43, 00).datetime,
                    Arrow(2017, 11, 14, 22, 58, 00).datetime
                ],
                "open_rate": [0.002543, 0.003003, 0.003089, 0.003214],
                "close_rate": [0.002546, 0.003014, 0.0032903, 0.003217],
                "trade_duration": [123, 34, 31, 14],
                "is_open": [False, False, False, True],
                "is_short": [False, False, False, False],
                "stake_amount": [0.01, 0.01, 0.01, 0.01],
                "exit_reason": [
                    ExitType.ROI, ExitType.ROI, ExitType.STOP_LOSS,
                    ExitType.FORCE_EXIT
                ]
            }),
            'config':
            default_conf,
            'locks': [],
            'final_balance':
            1000.02,
            'rejected_signals':
            20,
            'timedout_entry_orders':
            0,
            'timedout_exit_orders':
            0,
            'backtest_start_time':
            Arrow.utcnow().int_timestamp,
            'backtest_end_time':
            Arrow.utcnow().int_timestamp,
            'run_id':
            '124',
        }
    }

    stats = generate_backtest_stats(btdata, results, min_date, max_date)
    assert isinstance(stats, dict)
    assert 'strategy' in stats
    assert 'DefStrat' in stats['strategy']
    assert 'strategy_comparison' in stats
    strat_stats = stats['strategy']['DefStrat']

    assert pytest.approx(strat_stats['max_drawdown_account']) == 1.399999e-08
    assert strat_stats['drawdown_start'] == '2017-11-14 22:10:00'
    assert strat_stats['drawdown_end'] == '2017-11-14 22:43:00'
    assert strat_stats['drawdown_end_ts'] == 1510699380000
    assert strat_stats['drawdown_start_ts'] == 1510697400000
    assert strat_stats['pairlist'] == ['UNITTEST/BTC']

    # Test storing stats
    filename = Path(tmpdir / 'btresult.json')
    filename_last = Path(tmpdir / LAST_BT_RESULT_FN)
    _backup_file(filename_last, copy_file=True)
    assert not filename.is_file()

    store_backtest_stats(filename, stats)

    # get real Filename (it's btresult-<date>.json)
    last_fn = get_latest_backtest_filename(filename_last.parent)
    assert re.match(r"btresult-.*\.json", last_fn)

    filename1 = Path(tmpdir / last_fn)
    assert filename1.is_file()
    content = filename1.read_text()
    assert 'max_drawdown_account' in content
    assert 'strategy' in content
    assert 'pairlist' in content

    assert filename_last.is_file()

    _clean_test_file(filename_last)
    filename1.unlink()
示例#10
0
def test_informative_decorator(mocker, default_conf_usdt, trading_mode):
    candle_def = CandleType.get_default(trading_mode)
    default_conf_usdt['candle_type_def'] = candle_def
    test_data_5m = generate_test_data('5m', 40)
    test_data_30m = generate_test_data('30m', 40)
    test_data_1h = generate_test_data('1h', 40)
    data = {
        ('XRP/USDT', '5m', candle_def): test_data_5m,
        ('XRP/USDT', '30m', candle_def): test_data_30m,
        ('XRP/USDT', '1h', candle_def): test_data_1h,
        ('LTC/USDT', '5m', candle_def): test_data_5m,
        ('LTC/USDT', '30m', candle_def): test_data_30m,
        ('LTC/USDT', '1h', candle_def): test_data_1h,
        ('NEO/USDT', '30m', candle_def): test_data_30m,
        ('NEO/USDT', '5m', CandleType.SPOT): test_data_5m,  # Explicit request with '' as candletype
        ('NEO/USDT', '15m', candle_def): test_data_5m,  # Explicit request with '' as candletype
        ('NEO/USDT', '1h', candle_def): test_data_1h,
        ('ETH/USDT', '1h', candle_def): test_data_1h,
        ('ETH/USDT', '30m', candle_def): test_data_30m,
        ('ETH/BTC', '1h', CandleType.SPOT): test_data_1h,  # Explicitly selected as spot
    }
    default_conf_usdt['strategy'] = 'InformativeDecoratorTest'
    strategy = StrategyResolver.load_strategy(default_conf_usdt)
    exchange = get_patched_exchange(mocker, default_conf_usdt)
    strategy.dp = DataProvider({}, exchange, None)
    mocker.patch.object(strategy.dp, 'current_whitelist', return_value=[
        'XRP/USDT', 'LTC/USDT', 'NEO/USDT'
    ])

    assert len(strategy._ft_informative) == 6   # Equal to number of decorators used
    informative_pairs = [
        ('XRP/USDT', '1h', candle_def),
        ('LTC/USDT', '1h', candle_def),
        ('XRP/USDT', '30m', candle_def),
        ('LTC/USDT', '30m', candle_def),
        ('NEO/USDT', '1h', candle_def),
        ('NEO/USDT', '30m', candle_def),
        ('NEO/USDT', '5m', candle_def),
        ('NEO/USDT', '15m', candle_def),
        ('NEO/USDT', '2h', CandleType.FUTURES),
        ('ETH/BTC', '1h', CandleType.SPOT),  # One candle remains as spot
        ('ETH/USDT', '30m', candle_def)]
    for inf_pair in informative_pairs:
        assert inf_pair in strategy.gather_informative_pairs()

    def test_historic_ohlcv(pair, timeframe, candle_type):
        return data[
            (pair, timeframe or strategy.timeframe, CandleType.from_string(candle_type))].copy()

    mocker.patch('freqtrade.data.dataprovider.DataProvider.historic_ohlcv',
                 side_effect=test_historic_ohlcv)

    analyzed = strategy.advise_all_indicators(
        {p: data[(p, strategy.timeframe, candle_def)] for p in ('XRP/USDT', 'LTC/USDT')})
    expected_columns = [
        'rsi_1h', 'rsi_30m',                    # Stacked informative decorators
        'neo_usdt_rsi_1h',                      # NEO 1h informative
        'rsi_NEO_USDT_neo_usdt_NEO/USDT_30m',   # Column formatting
        'rsi_from_callable',                    # Custom column formatter
        'eth_btc_rsi_1h',                       # Quote currency not matching stake currency
        'rsi', 'rsi_less',                      # Non-informative columns
        'rsi_5m',                               # Manual informative dataframe
    ]
    for _, dataframe in analyzed.items():
        for col in expected_columns:
            assert col in dataframe.columns