Introduction
If you've written more than a couple of Expert Advisors in MQL5, you've probably noticed the same pattern: copy-pasting the same money management function, the same trailing stop logic, or the same trade entry helpers into every new EA file. It works, but it's fragile. Fix a bug in one place and you have to patch it across every EA manually. That's where MQL5 include files come in.
An include file (.mqh) lets you write a piece of code once — a function, a class, a set of constants — and pull it into any EA or indicator with a single #include directive. This guide walks you through creating, managing, and using include files in MetaEditor for MT5. By the end, you'll have a reusable library structure that saves you hours of repetitive work and makes your projects easier to maintain.
I've been using this approach for years across dozens of EAs, and it's saved me from countless late-night debugging sessions. The concept is simple, but the details matter — especially when you're juggling multiple projects or sharing code with a team.
Prerequisites
Before you start, you'll need:
- MetaTrader 5 installed and a demo or live account connected. The platform version should be at least build 2000 (check under Help > About). I'm on build 4230 as of writing, but anything from 2000 onward should work fine.
- MetaEditor — it ships with MT5. You can open it from the Tools menu or press F4. If you've never used it, don't worry — it's just a code editor with syntax highlighting.
- At least one MQL5 Expert Advisor you've written or downloaded, so you have something to test the include with. If you're new, create a blank EA via File > New > Expert Advisor in MetaEditor. Name it something like
TestInclude.mq5. - Basic MQL5 syntax knowledge — you should know what a function looks like and how to declare variables. You don't need to be a pro; the examples here are straightforward. If you've written a simple moving average crossover EA, you're good.
I'm assuming you're working on Windows (MT5 doesn't run natively on macOS or Linux without a VM or Wine). All paths and menus refer to the standard MT5 installation folder, typically C:\Users\[YourUserName]\AppData\Roaming\MetaQuotes\Terminal\[InstanceID]\MQL5. The [InstanceID] is a random-looking string of letters and numbers — you'll find it by opening MT5, going to File > Open Data Folder, and looking at the path in the address bar.
Step-by-Step Instructions: Creating and Using MQL5 Include Files
Step 1: Open MetaEditor and Create a New Include File
Launch MetaEditor from MT5's Tools menu (or press F4). In the file tree on the left, expand the MQL5 folder, then right-click the Include folder. Select Create New File.
In the dialog that opens:
- Choose Include File (.mqh) from the list of templates. If you don't see it, select "Other" and name the file with a
.mqhextension manually. - Name your file — something descriptive like
TradeHelpers.mqhorMoneyManagement.mqh. Avoid spaces; use underscores or CamelCase. I prefer CamelCase because it's easier to type in#includedirectives. - Click Create. MetaEditor generates a skeleton with a
#propertyline and an empty file.
You can also create the file manually in Windows Explorer: navigate to ...\MQL5\Include\ and create a new text file, then rename it to .mqh. But the MetaEditor method is cleaner because it sets the correct encoding (UTF-8 without BOM) automatically. If you create the file manually and later get weird compilation errors about invalid characters, re-save it as UTF-8 without BOM in Notepad++ or VS Code.
Step 2: Write Reusable Code in the Include File
Let's say you want a function that calculates position size based on account balance and a risk percentage — something you use in every EA. Open your new .mqh file and add this:
//+------------------------------------------------------------------+
//| MoneyManagement.mqh |
//| Reusable position sizing functions |
//+------------------------------------------------------------------+
#property copyright "YourName"
#property link "https://yourwebsite.com"
// Calculate lot size based on risk percentage of account balance
double CalculateLotSize(double riskPercent, double stopLossPips)
{
double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double riskAmount = accountBalance * (riskPercent / 100.0);
double lotSize = riskAmount / (stopLossPips * tickValue);
// Normalize to broker's lot step
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lotSize = MathFloor(lotSize / lotStep) * lotStep;
// Clamp to min/max
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
if(lotSize < minLot) lotSize = minLot;
if(lotSize > maxLot) lotSize = maxLot;
return NormalizeDouble(lotSize, 2);
}
Save the file (Ctrl+S). You can add multiple functions, constants, or even entire classes here. The key rule: do not include any EA-specific logic like OnTick() or trade opening code. Include files should be generic utilities.
Let me break down what this function does, because it's not immediately obvious from the code alone:
- It gets your current account balance using
AccountInfoDouble(ACCOUNT_BALANCE). - It figures out the tick value for the current symbol — that's how much one pip (or point) is worth in your account currency.
- It calculates the dollar amount you're willing to risk (e.g., 1.5% of $10,000 = $150).
- It divides that risk amount by the total pip value of your stop loss (e.g., $150 / (30 pips * $10 per pip) = 0.5 lots).
- It rounds down to the nearest lot step (e.g., 0.01 lot increments) and clamps to the broker's min/max lot sizes.
One thing I've learned the hard way: always normalize the lot size. Brokers vary in their lot step — some use 0.01, others 0.1. If you don't round down, you might get a "Invalid volume" error when placing the trade.
Step 3: Include the File in Your Expert Advisor
Open your EA's .mq5 file in MetaEditor. At the very top, after the #property lines, add:
#include <MoneyManagement.mqh>
Notice the angle brackets <> — they tell the compiler to look in the standard Include folder. If you put the include file in a subfolder (e.g., Include\MyLib\), use double quotes and the relative path:
#include "MyLib\MoneyManagement.mqh"
Now inside your EA's OnTick() or OnInit(), you can call CalculateLotSize() as if it were defined right there:
void OnTick()
{
double lot = CalculateLotSize(1.5, 30.0); // 1.5% risk, 30-pip stop
// ... rest of your trade logic
}
You can include multiple files, too. I typically have a block at the top of my EA that looks like this:
#include <MyLib_MoneyManagement.mqh>
#include <MyLib_TradeHelpers.mqh>
#include <MyLib_IndicatorWrappers.mqh>
The order matters if one include depends on another — put the dependency first. For example, if TradeHelpers.mqh uses a function from MoneyManagement.mqh, include MoneyManagement.mqh first.
Step 4: Compile and Test
Press F7 (or click the Compile button) in MetaEditor. If everything is correct, you'll see 0 error(s), 0 warning(s) in the log at the bottom. The compiler literally pastes the include file's code into your EA before compiling — so any error in the include file will show up as if it were in the EA.
Attach the EA to a chart in MT5, enable AutoTrading (the green triangle button in the toolbar), and check the Experts tab (View > Toolbox > Experts) for any runtime errors. A common oversight: forgetting to declare the include file's functions as #include-compatible (they must not be inside a class or namespace that expects a different scope).
Here's a quick test I always do: create a simple EA that calls your include function and prints the result. Something like:
//+------------------------------------------------------------------+
//| TestInclude.mq5 |
//+------------------------------------------------------------------+
#property copyright "Test"
#property version "1.00"
#include <MoneyManagement.mqh>
int OnInit()
{
double lot = CalculateLotSize(1.0, 20.0);
Print("Calculated lot size: ", lot);
return INIT_SUCCEEDED;
}
void OnTick() { }
Attach it to a chart and check the Experts tab. If you see a reasonable lot size (like 0.05 or 0.10), you're golden. If you see 0.0 or a huge number, double-check your tick value calculation — some brokers quote in 5 digits, so your pip value might be off by a factor of 10.
Tips and Best Practices from Experience
Over the years, I've refined how I structure include files. Here's what works:
Use a Naming Convention
Prefix your include files to group them logically. For example:
Lib_MoneyManagement.mqhLib_TradeHelpers.mqhLib_Indicators.mqh
This prevents name clashes with third-party includes and makes the Include folder scannable. I also use a version suffix when I'm making breaking changes — like Lib_MoneyManagement_v2.mqh — so old EAs don't suddenly break.
Guard Against Double Inclusion
If you include A.mqh in B.mqh and then include both in your EA, the compiler might error on redefinition. Use the standard header guard pattern at the top of each include file:
//+------------------------------------------------------------------+
//| MoneyManagement.mqh |
//+------------------------------------------------------------------+
#ifndef MONEYMANAGEMENT_MQH
#define MONEYMANAGEMENT_MQH
// ... your code here ...
#endif
The #ifndef / #define / #endif trick ensures the file's contents are only processed once per compilation unit. I always add this — it costs nothing and prevents nasty "redefinition of function" errors when projects grow. The naming convention for the guard macro is usually the filename in uppercase with underscores replacing dots — so MoneyManagement.mqh becomes MONEYMANAGEMENT_MQH.
Keep Include Files Focused
One file should do one thing. Don't throw everything into a single Utilities.mqh that's 2000 lines long. Split by domain: money management, order placement, indicator wrappers, string utilities. Your future self will thank you when you need to reuse only the trailing stop logic in a new EA without dragging in 15 unrelated functions.
I use a simple rule: if a file has more than 10 functions, or the functions don't share a common theme, it's time to split. For example, I keep my trailing stop logic in TrailingStops.mqh separate from MoneyManagement.mqh, even though both deal with risk. They're different concerns.
Document the Interface
Add comments above each function explaining parameters, return values, and any side effects. MQL5's MetaEditor doesn't have built-in IntelliSense for include files, so clear comments are your documentation:
// Calculates lot size for a given risk percentage and stop loss in pips
// riskPercent: percentage of account balance to risk (e.g., 1.5 = 1.5%)
// stopLossPips: stop loss distance in pips (e.g., 30.0)
// Returns: normalized lot size within broker limits
double CalculateLotSize(double riskPercent, double stopLossPips);
I also add a brief example in the comment block for complex functions. It's saved me from re-reading my own code months later.
Version Your Include Files
When you update an include file, old EAs that depend on it might break if you change function signatures. I add a version constant and check it in the EA's OnInit():
// In MoneyManagement.mqh
#define MONEY_MGMT_VERSION 2
// In EA
#include <MoneyManagement.mqh>
int OnInit()
{
if(MONEY_MGMT_VERSION != 2)
{
Print("Incompatible MoneyManagement version. Expected 2.");
return INIT_FAILED;
}
// ...
}
This is overkill for small projects but essential if you distribute your EAs or maintain a library shared by a team. I once broke a colleague's entire trading setup because I changed a function signature without bumping the version — never again.
Use a Consistent Folder Structure
As your library grows, organize includes into subfolders. My typical structure looks like:
| Folder | Contents |
|---|---|
| Include\MyLib\Risk | Money management, position sizing, risk percentage calculations |
| Include\MyLib\Trade | Order placement, modification, closing helpers |
| Include\MyLib\Indicators |
Frequently Asked Questions
Can I use MQL4 include files in MQL5?
No. MQL4 and MQL5 are different languages with different APIs. An MQL4 include file (.mqh extension is also used in MT4) will not compile in MetaEditor for MT5. You must write separate include files for each platform. However, the concept and syntax of #include are identical — only the functions and types differ.
What happens if I include the same file twice in the same EA?
Without header guards (#ifndef), the compiler will error on redefinition of functions, classes, or variables. With proper guards, the second inclusion is silently ignored. Always add the guard pattern to every include file — it's a one-time 3-line addition that prevents a whole class of bugs.
Can I put indicator calls or trade operations inside an include file?
Yes, but be careful. Functions that call iCustom(), CopyRates(), or OrderSend() are perfectly valid in an include file. The risk is making them too tightly coupled to a specific symbol or timeframe. Design your functions to accept symbol and timeframe as parameters, so they remain reusable across different charts.
How do I debug an include file? I can't set breakpoints inside it.
MetaEditor's debugger works on the compiled EA, which includes the include file's code. Set breakpoints in the include file's source — the debugger will stop there when the EA runs. If you get a compile error that references a line number in the include, note that line numbers in the error message refer to the combined file after inclusion. To locate the exact spot, temporarily copy the include's content into the EA file and compile — the line numbers will match directly.






