Add RunMode setting to determine bot state

This commit is contained in:
Matthias 2018-12-25 14:23:59 +01:00
parent fed3ebfb46
commit 1340b71633
9 changed files with 42 additions and 18 deletions

View File

@ -12,6 +12,7 @@ from jsonschema import Draft4Validator, validate
from jsonschema.exceptions import ValidationError, best_match from jsonschema.exceptions import ValidationError, best_match
from freqtrade import OperationalException, constants from freqtrade import OperationalException, constants
from freqtrade.state import RunMode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -34,9 +35,10 @@ class Configuration(object):
Reuse this class for the bot, backtesting, hyperopt and every script that required configuration Reuse this class for the bot, backtesting, hyperopt and every script that required configuration
""" """
def __init__(self, args: Namespace) -> None: def __init__(self, args: Namespace, runmode: RunMode = None) -> None:
self.args = args self.args = args
self.config: Optional[Dict[str, Any]] = None self.config: Optional[Dict[str, Any]] = None
self.runmode = runmode
def load_config(self) -> Dict[str, Any]: def load_config(self) -> Dict[str, Any]:
""" """
@ -68,6 +70,13 @@ class Configuration(object):
# Load Hyperopt # Load Hyperopt
config = self._load_hyperopt_config(config) config = self._load_hyperopt_config(config)
# Set runmode
if not self.runmode:
# Handle real mode, infer dry/live from config
self.runmode = RunMode.DRY_RUN if config.get('dry_run', True) else RunMode.LIVE
config.update({'runmode': self.runmode})
return config return config
def _load_config_file(self, path: str) -> Dict[str, Any]: def _load_config_file(self, path: str) -> Dict[str, Any]:

View File

@ -6,12 +6,13 @@ Common Interface for bot and strategy to access data.
""" """
import logging import logging
from pathlib import Path from pathlib import Path
from typing import List, Dict from typing import List
from pandas import DataFrame from pandas import DataFrame
from freqtrade.exchange import Exchange
from freqtrade.data.history import load_pair_history from freqtrade.data.history import load_pair_history
from freqtrade.exchange import Exchange
from freqtrade.state import RunMode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -66,10 +67,9 @@ class DataProvider(object):
pass pass
@property @property
def runmode(self) -> str: def runmode(self) -> RunMode:
""" """
Get runmode of the bot Get runmode of the bot
can be "live", "dry-run", "backtest", "edgecli", "hyperopt". can be "live", "dry-run", "backtest", "edgecli", "hyperopt".
""" """
# TODO: this needs to be set somewhere ... return self._config.get('runmode')
return str(self._config.get('runmode'))

View File

@ -39,7 +39,7 @@ def main(sysargv: List[str]) -> None:
return_code = 1 return_code = 1
try: try:
# Load and validate configuration # Load and validate configuration
config = Configuration(args).get_config() config = Configuration(args, None).get_config()
# Init the bot # Init the bot
freqtrade = FreqtradeBot(config) freqtrade = FreqtradeBot(config)
@ -76,7 +76,7 @@ def reconfigure(freqtrade: FreqtradeBot, args: Namespace) -> FreqtradeBot:
freqtrade.cleanup() freqtrade.cleanup()
# Create new instance # Create new instance
freqtrade = FreqtradeBot(Configuration(args).get_config()) freqtrade = FreqtradeBot(Configuration(args, None).get_config())
freqtrade.rpc.send_msg({ freqtrade.rpc.send_msg({
'type': RPCMessageType.STATUS_NOTIFICATION, 'type': RPCMessageType.STATUS_NOTIFICATION,
'status': 'config reloaded' 'status': 'config reloaded'

View File

@ -22,6 +22,7 @@ from freqtrade.data import history
from freqtrade.misc import file_dump_json from freqtrade.misc import file_dump_json
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.resolvers import StrategyResolver from freqtrade.resolvers import StrategyResolver
from freqtrade.state import RunMode
from freqtrade.strategy.interface import SellType, IStrategy from freqtrade.strategy.interface import SellType, IStrategy
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -452,7 +453,7 @@ def setup_configuration(args: Namespace) -> Dict[str, Any]:
:param args: Cli args from Arguments() :param args: Cli args from Arguments()
:return: Configuration :return: Configuration
""" """
configuration = Configuration(args) configuration = Configuration(args, RunMode.BACKTEST)
config = configuration.get_config() config = configuration.get_config()
# Ensure we do not use Exchange credentials # Ensure we do not use Exchange credentials

View File

@ -9,10 +9,11 @@ from typing import Dict, Any
from tabulate import tabulate from tabulate import tabulate
from freqtrade.edge import Edge from freqtrade.edge import Edge
from freqtrade.configuration import Configuration
from freqtrade.arguments import Arguments from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
from freqtrade.resolvers import StrategyResolver from freqtrade.resolvers import StrategyResolver
from freqtrade.state import RunMode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -83,7 +84,7 @@ def setup_configuration(args: Namespace) -> Dict[str, Any]:
:param args: Cli args from Arguments() :param args: Cli args from Arguments()
:return: Configuration :return: Configuration
""" """
configuration = Configuration(args) configuration = Configuration(args, RunMode.EDGECLI)
config = configuration.get_config() config = configuration.get_config()
# Ensure we do not use Exchange credentials # Ensure we do not use Exchange credentials

View File

@ -25,6 +25,7 @@ from freqtrade.configuration import Configuration
from freqtrade.data.history import load_data from freqtrade.data.history import load_data
from freqtrade.optimize import get_timeframe from freqtrade.optimize import get_timeframe
from freqtrade.optimize.backtesting import Backtesting from freqtrade.optimize.backtesting import Backtesting
from freqtrade.state import RunMode
from freqtrade.resolvers import HyperOptResolver from freqtrade.resolvers import HyperOptResolver
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -306,7 +307,7 @@ def start(args: Namespace) -> None:
# Initialize configuration # Initialize configuration
# Monkey patch the configuration with hyperopt_conf.py # Monkey patch the configuration with hyperopt_conf.py
configuration = Configuration(args) configuration = Configuration(args, RunMode.HYPEROPT)
logger.info('Starting freqtrade in Hyperopt mode') logger.info('Starting freqtrade in Hyperopt mode')
config = configuration.load_config() config = configuration.load_config()

View File

@ -13,3 +13,16 @@ class State(Enum):
RUNNING = 1 RUNNING = 1
STOPPED = 2 STOPPED = 2
RELOAD_CONF = 3 RELOAD_CONF = 3
class RunMode(Enum):
"""
Bot running mode (backtest, hyperopt, ...)
can be "live", "dry-run", "backtest", "edgecli", "hyperopt".
"""
LIVE = "live"
DRY_RUN = "dry_run"
BACKTEST = "backtest"
EDGECLI = "edgecli"
HYPEROPT = "hyperopt"
OTHER = "other" # Used for plotting scripts and test

View File

@ -1,10 +1,9 @@
from unittest.mock import Mock, MagicMock, PropertyMock from unittest.mock import MagicMock
from pandas import DataFrame from pandas import DataFrame
from freqtrade.data.dataprovider import DataProvider from freqtrade.data.dataprovider import DataProvider
from freqtrade.exchange import Exchange from freqtrade.tests.conftest import get_patched_exchange
from freqtrade.tests.conftest import get_patched_exchange, log_has
def test_ohlcv(mocker, default_conf, ticker_history): def test_ohlcv(mocker, default_conf, ticker_history):
@ -31,6 +30,5 @@ def test_historic_ohlcv(mocker, default_conf, ticker_history):
assert isinstance(data, DataFrame) assert isinstance(data, DataFrame)
assert historymock.call_count == 1 assert historymock.call_count == 1
assert historymock.call_args_list[0][1]['datadir'] is None assert historymock.call_args_list[0][1]['datadir'] is None
assert historymock.call_args_list[0][1]['refresh_pairs'] == False assert historymock.call_args_list[0][1]['refresh_pairs'] is False
assert historymock.call_args_list[0][1]['ticker_interval'] == '5m' assert historymock.call_args_list[0][1]['ticker_interval'] == '5m'

View File

@ -29,6 +29,7 @@ from freqtrade.configuration import Configuration
from freqtrade import constants from freqtrade import constants
from freqtrade.data import history from freqtrade.data import history
from freqtrade.resolvers import StrategyResolver from freqtrade.resolvers import StrategyResolver
from freqtrade.state import RunMode
import freqtrade.misc as misc import freqtrade.misc as misc
@ -82,7 +83,7 @@ def plot_profit(args: Namespace) -> None:
# to match the tickerdata against the profits-results # to match the tickerdata against the profits-results
timerange = Arguments.parse_timerange(args.timerange) timerange = Arguments.parse_timerange(args.timerange)
config = Configuration(args).get_config() config = Configuration(args, RunMode.OTHER).get_config()
# Init strategy # Init strategy
try: try: