MT4本地跟单功能实现方法解析

许多外汇交易者都有机会获得一些观察账户,用于查看某些平台或机构提供的账户交易状况。看到别人的账户盈利,自己难免会心动。

笔者通过反复测试,整理出一套本地跟单的实现方法,并制作了一个模型分享给大家。

首先,需要了解两个基本概念:

1. MQL4规定,文件读写操作只能在experts文件夹或其子文件夹内进行,这为本地跟单的实现提供了可能。

2. MT4终端软件安装完成后,可以将安装文件直接复制到硬盘的任何位置,甚至U盘,只需双击其中的“terminal.exe”即可运行。通过这种方式,可以在同一台电脑上同时运行多个MT4软件。

基于以上两点,本地跟单的工作原理描述如下:

MT4软件本地跟单方法的实现

我们将用于下单的平台定义为“信号平台”,在此平台上运行观察账户,并加载“信号EA”程序。一旦有开仓或平仓等操作,程序会自动将交易记录到指定的中间文件中,如上图所示的“交易信息”文件。

我们将用于跟单操作的平台定义为“操作平台”,并加载“跟单EA”。该程序会实时读取“交易信息”文件,识别最新的交易行为,并根据更新信息自动执行开仓或平仓操作。

通过这种方法实现跟单,理论上仅有毫秒级的延迟,可以说是非常迅速。如果你有兴趣,不妨动手尝试。

【第一步】准备两个平台

到软件官网下载MT4客户端并完成安装。

在D盘新建一个文件夹“myMT4”,将MT4安装文件夹中的所有文件复制到该文件夹中,即完成操作平台的搭建。

在“D:\myMT4\experts\files”目录下新建子文件夹“myMT4Signal”,同样将MT4安装文件夹中的所有文件复制到该文件夹中,即完成信号平台的搭建。

分别双击两个文件夹下的“terminal.exe”,系统会同时运行两个MT4终端,申请模拟账户后即可分别操作。

【第二步】编写两个程序

第一个程序命名为“myMT4Signal.mq4”,编译后运行在信号平台中,详细说明及源代码如下:

/*

程序名:myMT4Signal

程序任务:监控账户持仓单变化情况

1. 将新开仓订单信息写入“TradeInfo”文件中,包括开仓时间、订单号、货币对、订单类型、开仓量、开仓价、订单注释、订单特征码。

2. 如果没有持仓订单,则删除该文件。

*/

#property copyright "Copyright By Laoyee"

#property link "http://www.docin.com/yiwence"

int start()

{

if (OrdersTotal()==1 && OrderSelect(0, SELECT_BY_POS, MODE_TRADES))

{

int myHandle = FileOpen("TradeInfo.csv", FILE_CSV | FILE_WRITE, ",");

FileWrite(myHandle, OrderOpenTime(), OrderTicket(), OrderSymbol(), OrderType(), OrderLots(), OrderOpenPrice(), OrderComment(), OrderMagicNumber());

FileClose(myHandle);

}

if (OrdersTotal()==0) FileDelete("TradeInfo.csv");

return(0);

}

复制代码

第二个程序命名为“myMT4Trade.mq4”,编译后运行在操作平台中,详细说明及源代码如下:

/*

程序名:myMT4Trade

程序任务:监控账户持仓单变化情况

1. 读取“myMT4Trade”文档中的订单号、货币对、开仓类型、开仓量

2. 如果没有持仓订单,根据获取的货币对、开仓类型、开仓量进行市价开仓

3. 如果没有读取到指定文件,则将持仓单平仓

*/

#property copyright "Copyright By Laoyee"

#property link "http://www.docin.com/yiwence"

string myType, myLots, mySymobl;

int myHandle;

int start()

{

if (iReadFile() == 1 && OrdersTotal()==0)

{

int mycmd1 = StrToInteger(myType);

string mySymobl1 = mySymobl;

double mylots1 = NormalizeDouble(StrToDouble(myLots),2);

double myOpenPrice;

if (mycmd1 == 0) myOpenPrice = MarketInfo(mySymobl1, MODE_ASK);

if (mycmd1 == 1) myOpenPrice = MarketInfo(mySymobl1, MODE_BID);

OrderSend(mySymobl, mycmd1, mylots1, myOpenPrice, 0, 0, 0);

}

if (iReadFile() == 0 && OrderSelect(0, SELECT_BY_POS, MODE_TRADES))

{

double myClosePrice;

if (OrderType()==OP_BUY) myClosePrice=Bid;

if (OrderType()==OP_SELL) myClosePrice=Ask;

OrderClose(OrderTicket(), OrderLots(), myClosePrice, 0);

}

return(0);

}

int iReadFile()

{

myHandle = FileOpen("\myMT4Signal\experts\files\TradeInfo.csv", FILE_BIN | FILE_READ);

if (myHandle == -1) return(0);

string myValue;

myValue = FileReadString(myHandle, 60);

int myDatecnt = StringFind(myValue, ",", 0);

string myDate = StringSubstr(myValue, 0 ,myDatecnt);

int myTicketcnt = StringFind(myValue, ",", myDatecnt+1);

string myTicket = StringSubstr(myValue, myDatecnt+1, myTicketcnt-myDatecnt-1);

int mySymbolcnt = StringFind(myValue, ",", myTicketcnt+1);

mySymobl = StringSubstr(myValue, myTicketcnt+1, mySymbolcnt-myTicketcnt-1);

int myTypecnt = StringFind(myValue, ",", mySymbolcnt+1);

myType = StringSubstr(myValue, mySymbolcnt+1, myTypecnt-mySymbolcnt-1);

int myLotscnt = StringFind(myValue, ",", myTypecnt+1);

myLots = StringSubstr(myValue, myTypecnt+1, myLotscnt-myTypecnt-1);

int myPricecnt = StringFind(myValue, ",", myLotscnt+1);

string myPrice = StringSubstr(myValue, myLotscnt+1, myPricecnt-myLotscnt-1);

FileClose(myHandle);

return(1);

}

复制代码

【第三步】实施跟单测试

在信号平台手动开仓,观察操作平台是否自动开出相同类型的订单。

将信号平台的持仓单平仓,操作平台的对应持仓单也应随之平仓。

【总结】

信号平台从发出开仓指令到成交新订单并写入中间文件,可能需要约300毫秒;而操作平台从识别文件更新到发出开仓指令并成交,可能需要约500毫秒。因此,整体误差约为800毫秒,所以剥头皮类EA不适合采用此方法。

以上两个程序功能较为单一,主要提供一种实现思路,供学习测试使用。