一、系统的工作流程图(模块级)
其工作流程如下(以行情获取为例):
- 应用端向Application Server发起连接
- 应用服务器调用jfx模块
- jfx模块与NJ4X Server中的nj4x-ts连接
- nj4x-ts调用mt4if模块
- mt4if模块与Application Server建立连接
- Application Server模块发起数据请求(行情,交易,订单等等)
- mt4if模块向MT4 Terminal请求数据
- MT4 Terminal向交易商节点请求数据
- 交易商节点发送消息给MT4 Terminal
- MT4 Terminal将消息发送到mt4if
- mt4if将消息发送到Application Server的jfx中
- jfx将消息发送到server中
- server把数据发送到client中
二、NJ4X各个模块的作用
这个是对之前分析的补充和纠正
1. mt4if
这个是C++开发的模块主要作用如下:
- 通讯连接(两种方式:一种是调用jvm,另一种是直接用UDP的Socket,目前是用jvm)
- Candle运算,系统默认的是1s,1min,5min,30min,其他的是根据需求计算的
- mt4 terminal的代理模块
- 多线程的处理(稳定性)
2. nj4x-ts
这个是NJ4X终端服务器的java部分,作用如下:
- 与Application Server通讯
- 与mt4if交互,给mt4if发指令
- 操作界面
- 日志,存储等
3. jfx
这个模块是Application Server的组成部分,作用如下:
- 与nj4x-ts交互
- 与mt4if交互
- 对MT4交易方式的封装
- 对行情等信息的封装
4. ea
这个是Expert Advisor模块,这个模块中只有两个文件,jfx.mq4
和wnds.mq4
,根据MQ4官网的说法,所有的交易策略和逻辑都是以.mq4文件形式存在的。MQ4确实有专家系统,但是貌似和这个关系不大。
5. zero-term
这个模块存储着mt4 terminal的各种配置文件,根据货币,交易商的不同来给mt4 terminal生成不同的配置文件。
三 系统和MT4的交互方式
系统和MT4程序的交互主要是通过mt4if这个C++库的。mt4if这个模块提供了MT4程序的代理。体现在ea
模块的jfx.mq4
文件中.
其中:
#import "mt45if.dll"
string jfxConnect(string, int, string, int, string);
void jfxDisconnect(string&);
int jfxGetCommand(string&, string& p1, string& p2, string& p3, string& p4, string& p5, string& p6, string& p7, string& p8, string& p9, string& p10, string& p11, string& p12, string& p13, string& p14, string& p15);
void jfxSendResult(string&, string&);
void jfxLog(string&);
void jfxHWnd(int, bool);
void jfxPositionInit(string&, int);
int jfxPositionOrderInfo(string&, int, int, int, int, int, int, int, string&, string&, double, double, double, double, double, double, double, double);
string jfxPositionRes(string&, int, int);
int jfxMqlRatesInit(string&);
int jfxMqlRatesAdd(string&, MqlRates& rates);
string jfxMqlRatesRes(string&);
#import
定义了调用mt4if的函数,这些函数帮助mt4 terminal与外界通讯。
其中
switch (x) {
0:
res = IntegerToString(iBars(args0,StrToInteger(args1)));
if (maxDebug) Print("iBars", ", ", "symbol=", args0,", ", "timeframe=", args1);
break;
1:
res = IntegerToString( iBarShift(args0,StrToInteger(args1),StrToTime(args2),StrToInteger(args3)) );
if (maxDebug) Print("iBarShift", ", ", "symbol=", args0,", ", "timeframe=", args1,", ", "time=", args2,", ", "exact=", args3);
break;
2:
res = DoubleToString( iClose(args0,StrToInteger(args1),StrToInteger(args2)) );
if (maxDebug) Print("iClose", ", ", "symbol=", args0,", ", "timeframe=", args1,", ", "shift=", args2);
break;
3:
res = DoubleToString( iHigh(args0,StrToInteger(args1),StrToInteger(args2)) );
if (maxDebug) Print("iHigh", ", ", "symbol=", args0,", ", "timeframe=", args1,", ", "shift=", args2);
break;
以上代码就是判断通讯协议并作出不同的动作的代码
可以修改jfx.mq4来调整自己的策略。
4. MT4 TERMINAL与外界的通讯协议
0:"iBars";
1:"iBarShift";
2:"iClose";
3:"iHigh";
4:"iLow";
5:"iOpen";
6:"iVolume";
7:"iTime";
8:"iLowest";
9:"iHighest";
10:"AccountBalance";
11:"AccountCredit";
12:"AccountCompany";
13:"AccountCurrency";
14:"AccountEquity";
15:"AccountFreeMargin";
16:"AccountMargin";
17:"AccountName";
18:"AccountNumber";
19:"AccountProfit";
20:"GetLastError";
21:"IsConnected";
22:"IsDemo";
23:"IsTesting";
24:"IsVisualMode";
25:"GetTickCount";
26:"Comment";
27:"MarketInfo";
28:"Print";
29:"Day";
30:"DayOfWeek";
31:"DayOfYear";
32:"Hour";
33:"Minute";
34:"Month";
35:"Seconds";
36:"TimeCurrent";
37:"Year";
38:"ObjectCreate";
39:"ObjectCreate";
40:"ObjectCreate";
41:"ObjectDelete";
42:"ObjectGet";
43:"ObjectSet";
44:"ObjectGetFiboDescription";
45:"ObjectSetFiboDescription";
46:"ObjectSetText";
47:"ObjectsTotal";
48:"ObjectType";
49:"iAC";
50:"iAD";
51:"iAlligator";
52:"iADX";
53:"iATR";
54:"iAO";
55:"iBearsPower";
56:"iBands";
57:"iBullsPower";
58:"iCCI";
59:"iCustom";
60:"iDeMarker";
61:"iEnvelopes";
62:"iForce";
63:"iFractals";
64:"iGator";
65:"iBWMFI";
66:"iMomentum";
67:"iMFI";
68:"iMA";
69:"iOsMA";
70:"iMACD";
71:"iOBV";
72:"iSAR";
73:"iRSI";
74:"iRVI";
75:"iStdDev";
76:"iStochastic";
77:"iWPR";
78:"OrderClose";
79:"OrderCloseBy";
80:"OrderClosePrice";
81:"OrderCloseTime";
82:"OrderComment";
83:"OrderCommission";
84:"OrderDelete";
85:"OrderExpiration";
86:"OrderLots";
87:"OrderMagicNumber";
88:"OrderModify";
89:"OrderOpenPrice";
90:"OrderOpenTime";
91:"OrderPrint";
92:"OrderProfit";
93:"OrderSelect";
94:"OrderSend";
95:"OrdersHistoryTotal";
96:"OrderStopLoss";
97:"OrdersTotal";
98:"OrderSwap";
99:"OrderSymbol";
100:"OrderTakeProfit";
101:"OrderTicket";
102:"OrderType";
103:"IsTradeContextBusy";
104:"RefreshRates";
105:"AccountStopoutLevel";
106:"AccountStopoutMode";
107:"MessageBox";
108:"UninitializeReason";
109:"IsTradeAllowed";
110:"IsStopped";
111:"IsOptimization";
112:"IsLibrariesAllowed";
113:"IsDllsAllowed";
114:"IsExpertEnabled";
115:"AccountFreeMarginCheck";
116:"AccountFreeMarginMode";
117:"AccountLeverage";
118:"AccountServer";
119:"TerminalCompany";
120:"TerminalName";
121:"TerminalPath";
122:"Alert";
123:"PlaySound";
124:"ObjectDescription";
125:"ObjectFind";
126:"ObjectGetShiftByValue";
127:"ObjectGetValueByShift";
128:"ObjectMove";
129:"ObjectName";
130:"ObjectsDeleteAll";
131:"iIchimoku";
132:"HideTestIndicators";
133:"Period";
134:"Symbol";
135:"WindowBarsPerChart";
136:"WindowFirstVisibleBar";
137:"WindowExpertName";
138:"WindowFind";
139:"WindowIsVisible";
140:"WindowPriceMax";
141:"WindowPriceMin";
142:"WindowOnDropped";
143:"WindowXOnDropped";
144:"WindowYOnDropped";
145:"WindowPriceOnDropped";
146:"WindowTimeOnDropped";
147:"WindowsTotal";
148:"WindowRedraw";
149:"WindowScreenShot";
150:"WindowHandle";
151:"GlobalVariableCheck";
152:"GlobalVariableDel";
153:"GlobalVariableGet";
154:"GlobalVariableName";
155:"GlobalVariableSet";
156:"GlobalVariableSetOnCondition";
157:"GlobalVariablesDeleteAll";
158:"GlobalVariablesTotal";
159:"SymbolsTotal";
160:"SymbolName";
161:"SymbolSelect";
162:"TerminalClose";
163:"SymbolInfo";
164:"AccountInfo";
165:"serverTimeGMTOffset";
166:"IsTradeAllowed";
10000:"SetAutoRefresh";
10001:"MarketInfoAll";
10002:"NewTick";
10012:"TicksListenerAll";
10003:"OrderGet";
10004:"NewPosition";
10005:"OrderGetAll";
这些协议大部分是mq4语言中的方法名,根据这些方法名就可以执行相应的方法,后面还有参数。
有意思的是,为了解决这些方法的参数不同的问题,接收指令函数的参数有15个,应该是最长的那个函数的参数长度。如下:
jfxGetCommand(string&, string& p1, string& p2, string& p3, string& p4, string& p5, string& p6, string& p7, string& p8, string& p9, string& p10, string& p11, string& p12, string& p13, string& p14, string& p15);