PYTHON TOOLBOX
This tutorial explains the use of the Quantiacs Python Toolbox. The toolbox uses Python 3.7; it is highly recommended that you use the latest version of the toolbox.
This toolbox has all of the main functionality of the Matlab Toolbox but is available with in the free language, Python. Here you will find instructions on developing, evaluating, and submitting your own trading system.
A detailed documentation is available here, where you can find many useful information about the toolbox.
INSTALLING PYTHON
The easiest way to get going with python is to use the Anaconda Python distribution. The installation files can be downloaded from the Anaconda website. Installation instructions can be found on Continuum's Anaconda installation page. Anaconda takes care of all of the dependencies that the Quantiacs Toolbox needs.
When installing the python distribution it is important to know how to access this python distribution. You should know where it is installed and how to access the distribution. This is different for each operating system:

Windows: When installing Anaconda be sure to leave the ‘Add Anaconda to my PATH environment variable’ box checked. This makes the Anaconda distribution available from the command line. Additionally, after installation Anaconda supplies a command prompt that is pointed to the Anaconda distribution.

Linux/OSX: Following the instruction on the Anaconda installation page, be sure to select yes when prompted to add the Anaconda install location to your PATH. This will make the Anaconda distribution available form your command line.
INSTALLING THE TOOLBOX
The easiest way to install the toolbox is to use Anaconda and create a virtual environment for Quantiacs as follows:
 First, create the environment:
conda create name quantiacsbox
 Then, activate it using:
conda activate quantiacsbox
 Finally install the Quantiacs toolbox:
conda install c quantiacspkg quantiacstoolbox
Anaconda will take care of installing the required dependencies.
Installing the toolbox can be also done via the pip installer in Python. If installed python in a different manner, pip installation instructions can be found here. To install the toolbox via pip run the following at the command line (or from the anaconda command prompt in Windows—Start>Anaconda>Anaconda Command Prompt):
pip install quantiacsToolbox
If you don’t want to install the system download the toolbox from
my area on the Quantiacs site. Extract the contents, open a command prompt within the folder and type:
python setup.py install
If you have any issues write us to info@quantiacs.com and we’ll respond ASAP.
DEVELOPING YOUR OWN SYSTEM
Similar to the Matlab toolbox, your trading system only has to allocations or the percentage of your capital you with to apply to each equity in your market list (this is new in v2, previous toolboxes required the number of shares you wished to purchase). When defining your trading system, you must label the function definition as “myTradingSystem”. v2 of the toolbox allows for flexible data definitions, where you can request OPEN, HIGH, LOW, CLOSE, or VOL data for your system. A typical function definition is shown below.
def myTradingSystem(DATE, HIGH, CLOSE, VOL, exposure, equity, settings):
Within 'myTradingSystem' you can use any prediction method and mathematical technique imaginable.
PACKAGES
At the moment, the only python packages Quantiacs supports are:

numpy

Pandas

scipy

scikitlearn

talib

keras

tensorflow
Quantiacs is open to supporting more open source libraries, just send us a message at
office@quantiacs.com requesting your library and we'll look into it.
THE DATA
Data can be requested for your trading system through the arguments of the function definition. The current data types provided are the primary market data, 'DATE', 'OPEN', 'HIGH', 'LOW', 'CLOSE' and 'VOL'. These should be written in uppercase letters.
'DATE' is a column vector of size ['nLookback' x 1] that contains the ascending dates of the last nLookback trading days in the format YYYYMMDD. The most recent data is at the end of the vector.
'OPEN', 'HIGH', 'LOW', 'CLOSE', 'VOL' are matrices of size ['nLookback' x 'nMarkets']. E.g. 'OPEN' has the last 504 open values (rows) for the 100 markets (columns) in our portfolio.
'exposure' and 'equity' are also matrices of size ['nLookback' x 'nMarkets']. 'exposure' stores the last 'nLookback' values of realized exposure of your trading system. These are the quantities you held in your simulated broker account. 'equity' is the cumulated sum of your holding quantities times the change in price minus trading costs. Or simply put: It is what you made with each market over your lookback period.
'settings' contain your environment variables and can be defined as described below.
SYSTEM SETTINGS
For evaluation of a trading system, there must also be a settings function. This defines the markets you wish to trade, your budget, and market model parameters. This function is declared as seen below:
def mySettings():
within mySettings the market list and evaluation settings must be defined. The function should look something like this:
def mySettings():
settings['markets'] = ['F_AD', 'F_BO', 'F_BP', 'F_C', 'F_CD', 'F_CL', 'F_DJ', 'F_EC', 'F_ES', 'F_FV', 'F_GC', 'F_HG', 'F_HO', 'F_LC', 'F_LN', 'F_NG', 'F_NQ', 'F_RB', 'F_S', 'F_SF', 'F_SI', 'F_SM', 'F_SP', 'F_TY', 'F_US', 'F_W', 'F_YM']
settings['lookback']=504
settings['budget']=10**6
settings['slippage']=0.05
return settings
settings['markets'] Defines the markets you wish to trade. Any market on the markets page can be defined in this list.
settings['lookback'] An int definining the length of historical data passed to myTradingSystem .
settings['budget'] An int defining the initial budget of your simulated brokerage account.
settings['slippage'] A float defining
settings['beginInSample'] A string that defines the beginning of the time period over which you wish to evaluate your period. Must be in the form of YYYYMMDD
settings['endInSample] A string that defines the end date over which your system will be evaluated. Must be in the form YYYYMMDD
PLAYING WITH A SAMPLE SYSTEM
We’ve supplied a mean reversion system for you to start playing with. If you’ve downloaded the toolbox, just evaluate the meanReversion.py file contained within the zip file you’ve downloaded. If you installed the toolbox via pip, you can download the system here.
EVALUATING YOUR SYSTEM
If you have already developed your own system, you can run it by importing the toolbox and running the runts function with the file path to your system. Evaluation would look like this:
import quantiacsToolbox
returnDict = quantiacsToolbox.runts(‘/Path/to/your/TradingSystem.py’)
quantiacsToolbox.runts will evaluate your system on your settings and return a dictionary of performance values and a plot of the your system’s performance.
returnDict contains the following:
returnDict['tsName'] a string that contains the name of your trading system
returnDict['fundDate'] a list of the dates available to your trading system
returnDict['fundTradeDates'] a list of the dates traded by your trading system.
returnDict['fundEquity'] a list defining the equity of your portfolio
returnDict['marketEquity'] a list defining the equity earned in each market.
returnDict['marketExposure'] a list containing the equity made from each market in settings[‘markets’]
returnDict['errorLog'] a list describing any errors made in evaluation
returnDict['runtime'] a float containing the time required to evaluate your system.
returnDict['evalDate'] an int that describes the last date of evaluation for your system (in YYYYMMDD format)
returnDict['stats'] a dict containing the performance statistics of your system
returnDict['settings'] a dict containting the settings defined in mySettings
SUBMITTING YOUR SYSTEM
To submit a system to the Quantiacs server, simply run the submit function with the filepath to your system and the name you wish to use for your system. Submission must look like this:
import quantiacsToolbox
quantiacsToolbox.submit(‘/Path/to/your/TradingSystem.py’,’mySystemName’)
You can also upload your file using the upload form in your area.
QUANTIACS MATLAB TOOLBOX
The Toolbox contains

Endofday data of the 500 Stocks in the S&P 500 Index and of 44 Futures.

sample trading system functions trendfollowing and meanreversion

A function runts that runs and evaluates your tradingsystem

A function submit that uploads your tradingsystem to Quantiacs
A detailed documentation is available here which includes more information of the toolbox.
PACKAGES
We support the following Matlab ® Toolboxes:

Curve Fitting

Econometrics

Financial

Global Optimization

Neural Network

Optimization

Signal Processing

Statistics
WRITE YOUR TRADINGSYSTEM
Write a Matlab ® function with the following prototype:
function [p, settings] = ts(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings)
Your function will be called each day of the backtesting period with the most recent data as arguments. You return your desired exposure p for the next day.
THE ARGUMENTS
OPEN, HIGH, LOW, CLOSE, VOL, exposure and equity are each matrices of size [lookback x markets], where lookback represents the maximum lookback period in days and markets the number of markets.
If a market is not defined, its values are set to NaN. If data is missing within the series (for example due to a holiday) the missing data is replaced by the last known value with zero volume.
ARGUMENT DESCRIPTION

DATE

a date integer in the format YYYYMMDD

OPEN

the first price of the session

HIGH

the highest price in session

LOW

the lowest price in session

CLOSE

the last price of the session

VOL

the number of stocks traded that day

exposure

the realized quantities of your tradingsystem

equity

the cumulated performance of each market

settings

a structure that stores all relevant settings for the simulation.
For the contests your algorithm will always be called with the following settings:
settings.lookback = 504;
settings.budget = 1000000;
settings.slippage = 0.05;
THE RETURN VALUES
p is a vector of size 1 x markets with your desired holding quantities for the next day.

pi = 0

you don't hold asset i in your portfolio

pi > 0

you are invested long in asset i with weight p

pi < 0

you are invested short in asset i with weight p
You can modify the settings to fit your needs. But please note, that your algorithm will be called with the default settings for the contest.
TEST YOUR TRADINGSYSTEM
You can run your tradingsystem by typing
runts('tsFilename')
at the Matlab prompt. runts loads the market data and calls your tradingsystem for each day of the backtest with the most recent market data. It simulates the equity curve for your output values p. runts returns a struct with the exposures and the equity curves of the trading system. It computes the performance numbers of your system and plots its Factsheet.
DEVELOP A TREND FOLLOWING SYSTEM
In this tutorial we write a simple trend following algorithm for the 27 Futures of the CME. You find this tradingsystem trendfollowing.m in the toolbox.
We will create step by step the following Matlab® function:
function [p, settings] = trendfollowing(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings)
settings.markets = {'F_AD', 'F_BO', 'F_BP', 'F_C', 'F_CD', 'F_CL', 'F_DJ', 'F_EC', 'F_ES', 'F_FV', 'F_GC', 'F_HG', 'F_HO', 'F_LC', 'F_LN', 'F_NG', 'F_NQ', 'F_RB', 'F_S', 'F_SF', 'F_SI', 'F_SM', 'F_SP', 'F_TY', 'F_US', 'F_W', 'F_YM'};
settings.sampleend = 20121231;
settings.lookback = 504;
nMarkets = size(CLOSE,2);
periodLong = 200;
periodRecent = 40;
smaLong = sum(CLOSE(endperiodLong+1:end,:) ./periodLong);
smaRecent = sum(CLOSE(endperiodRecent+1:end,:) ./periodRecent);
long = smaRecent >= smaLong;
p = ones(1, nMarkets);
p(~long) = 1;
end
We implement a trend following classic: we compare two moving averages of the same data series. A moving average is the average price of an asset over the last n days. So we simply compare two differently averaged prices of the same stock.
We call the market bullish and expect rising prices, if a recent average is higher than a long term average. If for example the average price of a stock in the last 40 trading days was higher than the average price of the same stock in the last 200 tradingdays, prices went up recently. Since we try to follow the trend, we want to be invested long in that situation.
On the other hand, if the average price of the last 40 trading days dropped below the average price of the last 200 trading days, we assume the market is bearish. We expect further falling prices, and we want to be invested short.
In short, we measure in a very simple way what happened with the market recently, and assume a continuation of that price move.
The function template looks like this:
function [p, settings] = trendfollowing(DATE, OPEN, HIGH, LOW, CLOSE, VOL, exposure, equity, settings)
end
The arguments
DATE, OPEN, HIGH, LOW, CLOSE and
VOL are primary market variables, and thus written in upcase letters.
DATE is a column vector of size [504x1] that contains the ascending dates of the last 504 tradingdays in the format YYYYMMDD. The most recent data is at the end of the vector.
OPEN, HIGH, LOW, CLOSE, VOL are matrices of size [lookback x markets]. E.g.
OPEN has in our example the last 504 open values (rows) for the 27 markets (columns) in our portfolio.
exposure and
equity are also matrices of size [
lookback x
markets].
exposure stores the last 504 values of realized exposure of your tradingsystem. These are the percentage allocations for each asset you held in your simulated broker account the last two years.
equity is the cumulated sum of your holding quanities times the change in price minus trading costs. Or simply put: It is what you made with each asset in the last 2 years.
The settings struct stores all relevant settings. We could change the lookback with a different value for
settings.lookback or the portfolio composition with another
settings.markets list. But for this tutorial we’ll go with the defaults: A lookback length of 504 trading days, which covers approximately the last two years of data and the 27 CME Futures.
First we define three variables:
nMarkets = size(CLOSE,2);
periodLong = 200;
periodRecent = 40;
nMarkets stores the number of markets, by measuring how many columns the Matrix
CLOSE has. In our example
nMarkets is 27.
periodLong and
periodRecent are the two lookback periods, that we want to use to compute the average price.
Next we compute the two average prices for each market, and store the results in vectors of size [1x27]:
smaLong = sum(CLOSE(endperiodLong+1:end,:)) ./ periodLong;
smaRecent = sum(CLOSE(endperiodRecent+1:end,:)) ./ periodRecent;
What happened here? Let’s start with
CLOSE(endperiodLong+1:end,:). It uses the convenient way Matlab® provides to address only a part of a larger matrix.
Generally you can address specific values of a matrix if you use their coordinates:
CLOSE(504,27) returns you the last
CLOSE of market 27.
end can be used to address the last element of a row or column.
CLOSE(end,end) gives you the last
CLOSE of the last market. In this case
CLOSE(end, end) is equivalent to
CLOSE(504,27).
Not only can you address single numbers from a matrix, but you can also address arbitrary submatrices:
CLOSE(1:10,2) returns you the first 10 values of
CLOSE of the second market.
The
: returns all rows/columns. It is equivalent to
1:end. In our case it returns all 27 columns.
So what we were doing with
CLOSE(endperiodLong+1:end,:) was simply returning a submatrix of size [200x27] from
CLOSE of the last 200 days, and all markets.
We then use
sum to sum up the submatrix column wise. Thus we get a vector of size [1x27], containing the sum of the last 200 values of
CLOSE for each market.
Since we don’t want the sum but an average price, we have to divide each element of the vector by 200. The result of this computation is assigned to the variable
smaLong, a vector of size [1x27].
We compute
smaRecent the same way.
Now we can compare the two vectors and assign the result to a vector
long:
long = smaRecent >= smaLong;
smaRecent and
smaLong have the same size, [1x27]. That’s why we can perform an elementwise comparison, and get a boolean vector
long. It is 1, when
smaRecent is greater or equal to
smaLong and 0 otherwise.
Our trading system is almost complete. Now we just have to allocate the proper percentages. We start by defining our output value
p as a row vector of 27 ones. Then we replace the 1 with 1 wherever our field
long is false, since we want to be short in the market if there is no long signal:
p = ones(1, nMarkets);
p(~long) = 1;
The trading system allocates the same weight, either 1 or 1 to every market. Every market is traded with 1/nMarkets of the available capital.
That’s it, the first tradingsystem is ready. If you type runts('trendfollowing') at the Matlab® prompt, and hit return you see the poor result.
Surely you can do better than that.
OPTIMIZATION
In the developing tutorial, we chose our parameters periodLong and periodRecent at 200 and 40 in trendfollowing simply because it appeared reasonable. That choice was somewhat arbitrary. Maybe there is a better set of parameters for our system?
To compute several different parameterizations of the same system we can use the optimize function. To use this feature place a comment next to the parameter you wish to scan. Within the comment place the parameter domain and stepsize between two pound signs (similar to the Matlab vector notation). For our example system, we will scan over periodLong and periodRecent:
periodLong = 200; %#[150:10:300]#
periodRecent = 40; %#[20:5:60]#
With these settings we choose to vary periodLong from 150 to 300 in steps of 10, and periodRecent from 20 to 60 in steps of 5. To evaluate the entire parameter space, input the following into the Matlab prompt.
res = optimize('trendfollowing')
Press return to compute all instances of that parameter space. The result of the optimization is stored in the struct res. It contains the statistics of each instanceSharpe Ratio, average yearly performance, average volatility, etc.
To find the parameters of the system with the best Sharpe Ratio, enter into the prompt:
[m mIx] = max(res.sharpe)
Next we just only need look up the parameter values for the optimal instance. To find the parameter values, we find the parameter value at the optimal index, mIx. To do this type the following at the Matlab prompt:
res.periodLong(mIx)
res.periodRecent(mIx)
SUBMITTING
Type
submit('TSFile', 'nameTS') at the Matlab prompt.
TSFile is the name of the .m file on your computer,
nameTS is the name that you want to give your Tradingsystem on Quantiacs. If you don’t enter a name, the filename will be used as default nameTS.
You will be prompted to log in to complete the upload.
Alternatively you can upload a tradingsystem via the Upload button on the Website.
TRAIN YOUR MATLAB SKILLS
If you want to improve your Matlab skills we recommend Mathwork's Cody. It's a good problem solving challenge that features a lot of small programming problems with gradually increasing difficulty.
If you are already familiar with Matlab and want to improve your skills to expert level we recommend you solve a problem on Project Euler... or write an algorithm on Quantiacs!