How to Code & Compile MQL5 in Visual Studio - A Complete Guide

How to Code & Compile MQL5 in Visual Studio - A Complete Guide

13 July 2018, 21:52
Minions Labs
13
1 430

After reviewing a couple of alternative IDEs/Source Code Editors that could be used to code and compile in MQL5 instead of using the original Metaeditor IDE, I decided to go with Visual Studio Code, from Microsoft. I will not discuss here what was my approach to finally choose VSC as my official MQL5 IDE, the goal of this post is to present a complete guide for those of you who want to experiment a better IDE and eliminating some feature and productivity limitations presented by Metaeditor, that in my personal programming experience made me search for a better alternative.

When I started to look around my plan was to switch completely from Metaeditor to a 3rd party solution. One of the main concerns I had was to have the ability to get the compiling results within the IDE in some way, so I don't ever have to switch back and forth between VSC and Metaeditor to get my things done and ready to run. I think that I accomplished that with VSC.

Just a one-phrase background, I have more than 30 years of programming experience, and started programming - there were no source code editors at that time - in Applesoft BASIC's Command Line and saving my code in a tape recorder :D

And, just a last word before we begin, if you are a novice programmer (or even a good programmer, but new to MQL5) I strongly recommend to you to stick with Metaeditor for a while until you have enough comfort and experience to search for a better IDE. Additionally, if you are not familiar with Windows Powershell or JSON notation you may have a hard time configuring VSC to your needs. I prepared all this article as detailed as possible, but it is possible that in some step you will get confused or lost. So, please read the whole article before you take any action. If at any point you feel that this "is not for me", don't proceed!


WHY CHANGE?

  • Dark Mode - I always used dark backgrounds for everything I do in computers/devices. Using Metaeditor a lot and also for very long hours with light backgrounds spreads my attention away from the code and Syntax Highlighting gets weak. There are several reasons/stories/tribes in favor of both modes Ligth and Dark, and I will not discuss this in here. I want it Dark! Period.
  • I Hate the F7 Key - I always miss the F7 key to compile my code ending up hitting the other keys around. Also, the F7 key is located far away from both hands forcing me to move my forearm, or worse, lifting my whole arm just to hit the damn key. I know, I can click on "Compile" with my mouse, but this is not an option for me, I'm a keyboard guy.
  • Compiling Large Projects - Using Metaeditor, when editing a child file (i.e. #include file) of your project forces you to switch back to the Main tab of your project to compile it, otherwise you will be compiling the just the current file, not the entire project. So the compiling process gets really annoying and counterproductive.
  • No Key Bindings - The best Source Code Editor is the one who adapts to your needs and style, not the other way around. In Metaeditor you cannot remap your keyboard and this is imperative to me.
  • Code in Other Languages - I use other programming languages for other projects I have, so having a single harmonic IDE is a bless.
  • & Many Other Bells & Wisthles - Intellisense, Multi-cursors, Code Minimap, Line actions, Key binding, Rename Refactoring, Code folding, Smart indentation, and many more.

INSTALLING VISUAL STUDIO CODE

Well, we are talking here about the Open Source project from Microsoft called Visual Studio Code. It is completely FREE for personal and commercial use. Download it from here: code.visualstudio.com. Install it - the process is plain simple and common. Then, launch it. VSC will automatically launch a web page with initial tutorials, it is a good idea to have a peek at all those features since VSC is a very powerful tool and totally hackable to your needs. And that's tha magic behind it.

If you ever used editors like Sublime Text or Atom, you will find yourself at home with the Command Palette (CTRTL-SHIFT-P). This is were all the magic happens. Just type what you want, and voilà! If you never used editors such those, it will be a little strange since all settings are done through the use of JSON files, even the Main Preferences of VSC is a JSON file, but it is all very well docummented and easy to understand. So if this is your case, I recommend you to watch a couple of videos to get comfortable with your new home for coding. This is my current Code screen after applying all my desired configurations:

VSC main screen.



SETTING YOUR WORKSPACE

After launching VSC you will be presented with someting like this (after closing the Welcome Screen). Just click on Open Folder to prepare your environment for MQL5 coding:

empty workspace.

The folder to be referenced is the base MQL5 tree of your Metatrader data (where all indicators, experts and code reside). If you don't know where is it, just go to your Metaeditor, right-click on the MQL5 top node and choose "Open Folder":

Metaeditor navigator

To get the complete path, just click on the path address and Windows will give you the full stuff. Copy this address to the Clipboard.

Windows MQL5 data location

And that's it! You will have something like the screen below:

After opening a folder in VSC.

You can start browsing and opening all your files! But of course you need to start to set up your environment to your taste. By now, you will have all your world in plain Black&White. Why? by default VSC installation do not recognize MQL as a known language in order to activate the proper Syntax Highlighting.

VSC, but No Colors.


SETTING SYNTAX HIGHLIGHTING

One of the marvelous things about VSC is its Marketplace of Extensions, that can be plugged in at your command. Fast and Easy! You can visit the VSC Marketplace here. There are a couple of packages that could enable the recognition of the MQL5. You can install them directly from VSC or from the Marketplace (the extensions URLs will be activated within VSC). It is your choice. Let's use the Marketplace, searching for the keyword "MQL":

Marketplace search for "MQL"

To know better each of the found items, just click on each one to see the description and usage. Start by installing the "MQL4 Syntax Highlighting" extension. Just click on the big green "Install" button on the web page. The extension installation will be redirected to your VSC window. In VSC, click on the install button again. After installing you very first extension, instead of a green "install" button you will see now 2 Blue buttons: Reload and Uninstall. This is the common behavior of VSC for almost every extension you install. Because VSC just received a new extension in its environment you must reload the whole editor, just click "Reload" and that's it, you are done!

* Special thanks to Emmanuel Roche (NervTech) and @Nicholishen for those great extensions! *

If you go and open any .mq5 file again you will see your code in total color!

.mq5 code in color!

Then, install the "MQL Extension Pack" which will install the other 2 extensions (Snippets and Syntax Over CPP) and other 2 more extensions needed for the whole thing work (Code Intellisense). After all the installations, click on the Extensions Manager icon in your VSC envirnonment and click on the "mql-syntax-over-cpp" extension. You need to map the MQL file extensions in order for all to work. Read the "requirements" sections of this extension and copy the code stated there to your clipboard:

Mapping files for Intellisense.

Then, go to the menu FILE > PREFERENCES > SETTINGS. A 2-panel window will open. The left side is read-only and it is intended for you to read what is set in the environment and what could be changed (written/copied) to the right side of the window = Your User Settings. All User Settings are unique, so my settings are different from yours, but the current addition should be like this (don't forget the proper formatting of JSON files, do not forget to add commas when you add content to an existing file):

File associations for Intellisense.

Also, if you want to disable those red squiggles that would appear in some places on your code, just add to your User Settings the line below, as shown in the previous picture. Don't forget the commas!

"C_Cpp.errorSquiggles": "Disabled"

And that's it regarding Syntax Highlighting.


SETTING YOUR THEME

If the way of the colors presented in your code are not of your taste, you can change them - Another cool thing of VSC. There are tons of Themes in the Marketplace you can try. Some extensions could come with a multiple range of themes within a single Extension, others just have 1 theme per Extension. One I recommend is the "Rainglow" which comes with several cool color palettes. Feel free to try several of them until you choose the perfect one for you, just remember to uninstall all the unused ones to avoid bloating your VSC installation.

After installing a theme (do not forget to "Reload" your system), you can change the theme of your VSC using the keys CTRL-K-T (K and T pressed in sequence, while holding the CTRL) and a list of all the installed themes will appear. And, another violà!

TIP: Instead of choosing your Theme with the mouse, use the Up and Down arrows to cycle the theme list, so the Theme will be applied to your interface in realtime!

A new Theme selected from the list



PREPARING INTELLISENSE

#include References

Metatrader itself knows exactly where all its native #includes are (i.e. Trade class, Symbol Class, etc, etc...) but VSC don't. When you open a .mq5 file that has an #include of this type, a visual warning will appear on the code:

#include error detected.

To fix this, open the Command Palette (CTRL-SHIFT-P) and type "Config". Choose "C/Cpp: Edit Configurations...".

C/Cpp Config.

VSC will open the file c_cpp_properties.json. Just add one more line into the "includePath" section, referencing the full path to YOUR Metatrader 5 installation, adding at the end of the path the "\\Include" folder (you can find the exact location of your installation by right-clicking on the "MQL5" item in the Metaeditor Navigator, and then choose "Open Folder"). When inserting the new line into the JSON file, do not forget to add a comma at the previous line:

Adding MQL5 include path.



VERSION CONTROL OF YOUR CODE

It is always (and highly) recommended to use any kind of versioning of your code. Even if you don't know exactly what Version Control is, just at least use a manual cloud backup to, i.e. Dropbox, GDrive etc. Double backups! Always!

I love .Git and use it for several years now. In the long past ago I used CVS and Subversion. For MQL, I use a repository in my local machines and a second backup on the cloud via BitBucket. Just like choosing an IDE, chosing a Version Control solution is a personal choice that requires a little thinking about your needs. Metaquotes allow you to have a free storage space in their servers via MQL Storage and link it directly to your Metaeditor. The MQL Storage backend is Subversion. It is YOUR homework to find the best way to backup your code. I'm posting this section because Visual Studio Code allows right out of the box the use of .Git on your code and you will be tempted to try it out, and this could be dangerous.

SO, A WARNING!

DO NOT USE Git and Metaeditor's MQL Storage at the same time! Things could get very messy! If you already use MQL Storage and plan to migrate your versioning control to .Git, Double Backup your whole world of code manually, disable MQL Storage on your machines, Restore your backup, Check if everything is OK in all machines making sure that MQL Storage IS disabled, and then (and only then) you can start your repository in .Git.  If you don't know how to do it, stay with MQL Storage.



ESSENTIAL KEY BINDINGS

Below you will find some key mappings that I think are interesting. To add them to your VSC installation, go to the menu FILE > PREFERENCES > KEYBOARD SHORTCUTS, and on the window shown click on the link called "For advanced customizations open and edit keybindings.json". This will open on the left panel the overall key bindings (this is a read-only list) and on the right side you will see your personal Key Bindings. Paste there the code below - adapt/remap as you wish:

[
    { "key": "f5", "command": "workbench.action.reloadWindow" },
    { "key": "ctrl+shift+c", "command": "workbench.action.tasks.build" },
    { "key": "ctrl+shift+x", "command": "workbench.action.tasks.runTask", "args": "Compile-Project-X" },
    { "key": "f1", "command": "workbench.action.tasks.runTask", "args": "launch_offline_help" }
]
  1. The F5 key is a practical way to Reload your entire interface every time you install a new Extension.
  2. The CTRL-SHIFT-C is a remap of the VSC original Build Code (CTRL-SHIFT-B). I remapped because (to me) on my keyboard, I have to spread my fingers too much to repeatedly Build my MQL code. It's you choice to use any other key mapping.
  3. The CTRL-SHIFT-X is a key bind to compile a more complex object in MQL where the main .mq5 file is hard-coded on the task. (more on this on the next sections)
  4. The F1 key is mapped to launch a Context-Sensitive Help for the MQL5 Reference language. To be used, you just to highlight the keyword/function/statement in your MQL5 code and press F1. (the other part of this magic - calling the help file - I will explain in the next sections).

Remember to always make a backup of this settings anywhere you want. I prefer to save my code snippets in a a Gist in my GitHub space. So I can grab and update them easily over several machines.



UNDERSTANDING VSC TASKS

Tasks are another VSC wonder. They allow you to automate almost everything in your daily routine of coding, compiling, and whatever more you want. I will not get into the specifics since there is a single-page resource complete with full documentation and examples directly from the Microsoft Visual Studio Code website. I highly recommend to you reading this documentation, it is very easy to understand and to implement it takes a little experience with the Powershell and other Shells available out there.

The implementations I did in VSC Tasks demand the use of Powershell. Probably you only have 2 types of Shells in your Windows machine: Command Prompt (CMD) and Powershell. By installation default, VSC uses Powershell, but if you inadvertently changed it to CMD (Old DOS style shell) all the tasks programmed will fail since they expect to run in Windows Powershell. If you did that, please change it back using the Command Palette (CTRL-SHIFT-P) and just type "Shell". Then, select the "Terminal: Select Default Shell" option, and then, "Powershell". So, don't mess up! Always use Powershell!

Selecting the Default Shell.

Tasks can be run manually via Command Pallete (just type "task", and choose "Run Task") or via key binding. Tasks are saved in a JSON file called "tasks.json". If it is your first time creating a task for your VSC installation, bring up the Command Palette and type "Tasks" and choose the option "Configure Task". Then, choose the option of "Create tasks.json file from template". And then, Choose "Others".

Configure a Task.

Others.

Now you will have an empty template for your tasks. Just save it. This file, as with others you create, they will be bound and saved under the Root folder you chose for your project, that in our case is our base MQL5 data folder where we save all our work:

tasks.json saved.

So, let's configure our first task, the launch of the Context-Sensitive MQL5 help...




TASK TO LAUNCH CONTEXT SENSITIVE HELP  (F1)

Do you remember that we made a mapping to the key F1 to call the the label "launch_offline_help"? Well, let's create a task for it. Open your tasks.json from the navigator tree, or use the Command Palette (then type "task" and choose "Configure Task"). Since you have no useful code in the file (because it is new), you can just copy and paste the whole code below over the one you have in your screen:

(don't forget to update the path on the code to YOUR Metatrader instalation!)

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {   //set the label ID for the MQL5 Reference context-sensitive help to be launched
            "label": "launch_offline_help",
            "type": "shell",
            "presentation": {
                "echo": false,
                "reveal": "silent",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": false
            },
            "command": "hh.exe",
            "args": [
                "mk:@MSITStore:C:\\Users\\Acme\\AppData\\Roaming\\MetaQuotes\\Terminal\\Help\\mql5.chm::/${selectedText}.htm"
            ]
        }
    ]
}

I will not explain all the code here, please use the Tasks documentation to learn all the meaning of all the standard Tasks instructions present in the JSON, the important line is the process of invoking the Windows Help (the hh.exe file in the command statement) and passing to it as an argument the code to activate directly the specific Help Topic that is currently and supposedly selected by you in you MQL code file. "${selectedText}" is a global VSC variable that holds the current cursor selection of a piece of data. Nothing is perfect, so if in the case of nothing is currently selected on the code, if you press F1 it will produce an error message. But, I can live with that.



TASK TO LAUNCH THE COMPILE OF MQL CODE  (CTRL-SHIFT-C / CTRL-SHIFT-X)

When compiling MQL code you basically have 2 situations: You are building, let's say an indicator, that is formed by only one file (could have includes, but you are not editing those includes, just the main and solely file); Or you are building a more sophisticated project that is formed by various files and all of them could be being edited at the same time, but you need a way that when you hit the compile key, the appropriate master file is compiled, no matter in which code tab/file you currently are.

So I created 2 more tasks on our tasks.json file, one that uses the key binding CTRL-SHIFT-C for single .mq5 files and CTRL-SHIFT-X which uses a fixed .mq5 file to compile. You can map whatever key combination you like. It is your way, your freedom. This is the beauty of a hackable Editor.

The following code is the final tasks.json file, just copy the whole thing and paste over your old content:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Compile-Project-X",
            "type": "shell",
            "command": "C:\\Users\\Acme\\AppData\\Roaming\\MetaQuotes\\Terminal\\83D4764E0403A8685E84D6FCAB361879\\MQL5\\Compile-MQL.ps1  C:\\Users\\Acme\\AppData\\Roaming\\MetaQuotes\\Terminal\\83D4764E0403A8685E84D6FCAB361879\\MQL5\\Experts\\ProjectX\\ProjectX.mq5",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": false
            }
        },
        {
            "label": "Compile-MQL",
            "type": "shell",
            "command": "C:\\Users\\Acme\\AppData\\Roaming\\MetaQuotes\\Terminal\\83D4764E0403A8685E84D6FCAB361879\\MQL5\\Compile-MQL.ps1 ${file}",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": false
            },
            "group": {
                "kind": "build",
                "isDefault": true
            }
        },
        {
            "label": "launch_offline_help",
            "type": "shell",
            "presentation": {
                "echo": false,
                "reveal": "silent",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": false
            },
            "command": "hh.exe",
            "args": [
                "mk:@MSITStore:C:\\Users\\Acme\\AppData\\Roaming\\MetaQuotes\\Terminal\\Help\\mql5.chm::/${selectedText}.htm"
            ]
        }
    ]
}

And that's it regarding Tasks. The only piece missing is the Powershell file that do all the trick calling the Metaeditor compiler and filters out the results, giving you a cleaner visual feedback of what is going on with your code (Compile-MQL.ps1).



POWERSHELL COMPILER LAUNCHER - COMPILE-MQL.PS1

I isolated all the code realted to call the Metaeditor compiler and filter out the compiling results from the log files in one file which I named "Compile-MQL.ps1". It is a Powershell programmed file that is very simple and I tried to document each line to give you all necessary information about what is going on on each line so you can change/add/remove/hack eveything the way you need.

WARNING #1:  For some reason that I couldn't discover, compiling .mq5 files containing blank spaces on its names or on its paths will break the compilation process. I didn't dig deeper into the subject because all my files have no blank spaces on their names, so I'm OK with that. If you find a way to compile names with spaces ping me and I will update the code below.

WARNING #2:  There was another bizarre discovery I found that the CLI (Command Line Interface) compiling process DOESN'T signals Metatrader (Terminal64.exe) that a new code (.ex5) was recompiled (so it has to reload all from disk again, as it does when you recompile your code within Metaeditor). Recompiling you code with CLI DOESNOT reload the code within Terminal64! I tried everything, and the final "Wreck-It-Ralph" solution was knocking down Terminal64.exe from memory and, after a succesfully compilation, bring it back re-executing it. If you come up with an alternative, please share with us.

I use an Intel i5/16GB RAM as my DEV machine so in my development process doing this process of killing and respawning Terminal64 is pretty acceptable, but it all depends on what machine you have and all the programs you have running concurrently to have a good feeling if this is a good development solution for you. So, before you try this approach of VSC, try to kill and respawn Terminal/Terminal64 several times to see the loading time.

Instead of saving the file and maintaining several versions of the file I decide just to put the whole code here. Please copy the whole code and paste it in a clean source file and name it "Compile-MQL.ps1". Put it on the root of YOUR MQL5 data folder, as referenced on the code you read on the previous section.

#gets the File To Compile as an external parameter... Defaults to a Test file...
Param( $FileToCompile = "C:\Users\Acme\AppData\Roaming\MetaQuotes\Terminal\83D4764E0403A8685E84D6FCAB361879\MQL5\Experts\Test.mq5")

#cleans the terminal screen and sets the log file name...
Clear-Host
$LogFile = $FileToCompile + ".log"

#before continue check if the Compile File has any spaces in it...
if ($FileToCompile.Contains(" ")) {
    "";"";
    Write-Host "ERROR!  Impossible to Compile! Your Filename or Path contains SPACES!" -ForegroundColor Red;
    "";
    Write-Host $FileToCompile -ForegroundColor Red;
    "";"";
    return;
}

#first of all, kill MT Terminal (if running)... otherwise it will not see the new compiled version of the code...
Get-Process -Name terminal64 -ErrorAction SilentlyContinue | Where-Object {$_.Id -gt 0} | Stop-Process

#fires up the Metaeditor compiler...
& "C:\Program Files\MetaTrader 5\metaeditor64.exe" /compile:"$FileToCompile" /log:"$LogFile" /inc:"C:\Users\Flavio\AppData\Roaming\MetaQuotes\Terminal\83D4764E0403A8685E84D6FCAB361879\MQL5" | Out-Null

#get some clean real state and tells the user what is being compiled (just the file name, no path)...
"";"";"";"";""
$JustTheFileName = Split-Path $FileToCompile -Leaf
Write-Host "Compiling........: $JustTheFileName"
""

#reads the log file. Eliminates the blank lines. Skip the first line because it is useless.
$Log = Get-Content -Path $LogFile | Where-Object {$_ -ne ""} | Select-Object -Skip 1

#Green color for successful Compilation. Otherwise (error/warning), Red!
$WhichColor = "Red"
$Log | ForEach-Object { if ($_.Contains("0 error(s), 0 warning(s)")) { $WhichColor="Green" } }

#runs through all the log lines...
$Log | ForEach-Object {
     #ignores the ": information: error generating code" line when ME was successful
     if (-Not $_.Contains("information:")) {
           #common log line... just print it...
           Write-Host $_ -ForegroundColor $WhichColor
     }
}

#get the MT Terminal back if all went well...
if ( $WhichColor -eq "Green") { & "C:\Program Files\MetaTrader 5\terminal64.exe" }


And that's it! Your are ready to Roll!



EXAMPLES OF COMPILATION FEEDBACK

Succesfull compilation:

Compilação OK.


Compilation with error. The cool thing is that if you CTRL-Click with your mouse on each error you will be directed exactly to the offending line on your code!

Compilation with errors.



SAVING YOUR WORKSPACE

Well, the last thing you should do now is saving (backing up) your Workspace. The is a whole page explaining what is the difference between User Settings and Workspace Settings that is worth looking. I recommend you to save it in the cloud (Dropbox, GDrive, etc). Just go to the menu FILE > SAVE WORKSPACE AS, and you are done!

I hope this tutorial be helpful for those who always wanted a better IDE to build solutions in MQL5. I apologize for any inaccuracy on the text above, just ping me and I will correct/add/remove the glitches.



FINAL WORDS

All those steps presented in this article were done in a Windows 10 64-bits installation. I don't know if it works in Win7 or Win8. If anything breaks or didn't go well as shown on the steps above, it is YOUR homework to solve the problems. I'm assuming that you are a Power User like me trying to get the most out of a development process and hack your way in. There is plenty of information on the web about Windows, Visual Studio Code, Powershell and JSON. So, before you ping me try to Google the stuff you need. And the last thing, do not even ask me things like "How do I enable my Multi-Cursors?"...


Live Long and Prosper.



Share it with friends: