一个MT4跟单系统,功能有:绑定账号,开户【需要注意处理中文名字乱码】,入金,出金,下单等常规操作;可以查看本人的持仓、挂单和历史单。
跟单方案:顾问正常操作,客户可以查看顾问的订单以往交易情况,跟单后,会自动跟随按倍数下单;被跟单订单挂关闭或修改时也需要作相应动作。
智投方案:类似于跟单,但是添加了EA标识,只有该EA产生的订单下单、关闭或修改,才会有相应动作,顾问的其它订单修改,不会触发智投。
系统采用c++编写dll用于调用mtmanapi.dll【或mtmanapi64.dll】,生成dll以备java调用。
java调用c++产生的dll完成对应操作,需要区分direct和pump模式,并应用连接池提高效率。
java接口ManagerAPI.java:
package com.metoo.mt4.api;
/**
* Manager接口
* @author
* @time 下午2:14:52
*/
public class ManagerAPI {
//manager的指针地址
protected long ptr;
public ManagerAPI() {
ptr = Init();
if(ptr < 0){
throw new InitFailedException("Manager API Init fail.");
}
}
/**
* 销毁
* @author
* @time 下午2:37:14
*/
public boolean release() {
int release = Release(ptr);
return release == ResultCode.RET_OK.getValue();
}
//===========================动态库方法:开始===============================
/**
* lib:Init
* @return 返回CManagerInterface实例的地址
*/
protected native long Init();
/**
* lib:winsock startup
* @author
* @time 下午2:15:55
*/
protected static native void WinsockStartup();
/**
* lib:winsock cleanup
* @author
* @time 下午2:15:55
*/
protected native void WinsockCleanup();
//===========================动态库方法:开始===============================
/**
* API:release
* @param ptr
* @return
*/
protected native int Release(long ptr);
/**
* API:service methods
* 释放指针内存
* @param ptr
* @param targetPtr:待释放指针
* @return
*/
protected native void MemFree(long ptr, long targetPtr);
/**
* API:service methods
* 返回结果描述
* @param ptr
* @param code
* @return
*/
protected native String ErrorDescription(long ptr, int code);
/**
* API:service methods
* 设置工作目录
* @param ptr
* @param code
* @return 成功返回设置描述,否则返回null <br/>
* The specified directory must exist, the function does not create directories
*/
protected native void WorkingDirectory(long ptr, String path);
/**
* API:connection
* 连接到服务端
* @param ptr
* @param server
* @return
*/
protected native int Connect(long ptr,String server);
/**
* API:connection
* 断开链接
* @param ptr
* @return
*/
protected native int Disconnect(long ptr);
/**
* API:connection
* 是否连接
* @param ptr
* @return
*/
protected native int IsConnected(long ptr);
/**
* API:connection
* 登录
* @param ptr
* @param uid
* @param password
* @return
*/
protected native int Login(long ptr, int uid, String password);
/**
* API:connection
* 测试连通
* @param ptr
* @return
*/
protected native int Ping(long ptr);
/**
* API:connection
* 修改密码
* @param ptr
* @param pass
* @param is_investor 默认主密码(0)
* @return
*/
protected native int PasswordChange(long ptr, String pass, int is_investor);
/**
* API:connection
* Manager权限
* @param ptr
* @return
*/
protected native ConManager ManagerRights(long ptr);
/**
* API:server configuration:configuration request
* 品种组
* @return
*/
protected native ConSymbolGroup[] CfgRequestSymbolGroup(long ptr);
/**
* API:server configuration:configuration request
* 节假日
* @return
*/
protected native ConHoliday[] CfgRequestHoliday(long ptr);
/**
* API:server configuration:configuration request
* 品种对
* @return
*/
protected native ConSymbol[] CfgRequestSymbol(long ptr);
/**
* API:server configuration:configuration request
* 用户组
* @return
*/
protected native ConGroup[] CfgRequestGroup(long ptr);
/**
* API:server configuration:configuration request
* 管理员
* @return
*/
protected native ConManager[] CfgRequestManager(long ptr);
/**
* API:server configuration:configuration request
* 数据源
* @return
*/
protected native ConFeeder[] CfgRequestFeeder(long ptr);
/**
* API:server configuration:configuration request
* 资讯
* @return
*/
protected native ConLiveUpdate[] CfgRequestLiveUpdate(long ptr);
/**
* API:server configuration:configuration request
* 资讯
* @return
*/
protected native ConSync[] CfgRequestSync(long ptr);
/**
* API:server configuration:configuration update
* 修改新服务器时间
* @param conTime
* @return
*/
protected native int CfgUpdateTime(long ptr, ConTime conTime);
/**
* API:server configuration:configuration update
* 修改节假日
* @param conHoliday
* @param pos
* @return
*/
protected native int CfgUpdateHoliday(long ptr, ConHoliday conHoliday, int pos);
/**
* API:server configuration:configuration update
* 修改品种
* @param conSymbol
* @return
*/
protected native int CfgUpdateSymbol(long ptr, ConSymbol conSymbol);
/**
* API:server configuration:configuration update
* 修改品种分组
* @param conSymbolGroup
* @return
*/
protected native int CfgUpdateSymbolGroup(long ptr, ConSymbolGroup conSymbolGroup, int pos);
/**
* API:server configuration:configuration update
* 修改分组
* @param conGroup
* @return
*/
protected native int CfgUpdateGroup(long ptr, ConGroup conGroup);
/**
* API:server configuration:configuration update
* 修改Manager权限
* @param conManager
* @return
*/
protected native int CfgUpdateManager(long ptr, ConManager conManager);
/**
* API:server configuration:configuration update
* 修改数据源
* @param conFeeder
* @return
*/
protected native int CfgUpdateFeeder(long ptr, ConFeeder conFeeder);
/**
* API:server configuration:configuration update
* 修改备份配置
* @param conBackup
* @return
*/
protected native int CfgUpdateBackup(long ptr, ConBackup conBackup);
/**
* API:server configuration:configuration update
* 修改资讯配置
* @param conLiveUpdate
* @return
*/
protected native int CfgUpdateLiveUpdate(long ptr, ConLiveUpdate conLiveUpdate);
/**
* API:server configuration:configuration update
* 修改同步配置
* @param conSync
* @return
*/
protected native int CfgUpdateSync(long ptr, ConSync conSync);
/**
* API:server configuration:configuration delete
* 删除节假日
* @param pos
* @return
*/
protected native int CfgDeleteHoliday(long ptr, int pos);
/**
* API:server configuration:configuration delete
* 删除品种
* @param pos
* @return
*/
protected native int CfgDeleteSymbol(long ptr, int pos);
/**
* API:server configuration:configuration delete
* 删除分组
* @param pos
* @return
*/
protected native int CfgDeleteGroup(long ptr, int pos);
/**
* API:server configuration:configuration delete
* 删除Manager权限
* @param conManager
* @return
*/
protected native int CfgDeleteManager(long ptr, int pos);
/**
* API:server configuration:configuration delete
* 删除数据源
* @param pos
* @return
*/
protected native int CfgDeleteFeeder(long ptr, int pos);
/**
* API:server configuration:configuration delete
* 删除资讯配置
* @param pos
* @return
*/
protected native int CfgDeleteLiveUpdate(long ptr, int pos);
/**
* API:server configuration:configuration delete
* 删除同步配置
* @param pos
* @return
*/
protected native int CfgDeleteSync(long ptr, int pos);
/**
* API:server configuration:configuration shift
* 调节顺序:节假日
* @return
*/
protected native int CfgShiftHoliday(long ptr, int post, int shift);
/**
* API:server configuration:configuration shift
* 调节顺序:品种对
* @return
*/
protected native int CfgShiftSymbol(long ptr, int post, int shift);
/**
* API:server configuration:configuration shift
* 调节顺序:用户组
* @return
*/
protected native int CfgShiftGroup(long ptr, int post, int shift);
/**
* API:server configuration:configuration shift
* 调节顺序:管理员
* @return
*/
protected native int CfgShiftManager(long ptr, int post, int shift);
/**
* API:server configuration:configuration shift
* 调节顺序:数据源
* @return
*/
protected native int CfgShiftFeeder(long ptr, int post, int shift);
/**
* API:server configuration:configuration shift
* 调节顺序:资讯
* @return
*/
protected native int CfgShiftLiveUpdate(long ptr, int post, int shift);
/**
* API:server configuration:configuration shift
* 调节顺序:
* @return
*/
protected native int CfgShiftSync(long ptr, int post, int shift);
// -----symbols =================
protected native int SymbolsRefresh(long ptr);
protected native ConSymbol[] SymbolsGetAll(long ptr);
protected native ConSymbol SymbolGet(long ptr, String symbol);
protected native SymbolInfo SymbolInfoGet(long ptr, String symbol);
protected native int SymbolAdd(long ptr, String symbol);
protected native int SymbolHide(long ptr, String symbol);
protected native int SymbolSendTick(long ptr, String symbol, double bid, double ask);
// --- manager commands
protected native ConGroup[] GroupsRequest(long ptr);
protected native int MailSend(long ptr, MailBox mailBox, int[] logins);
protected native int NewsSend(long ptr, NewsTopic newsTopic);
// --- journal
protected native ServerLog[] JournalRequest(long ptr, int mode, int from, int to, String filter);
// --- users
protected native UserRecord[] UsersRequest(long ptr);
protected native UserRecord UserRecordsRequest(long ptr, int login);
// protected native UserRecord[] UserRecordsRequest(long ptr, int[] logins);
/**
* When calling the method, a check is made whether the entry already exists. If
* the record already exists, the function will return RET_ERROR. The key field
* to check is the login UserRecord::login. Make sure to fill in the
* UserRecord::group and UserRecord::leverage fields in the record you are
* adding.
*/
protected native int UserRecordNew(long ptr, UserRecord userRecord);
protected native int UserRecordUpdate(long ptr, UserRecord userRecord);
protected native int UsersGroupOp(long ptr, GroupCommandInfo info, int[] logins);
protected native int UserPasswordCheck(long ptr, int login, String password);
protected native int UserPasswordSet(long ptr, int login, String password, int change_investor, int clean_pubkey);
protected native OnlineRecord[] OnlineRequest(long ptr);
// --- orders
protected native int TradeTransaction(long ptr, TradeTransInfo tradeTransInfo);
protected native TradeRecord[] TradesRequest(long ptr);
protected native TradeRecord[] TradeRecordsRequest(long ptr, int[] orders);
protected native TradeRecord[] TradesUserHistory(long ptr, int login, int from, int to);
/**
* 检查是否可以挂单 The symbol, for which the order has been placed, is unavailable to
* the manager. * The pending order expiration time is less than 10 minutes
* from the current time.
* fill in cmd, volume, open_price and symbol when opening market orders, as well as sl and tp if such are set,
* additionally fill in expiration for pending orders; the close price is specified instead of open_price when closing market orders.
*
* The function checks whether the specified price of a pending order, Stop Loss or Take Profit is out of the forbidden channel set in ConSymbol::stops_level
*/
protected native int TradeCheckStops(long ptr, TradeTransInfo trade, double price);
// --- reports
protected native TradeRecord[] ReportsRequest(long ptr, ReportGroupRequest reportGroupRequest, int[] logins);
protected native DailyReport[] DailyReportsRequest(long ptr, DailyGroupRequest req, int[] logins);
// //+------------------------------------------------------------------+
// //| Notification callback function |
// //+------------------------------------------------------------------+
// typedef void (*MTAPI_NOTIFY_FUNC)(int code);
// //+------------------------------------------------------------------+
// //| Notification callback function |
// //+------------------------------------------------------------------+
// typedef void (*MTAPI_NOTIFY_FUNC_EX)(int code,int type,void * data,void *param);
/* ======================================= pumping =================*/
/**
* 切换到pumping
* @author
* @time 上午10:27:24
* @param code int code, 回调携带
* @param destwnd int destwnd不需要窗体
* @param eventmsg
* @param flags
* @return
*/
protected native int PumpingSwitch(long ptr, int eventmsg,int flags);
/**
* 获取用户组
* @author
* @time 下午6:12:37
* @return
*/
protected native ConGroup[] GroupsGet(long ptr);
/**
* 获取用户组
*/
protected native ConGroup GroupRecordGet(long ptr, String name);
/**
* 市场报价
* @author
* @time 下午6:11:04
* @param ptr
* @return
*/
protected native SymbolInfo[] SymbolInfoUpdated(long ptr, int max);
/**
* 获取用户记录
* @author
* @time 下午6:31:37
* @param ptr
* @return
*/
protected native UserRecord[] UsersGet(long ptr);
/**
* 获取用户记录
* @author
* @time 下午6:31:58
* @return
*/
protected native UserRecord UserRecordGet(long ptr, int login);
/**
* 获取在线用户记录
* @author
* @time 下午6:32:43
* @return
*/
protected native OnlineRecord[] OnlineGet(long ptr);
/**
* 获取在线用户记录
* @author
* @time 下午6:32:43
* @return
*/
protected native OnlineRecord OnlineRecordGet(long ptr, int login);
/**
* 获取交易记录
* @author
* @time 下午6:33:58
* @param ptr
* @return
*/
protected native TradeRecord[] TradesGet(long ptr);
/**
* 获取交易记录:品种
* @author
* @time 下午6:33:58
* @param ptr
* @return
*/
protected native TradeRecord[] TradesGetBySymbol(long ptr, String symbol);
/**
* 获取交易记录:用户
* @author
* @time 下午6:33:58
* @param ptr
* @return
*/
protected native TradeRecord[] TradesGetByLogin(long ptr, int login, String group);
/**
* 获取交易记录:市场
* @author
* @time 下午6:33:58
* @param ptr
* @return
*/
protected native TradeRecord[] TradesGetByMarket(long ptr);
/**
* 获取交易记录:单号
* @author
* @time 下午6:33:58
* @param ptr
* @return
*/
protected native TradeRecord TradeRecordGet(long ptr, int order);
/**
* 关闭交易的反馈
* @author
* @time 下午6:33:58
* @param ptr
* @return
*/
protected native int TradeClearRollback(long ptr, int order);
/**
* 备用金情况
*/
protected native MarginLevel[] MarginsGet(long ptr);
/**
* 备用金情况
*/
protected native MarginLevel MarginLevelGet(long ptr, int login, String group);
protected native RequestInfo[] RequestsGet(long ptr);
protected native RequestInfo RequestInfoGet(long ptr, int pos);
protected native ConPlugin[] PluginsGet(long ptr);
protected native ConPluginParam PluginParamGet(long ptr, int pos);
protected native int MailLast(long ptr, String path, int length);
protected native NewsTopic[] NewsGet(long ptr);
protected native int NewsTotal(long ptr);
protected native NewsTopic NewsTopicGet(long ptr,int pos, NewsTopic newsTopic);
protected native void NewsBodyRequest(long ptr,int key);
protected native String NewsBodyGet(long ptr,int key);
//--- dealing
protected native int DealerSwitch(long ptr,int code, int destwnd, int eventmsg);
protected native RequestInfo DealerRequestGet(long ptr);
protected native RequestInfo DealerSend(long ptr,int requote, int mode);
protected native int DealerReject(long ptr,int id);
protected native int DealerReset(long ptr,int id);
// ---
protected native TickInfo[] TickInfoLast(long ptr, String symbol);
protected native ConSymbolGroup[] SymbolsGroupsGet(long ptr);
/**
* API:connection 服务器时间 登录后才能获取
*
* @param ptr
* @return
*/
protected native long ServerTime(long ptr);
protected native MailBox[] MailsRequest(long ptr);
//--- risk management
protected native SymbolSummary[] SummaryGetAll(long ptr);
protected native SymbolSummary SummaryGet(long ptr, String symbol);
protected native SymbolSummary SummaryGetByCount(long ptr, int symbol);
protected native SymbolSummary SummaryGetByType(long ptr, int sectype);
protected native int SummaryCurrency(long ptr, String cur, int maxchars);
protected native ExposureValue[] ExposureGet(long ptr);
protected native ExposureValue ExposureValueGet(long ptr, String cur);
// ---
protected native MarginLevel MarginLevelRequest(long ptr, int login);
/**
* 返回重绘蜡烛块数量
* @author
* @time 下午3:17:18
* @param symbol
* @return
*/
protected native int HistoryCorrect(long ptr, String symbol);
// --- new chart bases
protected native RateInfo[] ChartRequest(long ptr, ChartInfo chartInfo);
protected native int ChartAdd(long ptr, String symbol, int period, RateInfo[] rates, int count);
protected native int ChartUpdate(long ptr, String symbol, int period, RateInfo[] rates, int count);
protected native int ChartDelete(long ptr, String symbol, int period, RateInfo[] rates, int count);
// --- ticks base
protected native TickRecord[] TicksRequest(long ptr, TickRequest request);
// --- internal methods
protected native int PumpingSwitchEx(long ptr, int flags, Object param);
protected native int UsersSyncStart(long ptr, int timestamp);
protected native UserRecord[] UsersSyncRead(long ptr);
protected native int[] UsersSnapshot(long ptr); // manage中的用户login
protected native int TradesSyncStart(long ptr, int timestamp);
protected native TradeRecord[] TradesSyncRead(long ptr);
protected native int[] TradesSnapshot(long ptr);
protected native int DailySyncStart(long ptr, int timestamp);
protected native DailyReport[] DailySyncRead(long ptr);
// --- profit recalculation 计算盈利 trade.profit
protected native double TradeCalcProfit(long ptr, TradeRecord TradeRecord);
// --- new symbol commands
protected native int SymbolChange(long ptr, SymbolProperties symbolProperties);
//--- notifications
/**
* @param metaquotes_ids
* A comma separated list of MetaQuotes IDs.
* @param message
* @return
*/
protected native int NotificationsSend(long ptr, String metaquotes_ids, String message);
protected native int NotificationsSend(long ptr, int[] logins, int logins_total, String message);
}
c++实现MyMT4Manager.cpp:
#include "MyMT4Manager.h"
CManagerFactory Factory;
JavaVM* javaVM;
static jclass g_ref_pump_notice_class = NULL;
static jmethodID g_ref_pump_notice_structor = NULL;
static jmethodID g_ref_pump_notice_pump_method = NULL;
static jmethodID g_ref_pump_notice_pumpex_method = NULL;
jint vesrion = JNI_VERSION_1_8;
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
javaVM = vm;
jint result = -1;
jint status = vm->GetEnv((void**)& env, vesrion);
printf("OnLoad[JNI_OnLoad stauts:%d]\n", status);
if (status != JNI_OK) {
goto over;
}
if (env == NULL) {
goto over;
}
result = vesrion;
over:
printf("OnLoad[JNI_OnLoad:%d]\n", result);
return result;
}
JNIEXPORT void JNICALL
JNI_OnUnload(JavaVM* vm, void* reserved) {
printf("OnLoad[JNI_OnUnload]\n");
}
/*
* Class: com_metoo_mt4_api_ManagerAPI
* Method: WinsockStartup
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_metoo_mt4_api_ManagerAPI_WinsockStartup
(JNIEnv* env, jclass clazz) {
Factory.WinsockStartup();
}
/*
* Class: com_metoo_mt4_api_ManagerAPI
* Method: WinsockCleanup
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_metoo_mt4_api_ManagerAPI_WinsockCleanup
(JNIEnv* env, jclass clazz) {
Factory.WinsockCleanup();
}
/*
* Class: com_metoo_mt4_api_ManagerAPI
* Method: Release
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_metoo_mt4_api_ManagerAPI_Release
(JNIEnv* env, jobject obj, jlong ptr) {
CManagerInterface* manager = (CManagerInterface*)ptr;
int result = manager->Release();
if (g_ref_pump_notice_class != NULL) {
env->DeleteGlobalRef(g_ref_pump_notice_class);
}
if (g_ref_pump_notice_st