def test_extract_trades_of_period(): pair = "UNITTEST/BTC" timerange = TimeRange(None, 'line', 0, -1000) data = load_pair_history(pair=pair, ticker_interval='1m', datadir=None, timerange=timerange) # timerange = 2017-11-14 06:07 - 2017-11-14 22:58:00 trades = DataFrame( {'pair': [pair, pair, pair, pair], 'profit_percent': [0.0, 0.1, -0.2, -0.5], 'profit_abs': [0.0, 1, -2, -5], 'open_time': to_datetime([Arrow(2017, 11, 13, 15, 40, 0).datetime, Arrow(2017, 11, 14, 9, 41, 0).datetime, Arrow(2017, 11, 14, 14, 20, 0).datetime, Arrow(2017, 11, 15, 3, 40, 0).datetime, ], utc=True ), 'close_time': to_datetime([Arrow(2017, 11, 13, 16, 40, 0).datetime, Arrow(2017, 11, 14, 10, 41, 0).datetime, Arrow(2017, 11, 14, 15, 25, 0).datetime, Arrow(2017, 11, 15, 3, 55, 0).datetime, ], utc=True) }) trades1 = extract_trades_of_period(data, trades) # First and last trade are dropped as they are out of range assert len(trades1) == 2 assert trades1.iloc[0].open_time == Arrow(2017, 11, 14, 9, 41, 0).datetime assert trades1.iloc[0].close_time == Arrow(2017, 11, 14, 10, 41, 0).datetime assert trades1.iloc[-1].open_time == Arrow(2017, 11, 14, 14, 20, 0).datetime assert trades1.iloc[-1].close_time == Arrow(2017, 11, 14, 15, 25, 0).datetime
def analyse_and_plot_pairs(config: Dict[str, Any]): plot_elements = init_plotscript(config) trades = plot_elements['trades'] strategy = StrategyResolver(config).strategy pair_counter = 0 plots = [] 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}) trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(dataframe, trades_pair) plots.append( analyze_results(pair=pair, data=dataframe, trades=trades_pair, indicators1=parse_indicators( config['indicators1'] if 'indicators1' in config.keys() else None), indicators2=parse_indicators( config['indicators2'] if 'indicators2' in config.keys() else None))) logger.info('End of ploting process %s plots generated', pair_counter) return plots
def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame], trades: pd.DataFrame, timeframe: str, stake_currency: str) -> go.Figure: # Combine close-values for all pairs, rename columns to "pair" try: df_comb = combine_dataframes_with_mean(data, "close") except ValueError: raise OperationalException( "No data found. Please make sure that data is available for " "the timerange and pairs selected.") # Trim trades to available OHLCV data trades = extract_trades_of_period(df_comb, trades, date_index=True) if len(trades) == 0: raise OperationalException('No trades found in selected timerange.') # Add combined cumulative profit df_comb = create_cum_profit(df_comb, trades, 'cum_profit', timeframe) # Plot the pairs average close prices, and total profit growth avgclose = go.Scatter( x=df_comb.index, y=df_comb['mean'], name='Avg close price', ) fig = make_subplots(rows=5, cols=1, shared_xaxes=True, row_heights=[1, 1, 1, 0.5, 1], vertical_spacing=0.05, subplot_titles=[ "AVG Close Price", "Combined Profit", "Profit per pair", "Parallelism", "Underwater", ]) fig['layout'].update(title="Freqtrade Profit plot") fig['layout']['yaxis1'].update(title='Price') fig['layout']['yaxis2'].update(title=f'Profit {stake_currency}') fig['layout']['yaxis3'].update(title=f'Profit {stake_currency}') fig['layout']['yaxis4'].update(title='Trade count') fig['layout']['yaxis5'].update(title='Underwater Plot') fig['layout']['xaxis']['rangeslider'].update(visible=False) fig.update_layout(modebar_add=["v1hovermode", "toggleSpikeLines"]) fig.add_trace(avgclose, 1, 1) fig = add_profit(fig, 2, df_comb, 'cum_profit', 'Profit') fig = add_max_drawdown(fig, 2, trades, df_comb, timeframe) fig = add_parallelism(fig, 4, trades, timeframe) fig = add_underwater(fig, 5, trades) for pair in pairs: profit_col = f'cum_profit_{pair}' try: df_comb = create_cum_profit(df_comb, trades[trades['pair'] == pair], profit_col, timeframe) fig = add_profit(fig, 3, df_comb, profit_col, f"Profit {pair}") except ValueError: pass return fig
def analyse_and_plot_pairs(config: Dict[str, Any]): """ From arguments provided in cli: -Initialise backtest env -Get tickers data -Generate Dafaframes populated with indicators and signals -Load trades excecuted on same periods -Generate Plotly plot objects -Generate plot files :return: None """ exchange = ExchangeResolver(config.get('exchange', {}).get('name'), config).exchange strategy = StrategyResolver(config).strategy if "pairs" in config: pairs = config["pairs"].split(',') else: pairs = config["exchange"]["pair_whitelist"] # Set timerange to use timerange = Arguments.parse_timerange(config["timerange"]) ticker_interval = strategy.ticker_interval tickers = history.load_data( datadir=Path(str(config.get("datadir"))), pairs=pairs, ticker_interval=config['ticker_interval'], refresh_pairs=config.get('refresh_pairs', False), timerange=timerange, exchange=exchange, live=config.get("live", False), ) pair_counter = 0 for pair, data in tickers.items(): pair_counter += 1 logger.info("analyse pair %s", pair) tickers = {} tickers[pair] = data dataframe = generate_dataframe(strategy, tickers, pair) if config["trade_source"] == "DB": trades = load_trades_from_db(config["db_url"]) elif config["trade_source"] == "file": trades = load_backtest_data(Path(config["exportfilename"])) trades = trades.loc[trades['pair'] == pair] trades = extract_trades_of_period(dataframe, trades) fig = generate_graph( pair=pair, data=dataframe, trades=trades, indicators1=config["indicators1"].split(","), indicators2=config["indicators2"].split(",") ) generate_plot_file(fig, pair, ticker_interval) logger.info('End of ploting process %s plots generated', pair_counter)
def generate_profit_graph(pairs: str, data: Dict[str, pd.DataFrame], trades: pd.DataFrame, timeframe: str) -> go.Figure: # Combine close-values for all pairs, rename columns to "pair" df_comb = combine_dataframes_with_mean(data, "close") # Trim trades to available OHLCV data trades = extract_trades_of_period(df_comb, trades, date_index=True) if len(trades) == 0: raise OperationalException('No trades found in selected timerange.') # Add combined cumulative profit df_comb = create_cum_profit(df_comb, trades, 'cum_profit', timeframe) # Plot the pairs average close prices, and total profit growth avgclose = go.Scatter( x=df_comb.index, y=df_comb['mean'], name='Avg close price', ) fig = make_subplots(rows=3, cols=1, shared_xaxes=True, row_width=[1, 1, 1], vertical_spacing=0.05, subplot_titles=[ "AVG Close Price", "Combined Profit", "Profit per pair" ]) fig['layout'].update(title="Freqtrade Profit plot") fig['layout']['yaxis1'].update(title='Price') fig['layout']['yaxis2'].update(title='Profit') fig['layout']['yaxis3'].update(title='Profit') fig['layout']['xaxis']['rangeslider'].update(visible=False) fig.add_trace(avgclose, 1, 1) fig = add_profit(fig, 2, df_comb, 'cum_profit', 'Profit') fig = add_max_drawdown(fig, 2, trades, df_comb, timeframe) for pair in pairs: profit_col = f'cum_profit_{pair}' try: df_comb = create_cum_profit(df_comb, trades[trades['pair'] == pair], profit_col, timeframe) fig = add_profit(fig, 3, df_comb, profit_col, f"Profit {pair}") except ValueError: pass return fig
def load_and_plot_trades(config: Dict[str, Any]): """ From configuration provided - Initializes plot-script - Get candle (OHLCV) data - Generate Dafaframes populated with indicators and signals based on configured strategy - Load trades executed during the selected period - Generate Plotly plot objects - Generate plot files :return: None """ strategy = StrategyResolver.load_strategy(config) exchange = ExchangeResolver.load_exchange(config['exchange']['name'], config) IStrategy.dp = DataProvider(config, exchange) plot_elements = init_plotscript(config, list(exchange.markets), strategy.startup_candle_count) timerange = plot_elements['timerange'] trades = plot_elements['trades'] pair_counter = 0 for pair, data in plot_elements["ohlcv"].items(): pair_counter += 1 logger.info("analyse pair %s", pair) df_analyzed = strategy.analyze_ticker(data, {'pair': pair}) df_analyzed = trim_dataframe(df_analyzed, timerange) if not trades.empty: trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(df_analyzed, trades_pair) else: trades_pair = trades fig = generate_candlestick_graph( pair=pair, data=df_analyzed, trades=trades_pair, indicators1=config.get('indicators1', []), indicators2=config.get('indicators2', []), plot_config=strategy.plot_config if hasattr( strategy, 'plot_config') else {}) store_plot_file(fig, filename=generate_plot_filename( pair, config['timeframe']), directory=config['user_data_dir'] / 'plot') logger.info('End of plotting process. %s plots generated', pair_counter)
def analyse_and_plot_pairs(config: Dict[str, Any]): """ From configuration provided - Initializes plot-script - Get tickers data - Generate Dafaframes populated with indicators and signals based on configured strategy - Load trades excecuted during the selected period - Generate Plotly plot objects - Generate plot files :return: None """ strategy = StrategyResolver(config).strategy plot_elements = init_plotscript(config) trades = plot_elements['trades'] 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}) 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"], ) 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)
def test_extract_trades_of_period(testdatadir): pair = "UNITTEST/BTC" # 2018-11-14 06:07:00 timerange = TimeRange('date', None, 1510639620, 0) data = load_pair_history(pair=pair, timeframe='1m', datadir=testdatadir, timerange=timerange) trades = DataFrame({ 'pair': [pair, pair, pair, pair], 'profit_ratio': [0.0, 0.1, -0.2, -0.5], 'profit_abs': [0.0, 1, -2, -5], 'open_date': to_datetime([ Arrow(2017, 11, 13, 15, 40, 0).datetime, Arrow(2017, 11, 14, 9, 41, 0).datetime, Arrow(2017, 11, 14, 14, 20, 0).datetime, Arrow(2017, 11, 15, 3, 40, 0).datetime, ], utc=True), 'close_date': to_datetime([ Arrow(2017, 11, 13, 16, 40, 0).datetime, Arrow(2017, 11, 14, 10, 41, 0).datetime, Arrow(2017, 11, 14, 15, 25, 0).datetime, Arrow(2017, 11, 15, 3, 55, 0).datetime, ], utc=True) }) trades1 = extract_trades_of_period(data, trades) # First and last trade are dropped as they are out of range assert len(trades1) == 2 assert trades1.iloc[0].open_date == Arrow(2017, 11, 14, 9, 41, 0).datetime assert trades1.iloc[0].close_date == Arrow(2017, 11, 14, 10, 41, 0).datetime assert trades1.iloc[-1].open_date == Arrow(2017, 11, 14, 14, 20, 0).datetime assert trades1.iloc[-1].close_date == Arrow(2017, 11, 14, 15, 25, 0).datetime
def analyse_and_plot_pairs(config: Dict[str, Any]): """ From arguments provided in cli: -Initialise backtest env -Get tickers data -Generate Dafaframes populated with indicators and signals -Load trades excecuted on same periods -Generate Plotly plot objects -Generate plot files :return: None """ plot_elements = init_plotscript(config) trades = plot_elements['trades'] strategy = plot_elements["strategy"] 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}) 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"].split(","), indicators2=config["indicators2"].split(",")) store_plot_file(fig, filename=generate_plot_filename( pair, config['ticker_interval']), directory=config['user_data_dir'] / "plot") logger.info('End of ploting process %s plots generated', pair_counter)
def load_and_plot_trades(config: Dict[str, Any]): """ From configuration provided - Initializes plot-script - Get candle (OHLCV) data - Generate Dafaframes populated with indicators and signals based on configured strategy - Load trades excecuted during the selected period - Generate Plotly plot objects - Generate plot files :return: None """ strategy = StrategyResolver.load_strategy(config) plot_elements = init_plotscript(config) trades = plot_elements['trades'] pair_counter = 0 for pair, data in plot_elements["ohlcv"].items(): pair_counter += 1 logger.info("analyse pair %s", pair) df_analyzed = strategy.analyze_ticker(data, {'pair': pair}) trades_pair = trades.loc[trades['pair'] == pair] trades_pair = extract_trades_of_period(df_analyzed, trades_pair) fig = generate_candlestick_graph( pair=pair, data=df_analyzed, trades=trades_pair, indicators1=config.get("indicators1", []), indicators2=config.get("indicators2", []), plot_config=strategy.plot_config if hasattr( strategy, 'plot_config') else {}) 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)