Click here to Login




Getting Accurate Backtesting Results: Survivorship bias-free S&P 500

Updated on 2012-05-31





You may be surprised how backtesting results can hugely change depending on the data you are using. If you are trading stocks from a particular index you may get completely different results depending on whether you are applying a static list of stocks (Stocks that compose that index today) or a dynamic list that simulate the index composition at any moment in the past.

The survivorship bias can hugely affect your trading strategy backtesting results. You will end up buying stocks that are currently included in your reference index but are not part of that index at the time the stock was purchased. Creating a survivorship bias free database for the indices you are trading should be a very important step in your strategy development process.

The composition of any index changes over time; there are many reasons that can explain why a stock is delisted from an index. Bankruptcy, merging with another company, transferred to another exchange or failing to meet an exchange listing requirements are some of these reasons. Data for delisted stocks can be downloaded using the following item: Historical Quotes for Delisted US Stocks

This article will show you how to implement survivorship bias-free backtesting by creating an historical database that contains an index composition at any moment in the past then using that database in your buy or short rules.


How ETFs can help us create a survivorship bias-free database

There are mainly two kinds of ETFs (Exchange Traded Funds): Swap-based ETFs uses derivatives to track a benchmark while physical-based ETFs replace an index by buying its constituents. The second one can employ sampling techniques where it purchases only a sub-set of index components or it can employ what is called full replication.
The latter kind of ETF is what interests us here. An ETF who employ a full replication purchases all stocks of an index. When the composition of the index it tracks changes, the ETF trust will buy and sell shares to make sure it keeps tracking that index as closely as possible.

An example of such ETF is the "IVV". It is issued by iShares and it replicates the performance of U.S. large-cap stocks by tracking the Standard & Poor's 500 Index.

By looking at "IVV" holdings at different points in time, you can build a database that contains the historical index compositions of the S&P 500 Index.


Download ETF Holdings

UPDATE (2014):
iShares website have changed the URL used to get historical data. You can get the new downloader here: Historical Index Composition
You can also continue reading this article starting from the "Implement your trading strategy" section below.

--------------------

In order to create our database, we must download ETF holdings first.
To ensure high level of transparency, ETF issuers are required to fully disclose holdings regularly. The iShares for example publishes the historical holdings of different ETFs on its website.

Historical holdings for the "IVV" ETF, which tracks the performance of the S&P 500 index, can be found here.

The data can be exported and we will use that export link to create our ETF holdings downloader.

https://us.ishares.com/product_info/fund/excel_holdings.htm?ticker=IVV&asofDt=2012-5-25

The above URL returns the ETF composition at the date specified in the "asofDt" parameter.


Create the database

- In QuantShare trading software, select "Data" then "Edit Databases"
- Select "Manage databases" tab
- In "Create a new custom database", type "index" as database name and "Historical" as database type
- Select the "Databases" tab
- Select "Custom" in "Choose database" then select "index" database
- In "Add/Update Fields", type "ivv" next to "Add Field" button then click on that button
- Close the database editor

We have just created a new database called "index". This database contains one single field whose name is "ivv" (ETF name of the iShares S&P 500 Index Fund).


Create the downloader

- Select "Download" then "Download Manager"
- Click on "Add" button
- In the new form, click on "Add URL" (top-right corner)
- Under "URL" column, type the following URL: (We removed the "asofDt" parameter to make it dynamic)

https://us.ishares.com/product_info/fund/excel_holdings.htm?ticker=IVV

- Click on the button under "Field(s)" then click on "Add Field"
- Set "asofDt" under "Field", "2012-5-25" under "Value" and "Date" under "Type".
- Under "Content Type", select "CSV"
- Click on "Parser" to download a sample data and bring the control that will allow us to define parser settings


Define Parser Settings

- Click four times on the "Add Column" button
- Under "Database -> Field", set "index -> ivv" in the first row, "index -> date" in the second row, "Quotes -> Skip" in the third row and "Quotes -> Symbol" in the fourth row.
- Set separator to "," and "skip first n lines" to 15
- Set "Date type" to "YMD" and "Date Separator" to "-"
- Check the "Automatically add new symbols" field to make sure unknown symbols are added to QuantShare
- Click on "Pre Script" then add the following code:

string date = Content.GetURLORFileName();
date = date.Substring(date.IndexOf("asofDt=") + 7);

for(int i=0;i < Content.Rows.Length;i++)
{
Content.Rows[i].Data[0] = "1";
Content.Rows[i].Data[1] = date;
if(Content.Rows[i].Data[3].Trim() == "")
{
Content.Rows[i].IsIgnoreLine = true;
}
}


The "Pre Script" script is used to set the "ivv" field value to "1" for all stocks that compose the S&P 500 index.
It also sets the "Date" field to the fund holding date.

- Click on "Next" to see how the data is parsed
- Click on "Next" again to get the parser output
- Click on "Finish" then on "OK" to save your downloader

Note that here, we have simply defined the parser settings and checked the result using sample data. The data is not yet parsed and added to the "index" database.


Create the S&P 500 survivorship bias-free database

Now that our downloader is created, we have to run it in order to create our S&P 500 database.

- Open the Download Manager
- Select the downloader we have previously created
- Click on "Open Selected Downloader"
- Under "Dates" tab, set the following settings:

Format: [Y]-[M]-[D]
Interval: Month
Click on "Save" to generate the dates that will be used by the downloader

- Click on "Start Downloading"
- You are done. You can get a ready-to-use item here: Historical Index Composition.




Display the data

- Select "Data" then "Edit Databases"
- Select "Custom" next to "Choose database" then choose "index" database
- Choose a symbol to display the data




Implement your trading strategy

Now the important part where you want to implement a trading system that purchases stocks that belong to the S&P 500 index.

Let us say that your current trading system formula is as follows:

buy = rsi(14) > 70;


What to add in order to use the historical database of the S&P 500?

First, we get database data using the "GetData" function.

Next, we use the "BetweenFirstLast" function to get a continuous signal between the first and last index listing. This trading function is available here: Trading Indicator: True between the first and last signal

Finally, we use the "hhv" function (highest value over a specified period) to extend this signal to another month (This is because the data is downloaded monthly and therefore we assume that a stock is listed during all this month)

The new trading system formula would be:

buy = rsi(14) > 70;

inIndex = GetData('index', 'ivv', Zero);
inIndex = BetweenFirstLast(inIndex);
inIndex = hhv(inIndex, 25);

buy = buy and inIndex;



Faster Simulations and Optimizations

In order to implement the latter strategy, you will have to include all stocks in your database. This is not very efficient given the fact that most of these stocks will never be used.

A better way to deal with this is to include only stocks that were part of the S&P 500 index at any point in time.

You can achieve this using the screener tool.

- Select "Analysis" then "Screener"
- Click on "Create a new screen"
- Type the following formula: (Editor Mode)

inIndex = GetData('index', 'ivv', Zero);
inIndex = BetweenFirstLast(inIndex);
filter = hhv(inIndex, 100000000);


- At the bottom of the control, click on "Copy Symbols to Clipboard"

- In "Create/Update Trading System" control, select "Symbols & Dates" tab
- Add only one condition, which is "Custom Symbols"
- Click on the cell under "Values"
- Paste symbols that were copied from the screener by typing CONTROL+V


Using the Composites tool

Another very common use of the historical index composition is when creating new composites based on that index.
If you are planning to create the number of advancing/declining issues for the S&P 500, then using a dynamic list of symbols will generate much more realistic results than using a static list of symbols that gets the index composition only at the present time.


Although, this article deals with the historical composition of the S&P 500 index, the same technique explained above can be applied to any other index. Simply find a physical ETF that employ full replication of your index and replace "IVV" with the new ETF symbol name.
To find these ETFs, look at the number of holdings (number of stocks) and if that number is pretty much the same than the number of components of the tracked index then you found it.












3 comments (Log in)

QuantShare Blog
QuantShare
Search Posts




QuantShare
Recent Posts

Lock, Link and Undock your Charts
Posted 474 days ago

QuantShare
Previous Posts

More Posts

Back







QuantShare
Product
QuantShare
Features
Create an account
Affiliate Program
Support
Contact Us
Trading Forum
How-to Lessons
Manual
Company
About Us
Privacy
Terms of Use

Copyright 2019 QuantShare.com
Social Media
Follow us on Facebook
Twitter Follow us on Twitter
Google+
Follow us on Google+
RSS Trading Items



Trading financial instruments, including foreign exchange on margin, carries a high level of risk and is not suitable for all investors. The high degree of leverage can work against you as well as for you. Before deciding to invest in financial instruments or foreign exchange you should carefully consider your investment objectives, level of experience, and risk appetite. The possibility exists that you could sustain a loss of some or all of your initial investment and therefore you should not invest money that you cannot afford to lose. You should be aware of all the risks associated with trading and seek advice from an independent financial advisor if you have any doubts.