I'm building a bot that analyzes my trades in the stock market. I have two axes, one plotting my trade orders, and one plotting the candlestick chart of the traded stock.
fig, (ax1, ax2) = plt.subplots(2)
# Plotting Trades
ax1.plot(...)
# Plotting Candlestick Chart
mpf.plot(stock.data, ax=ax2, type='candle')
ax2.set_title(f'Stock History of {stock.symbol}')
ax2.set_xlabel('Date')
ax2.set_ylabel('Price')
This works fine so far and plots the chart as envisioned.
However, I'd now like to add markers to the chart for when I entered and exited trades. To start simple, I took all the orders and put all dates and prices in separate lists, so that I could specify the X as the dates and Y as the prices.
# Plotting Orders
dates, prices = [], []
for key, order in broker.orders.items():
dates.append(order.date)
prices.append(order.price)
ax2.plot(dates, prices, 'o')
But instead, now the chart was completely gone and all I could see was the markers.
Even the dates are not showing up which is a bit confusing since I splitted up the dates in its own specific list so that the X-positions would still be correct.
Anyone who has an idea of what's going on here? Thanks beforehand.
It looks like mpf.plot(..., ax=ax2)
and ax2.plot(...)
override some important plot settings of each other. You should probably add your orders data with mplfinance.make_addplot() like this:
import mplfinance as mpf
import yfinance as yf
import matplotlib.pyplot as plt
import pandas as pd
# market data
df = yf.download("SPY", start="2024-02-13", end="2024-02-14", interval='1h')
# some fake data
d = {
'dates': ['2024-02-13 09:30:00', '2024-02-13 10:30:00', '2024-02-13 11:30:00', '2024-02-13 12:30:00', '2024-02-13 13:30:00', '2024-02-13 14:30:00', '2024-02-13 15:30:00'],
'prices': [493.5, 495.2, 495.8, 494.8, 492.0, 492.6, 493.0]
}
my_df = pd.DataFrame(data=d)
# show everything on one plot
fig, ax = plt.subplots()
my_dict = mpf.make_addplot(my_df['prices'], type='scatter', ax=ax)
mpf.plot(df,
ax=ax,
type="candle",
addplot=my_dict
)
plt.show()
The code produces the following image:
UPDATE
If your orders data is available only for some of the stock market timestamps, then you could make a combined dataframe with a price column having NaN
values in the rows, where orders data is "missing". In this way you would have two data frames of equal length, suitable to be shown on one plot with mpf.make_addplot()
and mpf.plot()
:
import mplfinance as mpf
import yfinance as yf
import matplotlib.pyplot as plt
import pandas as pd
# get market data
df = yf.download("SPY", start="2024-02-13", end="2024-02-14", interval="1h")
# make some fake data with the same time format as market data
my_prices = [493.5, 495.2, 495.8]
# these timestamps must be a subset of those from the market data
my_timestamps = pd.date_range("2024-02-13 09:30:00", periods=len(my_prices), freq="H", tz="America/New_York")
d = {
# this column must be named the same way as the column with timestamps from the market data
"Datetime": my_timestamps,
"Prices": my_prices
}
my_df = pd.DataFrame(data=d)
# merge data sets, resulting in a new column with prices, where prices for missing market dates are NaN
combined_df = df.merge(my_df, how="outer", on="Datetime")
# show everything on one plot
fig, ax = plt.subplots()
my_dict = mpf.make_addplot(combined_df["Prices"], type="scatter", color="red", ax=ax)
mpf.plot(df,
ax=ax,
type="candle",
addplot=my_dict
)
plt.show()
Here is the result: