From cf974168e97a2e3c279a77acc764e7f18919c05d Mon Sep 17 00:00:00 2001 From: misagh Date: Wed, 14 Nov 2018 12:37:15 +0100 Subject: [PATCH] Edge cli drafted --- freqtrade/arguments.py | 84 ++++++++++++++++++++++++++++++------- freqtrade/edge/__init__.py | 2 +- freqtrade/optimize/edge.py | 86 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 16 deletions(-) create mode 100644 freqtrade/optimize/edge.py diff --git a/freqtrade/arguments.py b/freqtrade/arguments.py index bb571b4ea..2b369561a 100644 --- a/freqtrade/arguments.py +++ b/freqtrade/arguments.py @@ -128,6 +128,22 @@ class Arguments(object): """ Parses given arguments for Backtesting scripts. """ + parser.add_argument( + '--eps', '--enable-position-stacking', + help='Allow buying the same pair multiple times (position stacking)', + action='store_true', + dest='position_stacking', + default=False + ) + + parser.add_argument( + '--dmmp', '--disable-max-market-positions', + help='Disable applying `max_open_trades` during backtest ' + '(same as setting `max_open_trades` to a very high number)', + action='store_false', + dest='use_max_market_positions', + default=True + ) parser.add_argument( '-l', '--live', help='using live data', @@ -171,6 +187,38 @@ class Arguments(object): metavar='PATH', ) + @staticmethod + def edge_options(parser: argparse.ArgumentParser) -> None: + """ + Parses given arguments for Backtesting scripts. + """ + parser.add_argument( + '-r', '--refresh-pairs-cached', + help='refresh the pairs files in tests/testdata with the latest data from the ' + 'exchange. Use it if you want to run your backtesting with up-to-date data.', + action='store_true', + dest='refresh_pairs', + ) + parser.add_argument( + '--export', + help='export backtest results, argument are: trades\ + Example --export=trades', + type=str, + default=None, + dest='export', + ) + parser.add_argument( + '--export-filename', + help='Save backtest results to this filename \ + requires --export to be set as well\ + Example --export-filename=user_data/backtest_data/backtest_today.json\ + (default: %(default)s)', + type=str, + default=os.path.join('user_data', 'backtest_data', 'backtest-result.json'), + dest='exportfilename', + metavar='PATH', + ) + @staticmethod def optimizer_shared_options(parser: argparse.ArgumentParser) -> None: """ @@ -184,6 +232,20 @@ class Arguments(object): dest='ticker_interval', type=str, ) + + parser.add_argument( + '--timerange', + help='specify what timerange of data to use.', + default=None, + type=str, + dest='timerange', + ) + + @staticmethod + def hyperopt_options(parser: argparse.ArgumentParser) -> None: + """ + Parses given arguments for Hyperopt scripts. + """ parser.add_argument( '--eps', '--enable-position-stacking', help='Allow buying the same pair multiple times (position stacking)', @@ -200,20 +262,6 @@ class Arguments(object): dest='use_max_market_positions', default=True ) - - parser.add_argument( - '--timerange', - help='specify what timerange of data to use.', - default=None, - type=str, - dest='timerange', - ) - - @staticmethod - def hyperopt_options(parser: argparse.ArgumentParser) -> None: - """ - Parses given arguments for Hyperopt scripts. - """ parser.add_argument( '-e', '--epochs', help='specify number of epochs (default: %(default)d)', @@ -237,7 +285,7 @@ class Arguments(object): Builds and attaches all subcommands :return: None """ - from freqtrade.optimize import backtesting, hyperopt + from freqtrade.optimize import backtesting, hyperopt, edge subparsers = self.parser.add_subparsers(dest='subparser') @@ -247,6 +295,12 @@ class Arguments(object): self.optimizer_shared_options(backtesting_cmd) self.backtesting_options(backtesting_cmd) + # Add edge subcommand + edge_cmd = subparsers.add_parser('edge', help='edge module') + edge_cmd.set_defaults(func=edge.start) + self.optimizer_shared_options(edge_cmd) + self.edge_options(edge_cmd) + # Add hyperopt subcommand hyperopt_cmd = subparsers.add_parser('hyperopt', help='hyperopt module') hyperopt_cmd.set_defaults(func=hyperopt.start) diff --git a/freqtrade/edge/__init__.py b/freqtrade/edge/__init__.py index 7b25a8306..bb1cd118f 100644 --- a/freqtrade/edge/__init__.py +++ b/freqtrade/edge/__init__.py @@ -35,7 +35,7 @@ class Edge(): 'pair_info', ['stoploss', 'winrate', 'risk_reward_ratio', 'required_risk_reward', 'expectancy']) - def __init__(self, config: Dict[str, Any], exchange, strategy) -> None: + def __init__(self, config: Dict[str, Any], exchange, strategy, refresh_pairs=True) -> None: self.config = config self.exchange = exchange diff --git a/freqtrade/optimize/edge.py b/freqtrade/optimize/edge.py new file mode 100644 index 000000000..49c58987b --- /dev/null +++ b/freqtrade/optimize/edge.py @@ -0,0 +1,86 @@ +# pragma pylint: disable=missing-docstring, W0212, too-many-arguments + +""" +This module contains the backtesting logic +""" +import logging +import operator +from argparse import Namespace +from copy import deepcopy +from datetime import datetime, timedelta +from pathlib import Path +from typing import Any, Dict, List, NamedTuple, Optional, Tuple +from freqtrade.edge import Edge + +import freqtrade.optimize as optimize +from freqtrade import DependencyException, constants +from freqtrade.arguments import Arguments +from freqtrade.configuration import Configuration +from freqtrade.exchange import Exchange +from freqtrade.misc import file_dump_json +from freqtrade.persistence import Trade +from freqtrade.strategy.interface import SellType +from freqtrade.strategy.resolver import IStrategy, StrategyResolver +import pdb + +logger = logging.getLogger(__name__) + + +class EdgeCli(object): + """ + Backtesting class, this class contains all the logic to run a backtest + + To run a backtest: + backtesting = Backtesting(config) + backtesting.start() + """ + + def __init__(self, config: Dict[str, Any]) -> None: + self.config = config + + # Reset keys for edge + self.config['exchange']['key'] = '' + self.config['exchange']['secret'] = '' + self.config['exchange']['password'] = '' + self.config['exchange']['uid'] = '' + self.config['dry_run'] = True + self.exchange = Exchange(self.config) + self.strategy = StrategyResolver(self.config).strategy + + self.edge = Edge(config, self.exchange, self.strategy) + + def start(self) -> None: + self.edge.calculate() + # pair_info(stoploss=-0.01, winrate=0.08333333333333333, risk_reward_ratio=0.6399436929988924, required_risk_reward=11.0, expectancy=-0.8633380255834255) + pdb.set_trace() + + +def setup_configuration(args: Namespace) -> Dict[str, Any]: + """ + Prepare the configuration for the backtesting + :param args: Cli args from Arguments() + :return: Configuration + """ + configuration = Configuration(args) + config = configuration.get_config() + + # Ensure we do not use Exchange credentials + config['exchange']['key'] = '' + config['exchange']['secret'] = '' + + return config + + +def start(args: Namespace) -> None: + """ + Start Edge script + :param args: Cli args from Arguments() + :return: None + """ + # Initialize configuration + config = setup_configuration(args) + logger.info('Starting freqtrade in Edge mode') + print('edge talking here...') + # Initialize Edge object + edge_cli = EdgeCli(config) + edge_cli.start()