When starting with Zorro, you might have used another trade platform or development system before, and would like to take over your familiar strategies, indicators, and algorithms. The examples below show how to convert the code of different platforms.

**TradeStation** was the first platform that supported automated trading. Its **EasyLanguage**™, also used by the MultiCharts platform, has a similar design philosophy as Zorro's lite-C. Although its syntax is a C/Pascal mix and requires some code modifications, conversion to C is relatively straightforward. EasyLanguage **Vars** are equivalent to lite-C data series. However, EasyLanguage makes no distinction between series and variables - f.i. **myseries** is the same as **myseries[0]**. In most cases, **Vars** is only a single variable (**var**), but sometimes it's a series (**vars**), as **movAvgVal** in the second example below. Easylanguage also stores the content of variables - if this is required, declare a **static var** in lite-C. Trigonometric functions expect angles in degrees, while in lite-C and most other languages angles are in radians.

EasyLanguage has no native functions, but separate scripts can be called like functions. The execution of an EasyLanguage script is similar to a lite-C script, with a lookback period determined by the **MaxBarsBack** variable. Aside from the function definitions, EasyLanguage strategies and lite-C strategies look very similar.

{ Easylanguage version } { Choppy Market Index Function by George Pruitt }

Inputs: periodLength(Numeric); Vars: num(0),denom(1);

if(periodLength <> 0) then

begin

denom = Highest(High,periodLength) – Lowest(Low,periodLength);

num = Close[periodLength-1] – Close;

ChoppyMarketIndex = 0.0;

if(denom <> 0) then ChoppyMarketIndex = AbsValue(num/demon)*100;

end;

// lite-C version // Choppy Market Index Function by George Pruitt

var ChoppyMarketIndex(int periodLength) { if(periodLength != 0) {

var denom = HH(periodLength) – LL(periodLength);

var num = priceClose(periodLength-1) – priceClose();

if(denom != 0) return abs(num/denom)*100; } return 0;

}

{ Easylanguage version }{ enter a trade when the RSI12 crosses over 75 or under 25 }Inputs: Price(Close),LengthLE(12),LengthSE(12), OverSold(25),OverBought(75),StoplossPips(200),ProfitTargetPips(200); variables: var0(0),var1(0);{ get the RSI series }var0 = RSI( Price, LengthLE ); var1 = RSI( Price, LengthSE );{ if rsi crosses over buy level, exit short and enter long }condition1 = Currentbar > 1 and var0 crosses over OverBought ; if condition1 then Buy( "RsiLE" ) next bar at market;{ if rsi crosses below sell level, exit long and enter short }condition2 = Currentbar > 1 and var1 crosses under OverSold ; if condition2 then Sell Short( "RsiSE" ) next bar at market;{ set up stop / profit levels }SetStoploss(StoplossPips); SetProfitTarget(ProfitTargetPips);

// Zorro version// enter a trade when the RSI12 crosses over 75 or under 25function run() {// get the RSI seriesvars Close = series(priceClose()); vars RSI12 = series(RSI(Close,12));// set up stop / profit levelsStop = 200*PIP; TakeProfit = 200*PIP;// if rsi crosses over buy level, exit short and enter longif(crossOver(RSI12,75)) enterLong();// if rsi crosses below sell level, exit long and enter shortif(crossUnder(RSI12,25)) enterShort(); }

This is a popular platform for private traders and provided by most brokers. The **MQ4** script language of its "Expert Advisors" (EAs) is based on C, which would theoretically allow easy conversion to Zorro's lite-C. Unfortunately, MQ4 has many issues that make "Expert Advisors" a lot more complex and difficult to handle than scripts of other platforms.

The MQ4 main script runs at every tick. This means that the last price candle is normally incomplete,
so indicators in EAs return a different value than the same indicators in other
platforms. For fixing this, the EA must check if the candle is complete, or the
indicator must be shifted so that its last value is from the previous candle. Trades are not managed by the platform, but must be managed by code in the script. Series are not natively supported, but emulated with loops and functions. Indicators often produce different results in MQ4 than in other platforms because the MQ4 standard indicators do not use their standard algorithms, but special MQ4 variants. Time zones and account parameters are not normalized, so EAs must be individually adapted to the broker. To complicate matters further, MQ4 does not use common trade units such as lots and pips, but calculates with "standard lots" and "points" that need to be multiplied with account-dependent conversion factors. Most code in an EA is therefore not used for the trade algorithm, but for working around all those problems. This results in the long and complex 'spaghetti code' that is typical for EAs.

For conversion, first remove the MQ4 specific code that is not needed in lite-C, such as trade management loops, broker dependent pip and trade size calculations, and array loops that emulate series. Then the rest can be converted by replacing the MQ4 indicators and trade commands by their lite-C equivalents. Note that the result can still differ due to the effects of incomplete candles and different indicator algorithms.

// MTR4 version // enter a trade when the RSI12 crosses over 75 or under 25int start() {// get the previous and current RSI valuesdouble current_rsi = iRSI(Symbol(), Period(), 12, PRICE_CLOSE, 1);// mind the '1' - candle '0' is incomplete!!double previous_rsi = iRSI(Symbol(), Period(), 12, PRICE_CLOSE, 2);// set up stop / profit levelsdouble stop = 200*Point; double takeprofit = 200*Point;// correction for prices with 3, 5, or 6 digitsint digits = MarketInfo(Symbol(), MODE_DIGITS);

if (digits == 5 || digits == 3) {

stop *= 10; takeprofit *= 10; } else if (digits == 6) {

stop *= 100; takeprofit *= 100; }// find the number of tradesint num_long_trades = 0; int num_short_trades = 0; int magic_number = 12345;

// exit all trades in opposite directionfor(int i = 0; i < OrdersTotal(); i++) {// use OrderSelect to get the info for each tradeif(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;// Trades not belonging to our EA are also found, so it's necessary to// compare the EA magic_number with the order's magic numberif(magic_number != OrderMagicNumber()) continue; if(OrderType() == OP_BUY) {// if rsi crosses below sell level,exit long tradesif((current_rsi < 25.0) && (previous_rsi >= 25.0)) OrderClose(OrderTicket(),OrderLots(),Bid,3,Green); else// otherwise count the tradesnum_long_trades++;} if(OrderType() == OP_SELL) {// if rsi crosses over buy level,exit short tradesif((current_rsi > 75.0) && (previous_rsi <= 75.0)) OrderClose(OrderTicket(),OrderLots(), Ask,3,Green); else// otherwise count the tradesnum_short_trades++; } }// if rsi crosses over buy level, enter longif((current_rsi > 75.0) && (previous_rsi <= 75.0) && (num_long_trades == 0)) { OrderSend(Symbol(),OP_BUY,1.0,Ask,3,Ask-stop,Bid+takeprofit,"",magic_number,0,Green); }// if rsi crosses below sell level, enter shortif((current_rsi < 25.0) && (previous_rsi >= 25.0) && (num_short_trades == 0)) { OrderSend(Symbol(),OP_SELL,1.0,Bid,3,Bid+stop,Ask-takeprofit,"", magic_number,0,Green); } return(0); }

Under Tips & Tricks you can find an example how to replicate MQ4-style indicator parameters with Zorro.// Zorro version// enter a trade when the RSI12 crosses over 75 or under 25function run() {// get the RSI seriesvars Close = series(priceClose()); vars RSI12 = series(RSI(Close,12));// set up stop / profit levels and max tradesStop = 200*PIP; TakeProfit = 200*PIP; MaxLong = MaxShort = 1;// if rsi crosses over buy level, exit short and enter longif(crossOver(RSI12,75)) enterLong();// if rsi crosses below sell level, exit long and enter shortif(crossUnder(RSI12,25)) enterShort(); }

**NinjaScript**™ is based on C# and thus similar in syntax to Zorro's lite-C. NinjaScript also supports data series in the same way as lite-C, and its basic function list is very similar; this makes script migration rather easy. One major difference is that all NinjaTrader indicator functions return data series, while Zorro indicators return single values. Use the series function (f.i. **series(indicator(..))**) for making Zorro indicators also return series.

// NinjaTrader version // Trade when a fast SMA crosses over a slow SMA

protected override void Initialize()

{// Run OnBarUpdate on the close of each bar

CalculateOnBarClose = true;// Set stop loss and profit target at $5 and $10SetStopLoss(CalculationMode.Ticks,5); SetProfitTarget(CalculationMode.Ticks,10); } protected override void OnBarUpdate()

{// don't trade during the LookBack periodif(CurrentBar < 20)

return; double Fast = 10; double Slow = 20;// Exit short and go long if 10 SMA crosses over 20 SMA

if(CrossAbove(SMA(Close,Fast),SMA(Close,Slow),1)) { ExitShort();

EnterLong(); }// Exit long and go short if 10 SMA crosses under 20 SMA

else if(CrossBelow(SMA(Close,Fast),SMA(Close,Slow),1)) { ExitLong();

EnterShort(); } }

// Zorro version// Trade when a fast SMA crosses over a slow SMA

void run()

{// Set stop loss and profit target at $5 and $10Stop = 5; TakeProfit = 10; vars Close = series(priceClose()); vars SMAFast = series(SMA(Close,10)); vars SMASlow = series(SMA(Close,20));// Exit short and go long if 10 SMA crosses over 20 SMA

if(crossOver(SMAFast,SMASlow))

enterLong();// Exit long and go short if 10 SMA crosses under 20 SMA

else if(crossUnder(SMAFast,SMASlow)) enterShort(); }

Amibroker's **AFL** language is a C dialect, with similar syntax as lite-C. But the script structure is different. Amibroker uses a "**Buy**" and "**Sell**" variable for entering trades, instead of a function call. On the other hand, Amibroker calls functions for setting system parameters, instead of using variables. This slightly confusing concept has its reason in a sort of vectorized approach to a trading system, where the code mainly initializes parameters and signal conditions. Variables are not declared, and they are usually series, as in EasyLanguage. Functions are often very similar to lite-C - for instance, **Plot()** or **Optimize()**. Others can be easily converted, f.i. Amibrokers "**Explore**" feature for printing values to a CSV file
is equivalent to Zorro's **print(TO_CSV)**.

// Amibroker version // Trade when a fast SMA crosses over a slow SMA

// Set stop loss and profit target at $5 and $10ApplyStop(stopTypeLoss,stopModePoint,5,0,True,0,0,-1); ApplyStop(stopTypeProfit,stopModePoint,10,0,True,0,0,-1); SMAFast = MA(C,10); SMASlow = MA(C,20);// Buy if 10 SMA crosses over 20 SMA

Buy = Cross(SMAFast,SMASlow);// Sell if 10 SMA crosses under 20 SMA

Sell = Cross(SMASlow,SMAFast);

// Zorro version// Trade when a fast SMA crosses over a slow SMA

void run()

{// Set stop loss and profit target at $5 and $10Stop = 5; TakeProfit = 10; vars Close = series(priceClose()); vars SMAFast = series(SMA(Close,10)); vars SMASlow = series(SMA(Close,20));// Exit short and go long if 10 SMA crosses over 20 SMA

if(crossOver(SMAFast,SMASlow))

enterLong();// Exit long and go short if 10 SMA crosses under 20 SMA

else if(crossUnder(SMAFast,SMASlow)) enterShort(); }

**Neuroshell Trader**™ is a platform specialized in employing a simple neural network for automated trading. Neuroshell indicators are functions added through DLLs. They take an input array, an output array, the array size, and additional parameters. Many other trade platforms use similar DLL based indicators. Such indicators are often based on normal C, thus conversion to Zorro is very easy - especially when you don't have to convert it at all and can call the DLL function directly.

When using an indicator made for a different platform, the array order convention must be take care of. Neuroshell stores time series in ascending order (contrary to most other platforms that store them in reverse order) and passes the end of the array, not its begin, to the indicator function. Neuroshell indicators normally return an output series instead of a single value. Below both methods of indicator conversion are shown.

// Neuroshell version - Entropy indicator // published by ForeTrade Technologies (www.foretrade.com/entropy.htm)#include "math.h" #include "stdlib.h" __declspec(dllexport) void Entropy (double *price, double *entropy, long int size, long int numbars) { double *in, *out, P, G; long int i,j; double sumx = 0.0; double sumx2 = 0.0; double avgx = 0.0; double rmsx = 0.0; in=price; out=entropy; for (i=0; i<size; i++) { if (i < numbars+1) *out = 3.4e38; else { sumx = sumx2 = avgx = rmsx = 0.0; for (j=0;j<numbars+1;j++) { sumx += log(*(in-j) / *(in-j-1)) ; sumx2 += log(*(in-j) / *(in-j-1)) * log(*(in-j) / *(in-j-1)); } if (numbars==0) { avgx = *in; rmsx = 0.0; } else { avgx = sumx / numbars; rmsx = sqrt(sumx2/numbars); } P = ((avgx/rmsx)+1)/2.0; G = P * log(1+rmsx) + (1-P) * log(1-rmsx); *out=G; } in++; out++; } }

// Zorro version - Entropy indicator // Method 1 - calling the DLL function directly// Copy the Entropy DLL into the Zorro folderint __stdcall Entropy(double *price, double *entropy, long size, long numbars);// function prototypeAPI(Entropy,entropy)// use the Entropy function from entropy.dllvar EntropyZ(vars Data,int Period) { Period = clamp(Period,1,LookBack-1);// prevent exceeding the Data sizedouble E;// single element "array" for receiving the output valueEntropy( Data+Period+1,// end of the array (element order does not matter here)&E, 1,// pointer to the output "array" with size 1Period); return E; }

// Zorro version - Entropy indicator // Method 2 - converting the DLL code to lite-Cvar EntropyZ(vars Data,int Period) { Period = clamp(Period,1,LookBack-1);// prevent exceeding the Data sizevar sumx = 0., sumx2 = 0.; int j; for (j=0; j<Period; j++) { sumx += log(Data[j]/Data[j+1]); sumx2 += log(Data[j]/Data[j+1]) * log(Data[j]/Data[j+1]); } var avgx = sumx/Period; var rmsx = sqrt(sumx2/Period); var P = ((avgx/rmsx)+1)/2.; return P * log(1+rmsx) + (1-P) * log(1-rmsx); }

R is an interactive script language and an open source environment for statistical computations and charting, developed in 1996 by New Zealand scientists Ross Ihaka and Robert Gentleman of Oakland University. It is meanwhile the global standard in statistical computations and has a large set of packages for all advanced fields of statistics, machine learning and data mining.

Although it is possible, it normally makes no sense to convert complex R calculations to lite-C scripts, especially when R 'packages' are used. An easier way is available through the R bridge for directly executing R functions in lite-C.

MatLab™ is a commercial computing environment and interactive programming language by MathWorks, Inc. Other than R, it is not specialized on data analysis and machine learning, but allows symbolic and numerical computing in all fields of mathematics. Its integrated compiler makes it relatively easy to convert a MatLab trading algorithm to a C/C++ DLL that can then be used with Zorro.