Migrating old MQL4 to new MQL4
This guide is for people that want to migrate existing MQL4 scripts to work with the new terminal build as quickly as possible without taking advantage of the new object oriented contructs available.
It has been collated from various posts on the mql4 forum.
Disclaimer: I've not tested all of this myself! First read as much as you can about the language changes (ignoring any Object Oriented related stuff).
Then check you code for all of the following contructs and review/fix...
In some cases the fixes below are not as good as restructuring your code to properly use the new features!
Once running, if your script is still a work in progress you may want to add the
#property strict directive and recompile again. This will mean you need to make more changes , to get your code to compile cleanly but it will result in cleaner code and may find some bugs.
New Reserved Keywords
MQL4 has some new reserved keywords such as 'char','long','short' and 'new'. If you have variables with the same name you'll need to change them. datetime is 64bit
The datetime type is a 64bit integer, so you will get loss of precision errors converting to int(which is 32bit). Avoid converting it to any other type but datetime ArrayCopyRates()
This has changed to making a static copy of the rates array (as opposed to pointing to a virtual area that is updated with each tick). Change code to use the new CopyRates() GetLastError()
GetLastError does not reset the previous error anymore. Call ResetError as required. Or replace with:
int GetLastErrorOld() { int err = GetLastError(); ResetError(); return err; } The Data Folder Location
Change all reference to file data paths. eg TerminalPath() becomes either TerminalInfoString(TERMINAL_DATA_PATH); or TerminalInfoString(TERMINAL_COMMONDATA_PATH) Unicode(UTF16) Strings
Strings are now unicode in MQL4. When passing strings to DLL functions either:
1. Use the UTF16(2byte wide) version of the function Eg. Use ShellExecuteW instead of ShellExecuteA
2.Convert the string to ASCII and use the existing function Arrays pass by value
You cannot pass arrays by value. There are two simple fixes:
1. If the function does not modify the local array, then simply pass it by reference (adding '&' ), and if applicable add a comment "do not modify local array"
2. If the function modified the local copy, then change it so it doesnt - eg make a local copy inside the function and use that. StringSubstr - end of string flag
The end-of-string flag is changed from 0 to -1 in line with MQL5. Also if thre start character is less than 0 then new MQL4 may corrupt strings. Use the following when migrating existing code:
string StringSubstrOld(string x,int a,int b=-1) { if (a < 0) a= 0; // Stop odd behaviour if (b<=0) b = -1; // new MQL4 EOL flag return StringSubstr(x,a,b); } It might be possible to #define this. Short Circuiting
Boolean expresions now short circuit. So if an expression contains a function call, that function would always get called on old MQL4, but might not get called in new MQL4. If the function changed something in the program (ie had a side effect), and that change is required to happen, then place the function call ahead of the boolean expression. Eg. replace and ensure functions with required side effects are called ahead of expression evaluation.
if (Ask > price && GetNextPrice(price2)) then ... with
bool tmp = GetNextPrice(price2); if (Ask > price && tmp) ) then ... Precedence
MQL4 Precedence is changed. In Old MQL4 boolean OR(||) had higher precedence than boolean AND(&&). Inew new MQL4 the precedence is the same. Search for expressions where || folow && and add brackets around immediate || arguments. History Files
History files and offline charts are changed. I must admit I haven't looked into these changes because I have not used these features. Sorry! Bug build 604: ArrayResize on non-dynamic arrays fails silently
Compiler should issue a warning when trying to resize a non-dynamic array. see Forum post Bug build 604: FileReadArray bug with strings
Strings are corrupted when read. Use FileReadString(handle) in a loop until fixed. see Forum post Bug build 604: Array Resize returns size of first dimension
ArrayResize returns size of first dimension not whole array. Contrary to documentation... Cant find thread where this was reported.. old version:
double ratesArrayCopy[][6]; int size = ArrayResize(ratesArrayCopy, 10); //I got size= 60 new version:
double ratesArrayCopy[][6]; int size = ArrayResize(ratesArrayCopy, 10); //I got size= 10 ?
Bookmarks