Strategy Coding Tutorial

A script describes the trading rules of a strategy in code - a sort of simplified language. Theoretically, there could be other ways to define trading rules, for instance by using a visual strategy builder, by setting up a list of indicators, or by entering formulas in a spreadsheet program. Unfortunately, this way only very primitive strategies can be created and superficially tested. Those simple systems have no real chance in today's financial markets. All known successful automated strategies are programmed or scripted, and underwent a solid development, optimization, and test process.

The disadvantage of script is obviously that you have to learn the script language. You do not need to dive deep into programming, since Zorro's script language 'hides' almost all complex programming stuff and allows you to concentrate on plain strategy. But a certain learning process can't be avoided: if you want to be successful with algorithmic trading, you're competing with traders that know coding and statistics. Inability to code would put you at a large disadvantage in this game.

A simple strategy script, coded in C, looks as shown below. This strategy uses two simple moving averages (SMA) with 30 and 100 bars time period, places a stop at 10 pip distance, and buys a long or short position when the faster average crosses over or under the slower average:

function run()
{
  vars Close = series(priceClose());
  vars SMA100 = series(SMA(Close,100));
  vars SMA30 = series(SMA(Close,30));


  if(crossOver(SMA30,SMA100))
    enterLong();
  if(crossUnder(SMA30,SMA100))
    enterShort();
}

C is used for the script language, since it's the fastest high-level language and most software today is written in C or C++. For the same reason, most trade platforms use C or a C variant for automated trading. The first 3 workshops will give you an introduction into formulating tasks in C code - also called coding. The next 4 workshops are about developing and optimizing trading strategies. For testing the examples, you can use the free Zorro platform (if you don't have Zorro yet, get it from zorro-project.com). A more comprehensive introduction into developing trading strategies and working with Zorro can be found in the Black Book.

Zorro's C variant, lite-C, is a 'light' version of the C/C++ programming language. The 'lite' just means it contains a framework that hides the complex stuff - like API calls, pointers, structs, etc. - that is difficult to beginners. lite-C was originally developed for the computer game company Atari for controlling the artificial intelligence of actors in computer games. As you can imagine, a language powerful enough to control simultaneously ten thousands of actors in a virtual world, and at the same time easy enough to be used by computer gamers for the behavior of their agents, is an excellent choice for trading strategies. Once familiar with C, you can use your programming knowledge not only for C based trading strategies. Since most languages have a similar structure, you'll also be able to at least understand code in Python, Pascal, or Tradestation's EasyLanguage, even though the latter declares a variable not with var x = 7, but with Vars: x(7).

If you already know C, you can skip the first 3 workshops. If you already know interpreter languages like R or Python, you'll notice soon that a compiled language like C has a crucial advantage for trading system development: It is much faster. A script in C will need only a few seconds for a high-resolution backtest. The same script in Python would need hours.

Here's our curriculum:

Although the strategies in this tutorial are profitable in the tests, they are meant for educational purposes only and are designed for simplicity, not for maximum profit. For trading with real money, better develop your own strategies.

Workshop 1: Variables

A script (or program) is a list of instructions in plain text format that tell the computer what to do under which circumstances. It consists of two types of objects, variables and functions. A variable is a place in memory (just like a container) that is used to store numbers, text, or other information. Because you don't want to have to remember where in the computer which number is stored, a variable has a name that's used in the script. A few example script lines that define variables:

var Price;
int Days = 7;
string Wealth = "I am rich!";
bool Winning = true;

In C, any variable must be defined (programmers also say 'declared') before it can be used. The only exception are pre-defined variables such as Spread, Stop etc. that Zorro already knows. Every variable name must start with either a letter or with an underscore _, and must not contain any special characters. Variable names are case sensitive: MyTradePositions is a different variable than mytradepositions.

Variables can have different types. The most often used: var (or double) for a number with decimals, like a price; vars for a series of many numbers; int for a number that has no decimals, f.i. for counting something; string for text; and bool for a 'flag', a sort of toggle switch that is either true or false. There are more variable types in C, and there are also complex variables, called struct, which are put together from basic variables. But in trading scripts you'll normally encounter only var, vars, int, string, and bool.

Any variable can receive an initial value at start, which can be omitted when the initial value does not matter. Examples:

int num_bars = 7;
var limit = 3.5;

We can add comments to the code. Every time it encounters two slashes //, Zorro will ignore the words that follow it, up to the end of the line. This way we can add useful information to our code:

int bar_width; // the width of one bar in minutes

or we can temporarily disable a line in the script by placing two slashes in front of it. This is called "commenting out" a line, and is used so frequently in programming that the script editor has two extra buttons for commenting out and commenting in.

Every definition or any command in C needs to end with a semicolon. If you forget to add ";" at the end of the line of code, you'll see an error message - not for the line with the missing semicolon, but for the following line! However, you can define several variables of the same type in one line. This saves lines and keeps your code short. Example:

var momentum, strength, score;
int width = 7, height = 14, depth = 20;

The first script

Start Zorro, select Workshop1 in the Script dropdown menu, then press [Edit]. The strategy script editor opens up and shows you this script:

// Tutorial Workshop 1: Variables
////////////////////////////////////////

function main()
{
  var a = 1;
  var b = 2;
  var c;

  c = a + b;
  printf("Result = %.f",c);
}

The script begins with a comment (the lines beginning with //). Then we have a function named main - everything that happens in a program is inside a function. In the next lines we can see that three variables a, b, c are defined. The action happens in the following line:

c = a + b;

This is a command (also called instruction) to the computer to add the content of the variables a and b, and store the result in the variable c. The last line is also a command, used for displaying the content of c in the message window:

printf("Result = %.f",c);

Now press [Test] on Zorro's panel and watch the script running.

Workshop 2: Functions

This is a function:

function add_numbers( )
{
   var a, b, c;
   a = 3;
   b = 5;
   c = a + b;
}

Functions are defined using the word function followed by the name of the function and a pair of parentheses ( ). The parentheses are used to pass additional variables to the function, if required. The body of the function (its list of commands) is written inside a pair of winged brackets { }. The body consists of one or more lines of C code that end with a semicolon. Programmers usually indent the code in the function body by some spaces or a tab, for making clear that it is inside something. The names used for the functions follow the same naming convention as for variables. Don't use the same name for a variable and a function!

Zorro follows the convention to use lowercase names for functions (except for indicators, such as EMA), 'CamelCase' names for variables, and UPPERCASE names for predefined numbers.

An example of a function that computes the number of days spent by me (or you) on Earth:

function compute_days()
{
  var my_age = 33;
  var days_a_year = 365.25;
  var number_of_days = my_age * days_a_year;
printf("I am %.f days old!",number_of_days); }

Enter this code in a new empty script, and save it (File / Save As) into the Strategy folder under a name like Myscript.c (don't forget the ".c" at the end - it means that this file contains C code). You should now find Myscript in the Script scrollbox. When you now select it and click [Test], you 'll get an error message "No main or run function!".

If a function is named main, it will automatically start when we start the script. The function named run is special to Zorro; it normally contains our trade strategy and is automatically run once for every bar period. If a script has neither a main nor a run function, Zorro assumes that you made a mistake and will give you this error message.

So enter a main function at the end of the script:

function main()
{
   compute_days();
}

This code 'calls' (meaning it executes) our compute_days function. For calling a function, we write its name followed by a pair of parenthesis and then we end the line of code with a semicolon. Tip: write the code for your functions first and and the code that calls them later. The computer reads code from the top of the script down to the bottom, line by line. Don't call or refer to something that was not defined before.

Don't forget to define your function first, otherwise the computer will complain when you try to use it. You will encounter such compiler errors frequently when you write scripts - even experienced programmers make such mistakes all the time. Sometimes it's a forgotten definition, sometimes a missing semicolon or bracket. Get used to compiler errors and don't be helpless when you see one. The computer (usually) tells you what's wrong and at which line in the script, so you won't need rocket science for fixing it.

Passing variables to and from functions

A function can also get variables or values from the calling function, use them for its calculation, and give the resulting value back in return. Example:

var compute_days(var age)
{
   return age * 356.25;
}

The var age between the parentheses is for passing a value to the function. This value is stored in the variable age, which can be used inside the function like any other variable. For returning a value from a function, just write it behind a return command. It can be a number, or a variable, or any arithmetic expression that calculates the returned value. The function then gives that value back to from where it was called. And when a function is expected to return something, it must be defined with the type of the returned variable. So if a function returns a variable of type int, define it with int; if it returns a var, define it with var.

This is our new script with passing variables to and from functions:

var compute_days(var age)
{
  return age * 365.25;
}
 
function main()
{
  var my_age = 33;
  var number_of_days = compute_days(my_age);
  printf("I am %.f days old!",number_of_days);
}

The "I am %.f days old!",number_of_days are the two variables that we pass to the printf function. The first variable is a string, used for displaying some text: "I am %.f days old!". The second variable is a var: number_of_days. You can read details about the printf function in the Zorro manual or any C book.

When a function returns a var, we can just place a call to this function in stead of the var itself - even inside the parentheses of another function. We'll save one variable and one line of script this way::

function main()
{
  var my_age = 33;
  printf("I am %.f days old!",compute_days(my_age));
}

 !!  Important tip when you call functions in your code that return something. Do not forget the parentheses - especially when the parameter list is empty! In C, an function name without parentheses means the address of that function in the computer memory. add_numbers and add_numbers() are both valid and won't give an error message in the code! But they are something entirely different.

Workshop 3: Branches and Loops

You will use "if" statements when you want your script to make decisions - meaning that it behaves differently depending on some conditions, like user input, a random number, the result of a mathematical operation, a crossing of two indicators, etc. Here's the simplest form of the "if" statement:

if(some condition is true)
    do_something(); // execute this command (a single command!)

A more complex form of the "if" instruction is listed below:

if(some condition is true)
{
    // execute one or several commands that are placed inside the curly brackets
} else {
    // execute one or several commands that are placed inside these curly brackets
}

The instructions placed inside the "else" part are executed only if "some condition" is not true. Here's a practical example:

if(my_age > 65)
    income = 2000;
else // age less than or equal to 65?
    income = 3000;

Income can be either 2000 or 3000 because only one of the branches will be executed. The conditional parts of the code are called "branches" because several nested if instructions can look like a tree with the root at the first "if" and many branches of which only one is executed. In the examples we indented the lines after the "if". The C language does not care how you indent lines or if you write a command on the same or on a new line, but we do that for clarity. The code reads easier if dependent lines are indented.

The "if" branching statements start with the if keyword followed by a pair of parentheses, which contain a comparison, or any other expression ("some condition") that can be true or false. If the expression is true, the following instruction or the set of instructions placed inside the first pair of curly brackets is executed; if the expression is false and we don't use "else", the set of instructions placed between the curly brackets is skipped (it isn't executed); and if the expression is false and we are using the "else" branch as well, the set of instructions placed inside the first pair of curly brackets is skipped, and the set of instructions placed inside the second pair of curly brackets is executed.

Another example:

function main()
{
  var profit = slider(3,50,0,200,"Profit",0);
  if(profit > 100)
    printf("Enough!");
  else
    printf("Not enough!");
}

When you now click [Test] to run the script again, you'll notice that the bottom slider gets the label "Profit". Move it all the way to the right, so that 200 appears in the small window, and click [Test] again. You can see that the result is now different. The slider() function has put its return value - which is the value from the bottom slider - into the profit variable, and thus the if(..) condition became true as the value was bigger than 100. You can see details of the slider function in the manual. Now let's assume that you want to do something only when two different conditions are fulfilled:

function main()
{
  var profit = slider(3,50,0,200,"Profit",0);
  var loss = slider(2,25,0,200,"Loss",0);
  if((profit > 50) and (loss == 0))
    printf("Enough!");
  else
    printf("Not enough!");
}

Now two sliders are involved. We can combine two conditions using the "and" keyword. That means both conditions must be true for the combination to be true. There is also an "or" keyword when only one of the conditions needs be true.**

The parentheses around (profit > 50) and (loss == 0) matter. Use parentheses to make sure that the program calculates in the same order that we want, and make sure that you have as many opening as closing parentheses! A missing parentheses at the end of a line is one of the most frequent reasons of compiler error messages. The computer will usually complain about an error in the following line because it's there looking for the missing parenthesis. That was the first tip.

Mind the double equals in "loss == 0 ". Whenever you compare two expressions (loss and 0 in the example above) you have to use "==" instead of "=", because a line of code that looks like this:

if(loss = 0)
{
    // do some stuff
}

is correct syntax, but will set loss to zero instead of comparing loss with zero!

Use the '==' comparison with care when comparing var variables. If a computer calculates a mathematical expression, the result is usually inaccurate due to the limited floating point precision. Instead of 0.333333333..., dividing 1 by 3 results in 0.3333329856. Thus a comparison will come out false. When comparing values with many decimals, such as prices, it's highly unlikely that two such values will be ever exactly equal. Normally you'll only use 'greater' or 'smaller' comparisons (< or >) with var variables. This problem does not affect int variables, as they have no decimals and can indeed be exactly equal.

Expressions

An (arithmetic) expression is a sequence of variables, numbers, operators, etc that are linked together. You can have simple expressions that look like the one below:

if(indicator > 50) // simple expression inside the parenthesis
   ...

Or you can have arbitrary complicated expressions that are a combination of sub-expressions:

if((factor1*indicator1 > 50)  and  (indicator2 < 35)  and  (volatility < 10)) // more complicated expression
   ...

You can combine as many expressions as you want, using parentheses, just like in the example above. The same rules from your math classes apply here, too.

While loops

An example of a "while loop":

while(my_money < 1000000)
    trade(my_money);

The while statement has the same syntax as the if statement. There is some expression - in this case the condition that the variable my_money is less than a million - and a command that is executed when the expression is true. However, in the case of an if statement, the program whould then go on with executing the next command afterwards. In the case of a while statement, the program "jumps back" to the while condition and tests it again. If it's still true, the command is executed again. And the while condition is then tested again. And so on. This process is repeated until the while expression eventually comes out false, or until eternity, whichever happens first.

A "loop" is called so because the program runs in a circle. Here's the basic form of the while loop:

while (some condition is true)
    do_something(); // execute this command repeatedly until the condition becomes false

and here the form with curly brackets:

while (some condition is true)
{
    // execute all commands inside the curly brackets repeatedly until the condition becomes false
}

Whatever those commands do, they must somehow affect the while condition, because when the condition never changes, we have an "infinite loop" that never ends!

Here's a practical example of a while loop. Run this in Zorro:

function main()
{
  int n = 0; 
  while(n < 10) { 
    n = n + 1;
    printf("%i ",n);
  }
} 

This little program adds 1 to the variable n, prints the variable to the message window, and repeats this until n is 10.

Loops are very useful when something has to be done repeatedly. For instance, when we want to execute the same trade algorithm several times, each time with a different asset. This way we can create a strategy that trades with a portfolio of assets.

And there's more...

We are now at the end of the three basic workshops that teach general programming. In the next workshops we'll begin with developing trade strategies; you've already learned all programming stuff that you'll need for those lessons. But there's far more to programming - we haven't touched yet concepts such as macros, pointers, arrays, structs, classes, or the Windows API. Zorro's lite-C variant also supports some elements from C++, the 'big brother' of C - such as methods or function overloading.

If you want, you can learn 'real' programming beyond the scope of trade strategies. Buy a C book or go through a free online C tutorial, such as Sam's Teach Yourself C in 24 Hours. You can also join the Gamestudio community that uses the lite-C language for programming small or large computer games. Check out how a 'real' C program looks like: open and run the script Mandelbrot. It has nothing to do with trading and you will probably not understand yet much of the code inside. It is a normal Windows graphics program. Don't worry, trading strategies won't be this complicated - it just shows that programming has a lot more depth and can be a lot more fun even without earning money with it.

 

Next: Trading


Further reading: ► Variables. Expressions. Functions, return, printf. if, for, slider.