跳到主要内容

Plotting

This page explains how to plot prices, indicators and profits.

Deprecated

The commands described in this page (plot-dataframe, plot-profit) should be considered deprecated and are in maintenance mode.

This is mostly for the performance problems even medium sized plots can cause, but also because "store a file and open it in a browser" isn't very intuitive from a UI perspective.

While there are no immediate plans to remove them, they are not actively maintained - and may be removed short-term should major changes be required to keep them working.

Please use FreqUI for plotting needs, which doesn't struggle with the same performance problems.

Installation / Setup

Plotting modules use the Plotly library. You can install / upgrade this by running the following command:

pip install -U -r requirements-plot.txt

Plot price and indicators

The freqtrade plot-dataframe subcommand shows an interactive graph with three subplots:

  • Main plot with candlesticks and indicators following price (sma/ema)
  • Volume bars
  • Additional indicators as specified by --indicators2

plot-dataframe

Example:

freqtrade plot-dataframe -p BTC/ETH --strategy AwesomeStrategy

The -p/--pairs argument can be used to specify pairs you would like to plot.

备注

The freqtrade plot-dataframe subcommand generates one plot-file per pair.

Specify custom indicators. Use --indicators1 for the main plot and --indicators2 for the subplot below (if values are in a different range than prices).

freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --indicators1 sma ema --indicators2 macd

Further usage examples

To plot multiple pairs, separate them with a space:

freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH XRP/ETH

To plot a timerange (to zoom in)

freqtrade plot-dataframe --strategy AwesomeStrategy -p BTC/ETH --timerange=20180801-20180805

To plot trades stored in a database use --db-url in combination with --trade-source DB:

freqtrade plot-dataframe --strategy AwesomeStrategy --db-url sqlite:///tradesv3.dry_run.sqlite -p BTC/ETH --trade-source DB

To plot trades from a backtesting result, use --export-filename <filename>

freqtrade plot-dataframe --strategy AwesomeStrategy --export-filename user_data/backtest_results/backtest-result.json -p BTC/ETH

Plot dataframe basics

plot-dataframe2

The plot-dataframe subcommand requires backtesting data, a strategy and either a backtesting-results file or a database, containing trades corresponding to the strategy.

The resulting plot will have the following elements:

  • Green triangles: Buy signals from the strategy. (Note: not every buy signal generates a trade, compare to cyan circles.)
  • Red triangles: Sell signals from the strategy. (Also, not every sell signal terminates a trade, compare to red and green squares.)
  • Cyan circles: Trade entry points.
  • Red squares: Trade exit points for trades with loss or 0% profit.
  • Green squares: Trade exit points for profitable trades.
  • Indicators with values corresponding to the candle scale (e.g. SMA/EMA), as specified with --indicators1.
  • Volume (bar chart at the bottom of the main chart).
  • Indicators with values in different scales (e.g. MACD, RSI) below the volume bars, as specified with --indicators2.
Bollinger Bands

Bollinger bands are automatically added to the plot if the columns bb_lowerband and bb_upperband exist, and are painted as a light blue area spanning from the lower band to the upper band.

Advanced plot configuration

An advanced plot configuration can be specified in the strategy in the plot_config parameter.

Additional features when using plot_config include:

  • Specify colors per indicator
  • Specify additional subplots
  • Specify indicator pairs to fill area in between

The sample plot configuration below specifies fixed colors for the indicators. Otherwise, consecutive plots may produce different color schemes each time, making comparisons difficult.

It also allows multiple subplots to display both MACD and RSI at the same time.

Plot type can be configured using type key. Possible types are:

  • scatter corresponding to plotly.graph_objects.Scatter class (default).
  • bar corresponding to plotly.graph_objects.Bar class.

Extra parameters to plotly.graph_objects.* constructor can be specified in plotly dict.

Sample configuration with inline comments explaining the process:

@property
def plot_config(self):
"""
There are a lot of solutions how to build the return dictionary.
The only important point is the return value.
Example:
plot_config = {'main_plot': {}, 'subplots': {}}

"""
plot_config = {}
plot_config['main_plot'] = {
# Configuration for main plot indicators.
# Assumes 2 parameters, emashort and emalong to be specified.
f'ema_{self.emashort.value}': {'color': 'red'},
f'ema_{self.emalong.value}': {'color': '#CCCCCC'},
# By omitting color, a random color is selected.
'sar': {},
# fill area between senkou_a and senkou_b
'senkou_a': {
'color': 'green', #optional
'fill_to': 'senkou_b',
'fill_label': 'Ichimoku Cloud', #optional
'fill_color': 'rgba(255,76,46,0.2)', #optional
},
# plot senkou_b, too. Not only the area to it.
'senkou_b': {}
}
plot_config['subplots'] = {
# Create subplot MACD
"MACD": {
'macd': {'color': 'blue', 'fill_to': 'macdhist'},
'macdsignal': {'color': 'orange'},
'macdhist': {'type': 'bar', 'plotly': {'opacity': 0.9}}
},
# Additional subplot RSI
"RSI": {
'rsi': {'color': 'red'}
}
}

return plot_config
备注

The above configuration assumes that ema10, ema50, senkou_a, senkou_b, macd, macdsignal, macdhist and rsi are columns in the DataFrame created by the strategy.

注意

plotly arguments are only supported with plotly library and will not work with freq-ui.

Trade position adjustments

If position_adjustment_enable / adjust_trade_position() is used, the trade initial buy price is averaged over multiple orders and the trade start price will most likely appear outside the candle range.

Plot profit

plot-profit

The plot-profit subcommand shows an interactive graph with three plots:

  • Average closing price for all pairs.
  • The summarized profit made by backtesting. Note that this is not the real-world profit, but more of an estimate.
  • Profit for each individual pair.
  • Parallelism of trades.
  • Underwater (Periods of drawdown).

The first graph is good to get a grip of how the overall market progresses.

The second graph will show if your algorithm works or doesn't. Perhaps you want an algorithm that steadily makes small profits, or one that acts less often, but makes big swings.

This graph will also highlight the start (and end) of the Max drawdown period.

The third graph can be useful to spot outliers, events in pairs that cause profit spikes.

The forth graph can help you analyze trade parallelism, showing how often max_open_trades have been maxed out.

The -p/--pairs argument, can be used to limit the pairs that are considered for this calculation.

Examples:

Use custom backtest-export file

freqtrade plot-profit  -p LTC/BTC --export-filename user_data/backtest_results/backtest-result.json

Use custom database

freqtrade plot-profit  -p LTC/BTC --db-url sqlite:///tradesv3.sqlite --trade-source DB
freqtrade --datadir user_data/data/binance_save/ plot-profit -p LTC/BTC

Plot Configuration Examples

Basic Configuration

plot_config = {
'main_plot': {
'sma_20': {'color': 'blue'},
'ema_50': {'color': 'red'},
'bb_upperband': {'color': 'gray'},
'bb_lowerband': {'color': 'gray', 'fill_to': 'bb_upperband'},
},
'subplots': {
'RSI': {
'rsi': {'color': 'purple'}
}
}
}

Advanced Configuration with Multiple Subplots

@property
def plot_config(self):
return {
'main_plot': {
'sma_9': {'color': 'blue'},
'sma_21': {'color': 'orange'},
'sma_50': {'color': 'red'},
'bb_upperband': {'color': 'lightgray'},
'bb_lowerband': {'color': 'lightgray', 'fill_to': 'bb_upperband'},
},
'subplots': {
'MACD': {
'macd': {'color': 'blue'},
'macdsignal': {'color': 'red'},
'macdhist': {'type': 'bar', 'plotly': {'opacity': 0.7}}
},
'RSI': {
'rsi': {'color': 'purple'}
},
'Volume': {
'volume': {'type': 'bar', 'plotly': {'opacity': 0.5}}
}
}
}

Best Practices

Performance Tips

  • Limit the number of pairs when plotting
  • Use timerange to focus on specific periods
  • Consider using FreqUI for better performance
  • Avoid plotting too many indicators simultaneously

Visualization Tips

  • Use consistent colors across different plots
  • Group related indicators in subplots
  • Use fill areas for bands and channels
  • Keep main plot clean with price-related indicators only

Debugging Strategies

  • Plot entry/exit signals to verify strategy logic
  • Compare backtest results with actual trades
  • Use different timeframes to understand market context
  • Analyze correlation between indicators and price movements

Troubleshooting

Common Issues

  1. Missing indicators: Ensure indicators are calculated in populate_indicators()
  2. Performance issues: Reduce number of pairs or timerange
  3. Memory errors: Use smaller datasets or increase system memory
  4. Color conflicts: Specify explicit colors in plot_config

Alternative Solutions

  • Use FreqUI for real-time plotting
  • Export data and use external tools like TradingView
  • Create custom analysis scripts with matplotlib or plotly
  • Use Jupyter notebooks for interactive analysis