TrendFollowing in Python
Below is a step by step walkthrough of a trend following system. The full text of the system can be found in our set of sample systems (and is copied below).
To begin we import numpy (a fundamental package for numerical computing) and define 'myTradingSystem', the function the toolbox looks for the evaluate the trading logic.
### Quantiacs Trend Following Trading System Example
# import necessary Packages below:
import numpy
def myTradingSystem(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings):
''' This system uses trend following techniques to allocate capital into the desired equities'''
nMarkets=CLOSE.shape[1]
Within, 'myTradingSystem', the strategy evaluates two averages over time of the close over a long/short time scale. It then determines whether or not to enter, exit, or short a market based on the comparison of the long/short term moving averages. In this sense the strategy 'follows the trend'. If a market has a significant upward trend, then follow the trend and go long in the market. If it lacks this trend, short the market. To start, the lenght of the two moving averages is defined.
periodLong=200
periodShort=40
The two simple moving averages are then calculated. That is, the sum of the values within the time-period divided by the length of the time-frame.
smaLong=numpy.nansum(CLOSE[-periodLong:,:],axis=0)/periodLong
smaRecent=numpy.nansum(CLOSE[-periodShort:,:],axis=0)/periodShort
Here the strategy decides whether to go long or to short a market. If the recent moving average is above the long-term moving average, then go long, otherwise short the market.
longEquity= numpy.array(smaRecent > smaLong)
shortEquity= ~longEquity
Finally, define the positions. Equal weight is placed on each market across the long/short positions.
pos=numpy.zeros((1,nMarkets))
pos[0,longEquity]=1
pos[0,shortEquity]=-1
Determine the weights of the positions and return the values and settings.
weights = pos/numpy.nansum(abs(pos))
return weights, settings
defining evaluation settings
With the logic of the trading algorithm defined, we look at evaluation settings. Within the function, 'mySettings', you define a dict of the markets you wish to trade, the time-period you wish to evaluate over, the lookback period you wish to include in your data, your budget and slippage settings.
def mySettings():
''' Define your trading system settings here '''
settings= {}
# S&P 100 stocks
# settings['markets']=['CASH','AAPL','ABBV','ABT','ACN','AEP','AIG','ALL',
# 'AMGN','AMZN','APA','APC','AXP','BA','BAC','BAX','BK','BMY','BRKB','C',
# 'CAT','CL','CMCSA','COF','COP','COST','CSCO','CVS','CVX','DD','DIS','DOW',
# 'DVN','EBAY','EMC','EMR','EXC','F','FB','FCX','FDX','FOXA','GD','GE',
# 'GILD','GM','GOOGL','GS','HAL','HD','HON','HPQ','IBM','INTC','JNJ','JPM',
# 'KO','LLY','LMT','LOW','MA','MCD','MDLZ','MDT','MET','MMM','MO','MON',
# 'MRK','MS','MSFT','NKE','NOV','NSC','ORCL','OXY','PEP','PFE','PG','PM',
# 'QCOM','RTN','SBUX','SLB','SO','SPG','T','TGT','TWX','TXN','UNH','UNP',
# 'UPS','USB','UTX','V','VZ','WAG','WFC','WMT','XOM']
# Futures Contracts
settings['markets'] = ['CASH','F_AD', 'F_BO', 'F_BP', 'F_C', 'F_CC', 'F_CD',
'F_CL', 'F_CT', 'F_DX', 'F_EC', 'F_ED', 'F_ES', 'F_FC','F_FV', 'F_GC',
'F_HG', 'F_HO', 'F_JY', 'F_KC', 'F_LB', 'F_LC', 'F_LN', 'F_MD', 'F_MP',
'F_NG', 'F_NQ', 'F_NR', 'F_O', 'F_OJ', 'F_PA', 'F_PL', 'F_RB', 'F_RU',
'F_S','F_SB', 'F_SF', 'F_SI', 'F_SM', 'F_TU', 'F_TY', 'F_US','F_W', 'F_XX',
'F_YM']
# settings['beginInSample'] = '20120506'
# settings['endInSample'] = '20150506'
settings['lookback']= 504
settings['budget']= 10**6
settings['slippage']= 0.05
return settings
Strategy Evaluation
With the trading logic and settings defined, it's now time to evaluate the system. Within the same file, the code snippet below will evaluate your trading system and return the results in a plot. From here, all you have to is runt your trading system file from the command line -- "python /path/to/trading_system.py"
if __name__ = "__main__":
import quantiacsToolbox
results = quantiacsToolbox.runts('path/to/trading_system.py')
The Full STrategy
### Quantiacs Trend Following Trading System Example
# import necessary Packages below:
import numpy
def myTradingSystem(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings):
''' This system uses trend following techniques to allocate capital into the desired equities'''
nMarkets=CLOSE.shape[1]
periodLong=200
periodShort=40
smaLong=numpy.nansum(CLOSE[-periodLong:,:],axis=0)/periodLong
smaRecent=numpy.nansum(CLOSE[-periodShort:,:],axis=0)/periodShort
longEquity= numpy.array(smaRecent > smaLong)
shortEquity= ~longEquity
pos=numpy.zeros((1,nMarkets))
pos[0,longEquity]=1
pos[0,shortEquity]=-1
weights = pos/numpy.nansum(abs(pos))
return weights, settings
def mySettings():
''' Define your trading system settings here '''
settings= {}
# S&P 100 stocks
# settings['markets']=['CASH','AAPL','ABBV','ABT','ACN','AEP','AIG','ALL',
# 'AMGN','AMZN','APA','APC','AXP','BA','BAC','BAX','BK','BMY','BRKB','C',
# 'CAT','CL','CMCSA','COF','COP','COST','CSCO','CVS','CVX','DD','DIS','DOW',
# 'DVN','EBAY','EMC','EMR','EXC','F','FB','FCX','FDX','FOXA','GD','GE',
# 'GILD','GM','GOOGL','GS','HAL','HD','HON','HPQ','IBM','INTC','JNJ','JPM',
# 'KO','LLY','LMT','LOW','MA','MCD','MDLZ','MDT','MET','MMM','MO','MON',
# 'MRK','MS','MSFT','NKE','NOV','NSC','ORCL','OXY','PEP','PFE','PG','PM',
# 'QCOM','RTN','SBUX','SLB','SO','SPG','T','TGT','TWX','TXN','UNH','UNP',
# 'UPS','USB','UTX','V','VZ','WAG','WFC','WMT','XOM']
# Futures Contracts
settings['markets'] = ['CASH','F_AD', 'F_BO', 'F_BP', 'F_C', 'F_CC', 'F_CD',
'F_CL', 'F_CT', 'F_DX', 'F_EC', 'F_ED', 'F_ES', 'F_FC','F_FV', 'F_GC',
'F_HG', 'F_HO', 'F_JY', 'F_KC', 'F_LB', 'F_LC', 'F_LN', 'F_MD', 'F_MP',
'F_NG', 'F_NQ', 'F_NR', 'F_O', 'F_OJ', 'F_PA', 'F_PL', 'F_RB', 'F_RU',
'F_S','F_SB', 'F_SF', 'F_SI', 'F_SM', 'F_TU', 'F_TY', 'F_US','F_W', 'F_XX',
'F_YM']
# settings['beginInSample'] = '20120506'
# settings['endInSample'] = '20150506'
settings['lookback']= 504
settings['budget']= 10**6
settings['slippage']= 0.05
return settings
if __name__ == "__main__":
import quantiacsToolbox
results = quantiacsToolbox.runts(__file__)
TRENDFOLLOWING in Matlab
Below is a step by step walkthrough of a trend following system using the Matlab toolbox. The full text of the system can be found in our set of sample systems (and is copied below).
To start, we define the trend following function and set the settings for our trading system. In this case, the function is call 'trendfollowing' and the settings are Quantiacs' futures markets, a lookback of 504 days, and a sample range of the beginning of our data (01-01-1991) to the end of 2013.
function [p, settings] = trendfollowing(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings)
settings.markets = {'CASH', 'F_AD', 'F_BO', 'F_BP', 'F_C', 'F_CC', 'F_CD', 'F_CL', 'F_CT', 'F_DX', 'F_EC', 'F_ED', 'F_ES', 'F_FC', 'F_FV', 'F_GC', 'F_HG', 'F_HO', 'F_JY', 'F_KC', 'F_LB', 'F_LC', 'F_LN', 'F_MD', 'F_MP', 'F_NG', 'F_NQ', 'F_NR', 'F_O', 'F_OJ', 'F_PA', 'F_PL', 'F_RB', 'F_RU', 'F_S', 'F_SB', 'F_SF', 'F_SI', 'F_SM', 'F_TU', 'F_TY', 'F_US', 'F_W', 'F_XX', 'F_YM'};
settings.sampleend = 20131231;
settings.lookback = 504;
nMarkets = size(CLOSE,2);
This strategy evaluates two averages over time of the close over a long/short time scale. It then determines whether or not to enter, exit, or short a market based on the comparison of the long/short term moving averages. In this sense the strategy 'follows the trend'. If a market has a significant upward trend, then follow the trend and go long in the market. If it lacks this trend, short the market. Below, we define the lengh ot the moving averages.
periodLong = 200;
periodRecent = 40;
In calculating the simple moving average, we sum the values within the time-frame and divide by the length of the time-frame.
smaLong = sum(CLOSE(end-periodLong+1:end,:)) / periodLong;
smaRecent = sum(CLOSE(end-periodRecent+1:end,:)) / periodRecent;
Here the strategy decides whether to go long or to short a market. If the recent moving average is above the long-term moving average, then go long, otherwise short the market.
long = smaRecent >= smaLong;
short = smaRecent < smaLong
Define the positions. Equal weight is placed on each market across the long/short positions. Determine the weights of the positions.
p = zeros(1, nMarkets);
p(long) = 1;
p(short) = -1;
p = p ./nansum(abs(p)
STRATEGY EVALUATION
To evaluate the strategy, with both the quantiacs Toolbox and your trading system in your Matlab Path, simply run the following command in the Matlab Command Window.
results = runts('trading_system_name')
THE FULL STRATEGY
function [p, settings] = trendfollowing(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings)
settings.markets = {'CASH', 'F_AD', 'F_BO', 'F_BP', 'F_C', 'F_CC', 'F_CD', 'F_CL', 'F_CT', 'F_DX', 'F_EC', 'F_ED', 'F_ES', 'F_FC', 'F_FV', 'F_GC', 'F_HG', 'F_HO', 'F_JY', 'F_KC', 'F_LB', 'F_LC', 'F_LN', 'F_MD', 'F_MP', 'F_NG', 'F_NQ', 'F_NR', 'F_O', 'F_OJ', 'F_PA', 'F_PL', 'F_RB', 'F_RU', 'F_S', 'F_SB', 'F_SF', 'F_SI', 'F_SM', 'F_TU', 'F_TY', 'F_US', 'F_W', 'F_XX', 'F_YM'};
settings.sampleend = 20131231;
settings.lookback = 504;
nMarkets = size(CLOSE,2);
periodLong = 200; %#[150:10:200]#
periodRecent = 40; %#[20:5:60]#
smaLong = sum(CLOSE(end-periodLong+1:end,:)) / periodLong;
smaRecent = sum(CLOSE(end-periodRecent+1:end,:)) / periodRecent;
long = smaRecent >= smaLong;
p = zeros(1, nMarkets);
p(long) = 1;
p(~long) = -1;
end