Merge pull request #2015 from hroff-1902/refactor/config2
Make configuration a module
This commit is contained in:
commit
5144e98a82
2
freqtrade/configuration/__init__.py
Normal file
2
freqtrade/configuration/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from freqtrade.configuration.arguments import Arguments, TimeRange # noqa: F401
|
||||||
|
from freqtrade.configuration.configuration import Configuration # noqa: F401
|
@ -5,6 +5,7 @@ import argparse
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from typing import List, NamedTuple, Optional
|
from typing import List, NamedTuple, Optional
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
from freqtrade import __version__, constants
|
from freqtrade import __version__, constants
|
||||||
|
|
48
freqtrade/configuration/check_exchange.py
Normal file
48
freqtrade/configuration/check_exchange.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import logging
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from freqtrade import OperationalException
|
||||||
|
from freqtrade.exchange import (is_exchange_bad, is_exchange_available,
|
||||||
|
is_exchange_officially_supported, available_exchanges)
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def check_exchange(config: Dict[str, Any], check_for_bad: bool = True) -> bool:
|
||||||
|
"""
|
||||||
|
Check if the exchange name in the config file is supported by Freqtrade
|
||||||
|
:param check_for_bad: if True, check the exchange against the list of known 'bad'
|
||||||
|
exchanges
|
||||||
|
:return: False if exchange is 'bad', i.e. is known to work with the bot with
|
||||||
|
critical issues or does not work at all, crashes, etc. True otherwise.
|
||||||
|
raises an exception if the exchange if not supported by ccxt
|
||||||
|
and thus is not known for the Freqtrade at all.
|
||||||
|
"""
|
||||||
|
logger.info("Checking exchange...")
|
||||||
|
|
||||||
|
exchange = config.get('exchange', {}).get('name').lower()
|
||||||
|
if not is_exchange_available(exchange):
|
||||||
|
raise OperationalException(
|
||||||
|
f'Exchange "{exchange}" is not supported by ccxt '
|
||||||
|
f'and therefore not available for the bot.\n'
|
||||||
|
f'The following exchanges are supported by ccxt: '
|
||||||
|
f'{", ".join(available_exchanges())}'
|
||||||
|
)
|
||||||
|
|
||||||
|
if check_for_bad and is_exchange_bad(exchange):
|
||||||
|
logger.warning(f'Exchange "{exchange}" is known to not work with the bot yet. '
|
||||||
|
f'Use it only for development and testing purposes.')
|
||||||
|
return False
|
||||||
|
|
||||||
|
if is_exchange_officially_supported(exchange):
|
||||||
|
logger.info(f'Exchange "{exchange}" is officially supported '
|
||||||
|
f'by the Freqtrade development team.')
|
||||||
|
else:
|
||||||
|
logger.warning(f'Exchange "{exchange}" is supported by ccxt '
|
||||||
|
f'and therefore available for the bot but not officially supported '
|
||||||
|
f'by the Freqtrade development team. '
|
||||||
|
f'It may work flawlessly (please report back) or have serious issues. '
|
||||||
|
f'Use it at your own discretion.')
|
||||||
|
|
||||||
|
return True
|
@ -3,17 +3,14 @@ This module contains the configuration class
|
|||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from typing import Any, Callable, Dict, Optional
|
from typing import Any, Callable, Dict, Optional
|
||||||
|
|
||||||
from jsonschema import Draft4Validator, validators
|
|
||||||
from jsonschema.exceptions import ValidationError, best_match
|
|
||||||
|
|
||||||
from freqtrade import OperationalException, constants
|
from freqtrade import OperationalException, constants
|
||||||
from freqtrade.exchange import (is_exchange_bad, is_exchange_available,
|
from freqtrade.configuration.check_exchange import check_exchange
|
||||||
is_exchange_officially_supported, available_exchanges)
|
from freqtrade.configuration.create_datadir import create_datadir
|
||||||
|
from freqtrade.configuration.json_schema import validate_config_schema
|
||||||
from freqtrade.loggers import setup_logging
|
from freqtrade.loggers import setup_logging
|
||||||
from freqtrade.misc import deep_merge_dicts
|
from freqtrade.misc import deep_merge_dicts
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
@ -22,31 +19,6 @@ from freqtrade.state import RunMode
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _extend_validator(validator_class):
|
|
||||||
"""
|
|
||||||
Extended validator for the Freqtrade configuration JSON Schema.
|
|
||||||
Currently it only handles defaults for subschemas.
|
|
||||||
"""
|
|
||||||
validate_properties = validator_class.VALIDATORS['properties']
|
|
||||||
|
|
||||||
def set_defaults(validator, properties, instance, schema):
|
|
||||||
for prop, subschema in properties.items():
|
|
||||||
if 'default' in subschema:
|
|
||||||
instance.setdefault(prop, subschema['default'])
|
|
||||||
|
|
||||||
for error in validate_properties(
|
|
||||||
validator, properties, instance, schema,
|
|
||||||
):
|
|
||||||
yield error
|
|
||||||
|
|
||||||
return validators.extend(
|
|
||||||
validator_class, {'properties': set_defaults}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
FreqtradeValidator = _extend_validator(Draft4Validator)
|
|
||||||
|
|
||||||
|
|
||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
"""
|
"""
|
||||||
Class to read and init the bot configuration
|
Class to read and init the bot configuration
|
||||||
@ -58,6 +30,16 @@ class Configuration(object):
|
|||||||
self.config: Optional[Dict[str, Any]] = None
|
self.config: Optional[Dict[str, Any]] = None
|
||||||
self.runmode = runmode
|
self.runmode = runmode
|
||||||
|
|
||||||
|
def get_config(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Return the config. Use this method to get the bot config
|
||||||
|
:return: Dict: Bot config
|
||||||
|
"""
|
||||||
|
if self.config is None:
|
||||||
|
self.config = self.load_config()
|
||||||
|
|
||||||
|
return self.config
|
||||||
|
|
||||||
def load_config(self) -> Dict[str, Any]:
|
def load_config(self) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Extract information for sys.argv and load the bot configuration
|
Extract information for sys.argv and load the bot configuration
|
||||||
@ -75,7 +57,7 @@ class Configuration(object):
|
|||||||
config['internals'] = {}
|
config['internals'] = {}
|
||||||
|
|
||||||
logger.info('Validating configuration ...')
|
logger.info('Validating configuration ...')
|
||||||
self._validate_config_schema(config)
|
validate_config_schema(config)
|
||||||
self._validate_config_consistency(config)
|
self._validate_config_consistency(config)
|
||||||
|
|
||||||
# Set strategy if not specified in config and or if it's non default
|
# Set strategy if not specified in config and or if it's non default
|
||||||
@ -185,21 +167,10 @@ class Configuration(object):
|
|||||||
logger.info(f'Using DB: "{config["db_url"]}"')
|
logger.info(f'Using DB: "{config["db_url"]}"')
|
||||||
|
|
||||||
# Check if the exchange set by the user is supported
|
# Check if the exchange set by the user is supported
|
||||||
self.check_exchange(config)
|
check_exchange(config)
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def _create_datadir(self, config: Dict[str, Any], datadir: Optional[str] = None) -> str:
|
|
||||||
if not datadir:
|
|
||||||
# set datadir
|
|
||||||
exchange_name = config.get('exchange', {}).get('name').lower()
|
|
||||||
datadir = os.path.join('user_data', 'data', exchange_name)
|
|
||||||
|
|
||||||
if not os.path.isdir(datadir):
|
|
||||||
os.makedirs(datadir)
|
|
||||||
logger.info(f'Created data directory: {datadir}')
|
|
||||||
return datadir
|
|
||||||
|
|
||||||
def _args_to_config(self, config: Dict[str, Any], argname: str,
|
def _args_to_config(self, config: Dict[str, Any], argname: str,
|
||||||
logstring: str, logfun: Optional[Callable] = None) -> None:
|
logstring: str, logfun: Optional[Callable] = None) -> None:
|
||||||
"""
|
"""
|
||||||
@ -225,9 +196,9 @@ class Configuration(object):
|
|||||||
the --datadir option
|
the --datadir option
|
||||||
"""
|
"""
|
||||||
if 'datadir' in self.args and self.args.datadir:
|
if 'datadir' in self.args and self.args.datadir:
|
||||||
config.update({'datadir': self._create_datadir(config, self.args.datadir)})
|
config.update({'datadir': create_datadir(config, self.args.datadir)})
|
||||||
else:
|
else:
|
||||||
config.update({'datadir': self._create_datadir(config, None)})
|
config.update({'datadir': create_datadir(config, None)})
|
||||||
logger.info('Using data directory: %s ...', config.get('datadir'))
|
logger.info('Using data directory: %s ...', config.get('datadir'))
|
||||||
|
|
||||||
def _load_optimize_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
def _load_optimize_config(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
@ -337,24 +308,6 @@ class Configuration(object):
|
|||||||
logstring='Using trades from: {}')
|
logstring='Using trades from: {}')
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def _validate_config_schema(self, conf: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Validate the configuration follow the Config Schema
|
|
||||||
:param conf: Config in JSON format
|
|
||||||
:return: Returns the config if valid, otherwise throw an exception
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
FreqtradeValidator(constants.CONF_SCHEMA).validate(conf)
|
|
||||||
return conf
|
|
||||||
except ValidationError as exception:
|
|
||||||
logger.critical(
|
|
||||||
'Invalid configuration. See config.json.example. Reason: %s',
|
|
||||||
exception
|
|
||||||
)
|
|
||||||
raise ValidationError(
|
|
||||||
best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message
|
|
||||||
)
|
|
||||||
|
|
||||||
def _validate_config_consistency(self, conf: Dict[str, Any]) -> None:
|
def _validate_config_consistency(self, conf: Dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
Validate the configuration consistency
|
Validate the configuration consistency
|
||||||
@ -383,51 +336,3 @@ class Configuration(object):
|
|||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'The config trailing_stop_positive_offset needs '
|
f'The config trailing_stop_positive_offset needs '
|
||||||
'to be greater than trailing_stop_positive_offset in your config.')
|
'to be greater than trailing_stop_positive_offset in your config.')
|
||||||
|
|
||||||
def get_config(self) -> Dict[str, Any]:
|
|
||||||
"""
|
|
||||||
Return the config. Use this method to get the bot config
|
|
||||||
:return: Dict: Bot config
|
|
||||||
"""
|
|
||||||
if self.config is None:
|
|
||||||
self.config = self.load_config()
|
|
||||||
|
|
||||||
return self.config
|
|
||||||
|
|
||||||
def check_exchange(self, config: Dict[str, Any], check_for_bad: bool = True) -> bool:
|
|
||||||
"""
|
|
||||||
Check if the exchange name in the config file is supported by Freqtrade
|
|
||||||
:param check_for_bad: if True, check the exchange against the list of known 'bad'
|
|
||||||
exchanges
|
|
||||||
:return: False if exchange is 'bad', i.e. is known to work with the bot with
|
|
||||||
critical issues or does not work at all, crashes, etc. True otherwise.
|
|
||||||
raises an exception if the exchange if not supported by ccxt
|
|
||||||
and thus is not known for the Freqtrade at all.
|
|
||||||
"""
|
|
||||||
logger.info("Checking exchange...")
|
|
||||||
|
|
||||||
exchange = config.get('exchange', {}).get('name').lower()
|
|
||||||
if not is_exchange_available(exchange):
|
|
||||||
raise OperationalException(
|
|
||||||
f'Exchange "{exchange}" is not supported by ccxt '
|
|
||||||
f'and therefore not available for the bot.\n'
|
|
||||||
f'The following exchanges are supported by ccxt: '
|
|
||||||
f'{", ".join(available_exchanges())}'
|
|
||||||
)
|
|
||||||
|
|
||||||
if check_for_bad and is_exchange_bad(exchange):
|
|
||||||
logger.warning(f'Exchange "{exchange}" is known to not work with the bot yet. '
|
|
||||||
f'Use it only for development and testing purposes.')
|
|
||||||
return False
|
|
||||||
|
|
||||||
if is_exchange_officially_supported(exchange):
|
|
||||||
logger.info(f'Exchange "{exchange}" is officially supported '
|
|
||||||
f'by the Freqtrade development team.')
|
|
||||||
else:
|
|
||||||
logger.warning(f'Exchange "{exchange}" is supported by ccxt '
|
|
||||||
f'and therefore available for the bot but not officially supported '
|
|
||||||
f'by the Freqtrade development team. '
|
|
||||||
f'It may work flawlessly (please report back) or have serious issues. '
|
|
||||||
f'Use it at your own discretion.')
|
|
||||||
|
|
||||||
return True
|
|
18
freqtrade/configuration/create_datadir.py
Normal file
18
freqtrade/configuration/create_datadir.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def create_datadir(config: Dict[str, Any], datadir: Optional[str] = None) -> str:
|
||||||
|
if not datadir:
|
||||||
|
# set datadir
|
||||||
|
exchange_name = config.get('exchange', {}).get('name').lower()
|
||||||
|
datadir = os.path.join('user_data', 'data', exchange_name)
|
||||||
|
|
||||||
|
if not os.path.isdir(datadir):
|
||||||
|
os.makedirs(datadir)
|
||||||
|
logger.info(f'Created data directory: {datadir}')
|
||||||
|
return datadir
|
53
freqtrade/configuration/json_schema.py
Normal file
53
freqtrade/configuration/json_schema.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import logging
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from jsonschema import Draft4Validator, validators
|
||||||
|
from jsonschema.exceptions import ValidationError, best_match
|
||||||
|
|
||||||
|
from freqtrade import constants
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _extend_validator(validator_class):
|
||||||
|
"""
|
||||||
|
Extended validator for the Freqtrade configuration JSON Schema.
|
||||||
|
Currently it only handles defaults for subschemas.
|
||||||
|
"""
|
||||||
|
validate_properties = validator_class.VALIDATORS['properties']
|
||||||
|
|
||||||
|
def set_defaults(validator, properties, instance, schema):
|
||||||
|
for prop, subschema in properties.items():
|
||||||
|
if 'default' in subschema:
|
||||||
|
instance.setdefault(prop, subschema['default'])
|
||||||
|
|
||||||
|
for error in validate_properties(
|
||||||
|
validator, properties, instance, schema,
|
||||||
|
):
|
||||||
|
yield error
|
||||||
|
|
||||||
|
return validators.extend(
|
||||||
|
validator_class, {'properties': set_defaults}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
FreqtradeValidator = _extend_validator(Draft4Validator)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_config_schema(conf: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Validate the configuration follow the Config Schema
|
||||||
|
:param conf: Config in JSON format
|
||||||
|
:return: Returns the config if valid, otherwise throw an exception
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
FreqtradeValidator(constants.CONF_SCHEMA).validate(conf)
|
||||||
|
return conf
|
||||||
|
except ValidationError as e:
|
||||||
|
logger.critical(
|
||||||
|
f"Invalid configuration. See config.json.example. Reason: {e}"
|
||||||
|
)
|
||||||
|
raise ValidationError(
|
||||||
|
best_match(Draft4Validator(constants.CONF_SCHEMA).iter_errors(conf)).message
|
||||||
|
)
|
@ -16,7 +16,7 @@ import arrow
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import OperationalException, misc
|
from freqtrade import OperationalException, misc
|
||||||
from freqtrade.arguments import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data.converter import parse_ticker_dataframe
|
from freqtrade.data.converter import parse_ticker_dataframe
|
||||||
from freqtrade.exchange import Exchange, timeframe_to_minutes
|
from freqtrade.exchange import Exchange, timeframe_to_minutes
|
||||||
|
|
||||||
|
@ -10,8 +10,7 @@ import utils_find_1st as utf1st
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import constants, OperationalException
|
from freqtrade import constants, OperationalException
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments, TimeRange
|
||||||
from freqtrade.arguments import TimeRange
|
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.strategy.interface import SellType
|
from freqtrade.strategy.interface import SellType
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ from argparse import Namespace
|
|||||||
from typing import Any, List
|
from typing import Any, List
|
||||||
|
|
||||||
from freqtrade import OperationalException
|
from freqtrade import OperationalException
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.worker import Worker
|
from freqtrade.worker import Worker
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ from typing import Any, Dict, List, NamedTuple, Optional
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.dataprovider import DataProvider
|
from freqtrade.data.dataprovider import DataProvider
|
||||||
from freqtrade.exchange import timeframe_to_minutes
|
from freqtrade.exchange import timeframe_to_minutes
|
||||||
|
@ -9,7 +9,7 @@ from tabulate import tabulate
|
|||||||
from freqtrade import constants
|
from freqtrade import constants
|
||||||
from freqtrade.edge import Edge
|
from freqtrade.edge import Edge
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.resolvers import StrategyResolver
|
from freqtrade.resolvers import StrategyResolver
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ from pandas import DataFrame
|
|||||||
from skopt import Optimizer
|
from skopt import Optimizer
|
||||||
from skopt.space import Dimension
|
from skopt.space import Dimension
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.data.history import load_data, get_timeframe
|
from freqtrade.data.history import load_data, get_timeframe
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
|
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
|
||||||
|
@ -4,7 +4,7 @@ from typing import Dict, List, Optional
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.btanalysis import (combine_tickers_with_mean,
|
from freqtrade.data.btanalysis import (combine_tickers_with_mean,
|
||||||
create_cum_profit, load_trades)
|
create_cum_profit, load_trades)
|
||||||
|
@ -6,7 +6,6 @@ from copy import deepcopy
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
|
||||||
from unittest.mock import MagicMock, PropertyMock
|
from unittest.mock import MagicMock, PropertyMock
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
@ -14,7 +13,7 @@ import pytest
|
|||||||
from telegram import Chat, Message, Update
|
from telegram import Chat, Message, Update
|
||||||
|
|
||||||
from freqtrade import constants, persistence
|
from freqtrade import constants, persistence
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.data.converter import parse_ticker_dataframe
|
from freqtrade.data.converter import parse_ticker_dataframe
|
||||||
from freqtrade.edge import Edge, PairInfo
|
from freqtrade.edge import Edge, PairInfo
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
@ -22,6 +21,7 @@ from freqtrade.freqtradebot import FreqtradeBot
|
|||||||
from freqtrade.resolvers import ExchangeResolver
|
from freqtrade.resolvers import ExchangeResolver
|
||||||
from freqtrade.worker import Worker
|
from freqtrade.worker import Worker
|
||||||
|
|
||||||
|
|
||||||
logging.getLogger('').setLevel(logging.INFO)
|
logging.getLogger('').setLevel(logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
@ -39,10 +39,17 @@ def log_has_re(line, logs):
|
|||||||
False)
|
False)
|
||||||
|
|
||||||
|
|
||||||
def get_args(args) -> List[str]:
|
def get_args(args):
|
||||||
return Arguments(args, '').get_parsed_arg()
|
return Arguments(args, '').get_parsed_arg()
|
||||||
|
|
||||||
|
|
||||||
|
def patched_configuration_load_config_file(mocker, config) -> None:
|
||||||
|
mocker.patch(
|
||||||
|
'freqtrade.configuration.configuration.Configuration._load_config_file',
|
||||||
|
lambda *args, **kwargs: config
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def patch_exchange(mocker, api_mock=None, id='bittrex') -> None:
|
def patch_exchange(mocker, api_mock=None, id='bittrex') -> None:
|
||||||
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
|
||||||
|
@ -4,7 +4,7 @@ import pytest
|
|||||||
from arrow import Arrow
|
from arrow import Arrow
|
||||||
from pandas import DataFrame, to_datetime
|
from pandas import DataFrame, to_datetime
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments, TimeRange
|
from freqtrade.configuration import Arguments, TimeRange
|
||||||
from freqtrade.data.btanalysis import (BT_DATA_COLUMNS,
|
from freqtrade.data.btanalysis import (BT_DATA_COLUMNS,
|
||||||
combine_tickers_with_mean,
|
combine_tickers_with_mean,
|
||||||
create_cum_profit,
|
create_cum_profit,
|
||||||
|
@ -12,7 +12,7 @@ import pytest
|
|||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import OperationalException
|
from freqtrade import OperationalException
|
||||||
from freqtrade.arguments import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.history import (download_pair_history,
|
from freqtrade.data.history import (download_pair_history,
|
||||||
load_cached_data_for_updating,
|
load_cached_data_for_updating,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, unused-argument
|
# pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, unused-argument
|
||||||
|
|
||||||
import json
|
|
||||||
import math
|
import math
|
||||||
import random
|
import random
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
@ -11,7 +10,7 @@ import pytest
|
|||||||
from arrow import Arrow
|
from arrow import Arrow
|
||||||
|
|
||||||
from freqtrade import DependencyException, constants
|
from freqtrade import DependencyException, constants
|
||||||
from freqtrade.arguments import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.btanalysis import evaluate_result_multi
|
from freqtrade.data.btanalysis import evaluate_result_multi
|
||||||
from freqtrade.data.converter import parse_ticker_dataframe
|
from freqtrade.data.converter import parse_ticker_dataframe
|
||||||
@ -22,7 +21,8 @@ from freqtrade.optimize.backtesting import Backtesting
|
|||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.strategy.default_strategy import DefaultStrategy
|
from freqtrade.strategy.default_strategy import DefaultStrategy
|
||||||
from freqtrade.strategy.interface import SellType
|
from freqtrade.strategy.interface import SellType
|
||||||
from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
|
from freqtrade.tests.conftest import (get_args, log_has, log_has_re, patch_exchange,
|
||||||
|
patched_configuration_load_config_file)
|
||||||
|
|
||||||
|
|
||||||
def trim_dictlist(dict_list, num):
|
def trim_dictlist(dict_list, num):
|
||||||
@ -165,9 +165,7 @@ def _trend_alternate(dataframe=None, metadata=None):
|
|||||||
|
|
||||||
# Unit tests
|
# Unit tests
|
||||||
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -205,10 +203,11 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
|
|||||||
|
|
||||||
|
|
||||||
def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
mocker.patch(
|
||||||
))
|
'freqtrade.configuration.configuration.create_datadir',
|
||||||
mocker.patch('freqtrade.configuration.Configuration._create_datadir', lambda s, c, x: x)
|
lambda c, x: x
|
||||||
|
)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -276,9 +275,7 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
|
|||||||
def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None:
|
||||||
default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
|
default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
|
||||||
|
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -295,9 +292,8 @@ def test_start(mocker, fee, default_conf, caplog) -> None:
|
|||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.start', start_mock)
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.start', start_mock)
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
'--strategy', 'DefaultStrategy',
|
'--strategy', 'DefaultStrategy',
|
||||||
@ -828,9 +824,7 @@ def test_backtest_start_live(default_conf, mocker, caplog):
|
|||||||
patch_exchange(mocker, api_mock)
|
patch_exchange(mocker, api_mock)
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock())
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock())
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table', MagicMock())
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table', MagicMock())
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -880,9 +874,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog):
|
|||||||
gen_strattable_mock = MagicMock()
|
gen_strattable_mock = MagicMock()
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table_strategy',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table_strategy',
|
||||||
gen_strattable_mock)
|
gen_strattable_mock)
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
# pragma pylint: disable=missing-docstring, C0103, C0330
|
# pragma pylint: disable=missing-docstring, C0103, C0330
|
||||||
# pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments
|
# pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments
|
||||||
|
|
||||||
import json
|
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from freqtrade.edge import PairInfo
|
from freqtrade.edge import PairInfo
|
||||||
from freqtrade.optimize import setup_configuration, start_edge
|
from freqtrade.optimize import setup_configuration, start_edge
|
||||||
from freqtrade.optimize.edge_cli import EdgeCli
|
from freqtrade.optimize.edge_cli import EdgeCli
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
|
from freqtrade.tests.conftest import (get_args, log_has, log_has_re, patch_exchange,
|
||||||
|
patched_configuration_load_config_file)
|
||||||
|
|
||||||
|
|
||||||
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -46,10 +44,11 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
|
|||||||
|
|
||||||
|
|
||||||
def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> None:
|
def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, edge_conf)
|
||||||
read_data=json.dumps(edge_conf)
|
mocker.patch(
|
||||||
))
|
'freqtrade.configuration.configuration.create_datadir',
|
||||||
mocker.patch('freqtrade.configuration.Configuration._create_datadir', lambda s, c, x: x)
|
lambda c, x: x
|
||||||
|
)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -92,9 +91,8 @@ def test_start(mocker, fee, edge_conf, caplog) -> None:
|
|||||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.optimize.edge_cli.EdgeCli.start', start_mock)
|
mocker.patch('freqtrade.optimize.edge_cli.EdgeCli.start', start_mock)
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, edge_conf)
|
||||||
read_data=json.dumps(edge_conf)
|
|
||||||
))
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
'--strategy', 'DefaultStrategy',
|
'--strategy', 'DefaultStrategy',
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# pragma pylint: disable=missing-docstring,W0212,C0103
|
# pragma pylint: disable=missing-docstring,W0212,C0103
|
||||||
import json
|
|
||||||
import os
|
import os
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
@ -16,7 +15,8 @@ from freqtrade.optimize.hyperopt import Hyperopt, HYPEROPT_LOCKFILE
|
|||||||
from freqtrade.optimize import setup_configuration, start_hyperopt
|
from freqtrade.optimize import setup_configuration, start_hyperopt
|
||||||
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
|
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
|
from freqtrade.tests.conftest import (get_args, log_has, log_has_re, patch_exchange,
|
||||||
|
patched_configuration_load_config_file)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='function')
|
@pytest.fixture(scope='function')
|
||||||
@ -44,9 +44,7 @@ def create_trials(mocker, hyperopt) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -82,10 +80,11 @@ def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, ca
|
|||||||
|
|
||||||
|
|
||||||
def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
mocker.patch(
|
||||||
))
|
'freqtrade.configuration.configuration.create_datadir',
|
||||||
mocker.patch('freqtrade.configuration.Configuration._create_datadir', lambda s, c, x: x)
|
lambda c, x: x
|
||||||
|
)
|
||||||
|
|
||||||
args = [
|
args = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -148,11 +147,8 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo
|
|||||||
|
|
||||||
|
|
||||||
def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
||||||
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
|
|
||||||
mocker.patch(
|
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
hyperopts = DefaultHyperOpts
|
hyperopts = DefaultHyperOpts
|
||||||
delattr(hyperopts, 'populate_buy_trend')
|
delattr(hyperopts, 'populate_buy_trend')
|
||||||
delattr(hyperopts, 'populate_sell_trend')
|
delattr(hyperopts, 'populate_sell_trend')
|
||||||
@ -172,10 +168,7 @@ def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
def test_start(mocker, default_conf, caplog) -> None:
|
def test_start(mocker, default_conf, caplog) -> None:
|
||||||
start_mock = MagicMock()
|
start_mock = MagicMock()
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
|
||||||
@ -198,10 +191,7 @@ def test_start(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_start_no_data(mocker, default_conf, caplog) -> None:
|
def test_start_no_data(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock(return_value={}))
|
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock(return_value={}))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.optimize.hyperopt.get_timeframe',
|
'freqtrade.optimize.hyperopt.get_timeframe',
|
||||||
@ -226,10 +216,7 @@ def test_start_no_data(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
def test_start_failure(mocker, default_conf, caplog) -> None:
|
def test_start_failure(mocker, default_conf, caplog) -> None:
|
||||||
start_mock = MagicMock()
|
start_mock = MagicMock()
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
|
||||||
@ -250,10 +237,7 @@ def test_start_failure(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
def test_start_filelock(mocker, default_conf, caplog) -> None:
|
def test_start_filelock(mocker, default_conf, caplog) -> None:
|
||||||
start_mock = MagicMock(side_effect=Timeout(HYPEROPT_LOCKFILE))
|
start_mock = MagicMock(side_effect=Timeout(HYPEROPT_LOCKFILE))
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ from unittest.mock import MagicMock
|
|||||||
import arrow
|
import arrow
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade.arguments import TimeRange
|
from freqtrade.configuration import TimeRange
|
||||||
from freqtrade.data.converter import parse_ticker_dataframe
|
from freqtrade.data.converter import parse_ticker_dataframe
|
||||||
from freqtrade.data.history import load_tickerdata_file
|
from freqtrade.data.history import load_tickerdata_file
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
|
@ -3,8 +3,9 @@ import argparse
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from freqtrade.arguments import (ARGS_DOWNLOADER, ARGS_PLOT_DATAFRAME,
|
from freqtrade.configuration import Arguments, TimeRange
|
||||||
Arguments, TimeRange, check_int_positive)
|
from freqtrade.configuration.arguments import ARGS_DOWNLOADER, ARGS_PLOT_DATAFRAME
|
||||||
|
from freqtrade.configuration.arguments import check_int_positive
|
||||||
|
|
||||||
|
|
||||||
# Parse common command-line-arguments. Used for all tools
|
# Parse common command-line-arguments. Used for all tools
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# pragma pylint: disable=missing-docstring, protected-access, invalid-name
|
# pragma pylint: disable=missing-docstring, protected-access, invalid-name
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
@ -11,12 +10,15 @@ import pytest
|
|||||||
from jsonschema import Draft4Validator, ValidationError, validate
|
from jsonschema import Draft4Validator, ValidationError, validate
|
||||||
|
|
||||||
from freqtrade import OperationalException, constants
|
from freqtrade import OperationalException, constants
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments, Configuration
|
||||||
from freqtrade.configuration import Configuration
|
from freqtrade.configuration.check_exchange import check_exchange
|
||||||
|
from freqtrade.configuration.create_datadir import create_datadir
|
||||||
|
from freqtrade.configuration.json_schema import validate_config_schema
|
||||||
from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL
|
from freqtrade.constants import DEFAULT_DB_DRYRUN_URL, DEFAULT_DB_PROD_URL
|
||||||
from freqtrade.loggers import _set_loggers
|
from freqtrade.loggers import _set_loggers
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
from freqtrade.tests.conftest import log_has, log_has_re
|
from freqtrade.tests.conftest import (log_has, log_has_re,
|
||||||
|
patched_configuration_load_config_file)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="function")
|
@pytest.fixture(scope="function")
|
||||||
@ -32,28 +34,25 @@ def test_load_config_invalid_pair(default_conf) -> None:
|
|||||||
default_conf['exchange']['pair_whitelist'].append('ETH-BTC')
|
default_conf['exchange']['pair_whitelist'].append('ETH-BTC')
|
||||||
|
|
||||||
with pytest.raises(ValidationError, match=r'.*does not match.*'):
|
with pytest.raises(ValidationError, match=r'.*does not match.*'):
|
||||||
configuration = Configuration(Namespace())
|
validate_config_schema(default_conf)
|
||||||
configuration._validate_config_schema(default_conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_missing_attributes(default_conf) -> None:
|
def test_load_config_missing_attributes(default_conf) -> None:
|
||||||
default_conf.pop('exchange')
|
default_conf.pop('exchange')
|
||||||
|
|
||||||
with pytest.raises(ValidationError, match=r'.*\'exchange\' is a required property.*'):
|
with pytest.raises(ValidationError, match=r'.*\'exchange\' is a required property.*'):
|
||||||
configuration = Configuration(Namespace())
|
validate_config_schema(default_conf)
|
||||||
configuration._validate_config_schema(default_conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_incorrect_stake_amount(default_conf) -> None:
|
def test_load_config_incorrect_stake_amount(default_conf) -> None:
|
||||||
default_conf['stake_amount'] = 'fake'
|
default_conf['stake_amount'] = 'fake'
|
||||||
|
|
||||||
with pytest.raises(ValidationError, match=r'.*\'fake\' does not match \'unlimited\'.*'):
|
with pytest.raises(ValidationError, match=r'.*\'fake\' does not match \'unlimited\'.*'):
|
||||||
configuration = Configuration(Namespace())
|
validate_config_schema(default_conf)
|
||||||
configuration._validate_config_schema(default_conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_file(default_conf, mocker, caplog) -> None:
|
def test_load_config_file(default_conf, mocker, caplog) -> None:
|
||||||
file_mock = mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
file_mock = mocker.patch('freqtrade.configuration.configuration.open', mocker.mock_open(
|
||||||
read_data=json.dumps(default_conf)
|
read_data=json.dumps(default_conf)
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -65,9 +64,7 @@ def test_load_config_file(default_conf, mocker, caplog) -> None:
|
|||||||
|
|
||||||
def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None:
|
def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None:
|
||||||
default_conf['max_open_trades'] = 0
|
default_conf['max_open_trades'] = 0
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = Arguments([], '').get_parsed_arg()
|
args = Arguments([], '').get_parsed_arg()
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
@ -89,7 +86,10 @@ def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
|
|||||||
config_files = [conf1, conf2]
|
config_files = [conf1, conf2]
|
||||||
|
|
||||||
configsmock = MagicMock(side_effect=config_files)
|
configsmock = MagicMock(side_effect=config_files)
|
||||||
mocker.patch('freqtrade.configuration.Configuration._load_config_file', configsmock)
|
mocker.patch(
|
||||||
|
'freqtrade.configuration.configuration.Configuration._load_config_file',
|
||||||
|
configsmock
|
||||||
|
)
|
||||||
|
|
||||||
arg_list = ['-c', 'test_conf.json', '--config', 'test2_conf.json', ]
|
arg_list = ['-c', 'test_conf.json', '--config', 'test2_conf.json', ]
|
||||||
args = Arguments(arg_list, '').get_parsed_arg()
|
args = Arguments(arg_list, '').get_parsed_arg()
|
||||||
@ -109,9 +109,7 @@ def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
|
|||||||
|
|
||||||
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None:
|
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None:
|
||||||
default_conf['max_open_trades'] = -1
|
default_conf['max_open_trades'] = -1
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = Arguments([], '').get_parsed_arg()
|
args = Arguments([], '').get_parsed_arg()
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
@ -126,7 +124,7 @@ def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) ->
|
|||||||
|
|
||||||
def test_load_config_file_exception(mocker) -> None:
|
def test_load_config_file_exception(mocker) -> None:
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.configuration.open',
|
'freqtrade.configuration.configuration.open',
|
||||||
MagicMock(side_effect=FileNotFoundError('File not found'))
|
MagicMock(side_effect=FileNotFoundError('File not found'))
|
||||||
)
|
)
|
||||||
configuration = Configuration(Namespace())
|
configuration = Configuration(Namespace())
|
||||||
@ -136,9 +134,7 @@ def test_load_config_file_exception(mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_load_config(default_conf, mocker) -> None:
|
def test_load_config(default_conf, mocker) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = Arguments([], '').get_parsed_arg()
|
args = Arguments([], '').get_parsed_arg()
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
@ -150,9 +146,8 @@ def test_load_config(default_conf, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_load_config_with_params(default_conf, mocker) -> None:
|
def test_load_config_with_params(default_conf, mocker) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--dynamic-whitelist', '10',
|
'--dynamic-whitelist', '10',
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'TestStrategy',
|
||||||
@ -173,9 +168,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
|
|||||||
conf = default_conf.copy()
|
conf = default_conf.copy()
|
||||||
conf["dry_run"] = False
|
conf["dry_run"] = False
|
||||||
conf["db_url"] = "sqlite:///path/to/db.sqlite"
|
conf["db_url"] = "sqlite:///path/to/db.sqlite"
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, conf)
|
||||||
read_data=json.dumps(conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'TestStrategy',
|
||||||
@ -191,9 +184,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
|
|||||||
conf = default_conf.copy()
|
conf = default_conf.copy()
|
||||||
conf["dry_run"] = True
|
conf["dry_run"] = True
|
||||||
conf["db_url"] = "sqlite:///path/to/db.sqlite"
|
conf["db_url"] = "sqlite:///path/to/db.sqlite"
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, conf)
|
||||||
read_data=json.dumps(conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'TestStrategy',
|
||||||
@ -209,9 +200,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
|
|||||||
conf = default_conf.copy()
|
conf = default_conf.copy()
|
||||||
conf["dry_run"] = False
|
conf["dry_run"] = False
|
||||||
del conf["db_url"]
|
del conf["db_url"]
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, conf)
|
||||||
read_data=json.dumps(conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'TestStrategy',
|
||||||
@ -229,9 +218,7 @@ def test_load_config_with_params(default_conf, mocker) -> None:
|
|||||||
conf = default_conf.copy()
|
conf = default_conf.copy()
|
||||||
conf["dry_run"] = True
|
conf["dry_run"] = True
|
||||||
conf["db_url"] = DEFAULT_DB_PROD_URL
|
conf["db_url"] = DEFAULT_DB_PROD_URL
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, conf)
|
||||||
read_data=json.dumps(conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'TestStrategy',
|
||||||
@ -249,9 +236,7 @@ def test_load_custom_strategy(default_conf, mocker) -> None:
|
|||||||
'strategy': 'CustomStrategy',
|
'strategy': 'CustomStrategy',
|
||||||
'strategy_path': '/tmp/strategies',
|
'strategy_path': '/tmp/strategies',
|
||||||
})
|
})
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = Arguments([], '').get_parsed_arg()
|
args = Arguments([], '').get_parsed_arg()
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
@ -262,9 +247,8 @@ def test_load_custom_strategy(default_conf, mocker) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_show_info(default_conf, mocker, caplog) -> None:
|
def test_show_info(default_conf, mocker, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--dynamic-whitelist', '10',
|
'--dynamic-whitelist', '10',
|
||||||
'--strategy', 'TestStrategy',
|
'--strategy', 'TestStrategy',
|
||||||
@ -287,9 +271,8 @@ def test_show_info(default_conf, mocker, caplog) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
'--strategy', 'DefaultStrategy',
|
'--strategy', 'DefaultStrategy',
|
||||||
@ -327,10 +310,11 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
|
|||||||
|
|
||||||
|
|
||||||
def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
mocker.patch(
|
||||||
))
|
'freqtrade.configuration.configuration.create_datadir',
|
||||||
mocker.patch('freqtrade.configuration.Configuration._create_datadir', lambda s, c, x: x)
|
lambda c, x: x
|
||||||
|
)
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -393,9 +377,7 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non
|
|||||||
"""
|
"""
|
||||||
Test setup_configuration() function
|
Test setup_configuration() function
|
||||||
"""
|
"""
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--config', 'config.json',
|
'--config', 'config.json',
|
||||||
@ -443,9 +425,8 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non
|
|||||||
|
|
||||||
|
|
||||||
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'hyperopt',
|
'hyperopt',
|
||||||
'--epochs', '10',
|
'--epochs', '10',
|
||||||
@ -469,25 +450,23 @@ def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_check_exchange(default_conf, caplog) -> None:
|
def test_check_exchange(default_conf, caplog) -> None:
|
||||||
configuration = Configuration(Namespace())
|
|
||||||
|
|
||||||
# Test an officially supported by Freqtrade team exchange
|
# Test an officially supported by Freqtrade team exchange
|
||||||
default_conf.get('exchange').update({'name': 'BITTREX'})
|
default_conf.get('exchange').update({'name': 'BITTREX'})
|
||||||
assert configuration.check_exchange(default_conf)
|
assert check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
||||||
caplog.record_tuples)
|
caplog.record_tuples)
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test an officially supported by Freqtrade team exchange
|
# Test an officially supported by Freqtrade team exchange
|
||||||
default_conf.get('exchange').update({'name': 'binance'})
|
default_conf.get('exchange').update({'name': 'binance'})
|
||||||
assert configuration.check_exchange(default_conf)
|
assert check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
||||||
caplog.record_tuples)
|
caplog.record_tuples)
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test an available exchange, supported by ccxt
|
# Test an available exchange, supported by ccxt
|
||||||
default_conf.get('exchange').update({'name': 'kraken'})
|
default_conf.get('exchange').update({'name': 'kraken'})
|
||||||
assert configuration.check_exchange(default_conf)
|
assert check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
||||||
r"by the Freqtrade development team\. .*",
|
r"by the Freqtrade development team\. .*",
|
||||||
caplog.record_tuples)
|
caplog.record_tuples)
|
||||||
@ -495,7 +474,7 @@ def test_check_exchange(default_conf, caplog) -> None:
|
|||||||
|
|
||||||
# Test a 'bad' exchange, which known to have serious problems
|
# Test a 'bad' exchange, which known to have serious problems
|
||||||
default_conf.get('exchange').update({'name': 'bitmex'})
|
default_conf.get('exchange').update({'name': 'bitmex'})
|
||||||
assert not configuration.check_exchange(default_conf)
|
assert not check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is known to not work with the bot yet\. "
|
assert log_has_re(r"Exchange .* is known to not work with the bot yet\. "
|
||||||
r"Use it only for development and testing purposes\.",
|
r"Use it only for development and testing purposes\.",
|
||||||
caplog.record_tuples)
|
caplog.record_tuples)
|
||||||
@ -503,7 +482,7 @@ def test_check_exchange(default_conf, caplog) -> None:
|
|||||||
|
|
||||||
# Test a 'bad' exchange with check_for_bad=False
|
# Test a 'bad' exchange with check_for_bad=False
|
||||||
default_conf.get('exchange').update({'name': 'bitmex'})
|
default_conf.get('exchange').update({'name': 'bitmex'})
|
||||||
assert configuration.check_exchange(default_conf, False)
|
assert check_exchange(default_conf, False)
|
||||||
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
||||||
r"by the Freqtrade development team\. .*",
|
r"by the Freqtrade development team\. .*",
|
||||||
caplog.record_tuples)
|
caplog.record_tuples)
|
||||||
@ -511,19 +490,18 @@ def test_check_exchange(default_conf, caplog) -> None:
|
|||||||
|
|
||||||
# Test an invalid exchange
|
# Test an invalid exchange
|
||||||
default_conf.get('exchange').update({'name': 'unknown_exchange'})
|
default_conf.get('exchange').update({'name': 'unknown_exchange'})
|
||||||
configuration.config = default_conf
|
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
OperationalException,
|
OperationalException,
|
||||||
match=r'.*Exchange "unknown_exchange" is not supported by ccxt '
|
match=r'.*Exchange "unknown_exchange" is not supported by ccxt '
|
||||||
r'and therefore not available for the bot.*'
|
r'and therefore not available for the bot.*'
|
||||||
):
|
):
|
||||||
configuration.check_exchange(default_conf)
|
check_exchange(default_conf)
|
||||||
|
|
||||||
|
|
||||||
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
|
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)))
|
|
||||||
# Prevent setting loggers
|
# Prevent setting loggers
|
||||||
mocker.patch('freqtrade.loggers._set_loggers', MagicMock)
|
mocker.patch('freqtrade.loggers._set_loggers', MagicMock)
|
||||||
arglist = ['-vvv']
|
arglist = ['-vvv']
|
||||||
@ -575,8 +553,7 @@ def test_set_loggers() -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_set_logfile(default_conf, mocker):
|
def test_set_logfile(default_conf, mocker):
|
||||||
mocker.patch('freqtrade.configuration.open',
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
mocker.mock_open(read_data=json.dumps(default_conf)))
|
|
||||||
|
|
||||||
arglist = [
|
arglist = [
|
||||||
'--logfile', 'test_file.log',
|
'--logfile', 'test_file.log',
|
||||||
@ -593,9 +570,7 @@ def test_set_logfile(default_conf, mocker):
|
|||||||
|
|
||||||
def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None:
|
def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None:
|
||||||
default_conf['forcebuy_enable'] = True
|
default_conf['forcebuy_enable'] = True
|
||||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
read_data=json.dumps(default_conf)
|
|
||||||
))
|
|
||||||
|
|
||||||
args = Arguments([], '').get_parsed_arg()
|
args = Arguments([], '').get_parsed_arg()
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
@ -609,12 +584,11 @@ def test_validate_default_conf(default_conf) -> None:
|
|||||||
validate(default_conf, constants.CONF_SCHEMA, Draft4Validator)
|
validate(default_conf, constants.CONF_SCHEMA, Draft4Validator)
|
||||||
|
|
||||||
|
|
||||||
def test__create_datadir(mocker, default_conf, caplog) -> None:
|
def test_create_datadir(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('os.path.isdir', MagicMock(return_value=False))
|
mocker.patch('os.path.isdir', MagicMock(return_value=False))
|
||||||
md = MagicMock()
|
md = MagicMock()
|
||||||
mocker.patch('os.makedirs', md)
|
mocker.patch('os.makedirs', md)
|
||||||
cfg = Configuration(Namespace())
|
create_datadir(default_conf, '/foo/bar')
|
||||||
cfg._create_datadir(default_conf, '/foo/bar')
|
|
||||||
assert md.call_args[0][0] == "/foo/bar"
|
assert md.call_args[0][0] == "/foo/bar"
|
||||||
assert log_has('Created data directory: /foo/bar', caplog.record_tuples)
|
assert log_has('Created data directory: /foo/bar', caplog.record_tuples)
|
||||||
|
|
||||||
@ -656,8 +630,7 @@ def test_load_config_default_exchange(all_conf) -> None:
|
|||||||
|
|
||||||
with pytest.raises(ValidationError,
|
with pytest.raises(ValidationError,
|
||||||
match=r'\'exchange\' is a required property'):
|
match=r'\'exchange\' is a required property'):
|
||||||
configuration = Configuration(Namespace())
|
validate_config_schema(all_conf)
|
||||||
configuration._validate_config_schema(all_conf)
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_default_exchange_name(all_conf) -> None:
|
def test_load_config_default_exchange_name(all_conf) -> None:
|
||||||
@ -671,8 +644,7 @@ def test_load_config_default_exchange_name(all_conf) -> None:
|
|||||||
|
|
||||||
with pytest.raises(ValidationError,
|
with pytest.raises(ValidationError,
|
||||||
match=r'\'name\' is a required property'):
|
match=r'\'name\' is a required property'):
|
||||||
configuration = Configuration(Namespace())
|
validate_config_schema(all_conf)
|
||||||
configuration._validate_config_schema(all_conf)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("keys", [("exchange", "sandbox", False),
|
@pytest.mark.parametrize("keys", [("exchange", "sandbox", False),
|
||||||
@ -695,7 +667,6 @@ def test_load_config_default_subkeys(all_conf, keys) -> None:
|
|||||||
|
|
||||||
assert subkey not in all_conf[key]
|
assert subkey not in all_conf[key]
|
||||||
|
|
||||||
configuration = Configuration(Namespace())
|
validate_config_schema(all_conf)
|
||||||
configuration._validate_config_schema(all_conf)
|
|
||||||
assert subkey in all_conf[key]
|
assert subkey in all_conf[key]
|
||||||
assert all_conf[key][subkey] == keys[2]
|
assert all_conf[key][subkey] == keys[2]
|
||||||
|
@ -6,11 +6,12 @@ from unittest.mock import MagicMock
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from freqtrade import OperationalException
|
from freqtrade import OperationalException
|
||||||
from freqtrade.arguments import Arguments
|
from freqtrade.configuration import Arguments
|
||||||
from freqtrade.freqtradebot import FreqtradeBot
|
from freqtrade.freqtradebot import FreqtradeBot
|
||||||
from freqtrade.main import main
|
from freqtrade.main import main
|
||||||
from freqtrade.state import State
|
from freqtrade.state import State
|
||||||
from freqtrade.tests.conftest import log_has, patch_exchange
|
from freqtrade.tests.conftest import (log_has, patch_exchange,
|
||||||
|
patched_configuration_load_config_file)
|
||||||
from freqtrade.worker import Worker
|
from freqtrade.worker import Worker
|
||||||
|
|
||||||
|
|
||||||
@ -50,10 +51,7 @@ def test_main_fatal_exception(mocker, default_conf, caplog) -> None:
|
|||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock())
|
||||||
mocker.patch('freqtrade.worker.Worker._worker', MagicMock(side_effect=Exception))
|
mocker.patch('freqtrade.worker.Worker._worker', MagicMock(side_effect=Exception))
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
||||||
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
||||||
|
|
||||||
@ -70,10 +68,7 @@ def test_main_keyboard_interrupt(mocker, default_conf, caplog) -> None:
|
|||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.cleanup', MagicMock())
|
||||||
mocker.patch('freqtrade.worker.Worker._worker', MagicMock(side_effect=KeyboardInterrupt))
|
mocker.patch('freqtrade.worker.Worker._worker', MagicMock(side_effect=KeyboardInterrupt))
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
||||||
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
||||||
|
|
||||||
@ -93,10 +88,7 @@ def test_main_operational_exception(mocker, default_conf, caplog) -> None:
|
|||||||
'freqtrade.worker.Worker._worker',
|
'freqtrade.worker.Worker._worker',
|
||||||
MagicMock(side_effect=OperationalException('Oh snap!'))
|
MagicMock(side_effect=OperationalException('Oh snap!'))
|
||||||
)
|
)
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
||||||
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
||||||
|
|
||||||
@ -118,10 +110,7 @@ def test_main_reload_conf(mocker, default_conf, caplog) -> None:
|
|||||||
State.RUNNING,
|
State.RUNNING,
|
||||||
OperationalException("Oh snap!")])
|
OperationalException("Oh snap!")])
|
||||||
mocker.patch('freqtrade.worker.Worker._worker', worker_mock)
|
mocker.patch('freqtrade.worker.Worker._worker', worker_mock)
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
reconfigure_mock = mocker.patch('freqtrade.main.Worker._reconfigure', MagicMock())
|
reconfigure_mock = mocker.patch('freqtrade.main.Worker._reconfigure', MagicMock())
|
||||||
|
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
||||||
@ -145,10 +134,7 @@ def test_reconfigure(mocker, default_conf) -> None:
|
|||||||
'freqtrade.worker.Worker._worker',
|
'freqtrade.worker.Worker._worker',
|
||||||
MagicMock(side_effect=OperationalException('Oh snap!'))
|
MagicMock(side_effect=OperationalException('Oh snap!'))
|
||||||
)
|
)
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, default_conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: default_conf
|
|
||||||
)
|
|
||||||
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
|
||||||
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
|
||||||
|
|
||||||
@ -159,10 +145,7 @@ def test_reconfigure(mocker, default_conf) -> None:
|
|||||||
# Renew mock to return modified data
|
# Renew mock to return modified data
|
||||||
conf = deepcopy(default_conf)
|
conf = deepcopy(default_conf)
|
||||||
conf['stake_amount'] += 1
|
conf['stake_amount'] += 1
|
||||||
mocker.patch(
|
patched_configuration_load_config_file(mocker, conf)
|
||||||
'freqtrade.configuration.Configuration._load_config_file',
|
|
||||||
lambda *args, **kwargs: conf
|
|
||||||
)
|
|
||||||
|
|
||||||
worker._config = conf
|
worker._config = conf
|
||||||
# reconfigure should return a new instance
|
# reconfigure should return a new instance
|
||||||
|
@ -5,7 +5,7 @@ from unittest.mock import MagicMock
|
|||||||
import plotly.graph_objs as go
|
import plotly.graph_objs as go
|
||||||
from plotly import tools
|
from plotly import tools
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments, TimeRange
|
from freqtrade.configuration import Arguments, TimeRange
|
||||||
from freqtrade.data import history
|
from freqtrade.data import history
|
||||||
from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data
|
from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data
|
||||||
from freqtrade.plot.plotting import (add_indicators, add_profit,
|
from freqtrade.plot.plotting import (add_indicators, add_profit,
|
||||||
|
@ -8,8 +8,10 @@ import sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from freqtrade.arguments import Arguments, TimeRange, ARGS_DOWNLOADER
|
from freqtrade.configuration import Arguments, TimeRange
|
||||||
from freqtrade.configuration import Configuration
|
from freqtrade.configuration import Configuration
|
||||||
|
from freqtrade.configuration.arguments import ARGS_DOWNLOADER
|
||||||
|
from freqtrade.configuration.check_exchange import check_exchange
|
||||||
from freqtrade.data.history import download_pair_history
|
from freqtrade.data.history import download_pair_history
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.misc import deep_merge_dicts
|
from freqtrade.misc import deep_merge_dicts
|
||||||
@ -79,7 +81,7 @@ if args.config and args.exchange:
|
|||||||
"using exchange settings from the configuration file.")
|
"using exchange settings from the configuration file.")
|
||||||
|
|
||||||
# Check if the exchange set by the user is supported
|
# Check if the exchange set by the user is supported
|
||||||
configuration.check_exchange(config)
|
check_exchange(config)
|
||||||
|
|
||||||
configuration._load_datadir_config(config)
|
configuration._load_datadir_config(config)
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ from typing import Any, Dict, List
|
|||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
from freqtrade.arguments import ARGS_PLOT_DATAFRAME, Arguments
|
from freqtrade.configuration import Arguments
|
||||||
|
from freqtrade.configuration.arguments import ARGS_PLOT_DATAFRAME
|
||||||
from freqtrade.data.btanalysis import extract_trades_of_period
|
from freqtrade.data.btanalysis import extract_trades_of_period
|
||||||
from freqtrade.optimize import setup_configuration
|
from freqtrade.optimize import setup_configuration
|
||||||
from freqtrade.plot.plotting import (init_plotscript, generate_candlestick_graph,
|
from freqtrade.plot.plotting import (init_plotscript, generate_candlestick_graph,
|
||||||
|
@ -8,7 +8,8 @@ import logging
|
|||||||
import sys
|
import sys
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from freqtrade.arguments import ARGS_PLOT_PROFIT, Arguments
|
from freqtrade.configuration import Arguments
|
||||||
|
from freqtrade.configuration.arguments import ARGS_PLOT_PROFIT
|
||||||
from freqtrade.optimize import setup_configuration
|
from freqtrade.optimize import setup_configuration
|
||||||
from freqtrade.plot.plotting import init_plotscript, generate_profit_graph, store_plot_file
|
from freqtrade.plot.plotting import init_plotscript, generate_profit_graph, store_plot_file
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
|
Loading…
Reference in New Issue
Block a user