
Candlestick Charts with Color Zones in Python
To understand tendencies, prices to buy and sell on any crypto or stock a candlestick charts is well regarded. Several tools allows the analyst to see the chart and to draw almost anything on them. That’s great!
The issue arises when we want to make something similar programmatically.
On this article I will be showing how I generate a chart with some lines on it and how to store it as an image using the power of Python.
Fetching the data
First we need the data.
We will be using Yahoo Finance to get the OHLC (Open High Low Close) data.
We can always can go to the Yahoo Finance site and download the file containing the data. But there is already a library to do that, let’s use it!
pip3 install yfinance
Then our code should look this:
import yfinance
# Fetching the BTC data from Yahoo Finance
data = yfinance.download('BTC-USD', period='6mo')
# Print some rows of the data
print(data.head())
and we got:
[*********************100%***********************] 1 of 1 completed Open High ... Adj Close Volume Date ... 2023-07-30 29357.093750 29443.169922 ... 29275.308594 8678454527 2023-07-31 29278.314453 29489.873047 ... 29230.111328 11656781982 2023-08-01 29230.873047 29675.732422 ... 29675.732422 18272392391 2023-08-02 29704.146484 29987.998047 ... 29151.958984 19212655598 2023-08-03 29161.812500 29375.707031 ... 29178.679688 12780357746 [5 rows x 6 columns]
It’s looking we got data in the data
variable. Let’s create an image with the mplfinance
library:
pip3 install mplfinance
Then we add the following lines to get a candlestick chart:
import mplfinance as fplt
import os
filesvg = os.path.join("/tmp/BTC6mo.png")
fplt.plot(
data,
type='candle',
style='yahoo',
title= "BTC-USD, daily",
ylabel='Price ($)',
volume=False,
ylabel_lower='Shares\nTraded',
savefig=filesvg
)
The filesvg
variable stores the absolute path to the file, here the path is hardwired and complete but maybe you want to use this platform agnostic then you should use:
filesvg = os.path.join("root_folder", "folder2",..., "BTC6mo.png")
Our case will look like this:
filesvg = os.path.join("/","tmp","BTC6mo.png")
The following lines makes the plot figure and save it to filesvg
the plot
function takes as arguments the OHLCV data, what type of chart (e.i.: candle, renko, line), the style, labels, title if the volume is going to be represented and finally the savefig
argument with the path to the image file.
Important: If you forget to change the name path between runs it will override the file with a new version.
If you go to your /tmp
folder you will see the BTC6mo.png
file:

No lets add a horizontal dashed line marking a price:
import numpy as np
entry=41000
signals = [fplt.make_addplot(np.full(len(data),entry), color="blue", linestyle='-', alpha=0.4, label='Entry: '+str(entry))]
filesvg = os.path.join("/tmp/BTC6mo3.png")
fplt.plot(
data,
type='candle',
style='yahoo',
title= "BTC-USD, daily",
ylabel='Price ($)',
volume=False,
ylabel_lower='Shares\nTraded',
addplot=signals,
savefig=filesvg
)
And the file is now BTC6mo3.png
at \tmp
. It looks like this:

Note that signals
was added to the plot before the savefig
using the property addplot
.
signals
is an array of addplot
created by the fplt.make_addplot
function. Receiving as parameters the data (a list of numbers), the color, the style, the transparency (alpha
) and the label for the legend.
The addition of the numpy
library facilitates the creation of a vector of number equal to entry
by using np.full(len(data), entry)
.
Lets add Stop Loss and Limit
limitPrice=42000
stopPrice=40000
signals = [fplt.make_addplot(np.full(len(data),entry), color="blue", linestyle='-', alpha=0.4, label='Entry: '+str(entry)),
fplt.make_addplot(np.full(len(data),limitPrice), color="green", linestyle='--', alpha=0.4, label='Limit: '+str(limitPrice)),
fplt.make_addplot(np.full(len(data),stopPrice), color="red", linestyle='-.', alpha=0.4, label='Stop Loss: '+str(stopPrice))]
filesvg = os.path.join("/tmp/BTC6mo4.png")
fplt.plot(
data,
type='candle',
style='yahoo',
title= "BTC-USD, daily",
ylabel='Price ($)',
volume=False,
ylabel_lower='Shares\nTraded',
addplot=signals,
savefig=filesvg
)
Now BTC6mo4.png
should look like this:

As you can see I added two more plots for the Limit and the Stop Loss Now I want to color the space between the Entry and the Limit with green and between Entry and the Stop Loss with red to signify a bullish and a bearish outcome respectively.
signals = [fplt.make_addplot(np.full(len(data),entry), color="blue", linestyle='-', alpha=0.4, label='Entry: '+str(entry)),
fplt.make_addplot(np.full(len(data),limitPrice), color="green", linestyle='--', alpha=0.4, fill_between=dict(y1=limitPrice, y2=entry, color='green', alpha=0.3), label='Limit: '+str(limitPrice)),
fplt.make_addplot(np.full(len(data),stopPrice), color="red", linestyle='-.', alpha=0.4, fill_between=dict(y1=stopPrice, y2=entry, color='red', alpha=0.3), label='Stop Loss: '+str(stopPrice))]
filesvg = os.path.join("/tmp/BTC6mo5.png")
fplt.plot(
data,
type='candle',
style='yahoo',
title= "BTC-USD, daily",
ylabel='Price ($)',
volume=False,
ylabel_lower='Shares\nTraded',
addplot=signals,
savefig=filesvg
)
Taking a look to BTC6mo5.png

The magic here was done using fill_between
taking a dict
with the y1
and y2
as the limits of the filling, color, an also transparency ( alpha
).
Just for fun lets change the Limit and the Stop Loss:
limitPrice = 49000
stopPrice = 38000
signals = [fplt.make_addplot(np.full(len(data),entry), color="blue", linestyle='-', alpha=0.4, label='Entry: '+str(entry)),
fplt.make_addplot(np.full(len(data),limitPrice), color="green", linestyle='--', alpha=0.4, fill_between=dict(y1=limitPrice, y2=entry, color='green', alpha=0.3), label='Limit: '+str(limitPrice)),
fplt.make_addplot(np.full(len(data),stopPrice), color="red", linestyle='-.', alpha=0.4, fill_between=dict(y1=stopPrice, y2=entry, color='red', alpha=0.3), label='Stop Loss: '+str(stopPrice))]
filesvg = os.path.join("/tmp/BTC6mo6.png")
fplt.plot(
data,
type='candle',
style='yahoo',
title= "BTC-USD, daily",
ylabel='Price ($)',
volume=False,
ylabel_lower='Shares\nTraded',
addplot=signals,
savefig=filesvg
)

Conclusion
On this article we show how to create images files of candlestick charts using Python. The complete code is this:
import yfinance
import mplfinance as fplt
import numpy as np
import os
# Fetching the BTC data from Yahoo Finance
data = yfinance.download('BTC-USD', period='6mo')
print(data.head())
limitPrice=49000
entry=41000
stopPrice=38000
signals = [fplt.make_addplot(np.full(len(data),entry), color="blue", linestyle='-', alpha=0.4, label='Entry: '+str(entry)),
fplt.make_addplot(np.full(len(data),limitPrice), color="green", linestyle='--', alpha=0.4, fill_between=dict(y1=limitPrice, y2=entry, color='green', alpha=0.3), label='Limit: '+str(limitPrice)),
fplt.make_addplot(np.full(len(data),stopPrice), color="red", linestyle='-.', alpha=0.4, fill_between=dict(y1=stopPrice, y2=entry, color='red', alpha=0.3), label='Stop Loss: '+str(stopPrice))]
filesvg = os.path.join("/tmp/BTC6mo7.png")
fplt.plot(
data,
type='candle',
style='yahoo',
title= "BTC-USD, daily",
ylabel='Price ($)',
volume=False,
ylabel_lower='Shares\nTraded',
addplot=signals,
savefig=filesvg
)
If you find value in this article, please consider clapping and following (or maybe inviting me to a cup of coffee?). Thank you!
Disclaimer: This article is for educational purposes and does not constitute financial advice. Trading carries risks, and it’s essential to consult with a financial professional before making any trading decisions.
Stackademic
Thank you for reading until the end. Before you go: