Lesson 4 · Finance and Stock Market Analytics
Financial Analytics Workflow Using Python: Step-by-Step Training for Beginners
This lesson demonstrates a hands-on workflow for analyzing real financial and stock market data using Python. The stock market is an essential economic…
- CourseFinance and Stock Market Analytics
- Lesson4 of 16
- Video26 min
- FormatJupyter notebook · 17 code cells
What you'll learn
Data
No separate download needed — the notebook creates or downloads everything it uses.
📓 Full notebook
Download .ipynbFinancial Analytics Workflow Using Python#
- This lesson demonstrates a hands-on workflow for analyzing real financial and stock market data using Python.
- The stock market is an essential economic engine, and analytics helps us identify trends, manage risks, and drive smart investment decisions.
- You will learn how to load, explore, and analyze real stock data, work with trading signals, handle financial fundamentals, and automate analytics tasksall with practical examples.
- Each step is broken down so that you understand both what the code does and why it matters for financial analysis.
import warnings
warnings.filterwarnings('ignore')
import pandas as pd
import numpy as np
import yfinance as yf
Financial data concepts you need to know#
- Most financial analytics problems involve tabular data: rows for time (or companies), columns for variables.
- Prices (like Open, High, Low, Close, Volume) are usually historical time series.
- Returns are percentage differences between prices over time, not raw values.
- Company data can be in 'wide' (one row per date, many columns for tickers) or 'long' (one row per date/ticker) format.
- Beginners often mix up price and returns, or mis-align data when merging different sources.
- Real-world data may have missing days, odd index types, or naming issuesalways inspect carefully before analysis.
# BEGINNER EXAMPLE 1: Download multi-ticker OHLCV stock data in long format
tickers = ['AAPL','MSFT','GOOGL','AMZN','TSLA']
ohlcv = yf.download(tickers, period='1y', auto_adjust=True, progress=False)
ohlcv = ohlcv.stack(future_stack=True).rename_axis(['Date','Ticker']).reset_index()
ohlcv.columns.name = None
print(ohlcv.shape)
print(ohlcv.head(3))
# BEGINNER EXAMPLE 2: Get closing prices in wide format
tickers = ['AAPL','MSFT','GOOGL','AMZN','TSLA']
df = yf.download(tickers, period='1y', auto_adjust=True, progress=False)
df = df['Close'].reset_index()
df.columns.name = None
print(df.shape)
print(df.head(3))
# BEGINNER EXAMPLE 3: Loading the S&P 500 companies master list
url = 'https://raw.githubusercontent.com/datasets/s-and-p-500-companies/main/data/constituents.csv'
sp500_companies = pd.read_csv(url)
print(sp500_companies.shape)
print(sp500_companies.head(3))
# INTERMEDIATE EXAMPLE 1: Compute daily percentage returns for SPY ETF
data = yf.download('SPY', period='2y', auto_adjust=True, progress=False)
spy = data[['Close', 'Volume']].reset_index()
spy.columns = ['date','price','volume']
spy['daily_return'] = (spy['price'].pct_change() * 100).round(4)
spy = spy.dropna().reset_index(drop=True)
print(spy.shape)
print(spy.head(3))
# INTERMEDIATE EXAMPLE 2: Pivoting multi-ticker OHLCV data to wide format for close prices
close_wide = ohlcv.pivot(index='Date', columns='Ticker', values='Close')
print(close_wide.shape)
print(close_wide.head(3))
# INTERMEDIATE EXAMPLE 3: Select and compare a single ticker from long format
aapl = ohlcv[ohlcv['Ticker'] == 'AAPL']
print(aapl.head(3))
# ADVANCED EXAMPLE 1: Compute moving averages and generate trading signals
data = yf.download('AAPL', period='1y', auto_adjust=True, progress=False)
df = data[['Close','Volume']].reset_index()
df.columns = ['date','close','volume']
df['sma20'] = df['close'].rolling(20).mean().round(2)
df['sma50'] = df['close'].rolling(50).mean().round(2)
df['signal'] = np.where(df['sma20'] > df['sma50'], 1, -1)
print(df.tail(3))
# ADVANCED EXAMPLE 2: Build a portfolio from 10 stocks and calculate percent gain
np.random.seed(42) # For reproducibility
tickers = ['AAPL','MSFT','GOOGL','AMZN','TSLA','NVDA','META','NFLX','JPM','JNJ']
sector_map = {'AAPL':'Tech','MSFT':'Tech','GOOGL':'Tech','AMZN':'Consumer',
'TSLA':'Auto','NVDA':'Tech','META':'Tech','NFLX':'Media',
'JPM':'Finance','JNJ':'Health'}
data = yf.download(tickers, period='1y', auto_adjust=True, progress=False)['Close']
rows = []
for tk in tickers:
buy = round(float(data[tk].iloc[0]), 2)
cur = round(float(data[tk].iloc[-1]), 2)
rows.append({'ticker': tk, 'shares': int(np.random.randint(5, 100)),
'buy_price': buy, 'cur_price': cur, 'sector': sector_map[tk]})
df_port = pd.DataFrame(rows)
df_port['gain_pct'] = np.round((df_port['cur_price'] - df_port['buy_price']) / df_port['buy_price'] * 100, 2)
print(df_port.head(3))
# ADVANCED EXAMPLE 3: Fetch real financial fundamentals for leading stocks
tickers = ['AAPL','MSFT','GOOGL','AMZN','TSLA','NVDA','META','JPM','JNJ','XOM','WMT','V']
rows = []
for tk in tickers:
info = yf.Ticker(tk).info
rows.append({
'ticker': tk,
'sector': info.get('sector', 'Unknown'),
'market_cap': info.get('marketCap'),
'pe_ratio': info.get('trailingPE'),
'eps': info.get('trailingEps'),
'profit_margin':info.get('profitMargins'),
'debt_equity': info.get('debtToEquity')
})
df_fund = pd.DataFrame(rows)
print(df_fund.head(3))
# ERROR HANDLING 1: What happens if a ticker is removed from S&P 500 list?
missing = sp500_companies[sp500_companies['Symbol'] == 'TWTR']
if missing.empty:
print('TWTR is not in the current S&P 500 list.')
else:
print(missing)
# ERROR HANDLING 2: Handling missing values when merging datasets
x = ohlcv.merge(sp500_companies, left_on='Ticker', right_on='Symbol', how='left')
n_missing = x['Security'].isna().sum()
print(f'Missing company matches: {n_missing}')
# ERROR HANDLING 3: Check for NaN in fundamentals and fill as needed
n_na = df_fund['debt_equity'].isna().sum()
print(f'{n_na} companies have missing debt-to-equity ratios.')
df_fund['debt_equity'] = df_fund['debt_equity'].fillna(-1)
# BEST PRACTICES: Always sort portfolios by percent gain before display
df_port_sorted = df_port.sort_values('gain_pct', ascending=False).reset_index(drop=True)
print(df_port_sorted.head(5))
# BEST PRACTICES: Always reset seeds if using simulated numbers
np.random.seed(42)
example_shares = np.random.randint(5, 100, size=5)
print("Random share example (should be reproducible):", example_shares)
# END-TO-END CASE: Analyze AAPL performance vs sector peers over one year
apple = ohlcv[ohlcv['Ticker'] == 'AAPL'].copy()
techs = ['AAPL', 'MSFT', 'GOOGL']
tech_df = ohlcv[ohlcv['Ticker'].isin(techs)]
apple['return'] = apple['Close'].pct_change() * 100
peers = tech_df.pivot(index='Date', columns='Ticker', values='Close')
peers_ret = peers.pct_change() * 100
avg_peer = peers_ret[['MSFT', 'GOOGL']].mean(axis=1)
import matplotlib.pyplot as plt
plt.figure(figsize=(10,4))
plt.plot(apple['Date'], apple['return'], label='AAPL daily return', alpha=0.6)
plt.plot(apple['Date'], avg_peer.values, label='MSFT/GOOGL mean', alpha=0.6)
plt.title('AAPL vs Tech Peer Daily Returns (1yr)')
plt.ylabel('% daily return')
plt.xlabel('Date')
plt.legend()
plt.tight_layout()
plt.show()
# BONUS: Export your end-to-end analysis as a CSV file for reporting
export_df = pd.DataFrame({'date': apple['Date'], 'aapl_return': apple['return'], 'peer_avg_return': avg_peer.values})
export_df.to_csv('aapl_vs_peers_returns.csv', index=False)
print('Exported CSV shape:', export_df.shape)
Congratulationsyou have completed the financial analytics workflow!#
- You have loaded real stock data, computed returns, built portfolios, worked with company fundamentals, handled common errors, and automated exports.
- With these techniques you are ready to tackle practical finance analytics tasks in Python.
- Practice with new data, adjust the code, and explore new ideas.
- Subscribe on YouTube for expert tips and full project walk-throughs.
Found this useful?
All lessons, notebooks and datasets here are free. If they helped you, a coffee keeps new lessons coming.



