Merge pull request #2176 from freqtrade/plot_commands

Move Plot scripts to freqtrade subcommands
This commit is contained in:
hroff-1902
2019-09-02 08:08:51 +03:00
committed by GitHub
18 changed files with 415 additions and 255 deletions

View File

@@ -89,17 +89,20 @@ def test_load_trades(default_conf, mocker):
db_mock = mocker.patch("freqtrade.data.btanalysis.load_trades_from_db", MagicMock())
bt_mock = mocker.patch("freqtrade.data.btanalysis.load_backtest_data", MagicMock())
default_conf['trade_source'] = "DB"
load_trades(default_conf)
load_trades("DB",
db_url=default_conf.get('db_url'),
exportfilename=default_conf.get('exportfilename'),
)
assert db_mock.call_count == 1
assert bt_mock.call_count == 0
db_mock.reset_mock()
bt_mock.reset_mock()
default_conf['trade_source'] = "file"
default_conf['exportfilename'] = "testfile.json"
load_trades(default_conf)
load_trades("file",
db_url=default_conf.get('db_url'),
exportfilename=default_conf.get('exportfilename'),)
assert db_mock.call_count == 0
assert bt_mock.call_count == 1

View File

@@ -4,7 +4,6 @@ import argparse
import pytest
from freqtrade.configuration import Arguments
from freqtrade.configuration.arguments import ARGS_PLOT_DATAFRAME
from freqtrade.configuration.cli_options import check_int_positive
@@ -149,20 +148,35 @@ def test_download_data_options() -> None:
def test_plot_dataframe_options() -> None:
args = [
'--indicators1', 'sma10,sma100',
'--indicators2', 'macd,fastd,fastk',
'-c', 'config.json.example',
'plot-dataframe',
'--indicators1', 'sma10', 'sma100',
'--indicators2', 'macd', 'fastd', 'fastk',
'--plot-limit', '30',
'-p', 'UNITTEST/BTC',
]
arguments = Arguments(args, '')
arguments._build_args(ARGS_PLOT_DATAFRAME)
pargs = arguments._parse_args()
assert pargs.indicators1 == "sma10,sma100"
assert pargs.indicators2 == "macd,fastd,fastk"
pargs = Arguments(args, '').get_parsed_arg()
assert pargs.indicators1 == ["sma10", "sma100"]
assert pargs.indicators2 == ["macd", "fastd", "fastk"]
assert pargs.plot_limit == 30
assert pargs.pairs == ["UNITTEST/BTC"]
def test_plot_profit_options() -> None:
args = [
'plot-profit',
'-p', 'UNITTEST/BTC',
'--trade-source', 'DB',
"--db-url", "sqlite:///whatever.sqlite",
]
pargs = Arguments(args, '').get_parsed_arg()
assert pargs.trade_source == "DB"
assert pargs.pairs == ["UNITTEST/BTC"]
assert pargs.db_url == "sqlite:///whatever.sqlite"
def test_check_int_positive() -> None:
assert check_int_positive("3") == 3
assert check_int_positive("1") == 1

View File

@@ -479,6 +479,7 @@ def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
def test_check_exchange(default_conf, caplog) -> None:
# Test an officially supported by Freqtrade team exchange
default_conf['runmode'] = RunMode.DRY_RUN
default_conf.get('exchange').update({'name': 'BITTREX'})
assert check_exchange(default_conf)
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
@@ -523,6 +524,11 @@ def test_check_exchange(default_conf, caplog) -> None:
):
check_exchange(default_conf)
# Test no exchange...
default_conf.get('exchange').update({'name': ''})
default_conf['runmode'] = RunMode.PLOT
assert check_exchange(default_conf)
def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
patched_configuration_load_config_file(mocker, default_conf)

View File

@@ -9,13 +9,15 @@ from plotly.subplots import make_subplots
from freqtrade.configuration import TimeRange
from freqtrade.data import history
from freqtrade.data.btanalysis import create_cum_profit, load_backtest_data
from freqtrade.plot.plot_utils import start_plot_dataframe, start_plot_profit
from freqtrade.plot.plotting import (add_indicators, add_profit,
analyse_and_plot_pairs,
generate_candlestick_graph,
generate_plot_filename,
generate_profit_graph, init_plotscript,
plot_trades, store_plot_file)
plot_profit, plot_trades, store_plot_file)
from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.tests.conftest import log_has, log_has_re
from freqtrade.tests.conftest import get_args, log_has, log_has_re
def fig_generating_mock(fig, *args, **kwargs):
@@ -49,7 +51,6 @@ def test_init_plotscript(default_conf, mocker):
assert "tickers" in ret
assert "trades" in ret
assert "pairs" in ret
assert "strategy" in ret
default_conf['pairs'] = ["POWR/BTC", "XLM/BTC"]
ret = init_plotscript(default_conf)
@@ -257,7 +258,11 @@ def test_generate_profit_graph():
fig = generate_profit_graph(pairs, tickers, trades)
assert isinstance(fig, go.Figure)
assert fig.layout.title.text == "Profit plot"
assert fig.layout.title.text == "Freqtrade Profit plot"
assert fig.layout.yaxis.title.text == "Price"
assert fig.layout.yaxis2.title.text == "Profit"
assert fig.layout.yaxis3.title.text == "Profit"
figure = fig.layout.figure
assert len(figure.data) == 4
@@ -270,3 +275,85 @@ def test_generate_profit_graph():
for pair in pairs:
profit_pair = find_trace_in_fig_data(figure.data, f"Profit {pair}")
assert isinstance(profit_pair, go.Scattergl)
def test_start_plot_dataframe(mocker):
aup = mocker.patch("freqtrade.plot.plotting.analyse_and_plot_pairs", MagicMock())
args = [
"--config", "config.json.example",
"plot-dataframe",
"--pairs", "ETH/BTC"
]
start_plot_dataframe(get_args(args))
assert aup.call_count == 1
called_config = aup.call_args_list[0][0][0]
assert "pairs" in called_config
assert called_config['pairs'] == ["ETH/BTC"]
def test_analyse_and_plot_pairs(default_conf, mocker, caplog):
default_conf['trade_source'] = 'file'
default_conf["datadir"] = history.make_testdata_path(None)
default_conf['exportfilename'] = str(
history.make_testdata_path(None) / "backtest-result_test.json")
default_conf['indicators1'] = ["sma5", "ema10"]
default_conf['indicators2'] = ["macd"]
default_conf['pairs'] = ["ETH/BTC", "LTC/BTC"]
candle_mock = MagicMock()
store_mock = MagicMock()
mocker.patch.multiple(
"freqtrade.plot.plotting",
generate_candlestick_graph=candle_mock,
store_plot_file=store_mock
)
analyse_and_plot_pairs(default_conf)
# Both mocks should be called once per pair
assert candle_mock.call_count == 2
assert store_mock.call_count == 2
assert candle_mock.call_args_list[0][1]['indicators1'] == ['sma5', 'ema10']
assert candle_mock.call_args_list[0][1]['indicators2'] == ['macd']
assert log_has("End of plotting process. 2 plots generated", caplog)
def test_start_plot_profit(mocker):
aup = mocker.patch("freqtrade.plot.plotting.plot_profit", MagicMock())
args = [
"--config", "config.json.example",
"plot-profit",
"--pairs", "ETH/BTC"
]
start_plot_profit(get_args(args))
assert aup.call_count == 1
called_config = aup.call_args_list[0][0][0]
assert "pairs" in called_config
assert called_config['pairs'] == ["ETH/BTC"]
def test_plot_profit(default_conf, mocker, caplog):
default_conf['trade_source'] = 'file'
default_conf["datadir"] = history.make_testdata_path(None)
default_conf['exportfilename'] = str(
history.make_testdata_path(None) / "backtest-result_test.json")
default_conf['pairs'] = ["ETH/BTC", "LTC/BTC"]
profit_mock = MagicMock()
store_mock = MagicMock()
mocker.patch.multiple(
"freqtrade.plot.plotting",
generate_profit_graph=profit_mock,
store_plot_file=store_mock
)
plot_profit(default_conf)
# Plot-profit generates one combined plot
assert profit_mock.call_count == 1
assert store_mock.call_count == 1
assert profit_mock.call_args_list[0][0][0] == default_conf['pairs']
assert store_mock.call_args_list[0][1]['auto_open'] is True