added returns for easier notebook plotting
This commit is contained in:
parent
0477e7938d
commit
85a0d2f6cb
@ -332,13 +332,14 @@ def load_and_plot_trades(config: Dict[str, Any]):
|
||||
- Load trades excecuted during the selected period
|
||||
- Generate Plotly plot objects
|
||||
- Generate plot files
|
||||
:return: None
|
||||
:return: Dict of fig, data, trades for each pair and interval
|
||||
"""
|
||||
strategy = StrategyResolver(config).strategy
|
||||
|
||||
plot_elements = init_plotscript(config)
|
||||
trades = plot_elements['trades']
|
||||
pair_counter = 0
|
||||
plot_data = {}
|
||||
for pair, data in plot_elements["tickers"].items():
|
||||
pair_counter += 1
|
||||
logger.info("analyse pair %s", pair)
|
||||
@ -359,16 +360,23 @@ def load_and_plot_trades(config: Dict[str, Any]):
|
||||
|
||||
store_plot_file(fig, filename=generate_plot_filename(pair, config['ticker_interval']),
|
||||
directory=config['user_data_dir'] / "plot")
|
||||
plot_data[generate_plot_filename(pair,
|
||||
config['ticker_interval'])] = {"fig": fig,
|
||||
"data": dataframe,
|
||||
"trades": trades}
|
||||
|
||||
logger.info('End of plotting process. %s plots generated', pair_counter)
|
||||
logger.info(f'fig, data, trades are available with the keys {list(plot_data)}')
|
||||
return plot_data
|
||||
|
||||
|
||||
def plot_profit(config: Dict[str, Any]) -> None:
|
||||
def plot_profit(config: Dict[str, Any], auto_open: bool = False) -> None:
|
||||
"""
|
||||
Plots the total profit for all pairs.
|
||||
Note, the profit calculation isn't realistic.
|
||||
But should be somewhat proportional, and therefor useful
|
||||
in helping out to find a good algorithm.
|
||||
:return: profit plot
|
||||
"""
|
||||
plot_elements = init_plotscript(config)
|
||||
trades = load_trades(config['trade_source'],
|
||||
@ -382,4 +390,5 @@ def plot_profit(config: Dict[str, Any]) -> None:
|
||||
# this could be useful to gauge the overall market trend
|
||||
fig = generate_profit_graph(plot_elements["pairs"], plot_elements["tickers"], trades)
|
||||
store_plot_file(fig, filename='freqtrade-profit-plot.html',
|
||||
directory=config['user_data_dir'] / "plot", auto_open=True)
|
||||
directory=config['user_data_dir'] / "plot", auto_open=auto_open)
|
||||
return fig
|
||||
|
@ -89,31 +89,38 @@
|
||||
"# Specify values for use in this script\n",
|
||||
"############### Customize to match your needs. ##################\n",
|
||||
"config_files = [\n",
|
||||
" Path('user_data', 'config.json'),\n",
|
||||
" Path(Path.home(), '.freqtrade', 'config.json')\n",
|
||||
" Path('user_data', 'user_repo', 'config.json'),\n",
|
||||
" Path(Path.home(), '.freqtrade', 'exchange-config.json')\n",
|
||||
"]\n",
|
||||
"# Create config object\n",
|
||||
"config = Configuration.from_files(config_files)\n",
|
||||
"\n",
|
||||
"############### Customize to match your needs. ##################\n",
|
||||
"# Define some constants\n",
|
||||
"ticker_interval = \"5m\"\n",
|
||||
"# Path to user data\n",
|
||||
"user_data_dir = Path('user_data')\n",
|
||||
"# Location of the ticker data\n",
|
||||
"datadir = Path(user_data_dir, 'data/binance')\n",
|
||||
"\n",
|
||||
"# These values must be included in config.json or set here\n",
|
||||
"# Name of the strategy class\n",
|
||||
"strategy_name = 'DefaultStrategy'\n",
|
||||
"config['strategy'] = 'DefaultStrategy'\n",
|
||||
"# Path to user data\n",
|
||||
"config['user_data_dir'] = Path('user_data')\n",
|
||||
"# Location of the ticker data\n",
|
||||
"config['datadir'] = Path('user_data', 'data/binance')\n",
|
||||
"# Location of the strategy\n",
|
||||
"strategy_path = Path(user_data_dir, 'strategies')\n",
|
||||
"config['strategy_path'] = Path('user_data', 'strategies')\n",
|
||||
"# Specify backtest results to load\n",
|
||||
"trade_source = 'file'\n",
|
||||
"exportfilename = Path(user_data_dir, 'backtest_results/backtest-result.json')\n",
|
||||
"db_url = 'sqlite://'\n",
|
||||
"config['trade_source'] = 'file'\n",
|
||||
"config['exportfilename'] = Path('user_data', 'backtest_results/backtest-result.json')\n",
|
||||
"config['db_url'] = 'sqlite://'\n",
|
||||
"\n",
|
||||
"# Specify interval to analyze\n",
|
||||
"ticker_interval = \"5m\"\n",
|
||||
"# Specify timerange to test\n",
|
||||
"timerange = '-100'\n",
|
||||
"# Pair to analyze - Only use one pair here\n",
|
||||
"pair = \"ETH/BTC\""
|
||||
"pair = \"ETH/BTC\"\n",
|
||||
"# Indicators from strategy to plot\n",
|
||||
"overlay_indicators = ['ema50', 'ema100']\n",
|
||||
"bottom_indicators = ['macd']"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -155,17 +162,14 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import logging\n",
|
||||
"\n",
|
||||
"import json\n",
|
||||
"from freqtrade.loggers import setup_logging\n",
|
||||
"\n",
|
||||
"# Configure logging\n",
|
||||
"logger = logging.getLogger()\n",
|
||||
"setup_logging(config)\n",
|
||||
"logger.setLevel(logging.INFO)\n",
|
||||
"logger.info(f'conf: {conf}')\n",
|
||||
"\n",
|
||||
"# Show config in memory\n",
|
||||
"logger.info(json.dumps(config, indent=1))"
|
||||
"logger.info(f'conf: {conf}')"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -177,8 +181,10 @@
|
||||
"* Load the history of the specified pair\n",
|
||||
"* Load the specified strategy\n",
|
||||
"* Generate buy and sell signals produced by the specified strategy\n",
|
||||
"* Plot the results\n",
|
||||
"\n",
|
||||
"* Return a dictionary with the figure, figure dataframe and trades dataframe\n",
|
||||
" * Key is the same as the figure filename. EG: 'freqtrade-plot-ETH_BTC-15m.html'\n",
|
||||
" * Display elements with dict indexing as demonstrated below\n",
|
||||
" * `fig.show()` displays the chart inline `fig.show(renderer=\"browser\")` displays the chart in a tab.\n",
|
||||
"\n",
|
||||
"*Note: `data.head()` may include empty values for indicators that require a startup period. This is expected behavior. For example `ma5` requires 5 candles before computing the first average*\n",
|
||||
"\n",
|
||||
@ -199,66 +205,21 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from pathlib import Path\n",
|
||||
"from freqtrade.plot.plotting import load_and_plot_trades\n",
|
||||
"\n",
|
||||
"import pandas as pd\n",
|
||||
"\n",
|
||||
"from freqtrade.data.btanalysis import load_trades\n",
|
||||
"from freqtrade.data.history import load_pair_history\n",
|
||||
"from freqtrade.resolvers import StrategyResolver\n",
|
||||
"from freqtrade.plot.plotting import extract_trades_of_period, generate_candlestick_graph\n",
|
||||
"# Load ticker history\n",
|
||||
"tickers = load_pair_history(pair=pair,\n",
|
||||
" ticker_interval=ticker_interval,\n",
|
||||
" datadir=datadir,\n",
|
||||
" timerange=TimeRange.parse_timerange(timerange))\n",
|
||||
"\n",
|
||||
"# Confirm success\n",
|
||||
"print(\"Loaded \" + str(len(tickers)) +\n",
|
||||
" f\" rows of data for {pair} from {datadir}\")\n",
|
||||
"\n",
|
||||
"# Load strategy\n",
|
||||
"strategy = StrategyResolver({\n",
|
||||
" 'strategy': strategy_name,\n",
|
||||
" 'user_data_dir': user_data_dir,\n",
|
||||
" 'strategy_path': strategy_path\n",
|
||||
"}).strategy\n",
|
||||
"\n",
|
||||
"# Generate buy/sell signals using strategy\n",
|
||||
"data = strategy.analyze_ticker(tickers, {'pair': pair})\n",
|
||||
"logger.info(f'Indicators: {list(data)[6:-2]}')\n",
|
||||
"\n",
|
||||
"# Collect trades if a backtest has been completed\n",
|
||||
"try:\n",
|
||||
" trades = load_trades(source=trade_source,\n",
|
||||
" db_url=db_url,\n",
|
||||
" exportfilename=exportfilename)\n",
|
||||
" trades = trades.loc[trades['pair'] == pair]\n",
|
||||
" trades = extract_trades_of_period(data, trades)\n",
|
||||
"except:\n",
|
||||
" trades = pd.DataFrame()\n",
|
||||
"\n",
|
||||
"# Build and display plot\n",
|
||||
"# Specify the indicators to plot as lists\n",
|
||||
"# indicators1 is a list of indicators to overlay on the price chart\n",
|
||||
"# indicators2 is a list of indicators to plot below the price chart\n",
|
||||
"fig = generate_candlestick_graph(\n",
|
||||
" pair=pair,\n",
|
||||
" data=data,\n",
|
||||
" trades=trades,\n",
|
||||
" indicators1=['ema20', 'ema50', 'ema100'],\n",
|
||||
" indicators2=['macd', 'macdsignal'])\n",
|
||||
"\n",
|
||||
"fig.show()\n",
|
||||
"display(data.tail())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Run Backtest\n",
|
||||
"Once you are happy with your strategy signals, run a backtest then plot again."
|
||||
"plot_data = load_and_plot_trades({'strategy': config['strategy'],\n",
|
||||
" 'strategy_path': Path(config['strategy_path']),\n",
|
||||
" 'timerange': timerange,\n",
|
||||
" 'ticker_interval': ticker_interval,\n",
|
||||
" 'strategy_path': Path(config['strategy_path']),\n",
|
||||
" 'datadir': Path(config['datadir']),\n",
|
||||
" 'user_data_dir': Path(config['user_data_dir']),\n",
|
||||
" 'exchange': config['exchange'],\n",
|
||||
" 'trade_source': config['trade_source'],\n",
|
||||
" 'exportfilename': config['exportfilename'],\n",
|
||||
" 'indicators1': overlay_indicators,\n",
|
||||
" 'indicators2': bottom_indicators\n",
|
||||
" })"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -267,8 +228,51 @@
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Run backtest\n",
|
||||
"!freqtrade {conf} backtesting --timerange={timerange} --ticker-interval {ticker_interval} --export=trades --export-filename={exportfilename}"
|
||||
"# Display charts and data inline\n",
|
||||
"for idx in list(plot_data.keys()):\n",
|
||||
" print(idx)\n",
|
||||
" plot_data[idx]['fig'].show()\n",
|
||||
" display(plot_data[idx]['data'].tail())\n",
|
||||
" display(plot_data[idx]['trades'].head())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Detailed analysis\n",
|
||||
"Slice and dice your data to generate insights"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def show_indicator_extremes(df, indicator):\n",
|
||||
" '''\n",
|
||||
" Sorts simulation dataframe by specified indicator\n",
|
||||
" '''\n",
|
||||
" df = df[df[indicator].notna()].sort_values(by=indicator, ascending=False)\n",
|
||||
" return df\n",
|
||||
"\n",
|
||||
"# Demonstrate with first item\n",
|
||||
"idx = list(plot_data.keys())[0]\n",
|
||||
"indicator = overlay_indicators[0]\n",
|
||||
"print(idx)\n",
|
||||
"data = plot_data[idx]['data']\n",
|
||||
"extremes = show_indicator_extremes(data, indicator)\n",
|
||||
"display(extremes.head(10))\n",
|
||||
"display(extremes.tail(10))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Run Backtest\n",
|
||||
"Once you are happy with your strategy signals, run a backtest then plot again."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user