Source code for tradingstrategy.analysis.profitdistribution
"""Show histograms how many trades were profitable or not.
.. warning ::
This module is deprecated and replaced by tradeexecutor analysis modules.
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as pyplot
from matplotlib.axes import SubplotBase
from matplotlib.axes._base import _AxesBase
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.container import BarContainer
from matplotlib.figure import Figure
[docs]def plot_trade_profit_distribution(df: pd.DataFrame, bins=25, cap_profit=1.1, vmin=-1, vmax=0.5) -> Figure:
"""Create a histogram of won and lost trades based on trade analyzer expanded timeline output.
See also :py:meth:`tradingstrategy.analysis.tradeanalyizer.expand_timeline`.
:param df: A DataFrame with a column `PnL % raw`
:param cap_profit: If profit is higher than this, cap the value so that one off mega profits to not break the diagram
"""
colormap: LinearSegmentedColormap = pyplot.cm.get_cmap("RdYlGn")
df = df[["PnL % raw"]].clip(-1, cap_profit)
# A single successfuk trade might be something like 400% or 4.0
max_profit_pct = df["PnL % raw"].max()
min_profit_pct = df["PnL % raw"].min()
# https://stackoverflow.com/questions/23061657/plot-histogram-with-colors-taken-from-colormap
Y: np.array
X: np.array
# https://numpy.org/doc/stable/reference/generated/numpy.histogram.html
# Always adjust left X to -100% or trade lost all money
Y, X = np.histogram(df, bins, range=(min_profit_pct, max_profit_pct))
x_span = X.max() - X.min()
C = []
for x in X:
# Map x back to the range -100% to 100% - 100% is the max green.
# Do not directly use the x co-ordinate on the bar diagram for the color
# as middle is not zero
# CLip
profit_clipped = min(vmax, x)
profit_clipped = max(vmin, profit_clipped)
green_percent = profit_clipped / (vmax - vmin)
colormap_adjusted = green_percent/2 + 0.5 # 0 ... 1.0
c = colormap(colormap_adjusted)
# print(c, x, profit_pct, X.min(), x_span)
C.append(c)
fig: Figure
ax: _AxesBase
fig, ax = pyplot.subplots()
# https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.bar.html
bar_container: BarContainer = ax.bar(
x=X[:-1],
height=Y,
color=C,
width=X[1] - X[0])
xtick_labels = [f"{x:.0%}" for x in ax.get_xticks()]
ax.set_xlabel("Trade profit %")
ax.set_ylabel("Number of trades")
ax.set_xticklabels(xtick_labels)
ax.set_title("Trade won/lost distribution")
# Retina!
fig.set_dpi(600)
return fig