https://levelup.gitconnected.
com/replicating-tradingview-chart-in-python-8bb6ff00bb4e
Search Medium
Write
Get unlimited access to the best of Medium for less than $1/week.
Become a member
Image by Author
Replicating TradingView Chart
in Python
With as less than 3 lines of code
Nikhil Adithyan
·
Follow
Published in
Level Up Coding
9 min read
Aug 2
350
5
I’ve always been a huge fan of TradingView’s charting tool,
especially for its beautifully crafted user interface and
design. And there’s never been a day I haven’t thought
about recreating the graph design in Python.
But, it’s always tough for Python developers to create
stunning and professional-looking visualizations (like
TradingView) using libraries like Matplotlib, Seaborn,
Altair, etc. Their style themes are so outdated and crappy.
Though all these modules provide features for customizing
the theme of the charts, it takes a toll on the developer as
there is a lot of work involved.
Fortunately, I recently came across an awesome library
called lightweight-charts-python providing features to easily
re-create the TradingView style with minimal code. In this
article, we will dive deep into this library, explore its
features, and code some cool TradingView charts in
Python.
Importing Packages
The first and foremost step of setting up the coding
environment is to import the required packages. In this
article, we are going to use five different packages which
are pandas for data manipulation, and requests for making
API calls, numpy for numerical
calculations, lightweight_chart for replicating the
TradingView look, time for time-related functions, and
finally asyncio and nest_asyncio for asynchronous
programming. The following code will import all the
mentioned packages into our Python environment:
import pandas as pd
import requests
import numpy as np
from lightweight_charts import Chart
import time
import asyncio
import nest_asyncio
nest_asyncio.apply()
If you haven’t installed any of the imported packages,
make sure to do so using the pip command in your
terminal. Before moving further, for extracting the data,
we’ll be using the APIs of FinancialModelingPrep. So for
the smooth execution of the upcoming code block, you
need to have an FMP developer account which you can
easily create using the link here.
Obtaining Data using FMP
In this section, we will use the stock historical data
endpoint provided by FMP to attain Apple’s price history.
This can be easily done by using the following code:
api_key = 'YOUR API KEY'
hist_json =
requests.get(f'https://financialmodelingprep.com/api/v3/historical-price-
full/AAPL?apikey={api_key}').json()
hist_df = pd.DataFrame(hist_json['historical']).drop('label', axis = 1)
hist_df = hist_df.iloc[::-1].reset_index().drop(['index','adjClose'], axis
= 1)
hist_df.date = pd.to_datetime(hist_df.date)
hist_df = hist_df.iloc[:,:6].iloc[-365:]
hist_df.columns = ['time', 'open', 'high', 'low', 'close', 'volume']
hist_df.tail()
In the above code, we are first storing the secret API key in
a variable (remember to replace YOUR API KEY with your
actual secret key), and then, using the get provided by the
Requests package, we are extracting the historical data of
Apple. We are then converting the JSON response into a
Pandas dataframe, and after performing some data
manipulation, this is the final output:
Image by Author
In the code, the reason for changing the column names is
that lightweight_charts demands a specific naming structure
to plot the data. Now that we are having adequate data to
work with, let’s make some cool visualizations.
TradingView Charts
In this section, we are going to dive deep into
the lightweight_charts module and explore the exciting
possibilities. Let’s start off with a basic graph in the style
of TradingView. Here’s the code to generate a
TradingView graph using the library:
chart = Chart()
chart.set(hist_df)
chart.show(block = False)
It just takes as less as three lines of code for creating a
graph in the look of TradingView’s charting platform. And
the code is very straightforward in nature. We are first
creating an instance of the class Chart and assigned it to
the chart variable. Then using the set function, we are
setting the data of the chart. Finally, we are displaying the
created chart with the help of the show function. This is the
resulting graph of the code:
A basic TradingView-style replication
This output is absolutely stunning for a program of three
lines of code. But people who are disappointed at the
output after viewing the thumbnail of this article, don't
worry! Because now, we are going to up the game by
customizing the whole theme of the plot, adding more
details, and simply, making it even more beautiful. Here’s
the code to do that:
chart = Chart()
chart.grid(vert_enabled = True, horz_enabled = True)
chart.layout(background_color='#131722', font_family='Trebuchet MS',
font_size = 16)
chart.candle_style(up_color='#2962ff', down_color='#e91e63',
border_up_color='#2962ffcb',
border_down_color='#e91e63cb',
wick_up_color='#2962ffcb', wick_down_color='#e91e63cb')
chart.volume_config(up_color='#2962ffcb', down_color='#e91e63cb')
chart.title('AAPL')
chart.legend(visible = True, font_family = 'Trebuchet MS', ohlc = True,
percent = True)
##########################################################################
###########
chart.set(hist_df)
sma20_line = chart.create_line(color = '#ffeb3b', width = 1, price_label =
True)
sma20 = pd.DataFrame(columns = ['time', 'value'])
sma20.time = hist_df.time
sma20.value = hist_df.close.rolling(window = 20).mean()
sma20_line.title('SMA 20')
sma20_line.set(sma20.dropna(), name = 'value')
sma50_line = chart.create_line(color = '#26c6da', width = 1, price_label =
True)
sma50 = pd.DataFrame(columns = ['time', 'value'])
sma50.time = hist_df.time
sma50.value = hist_df.close.rolling(window = 50).mean()
sma50_line.title('SMA 50')
sma50_line.set(sma50.dropna(), name = 'value')
chart.show(block = False)
The code might not be as shorter as the previous one for
the basic plot, but it’s actually very simple. And for easy
explanation, I’ve divided the code into two separate parts.
The first part is about theme customization. It includes
changing the background color, the colors of the candles
and volume bars, and so on. Basically, the things related to
the style of the plot are dealt with in the first part. The
second part is about adding details to the plot. The details
we are adding here are the SMA 20 and SMA 50 lines.
Here’s the final output:
An advanced TradingView-style replication
This is absolutely fantastic! We fully customized the whole
look and feel of the plot and added more details like SMA
lines and legends for a more insightful graph.
Now let’s move our focus from historical graphs to another
cool feature provided by the lightweight_charts library which
is the real-time charting feature. Real-time charts are
extremely useful for day traders to keep track of the latest
price movements and TradingView is most preferred for
such charts. Just like how we replicated the historical
charts of TradingView, let’s do the same thing for real-time
charts too. This is the code to create a real-time
TradingView chart:
rt_df1 = hist_df[:150]
rt_df2 = hist_df[150:]
rt_chart = Chart()
rt_chart.set(rt_df1)
rt_chart.show(block = False)
for i, series in rt_df2.iterrows():
rt_chart.update(series)
time.sleep(0.1)
In this code, we are not actually using the real-time data of
stock prices but rather simulating it using the previously
extracted historical data. But you can use actual real-time
data with the help of FMP’s real-time stock price data
endpoint. We are first splitting the historical data into two
separate dataframes. The first one is used as the initial
data for the plot and the second one is used as the real-
time data which is done by updating the data points of the
plot with the help of a for-loop. This is the final output:
A basic TradingView-style real-time chart
Pretty cool, right?! But like how there was a lot of scope
for improvements in the basic historical graph, this real-
time chart can also be improved and modified in a lot of
places. We can first change the theme of the plot and
similar to how we added SMA lines to the historical chart
for better insights, we can add more details for an
informative visualization. Here’s the code for the modified
or advanced version of the initial real-time chart:
hist_df['SMA9'] = hist_df.close.rolling(window = 9).mean()
hist_df['SMA12'] = hist_df.close.rolling(window = 12).mean()
hist_df = hist_df.dropna()
rt_df1 = hist_df[:25]
rt_df2 = hist_df[25:]
rt_chart = Chart()
rt_chart.grid(vert_enabled = True, horz_enabled = True)
rt_chart.layout(background_color='#131722', font_family='Trebuchet MS',
font_size = 16)
rt_chart.candle_style(up_color='#2962ff', down_color='#e91e63',
border_up_color='#2962ffcb',
border_down_color='#e91e63cb',
wick_up_color='#2962ffcb', wick_down_color='#e91e63cb')
rt_chart.volume_config(up_color='#2962ffcb', down_color='#e91e63cb')
rt_chart.legend(visible = True, font_family = 'Trebuchet MS', ohlc = True,
percent = True)
rt_chart.fit()
##########################################################################
###########
rt_chart.set(rt_df1)
sma9_line = rt_chart.create_line(color = '#ffeb3b')
sma9_line.set(rt_df1, name = 'SMA9')
sma12_line = rt_chart.create_line(color = '#26c6da')
sma12_line.set(rt_df1, name = 'SMA12')
rt_chart.show(block = False)
p_sma9, p_sma12 = rt_df1.iloc[-1]['SMA9'], rt_df1.iloc[-1]['SMA12']
for i, series in rt_df2.iterrows():
rt_chart.update(series)
sma9_series, sma12_series = series[['time','SMA9']],
series[['time','SMA12']]
sma9_series.index, sma12_series.index = ['time','value'],
['time','value']
sma9_line.update(sma9_series)
sma12_line.update(sma12_series)
c_sma9, c_sma12 = sma9_series['value'], sma12_series['value']
if p_sma9 < p_sma12 and c_sma9 > c_sma12:
rt_chart.marker(text = 'Buy Signal', position = 'below', shape =
'arrow_up', color = '#33de3d')
elif p_sma9 > p_sma12 and c_sma9 < c_sma12:
rt_chart.marker(text = 'Sell Signal', position = 'above', shape =
'arrow_down', color = '#f485fb')
p_sma9, p_sma12 = c_sma9, c_sma12
time.sleep(0.1)
The code can be a little overwhelming but I’ll try to break
down and simplify it. Like how we did with the advanced
historical graph, we are splitting the code into two
sections. The first section is about calculating the SMA
values and customizing the theme of the chart. The second
section is all about simulating real-time data and plotting
the data points using a for-loop. To up the game, we are
also plotting trading signals generated using a technical
strategy alongside real-time data.
In a nutshell, the style adopted in this code is the same as
we used in the historical graph and so are the details like
the SMA lines. But what we are additionally doing here is
that we are plotting the buy and sell signals generated by a
simple SMA crossover strategy in real time. And here’s the
final result:
An advanced TradingView-style real-time chart
This is freaking awesome! It’s a cool application in and of
itself. Speaking of applications, our charts are great but
they are not fully interactive and do not take any input
from the user. Now, let’s solve this problem with the help
of some amazing components provided
by lightweight_charts for interactivity. Here’s the code to
create an interactive graph:
def fetch_data(symbol):
api_key = 'YOUR API KEY'
hist_json =
requests.get(f'https://financialmodelingprep.com/api/v3/historical-price-
full/AAPL?apikey={api_key}').json()
hist_df = pd.DataFrame(hist_json['historical']).drop('label', axis =
1)
hist_df = hist_df.iloc[::-1].reset_index().drop(['index','adjClose'],
axis = 1)
hist_df.date = pd.to_datetime(hist_df.date)
hist_df = hist_df.iloc[:,:6].iloc[-365:]
hist_df.columns = ['time', 'open', 'high', 'low', 'close', 'volume']
return hist_df
class API:
def __init__(self):
self.chart = None
async def on_symbol_selection(self):
new_data = fetch_data(self.chart.topbar['symbol'].value)
if new_data.empty:
return
self.chart.set(new_data)
async def main():
api = API()
chart = Chart(api = api, topbar = True)
chart.legend(visible = True, font_family = 'Trebuchet MS')
chart.fit()
chart.topbar.switcher('symbol', api.on_symbol_selection, 'META',
'AAPL', 'AMZN', 'MSFT', 'GOOGL', default='AAPL')
df = fetch_data('AAPL')
chart.set(df)
await chart.show_async(block = True)
if __name__ == '__main__':
asyncio.run(main())
To be honest, there are quite some complex things
happening in this code like using asyncio for asynchronous
programming but the goal here is not to understand each
and every single line of code but to get a glimpse of the
interactive components provided by the module and how it
can be used to elevate our visualizations. This is the result
generated by the above code:
Interactive TradingView-style chart
This is just a very basic example of integrating interactive
components into our charts. There are still plenty of
options and components to significantly improve the whole
look and feel of the chart and it is highly recommended to
check them out.
Closing Notes
In this article, we explored an interesting library
called lightweight_charts which helps in creating financial
visualizations in the look of TradingView with as less code
as possible. We went from generating a basic historical
graph to real-time and interactive charts and during the
process, we experimented with different components
provided by the library.
It’s really great to see the scope of Python expanding day
by day. I was aware of the Lightweight chart API provided
by TradingView a while ago but I couldn’t actually use it
since it demanded coding knowledge in other languages.
But now, I was able to achieve a great-looking
TradingView chart in Python using just three lines of code.
Finally, a huge shoutout to FinancialModelingPrep for
creating such a great and reliable platform for accessing
various types of financial data ranging from fundamental
data to ESG and sentiment scores of securities. With that
being said, you’ve reached the end of the article. Hope you
learned something new.
Level Up Coding
Thanks for being a part of our community! Before you go:
👏 Clap for the story and follow the author 👉
📰 View more content in the Level Up Coding
publication
🔔 Follow us: Twitter | LinkedIn | Newsletter
🧠 AI Tools ⇒ Become an AI prompt engineer
Technology
Data Science
Python
Programming
Finance
350
5
Written by Nikhil Adithyan
2.9K Followers
·Writer for
Level Up Coding
Founder @BacktestZone (https://www.backtestzone.com/), a no-code backtesting platform |
Top Writer | Connect with me on LinkedIn: https://bit.ly/3yNuwCJ
Follow
More from Nikhil Adithyan and Level Up Coding
Nikhil Adithyan
in
DataDrivenInvestor
Stock Price Prediction with ChatGPT and Finazon
A fully AI-driven approach to predicting the stock prices
13 min read·May 26
384
12
Sanjay Priyadarshi
in
Level Up Coding
I Spent 30 Days Studying A Programmer Who Built a $230
Billion Company After Quitting His 9–5 —…
Steal This Programmer Blueprint
·13 min read·Aug 7
1.1K
10
Prathamesh Gadekar
in
Level Up Coding
Python Libraries for Lazy Data Scientists
Do you feel lethargic today? Use these five libraries to boost your productivity.
7 min read·Apr 8
1.1K
4
Nikhil Adithyan
in
Level Up Coding
A Step-By-Step Guide to Implementing the SuperTrend
Indicator in Python
Learn to build a powerful trading strategy with the SuperTrend indicator in python
26 min read·May 29, 2021
227
See all from Nikhil Adithyan
See all from Level Up Coding
Recommended from Medium
Prajjwal Chauhan
Stock Prediction and Forecasting Using LSTM(Long-Short-
Term-Memory)
In an ever-evolving world of finance, accurately predicting stock market movements
has long been an elusive goal for investors and traders…
6 min read·Jul 8
77
4
Constantin Picoron
How I ended up building a quantitative trading algorithm
without a data science degree
For the past 20 month or so, I’ve been building a quantitative trading algorithm in
Python by myself. It’s been quite a journey, and here…
6 min read·Mar 20
Lists
Coding & Development
11 stories·129 saves
Predictive Modeling w/ Python
20 stories·316 saves
ChatGPT
21 stories·125 saves
ChatGPT prompts
24 stories·303 saves
Rupe Dodkins
Full Control Options Backtesting on Historical Data (Without
Paying for Offline Options Data)
Welcome back! As you might remember from my last article, I introduced “Options
Backtest,” a new Python package that empowers us to perform…
5 min read·Jun 21
chatgpt-writer
Utilizing Volume-Weighted Average Price (VWAP) for Informed
Trading Strategies
In the dynamic world of financial markets, traders are continually seeking innovative
tools to gain a competitive edge and improve their…
3 min read·Jul 24
1
Michael May
Deep Learning and Stock Time Series Data
Using Univariate LSTM and CNN-LSTM models to predict stock prices
10 min read·Apr 23
3
martin vizzolini
in
Coinmonks
How to Beat the Stock Market with Maths: A Dual Strategy
Approach
Is it possible to discover a foolproof winning strategy? What if we could
simultaneously bet on red and black in a casino roulette while…
11 min read·Jul 27
See more recommendations
Help
Status
Writers
Blog
Careers
Privacy
Terms
About
Text to speech
Teams