From c60517a454823283f49fea548de0a44caf505dc2 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Tue, 3 Sep 2019 16:11:43 -0400 Subject: [PATCH 1/7] added function to find project root --- freqtrade/misc.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 12a90a14d..7eef795e9 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -3,6 +3,7 @@ Various tool function for Freqtrade and scripts """ import gzip import logging +from os import chdir import re from datetime import datetime from pathlib import Path @@ -114,3 +115,23 @@ def deep_merge_dicts(source, destination): destination[key] = value return destination + + +def find_project_root(path=None): + """Locates root directory of the project. + Root is defined by existence of "LICENSE" and the dir 'freqtrade'. + :param path: pathlib.Path object, or string pointing to project root directory. + :return: path to project root directory + """ + if path is None: + path = Path(__file__).parent + i = 0 + try: + chdir(path) + assert Path('LICENSE').is_file() and Path('freqtrade').exists() + except AssertionError: + while i < 5 and not (Path(path, 'LICENSE').is_file() and Path(path, 'freqtrade').exists()): + path = Path(path).parent + i += 1 + logger.info(f'project_root is {path}') + return path From 24cd151fcf947092904eda1e1adfc497bf04d9b0 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Tue, 3 Sep 2019 23:30:32 -0400 Subject: [PATCH 2/7] typo fixes --- freqtrade/data/history.py | 2 +- freqtrade/tests/test_plotting.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index aff9f5c74..ec7e769ac 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -61,7 +61,7 @@ def load_tickerdata_file(datadir: Optional[Path], pair: str, ticker_interval: st timerange: Optional[TimeRange] = None) -> Optional[list]: """ Load a pair from file, either .json.gz or .json - :return: tickerlist or None if unsuccesful + :return: tickerlist or None if unsuccessful """ filename = pair_data_filename(datadir, pair, ticker_interval) pairdata = misc.file_load_json(filename) diff --git a/freqtrade/tests/test_plotting.py b/freqtrade/tests/test_plotting.py index df208d4d2..32d6396f8 100644 --- a/freqtrade/tests/test_plotting.py +++ b/freqtrade/tests/test_plotting.py @@ -30,7 +30,7 @@ def find_trace_in_fig_data(data, search_string: str): return next(matches) -def generage_empty_figure(): +def generate_empty_figure(): return make_subplots( rows=3, cols=1, From 2ee89c4ef3b3b0a711b207cce01da11c59e6aed7 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Tue, 3 Sep 2019 23:34:59 -0400 Subject: [PATCH 3/7] changes to names --- freqtrade/plot/plot_utils.py | 4 ++-- freqtrade/resolvers/strategy_resolver.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/freqtrade/plot/plot_utils.py b/freqtrade/plot/plot_utils.py index 507e86d9d..e132ee2e4 100644 --- a/freqtrade/plot/plot_utils.py +++ b/freqtrade/plot/plot_utils.py @@ -9,10 +9,10 @@ def start_plot_dataframe(args: Namespace) -> None: Entrypoint for dataframe plotting """ # Import here to avoid errors if plot-dependencies are not installed. - from freqtrade.plot.plotting import analyse_and_plot_pairs + from freqtrade.plot.plotting import load_and_plot_trades config = setup_utils_configuration(args, RunMode.PLOT) - analyse_and_plot_pairs(config) + load_and_plot_trades(config) def start_plot_profit(args: Namespace) -> None: diff --git a/freqtrade/resolvers/strategy_resolver.py b/freqtrade/resolvers/strategy_resolver.py index 514e9f22b..72c61dcb4 100644 --- a/freqtrade/resolvers/strategy_resolver.py +++ b/freqtrade/resolvers/strategy_resolver.py @@ -24,8 +24,6 @@ class StrategyResolver(IResolver): This class contains all the logic to load custom strategy class """ - __slots__ = ['strategy'] - def __init__(self, config: Optional[Dict] = None) -> None: """ Load the custom class from config parameter @@ -123,7 +121,8 @@ class StrategyResolver(IResolver): current_path = Path(__file__).parent.parent.joinpath('strategy').resolve() abs_paths = [ - config['user_data_dir'].joinpath('strategies'), + Path(config['user_data_dir']).joinpath('strategies'), + config['strategy_path'], current_path, ] From 8250ce8da077054ca9f5bf0b222e525870966718 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Tue, 3 Sep 2019 23:38:41 -0400 Subject: [PATCH 4/7] function name change --- freqtrade/plot/plotting.py | 50 +++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index b0b8e3df9..309f4bfa3 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -33,21 +33,24 @@ def init_plotscript(config): pairs = config["pairs"] else: pairs = config["exchange"]["pair_whitelist"] + assert pairs is not None, ('No pairs available in config.') # Set timerange to use timerange = TimeRange.parse_timerange(config.get("timerange")) tickers = history.load_data( - datadir=Path(str(config.get("datadir"))), + datadir=Path(config.get("datadir"), config.get("exchange").get("name")), pairs=pairs, ticker_interval=config.get('ticker_interval', '5m'), timerange=timerange, ) + assert tickers is not None, ('No ticker data available as specified in config.') trades = load_trades(config['trade_source'], db_url=config.get('db_url'), exportfilename=config.get('exportfilename'), ) + assert trades is not None, ('No trades available as specified in config.') return {"tickers": tickers, "trades": trades, @@ -324,7 +327,7 @@ def store_plot_file(fig, filename: str, directory: Path, auto_open: bool = False logger.info(f"Stored plot as {_filename}") -def analyse_and_plot_pairs(config: Dict[str, Any]): +def load_and_plot_trades(config: Dict[str, Any]): """ From configuration provided - Initializes plot-script @@ -339,31 +342,34 @@ def analyse_and_plot_pairs(config: Dict[str, Any]): plot_elements = init_plotscript(config) trades = plot_elements['trades'] + if trades is None: + raise ValueError('No trades to analyze') + else: + pair_counter = 0 + for pair, data in plot_elements["tickers"].items(): + pair_counter += 1 + logger.info("analyse pair %s", pair) + tickers = {} + tickers[pair] = data - pair_counter = 0 - for pair, data in plot_elements["tickers"].items(): - pair_counter += 1 - logger.info("analyse pair %s", pair) - tickers = {} - tickers[pair] = data + dataframe = strategy.analyze_ticker(tickers[pair], {'pair': pair}) + logger.debug(f'pair: {pair}') - dataframe = strategy.analyze_ticker(tickers[pair], {'pair': pair}) + trades_pair = trades.loc[trades['pair'] == pair] + trades_pair = extract_trades_of_period(dataframe, trades_pair) - trades_pair = trades.loc[trades['pair'] == pair] - trades_pair = extract_trades_of_period(dataframe, trades_pair) + fig = generate_candlestick_graph( + pair=pair, + data=dataframe, + trades=trades_pair, + indicators1=config["indicators1"], + indicators2=config["indicators2"], + ) - fig = generate_candlestick_graph( - pair=pair, - data=dataframe, - trades=trades_pair, - indicators1=config["indicators1"], - indicators2=config["indicators2"], - ) + store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']), + directory=config['user_data_dir'] / "plot") - store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']), - directory=config['user_data_dir'] / "plot") - - logger.info('End of plotting process. %s plots generated', pair_counter) + logger.info('End of plotting process. %s plots generated', pair_counter) def plot_profit(config: Dict[str, Any]) -> None: From a82b87fcae4138ae2148de1ce0d73a6f4d99c772 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Tue, 3 Sep 2019 23:52:31 -0400 Subject: [PATCH 5/7] test fixes --- freqtrade/tests/test_plotting.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/freqtrade/tests/test_plotting.py b/freqtrade/tests/test_plotting.py index 32d6396f8..6936a8a76 100644 --- a/freqtrade/tests/test_plotting.py +++ b/freqtrade/tests/test_plotting.py @@ -71,7 +71,7 @@ def test_add_indicators(default_conf, caplog): # Generate buy/sell signals and indicators strat = DefaultStrategy(default_conf) data = strat.analyze_ticker(data, {'pair': pair}) - fig = generage_empty_figure() + fig = generate_empty_figure() # Row 1 fig1 = add_indicators(fig=deepcopy(fig), row=1, indicators=indicators1, data=data) @@ -93,7 +93,7 @@ def test_add_indicators(default_conf, caplog): def test_plot_trades(caplog): - fig1 = generage_empty_figure() + fig1 = generate_empty_figure() # nothing happens when no trades are available fig = plot_trades(fig1, None) assert fig == fig1 @@ -209,7 +209,7 @@ def test_generate_Plot_filename(): def test_generate_plot_file(mocker, caplog): - fig = generage_empty_figure() + fig = generate_empty_figure() plot_mock = mocker.patch("freqtrade.plot.plotting.plot", MagicMock()) store_plot_file(fig, filename="freqtrade-plot-UNITTEST_BTC-5m.html", directory=Path("user_data/plots")) @@ -229,7 +229,7 @@ def test_add_profit(): df = history.load_pair_history(pair="POWR/BTC", ticker_interval='5m', datadir=None, timerange=timerange) - fig = generage_empty_figure() + fig = generate_empty_figure() cum_profits = create_cum_profit(df.set_index('date'), bt_data[bt_data["pair"] == 'POWR/BTC'], From 021791e2c805a4ba66f9988a1c66d177dfa18a99 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Wed, 4 Sep 2019 20:56:25 -0400 Subject: [PATCH 6/7] fixed error checking --- freqtrade/data/history.py | 6 ++-- freqtrade/misc.py | 21 ------------- freqtrade/plot/plotting.py | 61 +++++++++++++++++++++----------------- 3 files changed, 36 insertions(+), 52 deletions(-) diff --git a/freqtrade/data/history.py b/freqtrade/data/history.py index ec7e769ac..e6863c9bd 100644 --- a/freqtrade/data/history.py +++ b/freqtrade/data/history.py @@ -128,9 +128,9 @@ def load_pair_history(pair: str, drop_incomplete=drop_incomplete) else: logger.warning( - f'No history data for pair: "{pair}", interval: {ticker_interval}. ' - 'Use --refresh-pairs-cached option or `freqtrade download-data` ' - 'script to download the data' + f'No history data for pair: "{pair}", interval: {ticker_interval}, in {datadir}. ' + 'Provide the correct path to datadir in config.json, or download data with ' + '--refresh-pairs-cached option or `freqtrade download-data`. ' ) return None diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 7eef795e9..12a90a14d 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -3,7 +3,6 @@ Various tool function for Freqtrade and scripts """ import gzip import logging -from os import chdir import re from datetime import datetime from pathlib import Path @@ -115,23 +114,3 @@ def deep_merge_dicts(source, destination): destination[key] = value return destination - - -def find_project_root(path=None): - """Locates root directory of the project. - Root is defined by existence of "LICENSE" and the dir 'freqtrade'. - :param path: pathlib.Path object, or string pointing to project root directory. - :return: path to project root directory - """ - if path is None: - path = Path(__file__).parent - i = 0 - try: - chdir(path) - assert Path('LICENSE').is_file() and Path('freqtrade').exists() - except AssertionError: - while i < 5 and not (Path(path, 'LICENSE').is_file() and Path(path, 'freqtrade').exists()): - path = Path(path).parent - i += 1 - logger.info(f'project_root is {path}') - return path diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index 309f4bfa3..df0dab889 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -3,7 +3,7 @@ from pathlib import Path from typing import Any, Dict, List import pandas as pd - +from freqtrade import OperationalException from freqtrade.configuration import TimeRange from freqtrade.data import history from freqtrade.data.btanalysis import (combine_tickers_with_mean, @@ -33,24 +33,29 @@ def init_plotscript(config): pairs = config["pairs"] else: pairs = config["exchange"]["pair_whitelist"] - assert pairs is not None, ('No pairs available in config.') + if pairs is None: + raise OperationalException('No pairs available in config.') # Set timerange to use timerange = TimeRange.parse_timerange(config.get("timerange")) + if timerange is None: + raise OperationalException('Could not parse timerange in config.') tickers = history.load_data( - datadir=Path(config.get("datadir"), config.get("exchange").get("name")), + datadir=Path(str(config.get("datadir"))), pairs=pairs, ticker_interval=config.get('ticker_interval', '5m'), timerange=timerange, ) - assert tickers is not None, ('No ticker data available as specified in config.') + if tickers is None: + raise OperationalException('No ticker data available as specified in config.') trades = load_trades(config['trade_source'], db_url=config.get('db_url'), exportfilename=config.get('exportfilename'), ) - assert trades is not None, ('No trades available as specified in config.') + if trades is None: + raise OperationalException('No trades available as specified in config.') return {"tickers": tickers, "trades": trades, @@ -342,34 +347,34 @@ def load_and_plot_trades(config: Dict[str, Any]): plot_elements = init_plotscript(config) trades = plot_elements['trades'] - if trades is None: - raise ValueError('No trades to analyze') - else: - pair_counter = 0 - for pair, data in plot_elements["tickers"].items(): - pair_counter += 1 - logger.info("analyse pair %s", pair) - tickers = {} - tickers[pair] = data + # if trades is None: + # # raise ValueError('No trades to analyze') + # else: + pair_counter = 0 + for pair, data in plot_elements["tickers"].items(): + pair_counter += 1 + logger.info("analyse pair %s", pair) + tickers = {} + tickers[pair] = data - dataframe = strategy.analyze_ticker(tickers[pair], {'pair': pair}) - logger.debug(f'pair: {pair}') + dataframe = strategy.analyze_ticker(tickers[pair], {'pair': pair}) + logger.debug(f'pair: {pair}') - trades_pair = trades.loc[trades['pair'] == pair] - trades_pair = extract_trades_of_period(dataframe, trades_pair) + trades_pair = trades.loc[trades['pair'] == pair] + trades_pair = extract_trades_of_period(dataframe, trades_pair) - fig = generate_candlestick_graph( - pair=pair, - data=dataframe, - trades=trades_pair, - indicators1=config["indicators1"], - indicators2=config["indicators2"], - ) + fig = generate_candlestick_graph( + pair=pair, + data=dataframe, + trades=trades_pair, + indicators1=config["indicators1"], + indicators2=config["indicators2"], + ) - store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']), - directory=config['user_data_dir'] / "plot") + store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']), + directory=config['user_data_dir'] / "plot") - logger.info('End of plotting process. %s plots generated', pair_counter) + logger.info('End of plotting process. %s plots generated', pair_counter) def plot_profit(config: Dict[str, Any]) -> None: From 17138dfdf9a0fb6af4458f71ad20496846603020 Mon Sep 17 00:00:00 2001 From: Jonathan Raviotta Date: Wed, 4 Sep 2019 21:14:27 -0400 Subject: [PATCH 7/7] removed extra comments --- freqtrade/plot/plotting.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/freqtrade/plot/plotting.py b/freqtrade/plot/plotting.py index df0dab889..176512fad 100644 --- a/freqtrade/plot/plotting.py +++ b/freqtrade/plot/plotting.py @@ -347,9 +347,6 @@ def load_and_plot_trades(config: Dict[str, Any]): plot_elements = init_plotscript(config) trades = plot_elements['trades'] - # if trades is None: - # # raise ValueError('No trades to analyze') - # else: pair_counter = 0 for pair, data in plot_elements["tickers"].items(): pair_counter += 1