How to Create a Stock Chart in Python

In today’s data-driven world, visualizing stock data is a crucial skill for investors, traders, and data enthusiasts. Python, with its powerful libraries, makes it easy to fetch and visualize stock data in an interactive and insightful way. I’ll walk you through a Python project that fetches stock data using the yfinance library and creates an interactive candlestick chart using plotly. I’ll also show you how to enhance the project with additional features like volume data, moving averages, and more.

Why Visualize Stock Data?

Stock charts are more than just lines and candles—they tell a story. Candlestick charts, in particular, provide a wealth of information about price movements, trends, and market sentiment. By visualizing stock data, you can:

  • Identify trends and patterns.
  • Make informed trading decisions.
  • Analyze historical performance.
  • Communicate insights effectively.

With Python, you can automate this process and create professional-quality visualizations in minutes.

Fetching and Visualizing Stock Data

The goal of this project is to create an interactive candlestick chart for a user-specified stock ticker. We’ll use the yfinance library to fetch historical stock data and the plotly library to create the chart. Along the way, I’ll explain each step and add practical enhancements to make the tool more versatile.

Setting Up the Environment

Before we start coding, we need to install the required libraries. Run the following command to install yfinance and plotly:

!pip install yfinance plotly
  • yfinance: A popular library for fetching stock data from Yahoo Finance.
  • plotly: A powerful library for creating interactive visualizations.

Importing Libraries

Next, we import the necessary libraries:

import yfinance as yf
import plotly.graph_objects as go
  • yfinance is imported as yf for fetching stock data.
  • plotly.graph_objects is imported as go for creating the candlestick chart.

Fetching Stock Data

We’ll prompt the user to input a stock ticker symbol (e.g., “AAPL” for Apple) and specify a date range for the data:

ticker = input("Enter stock name: ")
start_date = input("Enter start date (YYYY-MM-DD): ")
end_date = input("Enter end date (YYYY-MM-DD): ")

# Fetch stock data
try:
    data = yf.download(ticker, start=start_date, end=end_date)
    if data.empty:
        raise ValueError("No data found for the given ticker or date range.")
except Exception as e:
    print(f"Error: {e}")
    exit()
  • The yf.download() function fetches historical stock data for the specified ticker and date range.
  • We’ve added error handling to ensure the program doesn’t crash if the ticker or date range is invalid.

Creating the Candlestick Chart

Now, let’s create the candlestick chart using plotly:

fig = go.Figure(data=[go.Candlestick(
    x=data.index,
    open=data['Open'], high=data['High'],
    low=data['Low'], close=data['Close'],
    increasing_line_color='green',
    decreasing_line_color='red',
    name="Candlesticks"
)])
  • The go.Candlestick class is used to create the chart.
  • Green candlesticks indicate price increases, and red candlesticks indicate price decreases.

Enhancing the Chart

To make the chart more informative, we’ll add the following features:

Volume Data

Volume is a key indicator of market activity. We’ll add a bar chart for trading volume below the candlestick chart:

fig.add_trace(go.Bar(
    x=data.index,
    y=data['Volume'],
    name="Volume",
    marker_color='blue',
    yaxis="y2"
))

Moving Averages

Moving averages help identify trends. We’ll calculate and plot the 50-day and 200-day moving averages:

data['MA50'] = data['Close'].rolling(window=50).mean()
data['MA200'] = data['Close'].rolling(window=200).mean()

fig.add_trace(go.Scatter(
    x=data.index,
    y=data['MA50'],
    line=dict(color='orange', width=1),
    name="50-Day MA"
))

fig.add_trace(go.Scatter(
    x=data.index,
    y=data['MA200'],
    line=dict(color='purple', width=1),
    name="200-Day MA"
))

Custom Layout

We’ll update the chart layout to include titles and axis labels:

fig.update_layout(
    title=f"{ticker} Stock Price ({start_date} to {end_date})",
    xaxis_title="Date",
    yaxis_title="Stock Price (USD)",
    yaxis2=dict(title="Volume", overlaying="y", side="right"),
    xaxis_rangeslider_visible=False
)

Displaying and Saving the Chart

Finally, we’ll display the chart and give the user the option to save it as an interactive HTML file:

fig.show()

save_option = input("Do you want to save the chart as an HTML file? (y/n): ").lower()
if save_option == 'y':
fig.write_html(f"{ticker}_stock_chart.html")
print(f"Chart saved as {ticker}_stock_chart.html"

Final Enhanced Code

Here’s the complete code with all the enhancements:

# Install required libraries
!pip install yfinance plotly

# Import necessary libraries
import yfinance as yf
import plotly.graph_objects as go

# Get user input for the stock ticker
ticker = input("Enter stock name: ")
start_date = input("Enter start date (YYYY-MM-DD): ")
end_date = input("Enter end date (YYYY-MM-DD): ")

# Download stock data
try:
    data = yf.download(ticker, start=start_date, end=end_date)
    if data.empty:
        raise ValueError("No data found for the given ticker or date range.")
except Exception as e:
    print(f"Error: {e}")
    exit()

# Create a candlestick chart
fig = go.Figure(data=[go.Candlestick(
    x=data.index,
    open=data['Open'], high=data['High'],
    low=data['Low'], close=data['Close'],
    increasing_line_color='green',
    decreasing_line_color='red',
    name="Candlesticks"
)])

# Add additional features
print("Select additional features:")
print("1. Add Volume")
print("2. Add Moving Averages")
print("3. Both")
choice = input("Enter your choice (1/2/3): ")

if choice in ['1', '3']:
    fig.add_trace(go.Bar(
        x=data.index,
        y=data['Volume'],
        name="Volume",
        marker_color='blue',
        yaxis="y2"
    ))

if choice in ['2', '3']:
    data['MA50'] = data['Close'].rolling(window=50).mean()
    data['MA200'] = data['Close'].rolling(window=200).mean()
    fig.add_trace(go.Scatter(
        x=data.index,
        y=data['MA50'],
        line=dict(color='orange', width=1),
        name="50-Day MA"
    ))
    fig.add_trace(go.Scatter(
        x=data.index,
        y=data['MA200'],
        line=dict(color='purple', width=1),
        name="200-Day MA"
    ))

# Update the chart layout
fig.update_layout(
    title=f"{ticker} Stock Price ({start_date} to {end_date})",
    xaxis_title="Date",
    yaxis_title="Stock Price (USD)",
    yaxis2=dict(title="Volume", overlaying="y", side="right"),
    xaxis_rangeslider_visible=False
)

# Show the chart
fig.show()

# Save the chart as an HTML file
save_option = input("Do you want to save the chart as an HTML file? (y/n): ").lower()
if save_option == 'y':
    fig.write_html(f"{ticker}_stock_chart.html")
    print(f"Chart saved as {ticker}_stock_chart.html")

Final Thoughts

This project demonstrates how Python can be used to fetch and visualize stock data in a powerful and user-friendly way. By adding features like volume data, moving averages, and error handling, we’ve created a tool that’s both practical and insightful.

Related blog posts