def convert_parse_args(args: List[str]) -> Namespace: """ Parse args passed to the script :param args: Cli arguments :return: args: Array with all arguments """ arguments = Arguments(args, 'Convert datafiles') arguments.parser.add_argument( '-d', '--datadir', help='path to backtest data (default: %(default)s', dest='datadir', default=path.join('freqtrade', 'tests', 'testdata'), type=str, metavar='PATH', ) arguments.parser.add_argument( '-n', '--norename', help='don' 't rename files from BTC_<PAIR> to <PAIR>_BTC - ' 'Note that not renaming will overwrite source files', dest='norename', default=False, action='store_true') return arguments.parse_args()
def test_parse_args_backtesting_invalid() -> None: with pytest.raises(SystemExit, match=r'2'): Arguments(['backtesting --ticker-interval'], '').get_parsed_arg() with pytest.raises(SystemExit, match=r'2'): Arguments(['backtesting --ticker-interval', 'abc'], '').get_parsed_arg()
def main(sysargv: List[str]) -> None: """ This function will initiate the bot and start the trading loop. :return: None """ arguments = Arguments(sysargv, 'Free, open source crypto trading bot') args: Namespace = arguments.get_parsed_arg() # A subcommand has been issued. # Means if Backtesting or Hyperopt have been called we exit the bot if hasattr(args, 'func'): args.func(args) return worker = None return_code = 1 try: # Load and run worker worker = Worker(args) worker.run() except KeyboardInterrupt: logger.info('SIGINT received, aborting ...') return_code = 0 except OperationalException as e: logger.error(str(e)) return_code = 2 except BaseException: logger.exception('Fatal exception!') finally: if worker: worker.exit() sys.exit(return_code)
def test_load_config_with_params(default_conf, mocker) -> None: """ Test Configuration.load_config() with cli params used """ mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) arglist = [ '--dynamic-whitelist', '10', '--strategy', 'TestStrategy', '--strategy-path', '/some/path', '--db-url', 'sqlite:///someurl', ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('dynamic_whitelist') == 10 assert validated_conf.get('strategy') == 'TestStrategy' assert validated_conf.get('strategy_path') == '/some/path' assert validated_conf.get('db_url') == 'sqlite:///someurl' conf = default_conf.copy() conf["dry_run"] = False del conf["db_url"] mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(conf))) arglist = [ '--dynamic-whitelist', '10', '--strategy', 'TestStrategy', '--strategy-path', '/some/path' ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('db_url') == DEFAULT_DB_PROD_URL # Test dry=run with ProdURL conf = default_conf.copy() conf["dry_run"] = True conf["db_url"] = DEFAULT_DB_PROD_URL mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(conf))) arglist = [ '--dynamic-whitelist', '10', '--strategy', 'TestStrategy', '--strategy-path', '/some/path' ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('db_url') == DEFAULT_DB_DRYRUN_URL
def test_parse_args_config() -> None: args = Arguments(['-c', '/dev/null'], '').get_parsed_arg() assert args.config == ['/dev/null'] args = Arguments(['--config', '/dev/null'], '').get_parsed_arg() assert args.config == ['/dev/null'] args = Arguments(['--config', '/dev/null', '--config', '/dev/zero'], '').get_parsed_arg() assert args.config == ['/dev/null', '/dev/zero']
def test_testdata_dl_options() -> None: args = [ '--pairs-file', 'file_with_pairs', '--export', 'export/folder', '--days', '30', '--exchange', 'binance' ] arguments = Arguments(args, '') arguments.testdata_dl_options() args = arguments.parse_args() assert args.pairs_file == 'file_with_pairs' assert args.export == 'export/folder' assert args.days == 30 assert args.exchange == 'binance'
def main(sysargv: List[str]) -> None: """ This function will initiate the bot and start the trading loop. :return: None """ arguments = Arguments( sysargv, 'Free, open source crypto trading bot' ) args = arguments.get_parsed_arg() # A subcommand has been issued. # Means if Backtesting or Hyperopt have been called we exit the bot if hasattr(args, 'func'): args.func(args) return freqtrade = None return_code = 1 try: # Load and validate configuration config = Configuration(args).get_config() # Init the bot freqtrade = FreqtradeBot(config) state = None while True: state = freqtrade.worker(old_state=state) if state == State.RELOAD_CONF: freqtrade = reconfigure(freqtrade, args) except KeyboardInterrupt: logger.info('SIGINT received, aborting ...') return_code = 0 except OperationalException as e: logger.error(str(e)) return_code = 2 except BaseException: logger.exception('Fatal exception!') finally: if freqtrade: freqtrade.rpc.send_msg({ 'type': RPCMessageType.STATUS_NOTIFICATION, 'status': 'process died' }) freqtrade.cleanup() sys.exit(return_code)
def test_show_info(default_conf, mocker, caplog) -> None: """ Test Configuration.show_info() """ mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) arglist = [ '--dynamic-whitelist', '10', '--strategy', 'TestStrategy', '--db-url', 'sqlite:///tmp/testdb', ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) configuration.get_config() assert log_has( 'Parameter --dynamic-whitelist detected. ' 'Using dynamically generated whitelist. ' '(not applicable with Backtesting and Hyperopt)', caplog.record_tuples) assert log_has('Using DB: "sqlite:///tmp/testdb"', caplog.record_tuples) assert log_has('Dry run is enabled', caplog.record_tuples)
def test_show_info(default_conf, mocker, caplog) -> None: """ Test Configuration.show_info() """ mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = [ '--dynamic-whitelist', '10', '--strategy', 'TestStrategy', '--dry-run-db' ] args = Arguments(args, '').get_parsed_arg() configuration = Configuration(args) configuration.get_config() assert log_has( 'Parameter --dynamic-whitelist detected. ' 'Using dynamically generated whitelist. ' '(not applicable with Backtesting and Hyperopt)', caplog.record_tuples) assert log_has('Parameter --dry-run-db detected ...', caplog.record_tuples) assert log_has('Dry_run will use the DB file: "tradesv3.dry_run.sqlite"', caplog.record_tuples) # Test the Dry run condition configuration.config.update({'dry_run': False}) configuration._load_common_config(configuration.config) assert log_has('Dry run is disabled. (--dry_run_db ignored)', caplog.record_tuples)
def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None: conf1 = deepcopy(default_conf) conf2 = deepcopy(default_conf) del conf1['exchange']['key'] del conf1['exchange']['secret'] del conf2['exchange']['name'] conf2['exchange']['pair_whitelist'] += ['NANO/BTC'] config_files = [conf1, conf2] configsmock = MagicMock(side_effect=config_files) mocker.patch('freqtrade.configuration.Configuration._load_config_file', configsmock) arg_list = [ '-c', 'test_conf.json', '--config', 'test2_conf.json', ] args = Arguments(arg_list, '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() exchange_conf = default_conf['exchange'] assert validated_conf['exchange']['name'] == exchange_conf['name'] assert validated_conf['exchange']['key'] == exchange_conf['key'] assert validated_conf['exchange']['secret'] == exchange_conf['secret'] assert validated_conf['exchange']['pair_whitelist'] != conf1['exchange'][ 'pair_whitelist'] assert validated_conf['exchange']['pair_whitelist'] == conf2['exchange'][ 'pair_whitelist'] assert 'internals' in validated_conf assert log_has('Validating configuration ...', caplog.record_tuples)
def test_reconfigure(mocker, default_conf) -> None: patch_exchange(mocker) mocker.patch.multiple( 'freqtrade.freqtradebot.FreqtradeBot', _init_modules=MagicMock(), worker=MagicMock(side_effect=OperationalException('Oh snap!')), cleanup=MagicMock(), ) mocker.patch('freqtrade.configuration.Configuration._load_config_file', lambda *args, **kwargs: default_conf) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) freqtrade = FreqtradeBot(default_conf) # Renew mock to return modified data conf = deepcopy(default_conf) conf['stake_amount'] += 1 mocker.patch('freqtrade.configuration.Configuration._load_config_file', lambda *args, **kwargs: conf) # reconfigure should return a new instance freqtrade2 = reconfigure( freqtrade, Arguments(['-c', 'config.json.example'], '').get_parsed_arg()) # Verify we have a new instance with the new config assert freqtrade is not freqtrade2 assert freqtrade.config['stake_amount'] + 1 == freqtrade2.config[ 'stake_amount']
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None: mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) arglist = [ 'hyperopt', '--epochs', '10', '--spaces', 'all', ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) config = configuration.get_config() assert 'epochs' in config assert int(config['epochs']) == 10 assert log_has('Parameter --epochs detected ...', caplog.record_tuples) assert log_has('Will run Hyperopt with for 10 epochs ...', caplog.record_tuples) assert 'spaces' in config assert config['spaces'] == ['all'] assert log_has('Parameter -s/--spaces detected: [\'all\']', caplog.record_tuples)
def test_load_config_with_params(default_conf, mocker) -> None: """ Test Configuration.load_config() with cli params used """ mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = [ '--dynamic-whitelist', '10', '--strategy', 'TestStrategy', '--strategy-path', '/some/path', '--dry-run-db', ] args = Arguments(args, '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('dynamic_whitelist') == 10 assert validated_conf.get('strategy') == 'TestStrategy' assert validated_conf.get('strategy_path') == '/some/path' assert validated_conf.get('dry_run_db') is True
def test_main_reload_conf(mocker, default_conf, caplog) -> None: patch_exchange(mocker) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock()) # Simulate Running, reload, running workflow worker_mock = MagicMock(side_effect=[ State.RUNNING, State.RELOAD_CONF, State.RUNNING, OperationalException("Oh snap!") ]) mocker.patch('freqtrade.worker.Worker._worker', worker_mock) mocker.patch('freqtrade.configuration.Configuration._load_config_file', lambda *args, **kwargs: default_conf) reconfigure_mock = mocker.patch('freqtrade.main.Worker._reconfigure', MagicMock()) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock()) args = Arguments(['-c', 'config.json.example'], '').get_parsed_arg() worker = Worker(args=args, config=default_conf) with pytest.raises(SystemExit): main(['-c', 'config.json.example']) assert log_has('Using config: config.json.example ...', caplog.record_tuples) assert worker_mock.call_count == 4 assert reconfigure_mock.call_count == 1 assert isinstance(worker.freqtrade, FreqtradeBot)
def test_reconfigure(mocker, default_conf) -> None: patch_exchange(mocker) mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock()) mocker.patch('freqtrade.worker.Worker._worker', MagicMock(side_effect=OperationalException('Oh snap!'))) mocker.patch('freqtrade.configuration.Configuration._load_config_file', lambda *args, **kwargs: default_conf) mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock()) mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock()) args = Arguments(['-c', 'config.json.example'], '').get_parsed_arg() worker = Worker(args=args, config=default_conf) freqtrade = worker.freqtrade # Renew mock to return modified data conf = deepcopy(default_conf) conf['stake_amount'] += 1 mocker.patch('freqtrade.configuration.Configuration._load_config_file', lambda *args, **kwargs: conf) worker._config = conf # reconfigure should return a new instance worker._reconfigure() freqtrade2 = worker.freqtrade # Verify we have a new instance with the new config assert freqtrade is not freqtrade2 assert freqtrade.config['stake_amount'] + 1 == freqtrade2.config[ 'stake_amount']
def analyse_and_plot_pairs(config: Dict[str, Any]): """ From arguments provided in cli: -Initialise backtest env -Get tickers data -Generate Dafaframes populated with indicators and signals -Load trades excecuted on same periods -Generate Plotly plot objects -Generate plot files :return: None """ exchange = ExchangeResolver(config.get('exchange', {}).get('name'), config).exchange strategy = StrategyResolver(config).strategy if "pairs" in config: pairs = config["pairs"].split(',') else: pairs = config["exchange"]["pair_whitelist"] # Set timerange to use timerange = Arguments.parse_timerange(config["timerange"]) ticker_interval = strategy.ticker_interval tickers = history.load_data( datadir=Path(str(config.get("datadir"))), pairs=pairs, ticker_interval=config['ticker_interval'], refresh_pairs=config.get('refresh_pairs', False), timerange=timerange, exchange=exchange, live=config.get("live", False), ) pair_counter = 0 for pair, data in tickers.items(): pair_counter += 1 logger.info("analyse pair %s", pair) tickers = {} tickers[pair] = data dataframe = generate_dataframe(strategy, tickers, pair) if config["trade_source"] == "DB": trades = load_trades_from_db(config["db_url"]) elif config["trade_source"] == "file": trades = load_backtest_data(Path(config["exportfilename"])) trades = trades.loc[trades['pair'] == pair] trades = extract_trades_of_period(dataframe, trades) fig = generate_graph( pair=pair, data=dataframe, trades=trades, indicators1=config["indicators1"].split(","), indicators2=config["indicators2"].split(",") ) generate_plot_file(fig, pair, ticker_interval) logger.info('End of ploting process %s plots generated', pair_counter)
def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None: mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) mocker.patch('freqtrade.configuration.Configuration._create_datadir', lambda s, c, x: x) arglist = [ '--config', 'config.json', '--strategy', 'DefaultStrategy', '--datadir', '/foo/bar', 'backtesting', '--ticker-interval', '1m', '--live', '--enable-position-stacking', '--disable-max-market-positions', '--refresh-pairs-cached', '--timerange', ':100', '--export', '/bar/foo' ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) config = configuration.get_config() assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config assert 'exchange' in config assert 'pair_whitelist' in config['exchange'] assert 'datadir' in config assert log_has('Using data folder: {} ...'.format(config['datadir']), caplog.record_tuples) assert 'ticker_interval' in config assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) assert log_has('Using ticker_interval: 1m ...', caplog.record_tuples) assert 'live' in config assert log_has('Parameter -l/--live detected ...', caplog.record_tuples) assert 'position_stacking' in config assert log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples) assert 'use_max_market_positions' in config assert log_has('Parameter --disable-max-market-positions detected ...', caplog.record_tuples) assert log_has('max_open_trades set to unlimited ...', caplog.record_tuples) assert 'refresh_pairs' in config assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples) assert 'timerange' in config assert log_has( 'Parameter --timerange detected: {} ...'.format(config['timerange']), caplog.record_tuples) assert 'export' in config assert log_has( 'Parameter --export detected: {} ...'.format(config['export']), caplog.record_tuples)
def start(self) -> None: timerange = Arguments.parse_timerange(None if self.config.get( 'timerange') is None else str(self.config.get('timerange'))) data = load_data(datadir=str(self.config.get('datadir')), pairs=self.config['exchange']['pair_whitelist'], ticker_interval=self.ticker_interval, timerange=timerange) if self.has_space('buy'): self.analyze.populate_indicators = Hyperopt.populate_indicators # type: ignore self.processed = self.tickerdata_to_dataframe(data) logger.info('Preparing Trials..') signal.signal(signal.SIGINT, self.signal_handler) # read trials file if we have one if os.path.exists( self.trials_file) and os.path.getsize(self.trials_file) > 0: self.trials = self.read_trials() self.current_tries = len(self.trials.results) self.total_tries += self.current_tries logger.info('Continuing with trials. Current: %d, Total: %d', self.current_tries, self.total_tries) try: best_parameters = fmin(fn=self.generate_optimizer, space=self.hyperopt_space(), algo=tpe.suggest, max_evals=self.total_tries, trials=self.trials) results = sorted(self.trials.results, key=itemgetter('loss')) best_result = results[0]['result'] except ValueError: best_parameters = {} best_result = 'Sorry, Hyperopt was not able to find good parameters. Please ' \ 'try with more epochs (param: -e).' # Improve best parameter logging display if best_parameters: best_parameters = space_eval(self.hyperopt_space(), best_parameters) logger.info('Best parameters:\n%s', json.dumps(best_parameters, indent=4)) if 'roi_t1' in best_parameters: logger.info('ROI table:\n%s', self.generate_roi_table(best_parameters)) logger.info('Best Result:\n%s', best_result) # Store trials result to file to resume next time self.save_trials()
def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None: default_conf['forcebuy_enable'] = True mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = Arguments([], '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('forcebuy_enable') assert log_has('`forcebuy` RPC message enabled.', caplog.record_tuples)
def test_parse_args_hyperopt_custom() -> None: args = [ '-c', 'test_conf.json', 'hyperopt', '--epochs', '20', '--spaces', 'buy' ] call_args = Arguments(args, '').get_parsed_arg() assert call_args.config == 'test_conf.json' assert call_args.epochs == 20 assert call_args.loglevel == 0 assert call_args.subparser == 'hyperopt' assert call_args.spaces == ['buy'] assert call_args.func is not None
def test_load_config(default_conf, mocker) -> None: mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = Arguments([], '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('strategy') == 'DefaultStrategy' assert validated_conf.get('strategy_path') is None assert 'edge' not in validated_conf
def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None: """ Test setup_configuration() function """ mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = [ '--config', 'config.json', '--strategy', 'DefaultStrategy', '--datadir', '/foo/bar', 'backtesting', '--ticker-interval', '1', '--live', '--realistic-simulation', '--refresh-pairs-cached', '--timerange', ':100', '--export', '/bar/foo' ] args = Arguments(args, '').get_parsed_arg() configuration = Configuration(args) config = configuration.get_config() assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config assert 'exchange' in config assert 'pair_whitelist' in config['exchange'] assert 'datadir' in config assert log_has( 'Parameter --datadir detected: {} ...'.format(config['datadir']), caplog.record_tuples) assert 'ticker_interval' in config assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) assert log_has('Using ticker_interval: 1 ...', caplog.record_tuples) assert 'live' in config assert log_has('Parameter -l/--live detected ...', caplog.record_tuples) assert 'realistic_simulation' in config assert log_has('Parameter --realistic-simulation detected ...', caplog.record_tuples) assert log_has('Using max_open_trades: 1 ...', caplog.record_tuples) assert 'refresh_pairs' in config assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples) assert 'timerange' in config assert log_has( 'Parameter --timerange detected: {} ...'.format(config['timerange']), caplog.record_tuples) assert 'export' in config assert log_has( 'Parameter --export detected: {} ...'.format(config['export']), caplog.record_tuples)
def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> None: """ Test setup_configuration() function """ mocker.patch('freqtrade.configuration.open', mocker.mock_open( read_data=json.dumps(default_conf) )) arglist = [ '--config', 'config.json', 'backtesting', '--ticker-interval', '1m', '--export', '/bar/foo', '--strategy-list', 'DefaultStrategy', 'TestStrategy' ] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) config = configuration.get_config() assert 'max_open_trades' in config assert 'stake_currency' in config assert 'stake_amount' in config assert 'exchange' in config assert 'pair_whitelist' in config['exchange'] assert 'datadir' in config assert log_has( 'Using data folder: {} ...'.format(config['datadir']), caplog.record_tuples ) assert 'ticker_interval' in config assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples) assert log_has( 'Using ticker_interval: 1m ...', caplog.record_tuples ) assert 'strategy_list' in config assert log_has('Using strategy list of 2 Strategies', caplog.record_tuples) assert 'position_stacking' not in config assert 'use_max_market_positions' not in config assert 'timerange' not in config assert 'export' in config assert log_has( 'Parameter --export detected: {} ...'.format(config['export']), caplog.record_tuples )
def test_parse_args_backtesting_custom() -> None: args = [ '-c', 'test_conf.json', 'backtesting', '--live', '--ticker-interval', '1', '--refresh-pairs-cached' ] call_args = Arguments(args, '').get_parsed_arg() assert call_args.config == 'test_conf.json' assert call_args.live is True assert call_args.loglevel == logging.INFO assert call_args.subparser == 'backtesting' assert call_args.func is not None assert call_args.ticker_interval == 1 assert call_args.refresh_pairs is True
def main(sysargv: List[str]) -> None: """ This function will initiate the bot and start the trading loop. :return: None """ arguments = Arguments( sysargv, 'Simple High Frequency Trading Bot for crypto currencies' ) args = arguments.get_parsed_arg() # A subcommand has been issued. # Means if Backtesting or Hyperopt have been called we exit the bot if hasattr(args, 'func'): args.func(args) return freqtrade = None return_code = 1 try: # Load and validate configuration config = Configuration(args).get_config() # Init the bot freqtrade = FreqtradeBot(config) state = None while 1: state = freqtrade.worker(old_state=state) except KeyboardInterrupt: logger.info('SIGINT received, aborting ...') return_code = 0 except BaseException: logger.exception('Fatal exception!') finally: if freqtrade: freqtrade.clean() sys.exit(return_code)
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None: default_conf['max_open_trades'] = -1 mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = Arguments([], '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf['max_open_trades'] > 999999999 assert validated_conf['max_open_trades'] == float('inf') assert log_has('Validating configuration ...', caplog.record_tuples)
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None: mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) # Prevent setting loggers mocker.patch('freqtrade.configuration.set_loggers', MagicMock) arglist = ['-vvv'] args = Arguments(arglist, '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('verbosity') == 3 assert log_has('Verbosity set to 3', caplog.record_tuples)
def test_load_config(default_conf, mocker) -> None: """ Test Configuration.load_config() without any cli params """ mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = Arguments([], '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('strategy') == 'DefaultStrategy' assert validated_conf.get('strategy_path') is None assert 'dynamic_whitelist' not in validated_conf
def test_load_custom_strategy(default_conf, mocker) -> None: default_conf.update({ 'strategy': 'CustomStrategy', 'strategy_path': '/tmp/strategies', }) mocker.patch('freqtrade.configuration.open', mocker.mock_open(read_data=json.dumps(default_conf))) args = Arguments([], '').get_parsed_arg() configuration = Configuration(args) validated_conf = configuration.load_config() assert validated_conf.get('strategy') == 'CustomStrategy' assert validated_conf.get('strategy_path') == '/tmp/strategies'
def __init__(self, config: Dict[str, Any], exchange, strategy) -> None: self.config = config self.exchange = exchange self.strategy = strategy self.ticker_interval = self.strategy.ticker_interval self.tickerdata_to_dataframe = self.strategy.tickerdata_to_dataframe self.get_timeframe = get_timeframe self.advise_sell = self.strategy.advise_sell self.advise_buy = self.strategy.advise_buy self.edge_config = self.config.get('edge', {}) self._cached_pairs: Dict[str, Any] = {} # Keeps a list of pairs self._final_pairs: list = [] # checking max_open_trades. it should be -1 as with Edge # the number of trades is determined by position size if self.config['max_open_trades'] != float('inf'): logger.critical('max_open_trades should be -1 in config !') if self.config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT: raise OperationalException( 'Edge works only with unlimited stake amount') self._capital_percentage: float = self.edge_config.get( 'capital_available_percentage') self._allowed_risk: float = self.edge_config.get('allowed_risk') self._since_number_of_days: int = self.edge_config.get( 'calculate_since_number_of_days', 14) self._last_updated: int = 0 # Timestamp of pairs last updated time self._refresh_pairs = True self._stoploss_range_min = float( self.edge_config.get('stoploss_range_min', -0.01)) self._stoploss_range_max = float( self.edge_config.get('stoploss_range_max', -0.05)) self._stoploss_range_step = float( self.edge_config.get('stoploss_range_step', -0.001)) # calculating stoploss range self._stoploss_range = np.arange(self._stoploss_range_min, self._stoploss_range_max, self._stoploss_range_step) self._timerange: TimeRange = Arguments.parse_timerange( "%s-" % arrow.now().shift( days=-1 * self._since_number_of_days).format('YYYYMMDD')) self.fee = self.exchange.get_fee()