Extracting and analyzing inventory knowledge is vital to knowledgeable decision-making within the monetary panorama. This tutorial presents a complete information to constructing an built-in monetary evaluation and reporting instrument in Python. We’ll study to tug historic market knowledge from Yahoo Finance and compute important technical indicators reminiscent of Easy Shifting Averages, Bollinger Bands, MACD, and RSI. The information walks you thru producing insightful visualizations and compiling them into customized multi-page PDF experiences. Whether or not you’re a knowledge fanatic, monetary analyst, or Python developer seeking to increase your toolkit, this tutorial will equip you with abilities that assist flip uncooked market knowledge into actionable insights.
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
We import important Python libraries for monetary knowledge evaluation and visualization. Right here, yfinance is used for fetching inventory market knowledge, pandas for knowledge manipulation, matplotlib and numpy for creating and dealing with numerical plots, and PdfPages for compiling a number of plots right into a single PDF report.
def compute_indicators(df):
"""
Computes technical indicators for the DataFrame:
- 20-day and 50-day Easy Shifting Averages (SMA)
- Bollinger Bands (utilizing 20-day SMA ±2 commonplace deviations)
- MACD (12-day EMA minus 26-day EMA) and its 9-day Sign Line
- RSI (Relative Energy Index) over a 14-day lookback interval
"""
df['SMA20'] = df['Close'].rolling(window=20).imply()
df['SMA50'] = df['Close'].rolling(window=50).imply()
df['STD20'] = df['Close'].rolling(window=20).std()
df['UpperBand'] = df['SMA20'] + 2 * df['STD20']
df['LowerBand'] = df['SMA20'] - 2 * df['STD20']
df['EMA12'] = df['Close'].ewm(span=12, modify=False).imply()
df['EMA26'] = df['Close'].ewm(span=26, modify=False).imply()
df['MACD'] = df['EMA12'] - df['EMA26']
df['Signal'] = df['MACD'].ewm(span=9, modify=False).imply()
delta = df['Close'].diff()
achieve = delta.copy()
loss = delta.copy()
achieve[gain < 0] = 0
loss[loss > 0] = 0
loss = loss.abs()
avg_gain = achieve.rolling(window=14).imply()
avg_loss = loss.rolling(window=14).imply()
rs = avg_gain / avg_loss
df['RSI'] = 100 - (100 / (1 + rs))
return df
This perform computes key technical indicators—together with SMAs, Bollinger Bands, MACD, and RSI—for inventory worth knowledge contained within the enter DataFrame. It updates the DataFrame with extra columns for every indicator, enabling in-depth technical evaluation of historic inventory efficiency.
def create_cover_page(pdf):
"""
Creates and saves a canopy web page into the PDF report.
"""
fig = plt.determine(figsize=(11.69, 8.27))
plt.axis('off')
plt.textual content(0.5, 0.7, "Monetary Evaluation Report", fontsize=24, ha="middle")
plt.textual content(0.5, 0.62, "Evaluation of 5 Shares from Yahoo Finance", fontsize=16, ha="middle")
plt.textual content(0.5, 0.5, "Consists of Technical Indicators: SMA, Bollinger Bands, MACD, RSI", fontsize=12, ha="middle")
plt.textual content(0.5, 0.4, "Generated with Python and matplotlib", fontsize=10, ha="middle")
pdf.savefig(fig)
plt.shut(fig)
This perform creates a visually interesting cowl web page utilizing matplotlib and provides it as the primary web page of the PDF report by way of the supplied PdfPages object. It then closes the determine to unlock assets.
def plot_price_chart(ticker, df):
"""
Generates a worth chart with SMA and Bollinger Bands for a given ticker.
"""
fig, ax = plt.subplots(figsize=(14, 7))
ax.plot(df.index, df['Close'], label="Shut Worth", linewidth=1.5)
ax.plot(df.index, df['SMA20'], label="SMA (20)", linewidth=1.2)
ax.plot(df.index, df['SMA50'], label="SMA (50)", linewidth=1.2)
ax.plot(df.index, df['UpperBand'], label="Higher Bollinger Band", linestyle="--")
ax.plot(df.index, df['LowerBand'], label="Decrease Bollinger Band", linestyle="--")
ax.fill_between(df.index, df['LowerBand'], df['UpperBand'], colour="lightgray", alpha=0.3)
ax.set_title(f'{ticker}: Worth & Shifting Averages with Bollinger Bands')
ax.set_xlabel('Date')
ax.set_ylabel('Worth')
ax.legend()
ax.grid(True)
return fig
This perform generates a complete inventory worth chart for a given ticker that features the shut worth, 20-day and 50-day SMAs, and the Bollinger Bands. It returns a matplotlib determine that may be saved or additional processed in a PDF report.
def plot_macd_chart(ticker, df):
"""
Generates a MACD plot for the given ticker.
"""
fig, ax = plt.subplots(figsize=(14, 5))
ax.plot(df.index, df['MACD'], label="MACD", linewidth=1.5)
ax.plot(df.index, df['Signal'], label="Sign Line", linewidth=1.5)
ax.set_title(f'{ticker}: MACD')
ax.set_xlabel('Date')
ax.set_ylabel('MACD')
ax.legend()
ax.grid(True)
return fig
This perform generates a MACD chart for a specified ticker by plotting the MACD and its Sign Line over time. It returns a matplotlib determine that may be included into a bigger PDF report or displayed independently.
def plot_rsi_chart(ticker, df):
"""
Generates an RSI plot for the given ticker.
"""
fig, ax = plt.subplots(figsize=(14, 5))
ax.plot(df.index, df['RSI'], label="RSI", linewidth=1.5)
ax.axhline(70, colour="purple", linestyle="--", linewidth=1, label="Overbought (70)")
ax.axhline(30, colour="inexperienced", linestyle="--", linewidth=1, label="Oversold (30)")
ax.set_title(f'{ticker}: RSI')
ax.set_xlabel('Date')
ax.set_ylabel('RSI')
ax.legend()
ax.grid(True)
return fig
This perform generates an RSI chart for a given inventory ticker, plotting the RSI values together with horizontal reference strains on the overbought (70) and oversold (30) ranges. It returns a matplotlib determine that may be included into the ultimate monetary evaluation report.
def fundamental():
tickers = []
for i in vary(5):
ticker = enter(f"Enter ticker #{i+1}: ").higher().strip()
tickers.append(ticker)
pdf_filename = "financial_report.pdf"
with PdfPages(pdf_filename) as pdf:
create_cover_page(pdf)
for ticker in tickers:
print(f"Downloading knowledge for {ticker} from Yahoo Finance...")
df = yf.obtain(ticker, interval='1y')
if df.empty:
print(f"No knowledge discovered for {ticker}. Skipping to the following ticker.")
proceed
df = compute_indicators(df)
fig_price = plot_price_chart(ticker, df)
pdf.savefig(fig_price)
plt.shut(fig_price)
fig_macd = plot_macd_chart(ticker, df)
pdf.savefig(fig_macd)
plt.shut(fig_macd)
fig_rsi = plot_rsi_chart(ticker, df)
pdf.savefig(fig_rsi)
plt.shut(fig_rsi)
print(f"PDF report generated and saved as '{pdf_filename}'.")
Right here, this fundamental perform prompts the consumer to enter 5 inventory tickers, downloads one yr of knowledge for every from Yahoo Finance, computes key technical indicators, and generates corresponding worth, MACD, and RSI charts. It then compiles all of the charts right into a multi‐web page PDF report named “financial_report.pdf” and prints a affirmation message as soon as the report is saved.
if __name__ == "__main__":
fundamental()
Lastly, this block checks whether or not the script is executed instantly quite than imported as a module. In that case, it calls the principle() perform.
In conclusion, we’ve got demonstrated a technique for automating monetary evaluation utilizing Python. You may have realized how you can extract precious knowledge, calculate key technical indicators, and generate complete visible experiences in a multi-page PDF format. This built-in method streamlines the evaluation course of and gives a strong method to visualize market traits and monitor inventory efficiency. As you additional customise and increase upon this framework, you’ll be able to proceed to boost your analytical capabilities and make extra knowledgeable monetary choices.
Right here is the Colab Notebook. Additionally, don’t neglect to observe us on Twitter and be a part of our Telegram Channel and LinkedIn Group. Don’t Overlook to affix our 85k+ ML SubReddit.

Sana Hassan, a consulting intern at Marktechpost and dual-degree scholar at IIT Madras, is keen about making use of expertise and AI to deal with real-world challenges. With a eager curiosity in fixing sensible issues, he brings a recent perspective to the intersection of AI and real-life options.