Python for Investing
Learn Python from the beginning using financial examples. Every lesson works on prices, returns, positions or portfolios, and every code block on the page has been run.
38 lessons, about six hours in total. Start at Lesson 1 and work down. If you already write Python, start at the level that matches you.
- Beginner, 11 lessons, about 1.5 hours. Variables, arithmetic, lists, slicing, loops, conditions, functions, dictionaries and classes. Lesson 8 turns prices into returns.
- Intermediate, 14 lessons, about 2 hours. numpy and pandas: arrays, Series, DataFrames, loading a CSV, returns in one call, moving averages, lags, equity curves, grouping, joins and panels.
- Advanced, 13 lessons, about 2.5 hours. Moving averages and RSI, turning an indicator into a position, lagging the signal so it cannot see the future, trading costs, drawdown, Sharpe, a backtest in one function, and then the same job again using the
btandffnpackages.
By the end you can load a price file, build a signal from it, run a backtest that does not look ahead, and report what it earned after costs.
To check what stuck, the quiz draws ten questions at random from any level.
From Lesson 16 on, the lessons read a simulated prices.csv from disk. To fill the same table from a broker, connect Python to an Interactive Brokers paper account: the connection is read-only, and ib_async returns daily bars as a pandas DataFrame. How do I get market data into Python? covers the other sources and which one fits which test.
What is a variable in Python?
Name a price, a ticker and a share count, then value a position and a three-stock portfolio.
How do I do maths and print a result in Python?
Do arithmetic in Python and print the result with an f-string.
What are True and False in Python?
Compare two numbers, store the answer, and build a buy rule out of it.
What is a list in Python?
Hold many values under one name, count them, pick them out by position, and add new ones.
How do I slice a list in Python?
Slice a list with x[start:stop], and turn the last few closes into a moving average.
What is a for loop in Python?
Run the same lines once for every item in a list, and add the results up as you go.
What are if, elif and else in Python?
Pick one outcome with if, elif and else, and see how the order of the tests decides which one you get.
How do I turn prices into returns in Python?
Build a list of returns in a loop, then compound them into the return for the whole stretch.
What is a function in Python?
Give a calculation a name with def, feed it inputs, and get an answer back.
What is a dictionary in Python?
Map a key to a value, look it up by name, and use two dictionaries keyed by ticker to value a portfolio.
What is a class in Python?
Write your own class, build two objects from it, and read what self means on every line.
What is a NumPy array?
Hold many numbers in one array and do maths on all of them at once, without writing a loop.
How do I filter a NumPy array with a condition?
Turn a comparison into an array of True and False, use it to select elements, count them, and switch it into a position of 1 or 0.
What is a pandas Series?
Build a Series of closes, select by label and by position, and see arithmetic line up two price series on their dates.
What is a pandas DataFrame?
Build a table from a dictionary of lists, select columns from it, add a computed column, sort it, and filter its rows.
How do I load a CSV file with pandas read_csv?
Read a CSV into a DataFrame with pd.read_csv, parse the dates, and index the rows by date.
How do I compute returns in pandas with pct_change?
Turn a column of prices into a column of returns with pct_change, and handle the NaN it leaves in the first row.
Why is a NumPy array operation faster than a Python loop?
Time a Python loop against the same calculation written as one array operation, and see where the gap comes from.
How do I compute a moving average with pandas rolling?
Take the mean of the last n values at every row with .rolling(n).mean(), and put a 5-day and a 10-day average on a price column.
How do I use yesterday's value with pandas shift?
Move a column down one row with .shift(1) so every row can read the row above it.
How do I build an equity curve with pandas cumprod?
Turn a column of returns into the growth of one unit of money with (1 + r).cumprod().
How do I do the same thing per ticker with pandas groupby?
Split a stacked table into one group per ticker, run a calculation inside each group, and get the answers back.
How do I stack two tables with pandas concat?
Glue DataFrames together with pd.concat, top to bottom by default and side by side with axis=1.
How do I join two tables on a key with pandas merge?
Line two tables up on a shared column with pd.merge, and choose which rows survive with inner, left, right and outer.
What is a panel in pandas?
Put a date and a ticker in the index, pull out one date or one ticker, and switch between the long and wide shapes.
What is the difference between an SMA and an EMA in Python?
Compute a simple and an exponential moving average, and see how each one weights the past.
How do I compute RSI in Python?
Build the relative strength index from daily changes, Wilder smoothing, and the 0 to 100 formula.
How do I compute Bollinger bands in Python?
Draw a moving average with a band two standard deviations above and below it, and measure where the close sits inside that band.
How do I turn an indicator into a position in Python?
Read an indicator with a rule to get a signal, then lag the signal by one row to get the position you hold.
Why do I lag the signal in a Python backtest?
Shift a signal down one row so it sits in front of the return it earns, and see how much the total changes.
How do I charge trading costs in a Python backtest?
Charge a cost every time the position changes, using turnover = position.diff().abs() times a rate.
How do I compute a drawdown in Python?
Measure how far an equity curve sits below its own running peak, and how long it stays there.
How do I compute CAGR, volatility, Sharpe and Sortino in Python?
Compute CAGR, annualised volatility, Sharpe and Sortino on a return series, then put all of them in one function.
How do I put a backtest in one Python function?
Wrap the lag, the costs, the compounding and the metrics into one function that takes prices and a signal and hands back a table.
How do I test many backtest parameters at once in Python?
Run the backtest function once for every value in a list of parameters and collect the results in one table.
How do I bootstrap a Sharpe ratio in Python?
Resample a return series with replacement a few thousand times to see the range of Sharpe ratios the same data could have produced.
How do I backtest with the bt package in Python?
Run the Lesson 34 rule through the bt package and check its numbers against the hand built ones.
How do I get performance statistics with ffn in Python?
Call ffn.calc_stats on a price series to get CAGR, volatility, Sharpe, Sortino, drawdown and forty more, and check them against the ones you built by hand.