Download Python (3.10+): https://python.org
IDE/Editor: VS Code, PyCharm Community, or JupyterLab
Jupyter (notebook REPL in browser):
pip install jupyterlab
jupyter lab# Integer
x = 10
# Float
pi = 3.14159
# String
name = "Alice"
# Boolean
flag = True You can check types:
print(type(x), type(pi), type(name), type(flag))# Arithmetic
a, b = 7, 3
print(a + b, a - b, a * b, a / b, a // b, a % b, a ** b)
# String concatenation & formatting
greeting = "Hello"
msg = greeting + ", " + name + "!"
print(msg)
print(f"{name} has {a} apples and {b} oranges.")# List (mutable, ordered)
fruits = ["apple", "banana", "cherry"]
fruits.append("date")
print(fruits[1], len(fruits))
# Tuple (immutable, ordered)
colors = ("red", "green", "blue")
# colors[0] = "purple" # ❌ Error
# Dict (mutable key→value map)
person = {"name": "Bob", "age": 30}
print(person["name"])
person["age"] = 31
# Set (mutable, unordered, unique)
unique = set([1,2,2,3])
unique.add(4)
print(unique)if,
for, while# if/elif/else
n = 5
if n < 0:
print("Negative")
elif n == 0:
print("Zero")
else:
print("Positive")
# for loop
for fruit in fruits:
print(fruit.upper())
# while loop
count = 3
while count > 0:
print("Counting:", count)
count -= 1# Define a function
def square(x):
"""Return x squared."""
return x * x
print(square(4))
# Importing modules
import math
print(math.sqrt(16))
# Aliasing
import numpy as np
arr = np.array([1,2,3])Create your own module: save the above square in
mymath.py, then in another file:
from mymath import square
print(square(9))pipKeep projects isolated:
# Create venv
python3 -m venv venv
# Activate (macOS/Linux)
source venv/bin/activate
# Activate (Windows PowerShell)
.\venv\Scripts\Activate.ps1
# Install packages
pip install pandas numpy matplotlib yfinance openpyxl xlrd scipyWith your venv active, install:
pip install yfinance pandas numpy matplotlib openpyxl xlrd scipyyfinance: market & financial statements
pandas: data tables & Excel I/O
numpy: numeric operations
matplotlib: plotting
openpyxl/xlrd: Excel support
scipy: stats (optional)
yfinanceimport yfinance as yf
import pandas as pd
# Choose ticker
ticker = yf.Ticker("AAPL")
# 3.1 Historical price data (1 year)
hist = ticker.history(period="1y")
print(hist.head())
# 3.2 Quarterly financials (income statement)
q_fin = ticker.quarterly_financials
print(q_fin)
# Save financials to Excel
with pd.ExcelWriter("AAPL_financials.xlsx") as writer:
q_fin.to_excel(writer, sheet_name="IncomeStmt_Q")import pandas as pd
# Remove timezone info from the DatetimeIndex:
hist.index = hist.index.tz_localize(None)
# Now you can write to Excel without error:
hist.to_excel("AAPL_prices.xlsx", sheet_name="Prices")
# Read single sheet
df2 = pd.read_excel("AAPL_prices.xlsx", sheet_name="Prices", index_col=0)
print(df2.tail())
# Read multiple sheets
xls = pd.ExcelFile("AAPL_financials.xlsx")
income = pd.read_excel(xls, "IncomeStmt_Q", index_col=0)This code snippet focuses on calculating various financial metrics
and ratios using the Apple stock data (ticker set to
“AAPL”) fetched earlier in the script. It leverages
the numpy and pandas libraries for numerical
computations and data manipulation.
import numpy as np
# 5.1 Returns
df2["Return"] = df2["Close"].pct_change()
df2["LogReturn"] = np.log(df2["Close"] / df2["Close"].shift(1))
# 5.2 Moving Averages & Bollinger Bands
df2["MA50"] = df2["Close"].rolling(50).mean()
df2["BB_up"] = df2["MA50"] + 2*df2["Close"].rolling(50).std()
df2["BB_dn"] = df2["MA50"] - 2*df2["Close"].rolling(50).std()
# 5.3 Risk Metrics
daily_vol = df2["Return"].std()
ann_vol = daily_vol * (252**0.5)
sharpe = df2["Return"].mean() / daily_vol * (252**0.5)
print(f"Ann. Vol: {ann_vol:.2%}, Sharpe: {sharpe:.2f}")
# 5.4 Fundamental Ratios
bs = ticker.quarterly_balance_sheet
long_debt = bs.loc["Long Term Debt"]
short_debt = bs.get("Short Long Term Debt", pd.Series(0, index=bs.columns))
debt = long_debt + short_debt
equity = bs.loc["Stockholders Equity"]
de_ratio = (debt / equity).dropna()
print(de_ratio)
equity = bs.loc["Stockholders Equity"]
de_ratio = (debt / equity).dropna()
print("Debt/Equity:\n", de_ratio) ### Returns Calculation
# 5.1 Returns
df2["Return"] = df2["Close"].pct_change()
df2["LogReturn"] = np.log(df2["Close"] / df2["Close"].shift(1))
df2["Return"] = df2["Close"].pct_change():
This line calculates the simple percentage change in the closing price
(Close) of the stock and stores it in a new column
called Return within the df2 DataFrame.df2["LogReturn"] = np.log(df2["Close"] / df2["Close"].shift(1)):
This line calculates the logarithmic return of the stock’s closing
price. Logarithmic returns are often preferred in financial analysis as
they have desirable statistical properties. The result is stored in
the LogReturn column of df2.# 5.2 Moving Averages & Bollinger Bands
df2["MA50"] = df2["Close"].rolling(50).mean()
df2["BB_up"] = df2["MA50"] + 2*df2["Close"].rolling(50).std()
df2["BB_dn"] = df2["MA50"] - 2*df2["Close"].rolling(50).std()
df2["MA50"] = df2["Close"].rolling(50).mean():
This calculates the 50-day moving average of the closing price and
stores it in the MA50 column. Moving averages help smooth
out price fluctuations and identify trends.df2["BB_up"] = df2["MA50"] + 2*df2["Close"].rolling(50).std():
This calculates the upper Bollinger Band by adding two standard
deviations to the 50-day moving average. Bollinger Bands are used to
identify potential overbought and oversold conditions.df2["BB_dn"] = df2["MA50"] - 2*df2["Close"].rolling(50).std():
This calculates the lower Bollinger Band by subtracting two standard
deviations from the 50-day moving average.# 5.3 Risk Metrics
daily_vol = df2["Return"].std()
ann_vol = daily_vol * (252**0.5)
sharpe = df2["Return"].mean() / daily_vol * (252**0.5)
print(f"Ann. Vol: {ann_vol:.2%}, Sharpe: {sharpe:.2f}")
daily_vol = df2["Return"].std(): This
line calculates the daily volatility (standard deviation) of the stock’s
returns.ann_vol = daily_vol * (252**0.5): This
line calculates the annualized volatility by scaling the daily
volatility, assuming 252 trading days in a year.sharpe = df2["Return"].mean() / daily_vol * (252**0.5):
This line calculates the Sharpe ratio, a measure of risk-adjusted
return. A higher Sharpe ratio generally indicates a better
investment.print(f"Ann. Vol: {ann_vol:.2%}, Sharpe: {sharpe:.2f}"):
This line prints the calculated annualized volatility and Sharpe ratio
to the console.# 5.4 Fundamental Ratios
bs = ticker.quarterly_balance_sheet
long_debt = bs.loc["Long Term Debt"]
short_debt = bs.get("Short Long Term Debt", pd.Series(0, index=bs.columns))
debt = long_debt + short_debt
equity = bs.loc["Stockholders Equity"]
de_ratio = (debt / equity).dropna()
print(de_ratio)
equity = bs.loc["Stockholders Equity"]
de_ratio = (debt / equity).dropna()
print("Debt/Equity:\n", de_ratio)
bs = ticker.quarterly_balance_sheet:
This line retrieves the quarterly balance sheet data for the chosen
ticker (Apple) and assigns it to the bs DataFrame.long_debt = bs.loc["Long Term Debt"]:
This extracts the “Long Term Debt” values from the balance sheet.short_debt = bs.get("Short Long Term Debt", pd.Series(0, index=bs.columns)):
This extracts “Short Long Term Debt” if available, otherwise creates a
series of 0s.debt = long_debt + short_debt: This
calculates the total debt by summing long-term and short-term debt.equity = bs.loc["Stockholders Equity"]:
This extracts the “Stockholders Equity” values from the balance
sheet.de_ratio = (debt / equity).dropna():
This calculates the debt-to-equity ratio and removes any missing values
(dropna()).print(de_ratio): This line prints the
calculated debt-to-equity ratio to the console.import matplotlib.pyplot as plt
plt.figure(figsize=(10,5))
plt.plot(df2.index, df2["Close"], label="Close")
plt.plot(df2.index, df2["MA50"], label="50‑day MA")
plt.fill_between(df2.index, df2["BB_up"], df2["BB_dn"], alpha=0.3)
plt.title("AAPL Price & Bollinger Bands")
plt.legend()
plt.tight_layout()
plt.show() ## 7. Mini Backtest Example
# 7.1 Generate signals
signals = pd.DataFrame(index=df2.index)
signals["short_MA"] = df2["Close"].rolling(20).mean()
signals["long_MA"] = df2["Close"].rolling(50).mean()
signals["signal"] = 0.0
signals["signal"][20:] = np.where(
signals["short_MA"][20:] > signals["long_MA"][20:], 1.0, 0.0
)
signals["positions"] = signals["signal"].diff()
# 7.2 Plot signals
plt.figure(figsize=(10,5))
plt.plot(df2["Close"], label="Close")
plt.plot(signals["short_MA"], label="20‑day MA")
plt.plot(signals["long_MA"], label="50‑day MA")
plt.plot(signals.loc[signals.positions==1].index,
df2["Close"][signals.positions==1], "^", markersize=10, label="Buy")
plt.plot(signals.loc[signals.positions==-1].index,
df2["Close"][signals.positions==-1],"v", markersize=10, label="Sell")
plt.title("MA Crossover Signals")
plt.legend()
plt.tight_layout()
plt.show()
# 7.3 Compute P&L
initial_capital = 100000.0
portfolio = pd.DataFrame(index=signals.index)
portfolio["holdings"] = signals["signal"] * df2["Close"]
portfolio["cash"] = initial_capital - (signals.positions * df2["Close"]).cumsum()
portfolio["total"] = portfolio["holdings"] + portfolio["cash"]
print("Total Return:", (portfolio["total"].iloc[-1]/initial_capital - 1))Total Return: -0.0001750782775878923
Experiment with more indicators: RSI, MACD, ATR
Explore backtesting frameworks: Backtrader, Zipline
Automate data pulls & notifications
Connect to broker APIs (Alpaca, Interactive Brokers)
With this primer + finance toolkit, you’ll be analyzing markets, building signals, and running simple backtests in no time. Happy coding!