예제 #1
0
 def __init__(self, config: dict) -> None:
     """
     Init Analyze
     :param config: Bot configuration (use the one from Configuration())
     """
     self.config = config
     self.strategy = StrategyResolver(self.config).strategy
예제 #2
0
def test_load_not_found_strategy():
    strategy = StrategyResolver()
    with pytest.raises(
            ImportError,
            match=r'Impossible to load Strategy \'NotFoundStrategy\'.'
            r' This class does not exist or contains Python code errors'):
        strategy._load_strategy('NotFoundStrategy')
예제 #3
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()
예제 #4
0
def test_search_strategy():
    default_location = os.path.join(
        os.path.dirname(os.path.realpath(__file__)), '..', '..', 'strategy')
    assert isinstance(
        StrategyResolver._search_strategy(default_location, 'DefaultStrategy'),
        IStrategy)
    assert StrategyResolver._search_strategy(default_location,
                                             'NotFoundStrategy') is None
예제 #5
0
def test_load_strategy_custom_directory(result):
    resolver = StrategyResolver()
    extra_dir = os.path.join('some', 'path')
    with pytest.raises(
            FileNotFoundError,
            match=r".*No such file or directory: '{}'".format(extra_dir)):
        resolver._load_strategy('TestStrategy', extra_dir)

    assert hasattr(resolver.strategy, 'populate_indicators')
    assert 'adx' in resolver.strategy.populate_indicators(result)
예제 #6
0
def test_load_strategy_invalid_directory(result, caplog):
    resolver = StrategyResolver()
    extra_dir = path.join('some', 'path')
    resolver._load_strategy('TestStrategy', config={}, extra_dir=extra_dir)

    assert (
        'freqtrade.strategy.resolver',
        logging.WARNING,
        'Path "{}" does not exist'.format(extra_dir),
    ) in caplog.record_tuples

    assert 'adx' in resolver.strategy.advise_indicators(
        result, {'pair': 'ETH/BTC'})
예제 #7
0
def test_search_strategy():
    default_config = {}
    default_location = path.join(path.dirname(path.realpath(__file__)), '..',
                                 '..', 'strategy')
    assert isinstance(
        StrategyResolver._search_strategy(default_location,
                                          config=default_config,
                                          strategy_name='DefaultStrategy'),
        IStrategy)
    assert StrategyResolver._search_strategy(
        default_location,
        config=default_config,
        strategy_name='NotFoundStrategy') is None
예제 #8
0
def test_load_strategy_invalid_directory(result, caplog):
    resolver = StrategyResolver()
    extra_dir = os.path.join('some', 'path')
    resolver._load_strategy('TestStrategy', extra_dir)

    assert (
        'freqtrade.strategy.resolver',
        logging.WARNING,
        'Path "{}" does not exist'.format(extra_dir),
    ) in caplog.record_tuples

    assert hasattr(resolver.strategy, 'populate_indicators')
    assert 'adx' in resolver.strategy.populate_indicators(result)
예제 #9
0
def test_fmin_throw_value_error(mocker, default_conf, caplog) -> None:
    mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
    mocker.patch('freqtrade.optimize.hyperopt.fmin', side_effect=ValueError())

    conf = deepcopy(default_conf)
    conf.update({'config': 'config.json.example'})
    conf.update({'epochs': 1})
    conf.update({'timerange': None})
    conf.update({'spaces': 'all'})
    mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf',
                 return_value=conf)
    StrategyResolver({'strategy': 'DefaultStrategy'})
    hyperopt = Hyperopt(conf)
    hyperopt.trials = create_trials(mocker)
    hyperopt.tickerdata_to_dataframe = MagicMock()

    hyperopt.start()

    exists = [
        'Best Result:',
        'Sorry, Hyperopt was not able to find good parameters. Please try with more epochs '
        '(param: -e).',
    ]

    for line in exists:
        assert line in caplog.text
예제 #10
0
def test_load_strategy_byte64(result):
    with open("freqtrade/tests/strategy/test_strategy.py", "r") as file:
        encoded_string = urlsafe_b64encode(
            file.read().encode("utf-8")).decode("utf-8")
    resolver = StrategyResolver(
        {'strategy': 'TestStrategy:{}'.format(encoded_string)})
    assert 'adx' in resolver.strategy.advise_indicators(result, 'ETH/BTC')
예제 #11
0
def test_call_deprecated_function(result, monkeypatch):
    default_location = path.join(path.dirname(path.realpath(__file__)))
    resolver = StrategyResolver({
        'strategy': 'TestStrategyLegacy',
        'strategy_path': default_location
    })
    metadata = {'pair': 'ETH/BTC'}

    # Make sure we are using a legacy function
    assert resolver.strategy._populate_fun_len == 2
    assert resolver.strategy._buy_fun_len == 2
    assert resolver.strategy._sell_fun_len == 2

    indicator_df = resolver.strategy.advise_indicators(result,
                                                       metadata=metadata)
    assert type(indicator_df) is DataFrame
    assert 'adx' in indicator_df.columns

    buydf = resolver.strategy.advise_buy(result, metadata=metadata)
    assert type(buydf) is DataFrame
    assert 'buy' in buydf.columns

    selldf = resolver.strategy.advise_sell(result, metadata=metadata)
    assert type(selldf) is DataFrame
    assert 'sell' in selldf
예제 #12
0
def test_deprecate_populate_indicators(result):
    default_location = path.join(path.dirname(path.realpath(__file__)))
    resolver = StrategyResolver({
        'strategy': 'TestStrategyLegacy',
        'strategy_path': default_location
    })
    with warnings.catch_warnings(record=True) as w:
        # Cause all warnings to always be triggered.
        warnings.simplefilter("always")
        indicators = resolver.strategy.advise_indicators(result, 'ETH/BTC')
        assert len(w) == 1
        assert issubclass(w[-1].category, DeprecationWarning)
        assert "deprecated - check out the Sample strategy to see the current function headers!" \
            in str(w[-1].message)

    with warnings.catch_warnings(record=True) as w:
        # Cause all warnings to always be triggered.
        warnings.simplefilter("always")
        resolver.strategy.advise_buy(indicators, 'ETH/BTC')
        assert len(w) == 1
        assert issubclass(w[-1].category, DeprecationWarning)
        assert "deprecated - check out the Sample strategy to see the current function headers!" \
            in str(w[-1].message)

    with warnings.catch_warnings(record=True) as w:
        # Cause all warnings to always be triggered.
        warnings.simplefilter("always")
        resolver.strategy.advise_sell(indicators, 'ETH_BTC')
        assert len(w) == 1
        assert issubclass(w[-1].category, DeprecationWarning)
        assert "deprecated - check out the Sample strategy to see the current function headers!" \
            in str(w[-1].message)
예제 #13
0
def test_loss_calculation_prefer_correct_trade_count(hyperopt) -> None:
    StrategyResolver({'strategy': 'DefaultStrategy'})

    correct = hyperopt.calculate_loss(1, hyperopt.target_trades, 20)
    over = hyperopt.calculate_loss(1, hyperopt.target_trades + 100, 20)
    under = hyperopt.calculate_loss(1, hyperopt.target_trades - 100, 20)
    assert over > correct
    assert under > correct
예제 #14
0
def test_strategy_override_minimal_roi(caplog):
    caplog.set_level(logging.INFO)
    config = {'strategy': 'DefaultStrategy', 'minimal_roi': {"0": 0.5}}
    resolver = StrategyResolver(config)

    assert resolver.strategy.minimal_roi[0] == 0.5
    assert ('freqtrade.strategy.resolver', logging.INFO,
            'Override strategy \'minimal_roi\' with value in config file.'
            ) in caplog.record_tuples
예제 #15
0
def test_strategy_override_stoploss(caplog):
    caplog.set_level(logging.INFO)
    config = {'strategy': 'DefaultStrategy', 'stoploss': -0.5}
    resolver = StrategyResolver(config)

    assert resolver.strategy.stoploss == -0.5
    assert ('freqtrade.strategy.resolver', logging.INFO,
            'Override strategy \'stoploss\' with value in config file: -0.5.'
            ) in caplog.record_tuples
예제 #16
0
def test_strategy_override_ticker_interval(caplog):
    caplog.set_level(logging.INFO)

    config = {'strategy': 'DefaultStrategy', 'ticker_interval': 60}
    resolver = StrategyResolver(config)

    assert resolver.strategy.ticker_interval == 60
    assert (
        'freqtrade.strategy.resolver', logging.INFO,
        'Override strategy \'ticker_interval\' with value in config file: 60.'
    ) in caplog.record_tuples
예제 #17
0
def test_start_failure(mocker, default_conf, caplog) -> None:
    start_mock = MagicMock()
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: default_conf)
    mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
    patch_exchange(mocker)

    args = [
        '--config', 'config.json', '--strategy', 'TestStrategy', 'hyperopt',
        '--epochs', '5'
    ]
    args = get_args(args)
    StrategyResolver({'strategy': 'DefaultStrategy'})
    with pytest.raises(ValueError):
        start(args)
    assert log_has("Please don't use --strategy for hyperopt.",
                   caplog.record_tuples)
예제 #18
0
def test_resuming_previous_hyperopt_results_succeeds(mocker,
                                                     default_conf) -> None:
    trials = create_trials(mocker)

    conf = deepcopy(default_conf)
    conf.update({'config': 'config.json.example'})
    conf.update({'epochs': 1})
    conf.update({'mongodb': False})
    conf.update({'timerange': None})
    conf.update({'spaces': 'all'})

    mocker.patch('freqtrade.optimize.hyperopt.os.path.exists',
                 return_value=True)
    mocker.patch('freqtrade.optimize.hyperopt.len',
                 return_value=len(trials.results))
    mock_read = mocker.patch(
        'freqtrade.optimize.hyperopt.Hyperopt.read_trials',
        return_value=trials)
    mock_save = mocker.patch(
        'freqtrade.optimize.hyperopt.Hyperopt.save_trials', return_value=None)
    mocker.patch('freqtrade.optimize.hyperopt.sorted',
                 return_value=trials.results)
    mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
    mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
    mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf',
                 return_value=conf)

    StrategyResolver({'strategy': 'DefaultStrategy'})
    hyperopt = Hyperopt(conf)
    hyperopt.trials = trials
    hyperopt.tickerdata_to_dataframe = MagicMock()

    hyperopt.start()

    mock_read.assert_called_once()
    mock_save.assert_called_once()

    current_tries = hyperopt.current_tries
    total_tries = hyperopt.total_tries

    assert current_tries == len(trials.results)
    assert total_tries == (current_tries + len(trials.results))
예제 #19
0
def test_start(mocker, default_conf, caplog) -> None:
    start_mock = MagicMock()
    mocker.patch('freqtrade.configuration.Configuration._load_config_file',
                 lambda *args, **kwargs: default_conf)
    mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
    patch_exchange(mocker)

    args = [
        '--config', 'config.json', '--strategy', 'DefaultStrategy', 'hyperopt',
        '--epochs', '5'
    ]
    args = get_args(args)
    StrategyResolver({'strategy': 'DefaultStrategy'})
    start(args)

    import pprint
    pprint.pprint(caplog.record_tuples)

    assert log_has('Starting freqtrade in Hyperopt mode', caplog.record_tuples)
    assert start_mock.call_count == 1
예제 #20
0
def test_strategy(result):
    resolver = StrategyResolver({'strategy': 'DefaultStrategy'})

    assert hasattr(resolver.strategy, 'minimal_roi')
    assert resolver.strategy.minimal_roi[0] == 0.04

    assert hasattr(resolver.strategy, 'stoploss')
    assert resolver.strategy.stoploss == -0.10

    assert hasattr(resolver.strategy, 'populate_indicators')
    assert 'adx' in resolver.strategy.populate_indicators(result)

    assert hasattr(resolver.strategy, 'populate_buy_trend')
    dataframe = resolver.strategy.populate_buy_trend(
        resolver.strategy.populate_indicators(result))
    assert 'buy' in dataframe.columns

    assert hasattr(resolver.strategy, 'populate_sell_trend')
    dataframe = resolver.strategy.populate_sell_trend(
        resolver.strategy.populate_indicators(result))
    assert 'sell' in dataframe.columns
예제 #21
0
def test_start(mocker, default_conf, caplog) -> None:
    """
    Test start() function
    """
    start_mock = MagicMock()
    mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
    mocker.patch('freqtrade.configuration.open',
                 mocker.mock_open(read_data=json.dumps(default_conf)))
    args = [
        '--config', 'config.json', '--strategy', 'DefaultStrategy', 'hyperopt',
        '--epochs', '5'
    ]
    args = get_args(args)
    StrategyResolver({'strategy': 'DefaultStrategy'})
    start(args)

    import pprint
    pprint.pprint(caplog.record_tuples)

    assert log_has('Starting freqtrade in Hyperopt mode', caplog.record_tuples)
    assert start_mock.call_count == 1
예제 #22
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._init_modules()
예제 #23
0
def test_strategy(result):
    config = {'strategy': 'DefaultStrategy'}

    resolver = StrategyResolver(config)
    metadata = {'pair': 'ETH/BTC'}
    assert resolver.strategy.minimal_roi[0] == 0.04
    assert config["minimal_roi"]['0'] == 0.04

    assert resolver.strategy.stoploss == -0.10
    assert config['stoploss'] == -0.10

    assert resolver.strategy.ticker_interval == '5m'
    assert config['ticker_interval'] == '5m'

    df_indicators = resolver.strategy.advise_indicators(result,
                                                        metadata=metadata)
    assert 'adx' in df_indicators

    dataframe = resolver.strategy.advise_buy(df_indicators, metadata=metadata)
    assert 'buy' in dataframe.columns

    dataframe = resolver.strategy.advise_sell(df_indicators, metadata=metadata)
    assert 'sell' in dataframe.columns
예제 #24
0
def test_load_strategy(result):
    resolver = StrategyResolver({'strategy': 'TestStrategy'})
    metadata = {'pair': 'ETH/BTC'}
    assert 'adx' in resolver.strategy.advise_indicators(result,
                                                        metadata=metadata)
예제 #25
0
def test_load_strategy(result):
    resolver = StrategyResolver()
    resolver._load_strategy('TestStrategy')
    assert hasattr(resolver.strategy, 'populate_indicators')
    assert 'adx' in resolver.strategy.populate_indicators(result)
예제 #26
0
def test_fmin_best_results(mocker, default_conf, caplog) -> None:
    fmin_result = {
        "macd_below_zero": 0,
        "adx": 1,
        "adx-value": 15.0,
        "fastd": 1,
        "fastd-value": 40.0,
        "green_candle": 1,
        "mfi": 0,
        "over_sar": 0,
        "rsi": 1,
        "rsi-value": 37.0,
        "trigger": 2,
        "uptrend_long_ema": 1,
        "uptrend_short_ema": 0,
        "uptrend_sma": 0,
        "stoploss": -0.1,
        "roi_t1": 1,
        "roi_t2": 2,
        "roi_t3": 3,
        "roi_p1": 1,
        "roi_p2": 2,
        "roi_p3": 3,
    }

    conf = deepcopy(default_conf)
    conf.update({'config': 'config.json.example'})
    conf.update({'epochs': 1})
    conf.update({'timerange': None})
    conf.update({'spaces': 'all'})

    mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
    mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result)
    mocker.patch('freqtrade.optimize.hyperopt.hyperopt_optimize_conf',
                 return_value=conf)

    StrategyResolver({'strategy': 'DefaultStrategy'})
    hyperopt = Hyperopt(conf)
    hyperopt.trials = create_trials(mocker)
    hyperopt.tickerdata_to_dataframe = MagicMock()
    hyperopt.start()

    exists = [
        'Best parameters:',
        '"adx": {\n        "enabled": true,\n        "value": 15.0\n    },',
        '"fastd": {\n        "enabled": true,\n        "value": 40.0\n    },',
        '"green_candle": {\n        "enabled": true\n    },',
        '"macd_below_zero": {\n        "enabled": false\n    },',
        '"mfi": {\n        "enabled": false\n    },',
        '"over_sar": {\n        "enabled": false\n    },', '"roi_p1": 1.0,',
        '"roi_p2": 2.0,', '"roi_p3": 3.0,', '"roi_t1": 1.0,', '"roi_t2": 2.0,',
        '"roi_t3": 3.0,',
        '"rsi": {\n        "enabled": true,\n        "value": 37.0\n    },',
        '"stoploss": -0.1,',
        '"trigger": {\n        "type": "faststoch10"\n    },',
        '"uptrend_long_ema": {\n        "enabled": true\n    },',
        '"uptrend_short_ema": {\n        "enabled": false\n    },',
        '"uptrend_sma": {\n        "enabled": false\n    }',
        'ROI table:\n{0: 6.0, 3.0: 3.0, 5.0: 1.0, 6.0: 0}', 'Best Result:\nfoo'
    ]
    for line in exists:
        assert line in caplog.text
예제 #27
0
class Analyze(object):
    """
    Analyze class contains everything the bot need to determine if the situation is good for
    buying or selling.
    """
    def __init__(self, config: dict) -> None:
        """
        Init Analyze
        :param config: Bot configuration (use the one from Configuration())
        """
        self.config = config
        self.strategy = StrategyResolver(self.config).strategy

    @staticmethod
    def parse_ticker_dataframe(ticker: list) -> DataFrame:
        """
        Analyses the trend for the given ticker history
        :param ticker: See exchange.get_ticker_history
        :return: DataFrame
        """
        columns = {'C': 'close', 'V': 'volume', 'O': 'open', 'H': 'high', 'L': 'low', 'T': 'date'}
        frame = DataFrame(ticker).rename(columns=columns)
        if 'BV' in frame:
            frame.drop('BV', axis=1, inplace=True)

        frame['date'] = to_datetime(frame['date'], utc=True, infer_datetime_format=True)

        # group by index and aggregate results to eliminate duplicate ticks
        frame = frame.groupby(by='date', as_index=False, sort=True).agg({
            'close': 'last',
            'high': 'max',
            'low': 'min',
            'open': 'first',
            'volume': 'max',
        })
        return frame

    def populate_indicators(self, dataframe: DataFrame) -> DataFrame:
        """
        Adds several different TA indicators to the given DataFrame

        Performance Note: For the best performance be frugal on the number of indicators
        you are using. Let uncomment only the indicator you are using in your strategies
        or your hyperopt configuration, otherwise you will waste your memory and CPU usage.
        """
        return self.strategy.populate_indicators(dataframe=dataframe)

    def populate_buy_trend(self, dataframe: DataFrame) -> DataFrame:
        """
        Based on TA indicators, populates the buy signal for the given dataframe
        :param dataframe: DataFrame
        :return: DataFrame with buy column
        """
        return self.strategy.populate_buy_trend(dataframe=dataframe)

    def populate_sell_trend(self, dataframe: DataFrame) -> DataFrame:
        """
        Based on TA indicators, populates the sell signal for the given dataframe
        :param dataframe: DataFrame
        :return: DataFrame with buy column
        """
        return self.strategy.populate_sell_trend(dataframe=dataframe)

    def get_ticker_interval(self) -> int:
        """
        Return ticker interval to use
        :return: Ticker interval value to use
        """
        return self.strategy.ticker_interval

    def analyze_ticker(self, ticker_history: List[Dict]) -> DataFrame:
        """
        Parses the given ticker history and returns a populated DataFrame
        add several TA indicators and buy signal to it
        :return DataFrame with ticker data and indicator data
        """
        dataframe = self.parse_ticker_dataframe(ticker_history)
        dataframe = self.populate_indicators(dataframe)
        dataframe = self.populate_buy_trend(dataframe)
        dataframe = self.populate_sell_trend(dataframe)
        return dataframe

    def get_signal(self, pair: str, interval: int) -> Tuple[bool, bool]:
        """
        Calculates current signal based several technical analysis indicators
        :param pair: pair in format BTC_ANT or BTC-ANT
        :param interval: Interval to use (in min)
        :return: (Buy, Sell) A bool-tuple indicating buy/sell signal
        """
        ticker_hist = 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'])
        if signal_date < arrow.utcnow() - timedelta(minutes=(interval + 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

    def should_sell(self, trade: Trade, rate: float, date: datetime, buy: bool, sell: bool) -> bool:
        """
        This function evaluate if on the condition required to trigger a sell has been reached
        if the threshold is reached and updates the trade record.
        :return: True if trade should be sold, False otherwise
        """
        # Check if minimal roi has been reached and no longer in buy conditions (avoiding a fee)
        if self.min_roi_reached(trade=trade, current_rate=rate, current_time=date):
            logger.debug('Required profit reached. Selling..')
            return True

        # Experimental: Check if the trade is profitable before selling it (avoid selling at loss)
        if self.config.get('experimental', {}).get('sell_profit_only', False):
            logger.debug('Checking if trade is profitable..')
            if trade.calc_profit(rate=rate) <= 0:
                return False

        if sell and not buy and self.config.get('experimental', {}).get('use_sell_signal', False):
            logger.debug('Sell signal received. Selling..')
            return True

        return False

    def min_roi_reached(self, trade: Trade, current_rate: float, current_time: datetime) -> bool:
        """
        Based an earlier trade and current price and ROI configuration, decides whether bot should
        sell
        :return True if bot should sell at current rate
        """
        current_profit = trade.calc_profit_percent(current_rate)
        if self.strategy.stoploss is not None and current_profit < self.strategy.stoploss:
            logger.debug('Stop loss hit.')
            return True

        # Check if time matches and current rate is above threshold
        time_diff = (current_time.timestamp() - trade.open_date.timestamp()) / 60
        for duration, threshold in self.strategy.minimal_roi.items():
            if time_diff <= duration:
                return False
            if current_profit > threshold:
                return True

        return False

    def tickerdata_to_dataframe(self, tickerdata: Dict[str, List]) -> Dict[str, DataFrame]:
        """
        Creates a dataframe and populates indicators for given ticker data
        """
        return {pair: self.populate_indicators(self.parse_ticker_dataframe(pair_data))
                for pair, pair_data in tickerdata.items()}
예제 #28
0
def test_dataframe_load():
    StrategyResolver({'strategy': 'DefaultStrategy'})
    dataframe = load_dataframe_pair(_pairs)
    assert isinstance(dataframe, pandas.core.frame.DataFrame)
def plot_analyzed_dataframe(args: Namespace) -> None:
    """
    Calls analyze() and plots the returned dataframe
    :return: None
    """
    global _CONF

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

    print(_CONF)
    # Set the pair to audit
    pair = args.pair

    if pair is None:
        logger.critical('Parameter --pair mandatory;. E.g --pair ETH/BTC')
        exit()

    if '/' not in pair:
        logger.critical('--pair format must be XXX/YYY')
        exit()

    # Set timerange to use
    timerange = Arguments.parse_timerange(args.timerange)

    # 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()

    # Set the ticker to use
    tick_interval = strategy.ticker_interval

    # Load pair tickers
    tickers = {}
    if args.live:
        logger.info('Downloading pair.')
        tickers[pair] = exchange.get_candle_history(pair, tick_interval)
    else:
        tickers = optimize.load_data(
            datadir=_CONF.get("datadir"),
            pairs=[pair],
            ticker_interval=tick_interval,
            refresh_pairs=_CONF.get('refresh_pairs', False),
            timerange=timerange,
            exchange=Exchange(_CONF)
        )

        # No ticker found, or impossible to download
        if tickers == {}:
            exit()

    # Get trades already made from the DB
    trades = load_trades(args, pair, timerange)

    dataframes = strategy.tickerdata_to_dataframe(tickers)

    dataframe = dataframes[pair]
    dataframe = strategy.advise_buy(dataframe, {'pair': pair})
    dataframe = strategy.advise_sell(dataframe, {'pair': pair})

    if len(dataframe.index) > args.plot_limit:
        logger.warning('Ticker contained more than %s candles as defined '
                       'with --plot-limit, clipping.', args.plot_limit)
    dataframe = dataframe.tail(args.plot_limit)

    trades = trades.loc[trades['opents'] >= dataframe.iloc[0]['date']]
    fig = generate_graph(
        pair=pair,
        trades=trades,
        data=dataframe,
        args=args
    )

    plot(fig, filename=str(Path('user_data').joinpath('freqtrade-plot.html')))
예제 #30
0
def test_dataframe_columns_exists():
    StrategyResolver({'strategy': 'DefaultStrategy'})
    dataframe = load_dataframe_pair(_pairs)
    assert 'high' in dataframe.columns
    assert 'low' in dataframe.columns
    assert 'close' in dataframe.columns