Settings files vs hardcoded inputs: managing EA parameters across accounts
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
Key Considerations for Robustness
File Locks: Because FILE_READ is used without FILE_SHARE_READ, if an external program (like a Python script updating the JSON) is writing to the file at the exact millisecond the EA initializes, MetaTrader will throw a file-sharing violation (Error 5004). If you automate the updating of this JSON file, consider adding a retry mechanism with a small Sleep() in the EA.
Type Casting: MQL5 is strictly typed. If someone accidentally inputs "RiskPercent": "1.5" (as a string) instead of 1.5 (as a float) in the JSON, the parser might return a 0.0 depending on how strict the .ToDbl() conversion is handled inside the library. Always validate that critical variables (like risk) evaluate to > 0 before allowing the EA to trade.
File Locks: Because FILE_READ is used without FILE_SHARE_READ, if an external program (like a Python script updating the JSON) is writing to the file at the exact millisecond the EA initializes, MetaTrader will throw a file-sharing violation (Error 5004). If you automate the updating of this JSON file, consider adding a retry mechanism with a small Sleep() in the EA.
Type Casting: MQL5 is strictly typed. If someone accidentally inputs "RiskPercent": "1.5" (as a string) instead of 1.5 (as a float) in the JSON, the parser might return a 0.0 depending on how strict the .ToDbl() conversion is handled inside the library. Always validate that critical variables (like risk) evaluate to > 0 before allowing the EA to trade.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
To connect MQL5 directly to a C# background service, the industry standard has completely shifted. You no longer need to rely on outdated, third-party workarounds like RGiesecke's UnmanagedExports.
Starting with .NET 7 and .NET 8, Microsoft introduced Native AOT (Ahead-of-Time compilation). This allows you to compile C# code directly into a native, unmanaged Windows DLL that MetaTrader 5 can load natively using standard #import.
Here is how you build a custom C# DLL that acts as an Inter-Process Communication (IPC) bridge to your background service.
Starting with .NET 7 and .NET 8, Microsoft introduced Native AOT (Ahead-of-Time compilation). This allows you to compile C# code directly into a native, unmanaged Windows DLL that MetaTrader 5 can load natively using standard #import.
Here is how you build a custom C# DLL that acts as an Inter-Process Communication (IPC) bridge to your background service.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
1. Build the Native AOT C# DLL (The Bridge)
This DLL will be loaded by MetaTrader and will act as an IPC client (using Named Pipes, gRPC, or ZeroMQ) to request data from your separate C# Windows Service.
First, create a new .NET 8 Class Library and modify the .csproj to enable Native AOT:
This DLL will be loaded by MetaTrader and will act as an IPC client (using Named Pipes, gRPC, or ZeroMQ) to request data from your separate C# Windows Service.
First, create a new .NET 8 Class Library and modify the .csproj to enable Native AOT:
Code: Select all
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- This instructs the compiler to generate a true native unmanaged DLL -->
<PublishAot>true</PublishAot>
</PropertyGroup>
</Project>Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
Next, write the C# method. MQL5 expects functions in imported DLLs to use the stdcall calling convention. You enforce this using the [UnmanagedCallersOnly] attribute:
Code: Select all
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.IO.Pipes;
namespace Mql5IPCBridge
{
public class Bridge
{
// Expose this method to MQL5 via stdcall C ABI
[UnmanagedCallersOnly(EntryPoint = "GetRiskSetting", CallConvs = new[] { typeof(CallConvStdcall) })]
public static double GetRiskSetting(int magicNumber)
{
// IPC Logic: Connect to your background C# Windows Service
// Example using Named Pipes (System.IO.Pipes)
try
{
using var client = new NamedPipeClientStream(".", "TradingServicePipe", PipeDirection.InOut);
client.Connect(100); // 100ms timeout to prevent EA freezing
// In production, you would write the magicNumber to the stream
// and read the specific risk configuration back.
return 1.5; // Example returned risk %
}
catch
{
// CRITICAL: Never let exceptions cross the unmanaged boundary into MQL5.
// Unhandled managed exceptions will crash the MetaTrader terminal outright.
return -1.0;
}
}
}
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
To generate the unmanaged DLL, you must publish the project for the specific architecture (MetaTrader 5 is strictly 64-bit):
Take the resulting Mql5IPCBridge.dll from the publish folder and place it in your MetaTrader 5 MQL5\Libraries folder.
Code: Select all
dotnet publish -c Release -r win-x64Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
2. The MQL5 EA Integration
In your MQL5 code, importing and using this C# DLL is exactly the same as interacting with a standard C++ library.
In your MQL5 code, importing and using this C# DLL is exactly the same as interacting with a standard C++ library.
Code: Select all
// Import the custom Native AOT C# DLL
#import "Mql5IPCBridge.dll"
double GetRiskSetting(int magicNumber);
#import
int OnInit()
{
// Make sure "Allow DLL imports" is checked in the EA properties
double risk = GetRiskSetting(123456);
if(risk < 0)
{
Print("CRITICAL: Failed to connect to C# Background Service.");
return INIT_FAILED;
}
Print("Successfully fetched risk from C# Service: ", risk, "%");
return INIT_SUCCEEDED;
}Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
Pro Tip: The "No Custom DLL" Alternative
If your C# background service is already running a standard Named Pipe server using NamedPipeServerStream, you actually do not need a custom bridge DLL. MQL5 can natively call the Windows kernel32.dll to utilize functions like CreateFileW, WriteFile, and ReadFile, allowing the EA to talk directly to your C# service's named pipe. This removes the custom DLL dependency entirely, simplifies deployment, and is widely considered the lowest-latency IPC setup for high-frequency EAs.
If your C# background service is already running a standard Named Pipe server using NamedPipeServerStream, you actually do not need a custom bridge DLL. MQL5 can natively call the Windows kernel32.dll to utilize functions like CreateFileW, WriteFile, and ReadFile, allowing the EA to talk directly to your C# service's named pipe. This removes the custom DLL dependency entirely, simplifies deployment, and is widely considered the lowest-latency IPC setup for high-frequency EAs.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
Version control helps here too, even if you're not a programmer. Putting the set files in a git repository, or even just a folder with dated copies, means you can see what changed and when. If results suddenly get worse, the first question is usually what changed, and having a record makes that answerable. Without it, you're relying on memory, which tends to be unreliable for exactly the details that matter. A record that says what changed and when is what turns 'something feels different' into an answer. Memory is a poor version control system.
It’s Fairman 
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
One trap with set files: if you add a new input to the EA, old set files won't have it, and the EA uses the default value when you load them. That can quietly change behaviour if the default isn't what you want. After updating an EA, I'd load each set file, check the new inputs, and save again. It's tedious, but it avoids running with an unintended default for weeks before anyone notices. Writing the loaded inputs to the log at startup catches this quickly, because you can see the actual values instead of assuming them.
It’s Fairman 
-
FXS HongKong Scalper
- Posts: 396
- Joined: Sat Oct 24, 2026 10:15 pm
Re: Settings files vs hardcoded inputs: managing EA parameters across accounts
That default-value trap caught us once with a session filter input. The new version added a start hour defaulting to 0, the old set files did not have it, and the EA happily traded the whole day for a week.
Two habits that help besides logging the inputs at startup. First, put a version string in the EA and in every set file, and have OnInit() refuse to start if they do not match. Second, keep the set files in a small git repo or at least a dated folder, so you can diff them after an update and see exactly which values changed.
Two habits that help besides logging the inputs at startup. First, put a version string in the EA and in every set file, and have OnInit() refuse to start if they do not match. Second, keep the set files in a small git repo or at least a dated folder, so you can diff them after an update and see exactly which values changed.
FXS Official Team | Hong Kong Session Desk