コード例 #1
0
ファイル: test_exchange.py プロジェクト: ynzheng/freqtrade
def test_set_sandbox_exception(default_conf, mocker):
    """
    Test Fail scenario
    """
    api_mock = MagicMock()
    api_mock.load_markets = MagicMock(return_value={
        'ETH/BTC': '',
        'LTC/BTC': '',
        'XRP/BTC': '',
        'NEO/BTC': ''
    })
    url_mock = PropertyMock(return_value={'api': 'https://api.gdax.com'})
    type(api_mock).urls = url_mock

    mocker.patch('freqtrade.exchange.Exchange._init_ccxt',
                 MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes',
                 MagicMock())

    with pytest.raises(OperationalException,
                       match=r'does not provide a sandbox api'):
        exchange = Exchange(default_conf)
        default_conf['exchange']['sandbox'] = True
        exchange.set_sandbox(exchange._api, default_conf['exchange'],
                             'Logname')
コード例 #2
0
ファイル: test_exchange.py プロジェクト: ynzheng/freqtrade
def test_set_sandbox(default_conf, mocker):
    """
    Test working scenario
    """
    api_mock = MagicMock()
    api_mock.load_markets = MagicMock(return_value={
        'ETH/BTC': '',
        'LTC/BTC': '',
        'XRP/BTC': '',
        'NEO/BTC': ''
    })
    url_mock = PropertyMock(return_value={
        'test': "api-public.sandbox.gdax.com",
        'api': 'https://api.gdax.com'
    })
    type(api_mock).urls = url_mock
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt',
                 MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes',
                 MagicMock())

    exchange = Exchange(default_conf)
    liveurl = exchange._api.urls['api']
    default_conf['exchange']['sandbox'] = True
    exchange.set_sandbox(exchange._api, default_conf['exchange'], 'Logname')
    assert exchange._api.urls['api'] != liveurl
コード例 #3
0
ファイル: test_exchange.py プロジェクト: ynzheng/freqtrade
def test_symbol_price_prec(default_conf, mocker):
    '''
    Test rounds up to 4 decimal places
    '''
    api_mock = MagicMock()
    api_mock.load_markets = MagicMock(return_value={
        'ETH/BTC': '',
        'LTC/BTC': '',
        'XRP/BTC': '',
        'NEO/BTC': ''
    })
    mocker.patch('freqtrade.exchange.Exchange.name',
                 PropertyMock(return_value='binance'))

    markets = PropertyMock(
        return_value={'ETH/BTC': {
            'precision': {
                'price': 4
            }
        }})
    type(api_mock).markets = markets

    mocker.patch('freqtrade.exchange.Exchange._init_ccxt',
                 MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes',
                 MagicMock())
    exchange = Exchange(default_conf)

    price = 2.34559
    pair = 'ETH/BTC'
    price = exchange.symbol_price_prec(pair, price)
    assert price == 2.3456
コード例 #4
0
    def __init__(self, config: Dict[str, Any]) -> None:
        """
        Init all variables and object the bot need to work
        :param config: configuration dict, you can use the Configuration.get_config()
        method to get the config dict.
        """

        logger.info(
            'Starting freqtrade %s',
            __version__,
        )

        # Init bot states
        self.state = State.STOPPED

        # Init objects
        self.config = config
        self.strategy: IStrategy = StrategyResolver(self.config).strategy

        self.rpc: RPCManager = RPCManager(self)
        self.persistence = None
        self.exchange = Exchange(self.config)
        self.wallets = Wallets(self.exchange)
        pairlistname = self.config.get('pairlist',
                                       {}).get('method', 'StaticPairList')
        self.pairlists = PairListResolver(pairlistname, self,
                                          self.config).pairlist

        # Initializing Edge only if enabled
        self.edge = Edge(self.config, self.exchange, self.strategy) if \
            self.config.get('edge', {}).get('enabled', False) else None

        self.active_pair_whitelist: List[str] = self.config['exchange'][
            'pair_whitelist']
        self._init_modules()
コード例 #5
0
    def __init__(self, config: Dict[str, Any]) -> None:
        self.config = config

        # Reset keys for backtesting
        self.config['exchange']['key'] = ''
        self.config['exchange']['secret'] = ''
        self.config['exchange']['password'] = ''
        self.config['exchange']['uid'] = ''
        self.config['dry_run'] = True
        self.strategylist: List[IStrategy] = []
        if self.config.get('strategy_list', None):
            # Force one interval
            self.ticker_interval = str(self.config.get('ticker_interval'))
            for strat in list(self.config['strategy_list']):
                stratconf = deepcopy(self.config)
                stratconf['strategy'] = strat
                self.strategylist.append(StrategyResolver(stratconf).strategy)

        else:
            # only one strategy
            strat = StrategyResolver(self.config).strategy

            self.strategylist.append(StrategyResolver(self.config).strategy)
        # Load one strategy
        self._set_strategy(self.strategylist[0])

        self.exchange = Exchange(self.config)
        self.fee = self.exchange.get_fee()
コード例 #6
0
def test_init_exception(default_conf, mocker):
    default_conf['exchange']['name'] = 'wrong_exchange_name'

    with pytest.raises(
            OperationalException,
            match='Exchange {} is not supported'.format(default_conf['exchange']['name'])):
        Exchange(default_conf)

    default_conf['exchange']['name'] = 'binance'
    with pytest.raises(
            OperationalException,
            match='Exchange {} is not supported'.format(default_conf['exchange']['name'])):
        mocker.patch("ccxt.binance", MagicMock(side_effect=AttributeError))
        Exchange(default_conf)
コード例 #7
0
 def load_exchange(exchange_name: str,
                   config: dict,
                   validate: bool = True) -> Exchange:
     """
     Load the custom class from config parameter
     :param exchange_name: name of the Exchange to load
     :param config: configuration dictionary
     """
     # Map exchange name to avoid duplicate classes for identical exchanges
     exchange_name = MAP_EXCHANGE_CHILDCLASS.get(exchange_name,
                                                 exchange_name)
     exchange_name = exchange_name.title()
     exchange = None
     try:
         exchange = ExchangeResolver._load_exchange(exchange_name,
                                                    kwargs={
                                                        'config': config,
                                                        'validate': validate
                                                    })
     except ImportError:
         logger.info(
             f"No {exchange_name} specific subclass found. Using the generic class instead."
         )
     if not exchange:
         exchange = Exchange(config, validate=validate)
     return exchange
コード例 #8
0
ファイル: test_exchange.py プロジェクト: tucanae47/freqtrade
def test_name(default_conf, mocker):
    mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
                 side_effect=lambda s: True)
    default_conf['exchange']['name'] = 'binance'
    exchange = Exchange(default_conf)

    assert exchange.name == 'Binance'
コード例 #9
0
ファイル: test_exchange.py プロジェクト: tucanae47/freqtrade
def test_init_exception(default_conf):
    default_conf['exchange']['name'] = 'wrong_exchange_name'

    with pytest.raises(OperationalException,
                       match='Exchange {} is not supported'.format(
                           default_conf['exchange']['name'])):
        Exchange(default_conf)
コード例 #10
0
ファイル: plot_dataframe.py プロジェクト: sprgn/freqtrade
def get_trading_env(args: Namespace):
    """
    Initalize freqtrade Exchange and Strategy, split pairs recieved in parameter
    :return: Strategy
    """
    global _CONF

    # Load the configuration
    _CONF.update(setup_configuration(args))
    print(_CONF)

    pairs = args.pairs.split(',')
    if pairs is None:
        logger.critical('Parameter --pairs mandatory;. E.g --pairs ETH/BTC,XRP/BTC')
        exit()

    # Load the strategy
    try:
        strategy = StrategyResolver(_CONF).strategy
        exchange = Exchange(_CONF)
    except AttributeError:
        logger.critical(
            'Impossible to load the strategy. Please check the file "user_data/strategies/%s.py"',
            args.strategy
        )
        exit()

    return [strategy, exchange, pairs]
コード例 #11
0
ファイル: backtesting.py プロジェクト: tucanae47/freqtrade
    def __init__(self, config: Dict[str, Any]) -> None:
        self.config = config
        self.analyze = Analyze(self.config)
        self.ticker_interval = self.analyze.strategy.ticker_interval
        self.tickerdata_to_dataframe = self.analyze.tickerdata_to_dataframe
        self.populate_buy_trend = self.analyze.populate_buy_trend
        self.populate_sell_trend = self.analyze.populate_sell_trend

        # Reset keys for backtesting
        self.config['exchange']['key'] = ''
        self.config['exchange']['secret'] = ''
        self.config['exchange']['password'] = ''
        self.config['exchange']['uid'] = ''
        self.config['dry_run'] = True
        self.exchange = Exchange(self.config)
        self.fee = self.exchange.get_fee()
コード例 #12
0
ファイル: conftest.py プロジェクト: aliensmart/Freqtrade_bot
def get_patched_exchange(mocker,
                         config,
                         api_mock=None,
                         id='bittrex') -> Exchange:
    patch_exchange(mocker, api_mock, id)
    exchange = Exchange(config)
    return exchange
コード例 #13
0
def _download_trades_history(exchange: Exchange,
                             pair: str, *,
                             new_pairs_days: int = 30,
                             timerange: Optional[TimeRange] = None,
                             data_handler: IDataHandler
                             ) -> bool:
    """
    Download trade history from the exchange.
    Appends to previously downloaded trades data.
    """
    try:

        since = timerange.startts * 1000 if \
            (timerange and timerange.starttype == 'date') else int(arrow.utcnow().shift(
                days=-new_pairs_days).float_timestamp) * 1000

        trades = data_handler.trades_load(pair)

        # TradesList columns are defined in constants.DEFAULT_TRADES_COLUMNS
        # DEFAULT_TRADES_COLUMNS: 0 -> timestamp
        # DEFAULT_TRADES_COLUMNS: 1 -> id

        if trades and since < trades[0][0]:
            # since is before the first trade
            logger.info(f"Start earlier than available data. Redownloading trades for {pair}...")
            trades = []

        from_id = trades[-1][1] if trades else None
        if trades and since < trades[-1][0]:
            # Reset since to the last available point
            # - 5 seconds (to ensure we're getting all trades)
            since = trades[-1][0] - (5 * 1000)
            logger.info(f"Using last trade date -5s - Downloading trades for {pair} "
                        f"since: {format_ms_time(since)}.")

        logger.debug(f"Current Start: {format_ms_time(trades[0][0]) if trades else 'None'}")
        logger.debug(f"Current End: {format_ms_time(trades[-1][0]) if trades else 'None'}")
        logger.info(f"Current Amount of trades: {len(trades)}")

        # Default since_ms to 30 days if nothing is given
        new_trades = exchange.get_historic_trades(pair=pair,
                                                  since=since,
                                                  from_id=from_id,
                                                  )
        trades.extend(new_trades[1])
        # Remove duplicates to make sure we're not storing data we don't need
        trades = trades_remove_duplicates(trades)
        data_handler.trades_store(pair, data=trades)

        logger.debug(f"New Start: {format_ms_time(trades[0][0])}")
        logger.debug(f"New End: {format_ms_time(trades[-1][0])}")
        logger.info(f"New Amount of trades: {len(trades)}")
        return True

    except Exception:
        logger.exception(
            f'Failed to download historic trades for pair: "{pair}". '
        )
        return False
コード例 #14
0
def test_validate_pairs_exception(default_conf, mocker, caplog):
    caplog.set_level(logging.INFO)
    api_mock = MagicMock()
    mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value='Binance'))

    api_mock.load_markets = MagicMock(return_value={})
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock)
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
    mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())

    with pytest.raises(OperationalException, match=r'Pair ETH/BTC is not available at Binance'):
        Exchange(default_conf)

    mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
    Exchange(default_conf)
    assert log_has('Unable to validate pairs (assuming they are correct).',
                   caplog.record_tuples)
コード例 #15
0
ファイル: conftest.py プロジェクト: ychaim/freqtrade
def get_patched_exchange(mocker, config, api_mock=None, id='bittrex') -> Exchange:
    patch_exchange(mocker, api_mock, id)
    config["exchange"]["name"] = id
    try:
        exchange = ExchangeResolver(id, config).exchange
    except ImportError:
        exchange = Exchange(config)
    return exchange
コード例 #16
0
ファイル: test_exchange.py プロジェクト: tucanae47/freqtrade
def test_validate_pairs_not_available(default_conf, mocker):
    api_mock = MagicMock()
    api_mock.load_markets = MagicMock(return_value={})
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt',
                 MagicMock(return_value=api_mock))

    with pytest.raises(OperationalException, match=r'not available'):
        Exchange(default_conf)
コード例 #17
0
 def __init__(self, exchange_name: str, config: dict) -> None:
     """
     Load the custom class from config parameter
     :param config: configuration dictionary
     """
     try:
         self.exchange = self._load_exchange(exchange_name, kwargs={'config': config})
     except ImportError:
         logger.info(
             f"No {exchange_name} specific subclass found. Using the generic class instead.")
         self.exchange = Exchange(config)
コード例 #18
0
def test_validate_pairs_not_compatible(default_conf, mocker):
    api_mock = MagicMock()
    api_mock.load_markets = MagicMock(return_value={
        'ETH/BTC': '', 'TKN/BTC': '', 'TRST/BTC': '', 'SWT/BTC': '', 'BCC/BTC': ''
    })
    default_conf['stake_currency'] = 'ETH'
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
    mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())
    with pytest.raises(OperationalException, match=r'not compatible'):
        Exchange(default_conf)
コード例 #19
0
def test_validate_pairs(default_conf, mocker):
    api_mock = MagicMock()
    api_mock.load_markets = MagicMock(return_value={
        'ETH/BTC': '', 'LTC/BTC': '', 'XRP/BTC': '', 'NEO/BTC': ''
    })
    id_mock = PropertyMock(return_value='test_exchange')
    type(api_mock).id = id_mock

    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
    mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())
    Exchange(default_conf)
コード例 #20
0
def test__load_markets(default_conf, mocker, caplog):
    caplog.set_level(logging.INFO)
    api_mock = MagicMock()
    mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value='Binance'))

    api_mock.load_markets = MagicMock(return_value={})
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock)
    mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
    mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())

    expected_return = {'ETH/BTC': 'available'}
    api_mock.load_markets = MagicMock(return_value=expected_return)
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
    default_conf['exchange']['pair_whitelist'] = ['ETH/BTC']
    ex = Exchange(default_conf)
    assert ex.markets == expected_return

    api_mock.load_markets = MagicMock(side_effect=ccxt.BaseError())
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
    Exchange(default_conf)
    assert log_has('Unable to initialize markets. Reason: ', caplog.record_tuples)
コード例 #21
0
ファイル: test_exchange.py プロジェクト: tucanae47/freqtrade
def test_validate_pairs_stake_exception(default_conf, mocker, caplog):
    caplog.set_level(logging.INFO)
    conf = deepcopy(default_conf)
    conf['stake_currency'] = 'ETH'
    api_mock = MagicMock()
    api_mock.name = MagicMock(return_value='binance')
    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock)

    with pytest.raises(
            OperationalException,
            match=r'Pair ETH/BTC not compatible with stake_currency: ETH'):
        Exchange(conf)
コード例 #22
0
ファイル: history.py プロジェクト: Matix200/freqtrade-struga
def download_pair_history(datadir: Optional[Path],
                          exchange: Exchange,
                          pair: str,
                          ticker_interval: str = '5m',
                          timerange: Optional[TimeRange] = None) -> bool:
    """
    Download the latest ticker intervals from the exchange for the pair passed in parameters
    The data is downloaded starting from the last correct ticker interval data that
    exists in a cache. If timerange starts earlier than the data in the cache,
    the full data will be redownloaded

    Based on @Rybolov work: https://github.com/rybolov/freqtrade-data
    :param pair: pair to download
    :param ticker_interval: ticker interval
    :param timerange: range of time to download
    :return: bool with success state

    """
    try:
        path = make_testdata_path(datadir)
        filepair = pair.replace("/", "_")
        filename = path.joinpath(f'{filepair}-{ticker_interval}.json')

        logger.info('Download the pair: "%s", Interval: %s', pair,
                    ticker_interval)

        data, since_ms = load_cached_data_for_updating(filename,
                                                       ticker_interval,
                                                       timerange)

        logger.debug("Current Start: %s",
                     misc.format_ms_time(data[1][0]) if data else 'None')
        logger.debug("Current End: %s",
                     misc.format_ms_time(data[-1][0]) if data else 'None')

        # Default since_ms to 30 days if nothing is given
        new_data = exchange.get_history(
            pair=pair,
            ticker_interval=ticker_interval,
            since_ms=since_ms if since_ms else
            int(arrow.utcnow().shift(days=-30).float_timestamp) * 1000)
        data.extend(new_data)

        logger.debug("New Start: %s", misc.format_ms_time(data[0][0]))
        logger.debug("New End: %s", misc.format_ms_time(data[-1][0]))

        misc.file_dump_json(filename, data)
        return True
    except BaseException:
        logger.info('Failed to download the pair: "%s", Interval: %s', pair,
                    ticker_interval)
        return False
コード例 #23
0
ファイル: freqtradebot.py プロジェクト: DimaK79/xtrader
    def __init__(self, config: Dict[str, Any]) -> None:
        """
        Init all variables and object the bot need to work
        :param config: configuration dict, you can use the Configuration.get_config()
        method to get the config dict.
        """

        logger.info(
            'Starting freqtrade %s',
            __version__,
        )

        # Init bot states
        self.state = State.STOPPED

        # Init objects
        self.config = config
        self.strategy: IStrategy = StrategyResolver(self.config).strategy
        self.rpc: RPCManager = RPCManager(self)
        self.persistence = None
        self.exchange = Exchange(self.config)
        self._init_modules()
コード例 #24
0
ファイル: history.py プロジェクト: wesaka/freqtrade
def _download_pair_history(datadir: Path,
                           exchange: Exchange,
                           pair: str,
                           timeframe: str = '5m',
                           timerange: Optional[TimeRange] = None) -> bool:
    """
    Download latest candles from the exchange for the pair and timeframe passed in parameters
    The data is downloaded starting from the last correct data that
    exists in a cache. If timerange starts earlier than the data in the cache,
    the full data will be redownloaded

    Based on @Rybolov work: https://github.com/rybolov/freqtrade-data

    :param pair: pair to download
    :param timeframe: Ticker Timeframe (e.g 5m)
    :param timerange: range of time to download
    :return: bool with success state
    """
    try:
        logger.info(
            f'Download history data for pair: "{pair}", timeframe: {timeframe} '
            f'and store in {datadir}.'
        )

        data, since_ms = _load_cached_data_for_updating(datadir, pair, timeframe, timerange)

        logger.debug("Current Start: %s", misc.format_ms_time(data[1][0]) if data else 'None')
        logger.debug("Current End: %s", misc.format_ms_time(data[-1][0]) if data else 'None')

        # Default since_ms to 30 days if nothing is given
        new_data = exchange.get_historic_ohlcv(pair=pair,
                                               timeframe=timeframe,
                                               since_ms=since_ms if since_ms else
                                               int(arrow.utcnow().shift(
                                                   days=-30).float_timestamp) * 1000
                                               )
        data.extend(new_data)

        logger.debug("New Start: %s", misc.format_ms_time(data[0][0]))
        logger.debug("New End: %s", misc.format_ms_time(data[-1][0]))

        store_tickerdata_file(datadir, pair, timeframe, data=data)
        return True

    except Exception as e:
        logger.error(
            f'Failed to download history data for pair: "{pair}", timeframe: {timeframe}. '
            f'Error: {e}'
        )
        return False
コード例 #25
0
def test_validate_timeframes_not_in_config(default_conf, mocker):
    del default_conf["ticker_interval"]
    api_mock = MagicMock()
    id_mock = PropertyMock(return_value='test_exchange')
    type(api_mock).id = id_mock
    timeframes = PropertyMock(return_value={'1m': '1m',
                                            '5m': '5m',
                                            '15m': '15m',
                                            '1h': '1h'})
    type(api_mock).timeframes = timeframes

    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
    Exchange(default_conf)
コード例 #26
0
def test_validate_timeframes_failed(default_conf, mocker):
    default_conf["ticker_interval"] = "3m"
    api_mock = MagicMock()
    id_mock = PropertyMock(return_value='test_exchange')
    type(api_mock).id = id_mock
    timeframes = PropertyMock(return_value={'1m': '1m',
                                            '5m': '5m',
                                            '15m': '15m',
                                            '1h': '1h'})
    type(api_mock).timeframes = timeframes

    mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
    mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
    with pytest.raises(OperationalException, match=r'Invalid ticker 3m, this Exchange supports.*'):
        Exchange(default_conf)
コード例 #27
0
ファイル: analyze.py プロジェクト: tucanae47/freqtrade
    def get_signal(self, exchange: Exchange, pair: str,
                   interval: str) -> Tuple[bool, bool]:
        """
        Calculates current signal based several technical analysis indicators
        :param pair: pair in format ANT/BTC
        :param interval: Interval to use (in min)
        :return: (Buy, Sell) A bool-tuple indicating buy/sell signal
        """
        ticker_hist = exchange.get_ticker_history(pair, interval)
        if not ticker_hist:
            logger.warning('Empty ticker history for pair %s', pair)
            return False, False

        try:
            dataframe = self.analyze_ticker(ticker_hist)
        except ValueError as error:
            logger.warning('Unable to analyze ticker for pair %s: %s', pair,
                           str(error))
            return False, False
        except Exception as error:
            logger.exception(
                'Unexpected error when analyzing ticker for pair %s: %s', pair,
                str(error))
            return False, False

        if dataframe.empty:
            logger.warning('Empty dataframe for pair %s', pair)
            return False, False

        latest = dataframe.iloc[-1]

        # Check if dataframe is out of date
        signal_date = arrow.get(latest['date'])
        interval_minutes = constants.TICKER_INTERVAL_MINUTES[interval]
        if signal_date < (arrow.utcnow() -
                          timedelta(minutes=(interval_minutes + 5))):
            logger.warning(
                'Outdated history for pair %s. Last tick is %s minutes old',
                pair, (arrow.utcnow() - signal_date).seconds // 60)
            return False, False

        (buy, sell) = latest[SignalType.BUY.value] == 1, latest[
            SignalType.SELL.value] == 1
        logger.debug('trigger: %s (pair=%s) buy=%s sell=%s', latest['date'],
                     pair, str(buy), str(sell))
        return buy, sell
コード例 #28
0
    def __init__(self, config: Dict[str, Any]) -> None:
        self.config = config

        # Reset keys for edge
        remove_credentials(self.config)
        self.config['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
        self.exchange = Exchange(self.config)
        self.strategy = StrategyResolver(self.config).strategy

        self.edge = Edge(config, self.exchange, self.strategy)
        # Set refresh_pairs to false for edge-cli (it must be true for edge)
        self.edge._refresh_pairs = False

        self.timerange = TimeRange.parse_timerange(None if self.config.get(
            'timerange') is None else str(self.config.get('timerange')))

        self.edge._timerange = self.timerange
コード例 #29
0
async def test__async_get_candle_history_empty(default_conf, mocker, caplog):
    """ Test empty exchange result """
    tick = []

    caplog.set_level(logging.DEBUG)
    exchange = get_patched_exchange(mocker, default_conf)
    # Monkey-patch async function
    exchange._api_async.fetch_ohlcv = get_mock_coro([])

    exchange = Exchange(default_conf)
    pair = 'ETH/BTC'
    res = await exchange._async_get_candle_history(pair, "5m")
    assert type(res) is tuple
    assert len(res) == 2
    assert res[0] == pair
    assert res[1] == tick
    assert exchange._api_async.fetch_ohlcv.call_count == 1
コード例 #30
0
def download_backtesting_testdata(datadir: str,
                                  exchange: Exchange,
                                  pair: str,
                                  tick_interval: str = '5m',
                                  timerange: Optional[TimeRange] = None) -> None:

    """
    Download the latest ticker intervals from the exchange for the pairs passed in parameters
    The data is downloaded starting from the last correct ticker interval data that
    esists in a cache. If timerange starts earlier than the data in the cache,
    the full data will be redownloaded

    Based on @Rybolov work: https://github.com/rybolov/freqtrade-data
    :param pairs: list of pairs to download
    :param tick_interval: ticker interval
    :param timerange: range of time to download
    :return: None

    """

    path = make_testdata_path(datadir)
    filepair = pair.replace("/", "_")
    filename = os.path.join(path, f'{filepair}-{tick_interval}.json')

    logger.info(
        'Download the pair: "%s", Interval: %s',
        pair,
        tick_interval
    )

    data, since_ms = load_cached_data_for_updating(filename, tick_interval, timerange)

    logger.debug("Current Start: %s", misc.format_ms_time(data[1][0]) if data else 'None')
    logger.debug("Current End: %s", misc.format_ms_time(data[-1][0]) if data else 'None')

    new_data = exchange.get_ticker_history(pair=pair, tick_interval=tick_interval,
                                           since_ms=since_ms)
    data.extend(new_data)

    logger.debug("New Start: %s", misc.format_ms_time(data[0][0]))
    logger.debug("New End: %s", misc.format_ms_time(data[-1][0]))

    misc.file_dump_json(filename, data)