Fix create_cum_profit to work with trades that don't open on candle

opens
This commit is contained in:
Matthias 2019-10-28 14:24:12 +01:00
parent a74b941b72
commit dab4ab78fc
4 changed files with 17 additions and 11 deletions

View File

@ -150,15 +150,21 @@ def combine_tickers_with_mean(tickers: Dict[str, pd.DataFrame], column: str = "c
return df_comb return df_comb
def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str) -> pd.DataFrame: def create_cum_profit(df: pd.DataFrame, trades: pd.DataFrame, col_name: str,
timeframe: str) -> pd.DataFrame:
""" """
Adds a column `col_name` with the cumulative profit for the given trades array. Adds a column `col_name` with the cumulative profit for the given trades array.
:param df: DataFrame with date index :param df: DataFrame with date index
:param trades: DataFrame containing trades (requires columns close_time and profitperc) :param trades: DataFrame containing trades (requires columns close_time and profitperc)
:param col_name: Column name that will be assigned the results
:param timeframe: Timeframe used during the operations
:return: Returns df with one additional column, col_name, containing the cumulative profit. :return: Returns df with one additional column, col_name, containing the cumulative profit.
""" """
# Use groupby/sum().cumsum() to avoid errors when multiple trades sold at the same candle. from freqtrade.exchange import timeframe_to_minutes
df[col_name] = trades.groupby('close_time')['profitperc'].sum().cumsum() ticker_minutes = timeframe_to_minutes(timeframe)
# Resample to ticker_interval to make sure trades match candles
_trades_sum = trades.resample(f'{ticker_minutes}min', on='close_time')[['profitperc']].sum()
df.loc[:, col_name] = _trades_sum.cumsum()
# Set first value to 0 # Set first value to 0
df.loc[df.iloc[0].name, col_name] = 0 df.loc[df.iloc[0].name, col_name] = 0
# FFill to get continuous # FFill to get continuous

View File

@ -264,12 +264,12 @@ def generate_candlestick_graph(pair: str, data: pd.DataFrame, trades: pd.DataFra
def generate_profit_graph(pairs: str, tickers: Dict[str, pd.DataFrame], def generate_profit_graph(pairs: str, tickers: Dict[str, pd.DataFrame],
trades: pd.DataFrame) -> go.Figure: trades: pd.DataFrame, timeframe: str) -> go.Figure:
# Combine close-values for all pairs, rename columns to "pair" # Combine close-values for all pairs, rename columns to "pair"
df_comb = combine_tickers_with_mean(tickers, "close") df_comb = combine_tickers_with_mean(tickers, "close")
# Add combined cumulative profit # Add combined cumulative profit
df_comb = create_cum_profit(df_comb, trades, 'cum_profit') df_comb = create_cum_profit(df_comb, trades, 'cum_profit', timeframe)
# Plot the pairs average close prices, and total profit growth # Plot the pairs average close prices, and total profit growth
avgclose = go.Scatter( avgclose = go.Scatter(
@ -293,7 +293,7 @@ def generate_profit_graph(pairs: str, tickers: Dict[str, pd.DataFrame],
for pair in pairs: for pair in pairs:
profit_col = f'cum_profit_{pair}' profit_col = f'cum_profit_{pair}'
df_comb = create_cum_profit(df_comb, trades[trades['pair'] == pair], profit_col) 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}") fig = add_profit(fig, 3, df_comb, profit_col, f"Profit {pair}")
@ -382,9 +382,9 @@ def plot_profit(config: Dict[str, Any]) -> None:
) )
# Filter trades to relevant pairs # Filter trades to relevant pairs
trades = trades[trades['pair'].isin(plot_elements["pairs"])] trades = trades[trades['pair'].isin(plot_elements["pairs"])]
# Create an average close price of all the pairs that were involved. # Create an average close price of all the pairs that were involved.
# this could be useful to gauge the overall market trend # this could be useful to gauge the overall market trend
fig = generate_profit_graph(plot_elements["pairs"], plot_elements["tickers"], trades) fig = generate_profit_graph(plot_elements["pairs"], plot_elements["tickers"],
trades, config.get('ticker_interval', '5m'))
store_plot_file(fig, filename='freqtrade-profit-plot.html', 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=True)

View File

@ -130,7 +130,7 @@ def test_create_cum_profit(testdatadir):
cum_profits = create_cum_profit(df.set_index('date'), cum_profits = create_cum_profit(df.set_index('date'),
bt_data[bt_data["pair"] == 'POWR/BTC'], bt_data[bt_data["pair"] == 'POWR/BTC'],
"cum_profits") "cum_profits", timeframe="5m")
assert "cum_profits" in cum_profits.columns assert "cum_profits" in cum_profits.columns
assert cum_profits.iloc[0]['cum_profits'] == 0 assert cum_profits.iloc[0]['cum_profits'] == 0
assert cum_profits.iloc[-1]['cum_profits'] == 0.0798005 assert cum_profits.iloc[-1]['cum_profits'] == 0.0798005

View File

@ -234,7 +234,7 @@ def test_add_profit(testdatadir):
cum_profits = create_cum_profit(df.set_index('date'), cum_profits = create_cum_profit(df.set_index('date'),
bt_data[bt_data["pair"] == 'POWR/BTC'], bt_data[bt_data["pair"] == 'POWR/BTC'],
"cum_profits") "cum_profits", timeframe="5m")
fig1 = add_profit(fig, row=2, data=cum_profits, column='cum_profits', name='Profits') fig1 = add_profit(fig, row=2, data=cum_profits, column='cum_profits', name='Profits')
figure = fig1.layout.figure figure = fig1.layout.figure
@ -256,7 +256,7 @@ def test_generate_profit_graph(testdatadir):
) )
trades = trades[trades['pair'].isin(pairs)] trades = trades[trades['pair'].isin(pairs)]
fig = generate_profit_graph(pairs, tickers, trades) fig = generate_profit_graph(pairs, tickers, trades, timeframe="5m")
assert isinstance(fig, go.Figure) assert isinstance(fig, go.Figure)
assert fig.layout.title.text == "Freqtrade Profit plot" assert fig.layout.title.text == "Freqtrade Profit plot"