C#程序如何获取MetaTrader5(MT5)账户持仓订单及MagicNumber?
可行实现方案及C#集成方法
方案一:MQL5脚本导出持仓数据到本地文件,C#读取
无需依赖Python,直接用MT5自带的MQL5语言导出数据,C#读取解析即可,适合非实时场景。
步骤1:编写MQL5脚本导出持仓数据
打开MT5的MetaEditor,创建新脚本(Script),写入以下代码:
//+------------------------------------------------------------------+ //| ExportPositions.mq5 | //+------------------------------------------------------------------+ #property version "1.00" #property strict //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { ulong total_positions = PositionsTotal(); if(total_positions == 0) { Print("无持仓订单"); return; } // 打开CSV文件,路径可自行修改,需确保MT5有文件写入权限 int file_handle = FileOpen("MT5_Positions.csv", FILE_WRITE|FILE_CSV|FILE_ANSI, ','); if(file_handle == INVALID_HANDLE) { Print("文件打开失败,错误码: ", GetLastError()); return; } // 写入表头 FileWrite(file_handle, "订单ID", "MagicNumber", "品种", "持仓方向", "持仓量"); // 遍历所有持仓并写入数据 for(int i=0; i<total_positions; i++) { ulong position_id = PositionGetTicket(i); if(PositionSelectByTicket(position_id)) { long magic = PositionGetInteger(POSITION_MAGIC); string symbol = PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double volume = PositionGetDouble(POSITION_VOLUME); FileWrite(file_handle, position_id, magic, symbol, type == POSITION_TYPE_BUY ? "多单" : "空单", volume); } } FileClose(file_handle); Print("持仓数据已导出到文件: MT5_Positions.csv"); } //+------------------------------------------------------------------+
编译后在MT5终端运行脚本,文件会生成在MT5数据目录的MQL5/Files下(可通过MT5菜单-文件-打开数据文件夹定位)。
步骤2:C#读取并解析CSV文件
在C#程序中添加读取逻辑:
using System; using System.Collections.Generic; using System.IO; public class MT5Position { public ulong TicketId { get; set; } public long MagicNumber { get; set; } public string Symbol { get; set; } public string Direction { get; set; } public double Volume { get; set; } } public class MT5DataReader { public static List<MT5Position> ReadPositionsFromCsv(string filePath) { var positions = new List<MT5Position>(); var lines = File.ReadAllLines(filePath); // 跳过表头,解析数据行 for(int i=1; i<lines.Length; i++) { var parts = lines[i].Split(','); if(parts.Length >=5) { positions.Add(new MT5Position { TicketId = ulong.Parse(parts[0]), MagicNumber = long.Parse(parts[1]), Symbol = parts[2], Direction = parts[3], Volume = double.Parse(parts[4]) }); } } return positions; } } // 使用示例 // var positions = MT5DataReader.ReadPositionsFromCsv(@"你的MT5数据文件夹路径\MQL5\Files\MT5_Positions.csv");
方案二:MQL5与C#通过本地命名管道实时通信
适合需要实时获取持仓数据的场景,通过Windows命名管道实现MT5和C#的直接数据传输。
步骤1:MQL5端编写管道服务
创建MQL5脚本,实现向命名管道发送持仓数据:
//+------------------------------------------------------------------+ //| PipeServer.mq5 | //+------------------------------------------------------------------+ #property version "1.00" #property strict #include <WinUser32.mqh> #define PIPE_NAME "\\\\.\\pipe\\MT5PositionsPipe" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { HANDLE pipe_handle = CreateNamedPipeA(PIPE_NAME, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_MESSAGE|PIPE_WAIT, 1, 1024*1024, 1024*1024, 0, NULL); if(pipe_handle == INVALID_HANDLE_VALUE) { Print("创建管道失败,错误码: ", GetLastError()); return; } Print("等待C#客户端连接..."); if(ConnectNamedPipe(pipe_handle, NULL)) { Print("客户端已连接"); SendPositionsData(pipe_handle); } else { Print("连接失败,错误码: ", GetLastError()); } CloseHandle(pipe_handle); } //+------------------------------------------------------------------+ //| 发送持仓数据到管道 | //+------------------------------------------------------------------+ void SendPositionsData(HANDLE pipe) { ulong total_positions = PositionsTotal(); string json_data = "["; for(int i=0; i<total_positions; i++) { ulong ticket = PositionGetTicket(i); if(PositionSelectByTicket(ticket)) { long magic = PositionGetInteger(POSITION_MAGIC); string symbol = PositionGetString(POSITION_SYMBOL); ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); double volume = PositionGetDouble(POSITION_VOLUME); string item = StringFormat("{\"TicketId\":%llu,\"MagicNumber\":%ld,\"Symbol\":\"%s\",\"Direction\":\"%s\",\"Volume\":%.2f}", ticket, magic, symbol, type == POSITION_TYPE_BUY ? "多单" : "空单", volume); json_data += item; if(i != total_positions -1) json_data += ","; } } json_data += "]"; DWORD bytes_written; WriteFile(pipe, json_data, StringLen(json_data), &bytes_written, NULL); Print("已发送", bytes_written, "字节数据"); } //+------------------------------------------------------------------+
编译运行脚本后,MT5会等待C#客户端连接。
步骤2:C#端编写管道客户端
在C#程序中连接管道并接收数据:
using System; using System.IO.Pipes; using System.Text; using System.Web.Script.Serialization; // 需引用System.Web.Extensions程序集 public class MT5Position { public ulong TicketId { get; set; } public long MagicNumber { get; set; } public string Symbol { get; set; } public string Direction { get; set; } public double Volume { get; set; } } public class MT5PipeClient { public static List<MT5Position> GetPositionsFromPipe() { using(var pipeClient = new NamedPipeClientStream(".", "MT5PositionsPipe", PipeDirection.In)) { pipeClient.Connect(5000); // 5秒超时 var reader = new StreamReader(pipeClient, Encoding.Default); string json = reader.ReadToEnd(); var serializer = new JavaScriptSerializer(); return serializer.Deserialize<List<MT5Position>>(json); } } } // 使用示例 // var positions = MT5PipeClient.GetPositionsFromPipe(); // foreach(var pos in positions) // { // Console.WriteLine($"MagicNumber: {pos.MagicNumber}, 订单ID: {pos.TicketId}"); // }
方案三:C#调用极简Python脚本(无需Python基础)
如果需要利用MT5官方Python集成,只需编写极简Python代码,C#通过进程调用获取结果。
步骤1:编写极简Python脚本
创建get_mt5_positions.py文件,写入以下代码:
import MetaTrader5 as mt5 mt5.initialize() positions = mt5.positions_get() result = [{"TicketId": pos.ticket, "MagicNumber": pos.magic} for pos in positions] print(result) mt5.shutdown()
先安装MT5 Python包:打开MT5菜单-工具-选项-EA交易,勾选"允许自动交易"和"允许DLL导入",然后在命令行执行pip install MetaTrader5。
步骤2:C#调用Python脚本并解析输出
C#代码通过Process调用脚本并捕获输出:
using System; using System.Diagnostics; using System.Web.Script.Serialization; public class MT5Position { public ulong TicketId { get; set; } public long MagicNumber { get; set; } } public class MT5PythonClient { public static List<MT5Position> GetPositionsFromPython(string scriptPath) { var processStartInfo = new ProcessStartInfo { FileName = "python.exe", // 若python不在环境变量,写绝对路径如"C:\\Python39\\python.exe" Arguments = scriptPath, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using(var process = Process.Start(processStartInfo)) { string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); var serializer = new JavaScriptSerializer(); return serializer.Deserialize<List<MT5Position>>(output); } } } // 使用示例 // var positions = MT5PythonClient.GetPositionsFromPython(@"C:\path\to\get_mt5_positions.py");
内容的提问来源于stack exchange,提问作者Dragon
相关产品推荐
相关产品推荐

