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
= 10
x # Float
= 3.14159
pi # String
= "Alice"
name # Boolean
= True flag
You can check types:
print(type(x), type(pi), type(name), type(flag))
# Arithmetic
= 7, 3
a, b print(a + b, a - b, a * b, a / b, a // b, a % b, a ** b)
# String concatenation & formatting
= "Hello"
greeting = greeting + ", " + name + "!"
msg print(msg)
print(f"{name} has {a} apples and {b} oranges.")
# List (mutable, ordered)
= ["apple", "banana", "cherry"]
fruits "date")
fruits.append(print(fruits[1], len(fruits))
# Tuple (immutable, ordered)
= ("red", "green", "blue")
colors # colors[0] = "purple" # ❌ Error
# Dict (mutable key→value map)
= {"name": "Bob", "age": 30}
person print(person["name"])
"age"] = 31
person[
# Set (mutable, unordered, unique)
= set([1,2,2,3])
unique 4)
unique.add(print(unique)
if
,
for
, while
# if/elif/else
= 5
n if n < 0:
print("Negative")
elif n == 0:
print("Zero")
else:
print("Positive")
# for loop
for fruit in fruits:
print(fruit.upper())
# while loop
= 3
count while count > 0:
print("Counting:", count)
-= 1 count
# 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
= np.array([1,2,3]) arr
Create your own module: save the above square
in
mymath.py
, then in another file:
from mymath import square
print(square(9))
pip
Keep 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 scipy
With your venv active, install:
pip install yfinance pandas numpy matplotlib openpyxl xlrd scipy
yfinance: market & financial statements
pandas: data tables & Excel I/O
numpy: numeric operations
matplotlib: plotting
openpyxl/xlrd: Excel support
scipy: stats (optional)
yfinance
import yfinance as yf
import pandas as pd
# Choose ticker
= yf.Ticker("AAPL")
ticker
# 3.1 Historical price data (1 year)
= ticker.history(period="1y")
hist print(hist.head())
# 3.2 Quarterly financials (income statement)
= ticker.quarterly_financials
q_fin print(q_fin)
# Save financials to Excel
with pd.ExcelWriter("AAPL_financials.xlsx") as writer:
="IncomeStmt_Q") q_fin.to_excel(writer, sheet_name
import pandas as pd
# Remove timezone info from the DatetimeIndex:
= hist.index.tz_localize(None)
hist.index
# Now you can write to Excel without error:
"AAPL_prices.xlsx", sheet_name="Prices")
hist.to_excel(
# Read single sheet
= pd.read_excel("AAPL_prices.xlsx", sheet_name="Prices", index_col=0)
df2 print(df2.tail())
# Read multiple sheets
= pd.ExcelFile("AAPL_financials.xlsx")
xls = pd.read_excel(xls, "IncomeStmt_Q", index_col=0) income
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
"Return"] = df2["Close"].pct_change()
df2["LogReturn"] = np.log(df2["Close"] / df2["Close"].shift(1))
df2[
# 5.2 Moving Averages & Bollinger Bands
"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[
# 5.3 Risk Metrics
= df2["Return"].std()
daily_vol = daily_vol * (252**0.5)
ann_vol = df2["Return"].mean() / daily_vol * (252**0.5)
sharpe print(f"Ann. Vol: {ann_vol:.2%}, Sharpe: {sharpe:.2f}")
# 5.4 Fundamental Ratios
= ticker.quarterly_balance_sheet
bs = bs.loc["Long Term Debt"]
long_debt = bs.get("Short Long Term Debt", pd.Series(0, index=bs.columns))
short_debt = long_debt + short_debt
debt = bs.loc["Stockholders Equity"]
equity = (debt / equity).dropna()
de_ratio print(de_ratio)
= bs.loc["Stockholders Equity"]
equity = (debt / equity).dropna()
de_ratio 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
=(10,5))
plt.figure(figsize"Close"], label="Close")
plt.plot(df2.index, df2["MA50"], label="50‑day MA")
plt.plot(df2.index, df2["BB_up"], df2["BB_dn"], alpha=0.3)
plt.fill_between(df2.index, df2["AAPL Price & Bollinger Bands")
plt.title(
plt.legend()
plt.tight_layout() plt.show()
## 7. Mini Backtest Example
# 7.1 Generate 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()
signals[
# 7.2 Plot signals
=(10,5))
plt.figure(figsize"Close"], label="Close")
plt.plot(df2["short_MA"], label="20‑day MA")
plt.plot(signals["long_MA"], label="50‑day MA")
plt.plot(signals[==1].index,
plt.plot(signals.loc[signals.positions"Close"][signals.positions==1], "^", markersize=10, label="Buy")
df2[==-1].index,
plt.plot(signals.loc[signals.positions"Close"][signals.positions==-1],"v", markersize=10, label="Sell")
df2["MA Crossover Signals")
plt.title(
plt.legend()
plt.tight_layout()
plt.show()
# 7.3 Compute P&L
= 100000.0
initial_capital = 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"]
portfolio[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!