Migration from MQL to C#

Both MQL and C# share the basic C language syntax, which makes it easy to migrate from MQL4 to C#. Most operations, operators, expressions are identical in both languages and will work without a change. Most of the primitive types have their C# equivalents. Check out the language primitive types comparison table.

MQL C#
int int
double double
bool bool
string string
datetime System.DateTime
color System.Drawing.Color
void void

Arrays

The syntax for arrays is similar, but has a small differences. Array access and initialization is the same. Array declaration differs a little. For example :

MQL C#
// array of integers with a fixed size int years[10]; // array of integers with unknown size int years[]; // 2-dimensional array int deck[4][13]; int card = deck[0][5]; // array of integers with a fixed size int[] years = new int[10]; // array of integers with unknown size int years[]; // 2-dimensional array int[,] deck = new int[4, 13]; int card = deck[0, 5];

datetime

In MQL datetime can be seemlessly converted to integer and back. Normally you don't use this, and you manipulate datetime variables using datetime functions. When you want to add or subtract some seconds to a date value, you can use "TimeSpan.FromSeconds(n)" method. In case you need to convert, the NQuotes library provides the API - MqlDateTime class.

Be careful about time zones. All MQL functions and MqlDateTime class return dates as a DateTime in unknown time zone (DateTimeKind.Unspecified). If you are comparing dates returned from the same source, this is not a problem, but if you want to compare dates returned from different sources, or save a date in a known format to be used by another program, you'll have to convert it into a certain time zone (for example GMT).

  • Let's say you want to convert a date that's returned by TimeLocal() into GMT. This is the simplest, just call: date.ToUniversalTime()
  • If you use Alpari NZ terminal and connect to an "Alpari-ECN-Demo" server, then Time[] array contains GMT datetimes in MQL. If you want to convert a date returned from Time[i] to DateTimeKind.Utc, you could use: TimeZoneInfo.ConvertTimeFromUtc(date, TimeZoneInfo.Utc)
  • Depending on your broker, a datetime returned from TimeCurrent() can be in various time zones. For example, "Alpari-ECN-Demo" server gives this date in CET. If you want to convert such a DateTime into GMT, you would call: TimeZoneInfo.ConvertTimeBySystemTimeZoneId(date, "Central European Standard Time", "UTC")

Sometimes functions take uninitialized date value (zero) as a default argument. In this case you should use "DateTime.MinValue" constant.

color

In MQL color can be seemlessly converted to integer and back. In C# normally the System.Drawing.Color methods are used to create colors. For example, instead of "Red" constant you can use "Color.Red". In the case when you need to convert a numeric color value to the Color object, there's a standard API to do that:
- System.Drawing.ColorTranslator.ToWin32 to convert from System.Drawing.Color to MQL integer color
- System.Drawing.ColorTranslator.FromWin32 to convert from to MQL integer color to System.Drawing.Color

Sometimes functions take a special color value "CLR_NONE" as a default argument. In this case you should use "Color.Empty" constant.

Passing parameters by reference

MQL C#
void whereIsIt(int& x, int& y) { x = 100; y = 200; } void whereIsIt(ref int x, ref int y) { x = 100; y = 200; }

Expert advisor migration

C# doesn't have the global space. All functions and variables must be placed inside classes. To access the MQL API you need to inherit the class from "NQuotes.MqlApi" class. Special functions (init, deinit and start) must be declared with "public override". Special functions must return "int", not "void". For example:

MQL C#
// MyExpert.mq4 int foo = 1; int init() { return (0); } int start() { Print("hello"); return (0); } public class MyExpert : NQuotes.MqlApi { int foo = 1; public override int init() { return (0); } public override int start() { Print("hello"); return (0); } }

Preprocessor

C# doesn't have an MQL4 preprocessor, but it has equivalent features.

Instead of "#include" you normally place the functions into a static class and then refer to functions through this class name prefix. It is also possible to implement these functions as extensions of the expert advisor class, and refer to them with "this." prefix.

Instead of "#define" you should use constants. For example:

MQL C#
#define PI 0.314 const double PI = 0.314;

If you are using DLLs with "#import", you can instead use the Platform Invocation Services (PInvoke).

"extern" and "input" parameters

Extern or input variables determine inputs of the program. They can be altered in a dialog that shows up when you start an expert advisor. The parameter type must be one of the primitive types (see the table above).

MQL C#
extern double TrailingStop = 30; public double TrailingStop = 30;

For more details see the guide: How to use extern variables and optimization.

Compilation properties

In C# you normally use a special file "AssemblyInfo.cs" in the "Properties" folder to specify the assembly attributes like AssemblyProduct and AssemblyCopyright. It is possible to customize MQL "#property link" and "#property copyright" and some other "#property" directives. For more details see the guide: How to customize expert branding and prepare for distribution.