Zorro on Steroids III - Backtesting with Variable Spread

Many brokers use floating spread which means that the difference between ask and bid prices changes in time. If you want to test a strategy in Zorro with this kind of data you have basically two options. You can either approximate by setting the spread variable in History\AssetsFix.csv file to a fixed value or you can create your own data history files as described in Data Conversion article.

In case of T6 history files the whole process is relatively easy because the T6 structs contain fVal and fVol variables that can be used to store additional data beside OHLC prices. So you can store the spread value there and set it during the backtest. In most situations the closing price of the last candle is used for entry/exit price but in case of time entries and exits the opening price of the next candle is used so bear that in mind.

In case of T1 data the situation is more complicated because there's no variable for storing additional data. So you have to create two separate files for each year worth of data. One file contains the ask prices and the other contains bid prices or spread. During the backtest you use a dummy asset as illustrated further in the article. Note that in order to calculate the spread for current entry or exit you have to process the dummy asset first. You can influence the asset order in the loop but if you want to let's say analyze spread for each price tick, the tick() function processes prices with the same timestamp in alphabetical order according to the corresponding asset name (e.g. "EUR/USD" comes before "EUR/USD_bid").

So let's assume we have created T1 history data files. Their names are EURUSD_2017.t1 for T1 ask prices and !EURUSD_2017.t1 for bid prices. Now there are several approaches we can choose. One of them is to create a setSpread() function in our script. You can call this function before each entry or exit or on every bar. It's important to loop through the two assets in the correct order (bid first) and to use a condition like if(strcmp(Asset, asset_bid)) in order to trade only the real asset. We also have to assign the bid variable when we're currently looping through the bid (dummy) asset.

#include <default.c>

string asset_ask = "";  
string asset_bid = "";  
var bid = 0;

function setSpread()  
{
    if(strcmp(Asset, asset_bid)) { // if it isn't the dummy asset
        Spread = (var)priceClose() - bid;
    }
}

function run()  
{
    if(is(INITRUN))
    {
        asset_ask = Asset;
        asset_bid = strf("!%s", Asset);
    }

    while(asset(loop(asset_bid, asset_ask)))
    {
        if(strcmp(Asset, asset_bid)) { //if it is not the dummy asset
            setSpread();
            // put trade functions here
        }
        else {
            bid = (var)priceClose();
        }
    }
}

The downside of this solution is that it's easier to exceed the allowed memory limits this way. So if you trade only on each candle and don't use a profit target or a stop loss I would recommend to stick with T6 data anyway. It's faster and safer.

Schizo Frenetik

Read more posts by this author.

Subscribe to StatsMage — Quant Ideas Worth Sharing

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!