This library makes possible to develop applications on any .NET compatible language using MetaQuotes MetaTrader 4 Manager API.
It has been build using C#, it can be used within Any CPU platform, it automatically chooses right library (mtmanapi.dll or mtmanapi64.dll) to be dynamically linked at run-time.
Manager API provides 3 different kind of connection to MT4 server:
- Normal mode
Request/Response scheme like the way MetaTrader Administrator works. - Pumping mode
Getting real-time data from server, MetaTrader Manager works this way. - Dealing mode
Proceed clients requests, Dealer feature of MetaTrader Manager
Quick startup guide #
All the examples provided here will be written on C# in Visual Studio 2019. It's up to you to choose any .NET language and visual studio version.
Check that your server has .NET Runtime installed (.NET 4.6.2, .NET core 3.1 Runtime or even better NET 5.0 Runtime).
In VisualStudio you can add http://nuget.cplugin.com/feeds/default as a packages source (https://docs.microsoft.com/en-us/nuget/consume-packages/install-use-packages-visual-studio#package-sources) and add CPlugin.PlatformWrapper.MetaTrader4
reference to project.
(To manual download package from our NuGet navigate to: http://nuget.cplugin.com/feeds/default/CPlugin.PlatformWrapper.MetaTrader4/versions and add as reference to the project)
Working examples: https://github.com/CPlugin/PlatformWrapper.Examples
Next, create account in MT4 in manager group (using Manager or Administrator) and bring it to the managers list (using Administrator). API can use only manager account. Depends on task you are going to do it will need permissions being granted to the account.
Ready to go?
For convenience, add namespace usage globally to your source file as of:
using CPlugin.PlatformWrapper.MetaTrader4;
After that you can instantiate object of required connection type, Manager
for example:
var mgr = new Manager("localhost:443", 1, "manager");
Let’s try connect to MT4 server using this class:
var rc = mgr.Connect();
if (rc != ResultCode.Ok)
{
Console.WriteLine($"Connection error [{rc}] - {mgr.ErrorDescription(rc)}");
return;
}
Let assume that connection is up, starting from now we are able to work with all features of this MT4 server using mgr object.
Demo version limitation #
This library will work for 30 days with no limitations. After that valid license needed.
The files provided here are secured, it needs to protect quality, to offer guarantee and provide after-sale technical support. All reverse engineering attempts prohibited and will void all current and future business relations with us.
Working examples #
Source code posted here might be obsolete.
Up-to-date working code examples you shall find in our GitHub repository at: https://github.com/CPlugin/PlatformWrapper.Examples.
Also, you can subscribe of all updates to be informed.
Important to know #
IDisposable #
Each Manager class inherits IDisposable interface to safely release resources allocated by native library.
Exceptions #
It will throw out exceptions.
Getting messages from wrapper to know what is happening #
You can catch messages written by Manager classes if you fill Log field, there you can catch messages from wrapper. For example:
var mgr = new ManagerPumpEx("mt4.broker.com:443", 1, "manager");
// Console logging
mgr.Logger = (ctx, type, message, ex) => Console.WriteLine($"[{type}] {message} ({exception})");
// OR
// Logging using NLog, mentioned extension you will find at bottom of this page
mgr.Logger = (ctx, type, message, ex) => Log.ProceedMT4WrapperMessages(type, message, ex);
Thread safe #
All Manager classes are thread safe, so you can call its methods from multi-threaded environment. It will use lock internally.
Normal mode connection #
This mode provided basic connection. It provides all features you can utilize using MT4 Administrator terminal.
When you need to maintain connections, you can call method KeepAlive, it will create separate thread and will ping MT4 server every three seconds.
using (var man = new Manager("127.0.0.1:443", 1, "manager"))
{
Console.WriteLine("{0}", man.FullVersion);
// get all users from MT4 server
var allUsers = man.UsersRequest();
// create new user
var ur = new UserRecord()
{
Group = "Classic",
Name = "Name Surname",
Leverage = 100 // for 1:100
};
var result = man.UserRecordNew(ref ur);
// check result
Debug.Assert(result == ResultCode.Ok);
Debug.Assert(ur.Login != 0);
} // dispose Manager class when you don' need it anymore
Pumping mode connection #
This mode needs if you want to get updates from MT4 server at real-time. Like you are using MT4 Manager terminal. To subscribe to events, you have a list of object of type event to subscribe to, for example:
// create instance
var mgr = new ManagerPumpEx("127.0.0.1", 1, "manager")
{
Logger = (type, message) => { Console.WriteLine($"[{type}] {message}"); }
};
// connect to MT4
var result = mgr.Connect();
mgr.OnStart = sender => {
// get symbols list from local cache
var sga = sender.SymbolsGetAll();
foreach (var conSymbol in sga)
{
// subscribe to each symbol update
result = sender.SymbolAdd(conSymbol.Key);
}
};
// symbols updated
mgr.OnSymbols = sender => {
Console.WriteLine("OnSymbols");
};
// symbol settings updated
mgr.OnSymbolsEx = (sender, type, cs) => {
Console.WriteLine("{0} - {1}", type, cs);
};
// catch ping event
mgr.OnPing = sender => {
Console.WriteLine("Ping");
};
// catch quotes
mgr.OnBidAsk = sender => {
// get last quotes came from server since last update
var ticks = mgr.SymbolInfoUpdated();
};
while (true)
{
if (Console.KeyAvailable)
{
var kki = Console.ReadKey(true);
if (kki.Key == ConsoleKey.Q)
{
Console.WriteLine("User pressed 'Q' key");
mgr.Disconnect();
break;
}
}
}
Useful helpers
public static class NLogHelpers
{
public static void ProceedMT4WrapperMessages(this Logger logger, Logging.EnMessageType type, string message, Exception ex)
{
switch (type)
{
case Logging.EnMessageType.Debug:
logger.Debug(message);
break;
case Logging.EnMessageType.Error:
logger.Error(message);
break;
case Logging.EnMessageType.Info:
logger.Info(message);
break;
case Logging.EnMessageType.Verbose:
logger.Trace(message);
break;
case Logging.EnMessageType.Warning:
logger.Warn(message);
break;
case Logging.EnMessageType.Exception:
if (ex != null)
logger.Error(ex);
else
logger.Error(message);
break;
default:
logger.Debug(message);
break;
}
}
}