Simplest Parameter Optimization in Zorro Trader

September 18, 2022by Algo Mike0
Zorro_Trader_Price_SMA_SPY-1280x663.png

Remember our simplest trend following strategy in Zorro Trader? We were trading the SPY, and we used a moving average of a certain length (50 days) as our trend indicator. When the price crossed above this moving average, we closed any short positions and entered a long position. When the price crossed below the moving average, we closed any long positions, and entered a short position. We made an Annual Return of 3% with a Sharpe Ratio of 0.27, which makes this a poor trading strategy. The equity curve of the strategy is in the picture above, and it does not look too good.

We tried to improve this strategy in several ways, trading several assets. We noticed that changing the length of the moving average does impact our results (for better or worse). Actually, this simple algorithmic trading strategy depends on a single parameter: the length of the simple moving average. The astute reader will surely ask the question: can we find the optimal value for this parameter? What exactly “optimal” means is a more complicated conversation, and we will discuss it in another post. In this post we will demonstrate how easily parameter optimization can be implemented in Zorro Trader.

Zorro Trader Optimization

Simple parameter optimization in Zorro Trader is, indeed… very simple! Basically, we need to tell Zorro Trader that we want to find the “best value” for a parameter, by adding the following line right at the beginning of our code inside the run() function:

set(PARAMETERS);

This statement is something we call a system flag. It tells Zorro to “switch on” a certain type of behavior, which in this case is the complex process of finding the best value for one or more parameters. Luckily for us, this complex process happens behind the scenes, and the creators of Zorro Trader have taken care of all the details for us. All we have to do is setting this system flag, and then tell Zorro Trader what parameter (or parameters) we want to optimize. We did not define the parameter we want to optimize yet, so we will do so now. The line below goes right after the BarPeriod initialization.

var sma_period = optimize(2,2,50,1);

We already know what var means. It is the type of the variable we want, and in this case it holds a single number (not a series). Since what we want is to optimize the formation period of the simple moving average, we will name this variable sma_period. We will use Zorro Trader’s internal function optimize() in order to calculate the optimal value for this variable. By default, optimal means the most robust value for the parameter, on the current asset, and over the time period we are testing. Zorro Trader will try all values we tell it to try for the parameter, and return the most robust one.

Optimize() function’s arguments

The optimize() function has four arguments. The first one is the value Zorro Trader will try first. In this case we will start at 2, as 1 is not really a formation period for a simple moving average. The second and third values are the minimum and the maximum values Zorro Trader will try. Here, we will try all possible values between 2 and 50. The last argument is the step we will use. A step of 1 means trying every single value. A step of 2 means trying every second value, etc. For example, in this case a step of 3 would mean to try only the values: 2, 5, 8, …

Why would we want to use any other step than 1? Well, it primarily depends on the lengths of the intervals we want to use when optimizing multiple parameters. In this example, we are optimizing only one, so we will keep things simple and set a step of 1. If we had two parameters to optimize, and the intervals we wanted to try for them were very different in size, it would make sense to use a step of 2 for the parameter with the bigger range of values. More on this in the members area of our website, and the following posts.

Using the optimized value in the code

Now that we got the most robust value for our simple moving average formation period stored in the variable sma_period, what do we do with it? Well, Zorro Trader makes this really simple. Remember the line where we were telling Zorro Trader we wanted a simple moving average of 50 days?

vars sma = series(SMA(price, 50));

In order to use the optimized value, we simply change the value 50 to the name of the variable holding the optimized parameter, like this:

vars sma = series(SMA(price, sma_period));

The full code of the strategy is below:

function run()
{
set(PARAMETERS);

BarPeriod = 1440;

var sma_period = optimize(2,2,50,1);

vars price = series(priceClose());
vars sma = series(SMA(price, sma_period));

if(crossOver(price, sma)) enterLong();
if(crossUnder(price, sma)) enterShort();

plot("SMA", sma, LINE, BLUE);
}

Zorro Trader in Training Mode

When we first ran our simplest trend following strategy, all we had to do was to click the Test button. As we are now using parameter optimization, we will begin our back-test by hitting the Train button. This will put Zorro Trader in training mode, which will find us the optimal parameter for our simple moving average formation period. The optimization calculations will take a few seconds. The last few lines of the result of the optimization process are shown below:

Parameter 1 step 45: 46.00 => 0.93 24/57
Parameter 1 step 46: 47.00 => 0.80 20/59
Parameter 1 step 47: 48.00 => 0.79 19/60
Parameter 1 step 48: 49.00 => 0.80 18/61
Parameter 1 step 49: 50.00 => 0.90 19/52
Selected p1[12] = 13.01 => 1.04

SPY: 13.01=> 1.496

Parameters stored in HelloWorld_SPY.par

Zorro Trader is trying every value for “Parameter 1”, which is the length of the moving average, starting with 2 and ending at 50. For each tested value, it gives us the profit factor, and the number of winning and losing trades. The optimal selected value is 13, which is then stored in a special file of type .par for later use in test mode. We will run the back-test by hitting the Test button, and Zorro Trader will automatically read the optimal value from the saved file, and use it in the back-test.

Conclusion

By adding just two more lines of code, and making a small change to an existing one, we managed to unleash the power of Zorro Trader’s optimization functionality. Zorro Trader found the most robust value for the length of our simple moving average, and stored it in a file for later use in a back-test. When we first back-tested our simplest trend following strategy, we arbitrarily chose the value 50 for the formation period. Zorro Trader thinks that 13 is the optimal value, and 13 is not a close value to 50. Will this optimal value improve the performance of our algorithmic trading strategy? We will find out in the next post!

 

 

 

 

 

by Algo Mike

Experienced algorithmic and quantitative trading professional.