Calculating Indicators

Indicators are numeric values that are calculated from raw price and/or financial data. When doing a vectorized backtest, we append a column onto the pandas dataframe for each indicator that we are calculating. The name of the column will be the ticker, plus a colon, then the name of the indicator. So for example, a 10 period moving average for AAPL may have a column name such as "AAPL:MA-10".

Each indicator is implemented as a function which takes the price dataframe, and just appends the calculated indicator onto the dataframe. The prices are assumed to follow the standard format where the ticker is first, then a colon, and then the type of price. For example, "AAPL:Close" represents the closing price of Apple.

Example Indicator - Moving Average

def moving_average(df, column, size, name): df[name] = df[column].rolling(window=size).mean() pass def moving_averages(df, tickers, sizes): for ticker in tickers: for mav in sizes: moving_average(df, ticker+':Close',mav, ticker+':MA'+str(mav)) pass pass for mav in sizes: filtered = filter(lambda x:x>mav, sizes) for top in filtered: for ticker in tickers: df[ticker+':MA'+str(mav)+'-MA'+str(top)] = df[ticker+':MA'+str(mav)] - df[ticker+':MA'+str(top)] pass pass pass pass

Full Sample Code

import numpy as np import pandas as pd def moving_average(df, column, size, name): df[name] = df[column].rolling(window=size).mean() pass def moving_averages(df, tickers, sizes): for ticker in tickers: for mav in sizes: moving_average(df, ticker+':Close',mav, ticker+':MA'+str(mav)) pass pass for mav in sizes: filtered = filter(lambda x:x>mav, sizes) for top in filtered: for ticker in tickers: df[ticker+':MA'+str(mav)+'-MA'+str(top)] = df[ticker+':MA'+str(mav)] - df[ticker+':MA'+str(top)] pass pass pass pass def returns(df, tickers, periods): for ticker in tickers: df[ticker+':Log-Close'] = np.log(df[ticker+':Close']) for period in periods: df[ticker+':Return_Period='+str(period)] = df[ticker+':Close'].pct_change(periods=period) df[ticker+':Log-Diff_Period='+str(period)] = df[ticker+':Log-Close'].diff(periods=1) pass def volatilities(df, tickers, sizes=[]): for ticker in tickers: df[ticker+':Return'] = df[ticker+':Close'].pct_change(periods=1) df[ticker+':Volatility'] = df[ticker+':Return'] * df[ticker+':Return'] for vol in sizes: for ticker in tickers: df[ticker+':Volatility_Ewma'+str(vol)] = df[ticker+':Volatility'].ewm(span=vol, adjust=False).mean() for ticker in tickers: for vol in sizes: df[ticker+':Vol_Pct'+str(vol)] = df[ticker+':Volatility']/df[ticker+':Volatility_Ewma'+str(vol)] pass