Strategy development with Visual Studio™

Zorro supports three types of strategy files in the Strategy folder: C code (.c), lite-C executables (.x), and DLLs (.dll). These 3 file types automatically appear in the Script scrollbox. The free Zorro version can run all 3 strategy types, but can only create strategies in .c code. Zorro S can compile .c strategies to .x executables with the EXE flag or via command line, and can also be used for creating and debugging .dll strategies. Any language that can generate a Win32 DLL can be used, such as C#, Java, Pascal, Delphi, Basic, and of course C++.

For developing strategies with the lite-C compiler, you need no further tools; the process is described in the tutorial. For developing strategy DLLs in other languages you'll need an external development platform with a compiler. We recommend Visual Studio™ Community Edition. It is a powerful development suite that can be freely downloaded from Microsoft™. Writing a strategy as a VC++ DLL has several advantages. All tools of Visual Studio can be used, especially the debugger and profiler. External function libraries, such as Boost, can be directly integrated without the need to write a wrapper. With all optimization features enabled, VC++ produces code that runs slightly faster than lite-C (about 20%). The disadvantages are that any project must be set up as described below before you can start coding, and the DLL must be compiled after every code change.

The VC++ debugger displays local and global variables and can step into code without the need of watch statements (which are not supported by VC++ anyway). It is better suited than lite-C for finding bugs in the code. For finding bugs or flaws in the trading logic, the visual debugger can still be used even with DLL based projects.

DLLs can be used not only for developing strategies, but also for extending Zorro's C language with external packages (see using DLLs). The code syntax for strategies in VC++ is almost the same as in lite-C (differences are listed below), and functions and system variables can be used in the same way. Additionally you have all object oriented language features of C++ at your disposal.

Setting up VC++

The dialogs and setup procedures shown below are slightly different for any VC++ version. A project setup (.vcxprj) is included, but even with it you need to adapt the Zorro paths to your Zorro folder. Here's the detailed setup for Visual C++ 2017 Community Edition; the setup for VC++ 2019 is very similar:

The file MyStrategy.cpp in the Source\VC++ folder contains VC++ versions of Workshops 6..8, the RTest script, and the DeepLearn script. Which one to compile can be selected with a #define at the begin. Check it out for learning the differences of writing a strategy in VC++ instead of lite-C. All known code differences are listed below. If you encounter any other incompatility with a function or variable, please report on the user forum or to Zorro support. An alternative framework for creating Zorro strategies with VC++ has been developed by a user and is available on

Migrating a lite-C script to VC++

Lite-C contains 'abbreviations' to make code shorter and less complex. Most of them, but not all, work also with 'real' C++. When converting a lite-C strategy to C++, please mind the following subtle differences (see also lite-C for C/C++ programmers):

No variable initialization

The lite-C compiler initializes all global and local variables and arrays to 0; a normal C++ compiler does not. This means they have random content at start. So take care to properly initialize all variables when necessary (normally also recommended in lite-C code!):
var MyArray[10];  // lite-C; automatically initialized to zero
var MyArray[10] = { 0,0,0,0,0,0,0,0,0,0 }; // C++

No parameter omitting

Some functions, for instance the date/time functions, can be called without parameter. The lite-C compiler replaces the missing parameter with 0. Not so in C++. Pass all required parameters.
int CurrentMonth = month();  // lite-C; missing parameter is assumed zero
int CurrentMonth = month(0); // C++

No automatic type conversion

In lite-C, 32-bit integer types or pointers like char*, void*, int, long, DWORD etc are converted without explicit typecasting. Not so in C++. Use typecast operators when required.
int Pos = brokerCommand(GET_POSITION,Asset);  // lite-C
int Pos = brokerCommand(GET_POSITION,(DWORD)Asset);  // C++

Early comparison abort

In lite-C, the order of expressions in a comparison plays no role. In C/C++, comparisons with && or || are order sensitive. The comparison is aborted when a && is encountered and the expression so far evaluated to false, or when a || is encountered and the expression evaluated to true. This can cause a different behavior when the comparison contains function calls:
if(test(x) && test(y)) .. // lite-C always calls test(x) and test(y)
if(test(x) && test(y)) .. // C++ calls test(y) dependent on what's returned by test(x)

Exported and void functions

If functions do not return something, define them with void. A function defined with function must return an int. If functions are exported by the DLL - such as run, main, objective, etc - define them also with the DLLFUNC macro:
function run() { ... } // lite-C
DLLFUNC void run() { ... } // C++

No parameter skipping

In lite-C, function parameters can often be omitted when they are 0. For this purpose, the lite-C compiler offers a variable that contains the number of parameters. This variable is not available in C++, so default parameters must be explicitely defined. The zorro.h include file has such definitions for most functions with multiple parameters, but not for single-parameter functions.
var Close = priceClose();  // lite-C
var Close = priceClose(0); // C++

Different string type

In lite-C, strings can be compared with string constants using the normal comparison operators, such as ==, !=, or In the C++ DLL headers, a string is typedef'd as a char* pointer, and comparison with a constant would always result in false. Either use C++ types like CString or basic_string for string handling (but make sure to call lite-C functions always with C-style, null-terminated strings), or use the str... functions from the C library.
if(Algo == "TRND") ... // lite-C
if(0 == strcmp(Algo,"TRND")) ... // C++

Different bool type

In lite-C, bool has a size of 4 bytes, in C++ it's 1 byte. The lite-C bool type is equivalent to the Win32 BOOL type. For avoiding confusion, you might prefer to use int instead of bool / BOOL.

No watch() statements

Zorro's single-step debugger can still be used with a DLL, but the watch statement can not. Use printf() or print(TO_WINDOW,...) instead.
watch("My Variable: ",MyVar) // lite-C
print(TO_WINDOW,"\nMy Variable: %.2f",MyVar) // C++

Colliding definitions

Many lite-C variables and flags are pre-defined in variables.h and trading.h. If you're using a C++ library with a function, variable, or flag that has the same name, undefine the lite-C keyword with an #undef statement after including zorro.h and before including the headers of your library. Otherwise you'll get compiler errors.

Using DLL functions

In lite-C, the API macro imports functions from a DLL library. In C/C++, use the LoadLibrary and GetProcAddress standard functions for that:
int __stdcall MyDLLFunction(double a,double b);
API(MyDLL,MyDLLFunction) // lite-C
int (__stdcall *MyDLLFunction)(double a,double b);
HMODULE DllHandle = LoadLibrary("MyDLL");  // C/C++
if(DllHandle) {
   *(FARPROC*)&MyDLLFunction = GetProcAddress(DllHandle,"MyDLLFunction");
if(DllHandle) FreeLibrary(DllHandle);

Lite-C libraries

Some lite-C libraries such as profile.c or r.h contain function bodies, so they can be included in the main strategy code only, but not in multiple source modules.

Click and evaluate

In lite-C, click and evaluate functions could be triggered by button clicks even after the script run, as long as no other script was selected. DLL functions can only be triggered while the script is running.

Using other languages

You can write strategy DLLs in any language that supports 32-bit dynamic link libraries. In that case you must adapt the headers to the used language, and also adapt the ZorroDLL.cpp. Aside from the DLL entry point that is unused, it contains a zorro() function that is called upon strategy start, and receives a pointer to the GLOBALS struct. The GLOBALS struct is defined in trading.h. It is a singleton with all predefined variables and functions. Its Functions pointer leads to a list of 32-bit addresses of the functions in the same order as listed in functions.h. The functions must be called with __cdecl calling convention.

When importing the GLOBALS struct, set up the compiler so that it does not pad structs with dummy elements for aligning the struct members. If available, set the struct alignment to 4 bytes or below. This is needed to ensure that the structs have identical size in your DLL and in Zorro.  

See also:

API, lite-C vs C++, migration, engine API

► latest version online