外汇交易一般都在MetaTrader 4,简称MT4上进行,MT4提供了一种编程语言类似C/C++,叫MQL4,可以直接挂到对应的图表上,接收数据。MT4上的脚本也有很多类型,实时抓取数据的脚本叫EA脚本。
主要思路就是用cmd命令自动打开MT4,然后使用自动化脚本把写好的抓取数据脚本attach到行情图上,就可以开始抓数据了,收到数据之后实时写到mysql中,完成实时数据的抓取。抓到的都是tick data,也就是毫秒级的数据。如果需要时间段的数据,比如5分钟,4小时,1天的数据,恐怕得自己在后台去算。
下面看一下具体过程:
首先,cmd里写打开MT4软件的命令
-
@echo off
-
set mt4path=D:\MetaTrader 4 at FOREX.com\
-
"%mt4path%terminal.exe" "%mt4path%config\wscn\realtime.txt"
然后,我们看一下realtime这个配置文件
Profile=AllCharts
Template=
Expert=
ExpertParameters=
Script=AutoApplyEAToAllCharts
ScriptParameters
上面的Profile代表打开MT4的时候,自动打开的空间文件,其实就是默认打开哪些行情图表。然后Script的意思是打开MT4以后自动运行这个脚本。
接着看AutoApplyEAToAllCharts脚本主要干什么
-
string EA_SCRIPT_NAME = "insertMySql";
-
string properties[1000][2],currency[];
-
int start()
-
{
-
readPropertyFile(properties,getRealtimeConfigFilePath());
-
getFetchRealTimeCharts(properties,currency);
-
Sleep(60000);
-
for(int i=0;i<ArraySize(currency);i++){
-
string cur = StringTrimRight(StringTrimLeft(currency[i]));
-
//Print("cur",cur);
-
if(cur == "")continue;
-
int hwnd = Window.getHandle(cur);
-
Window.activate(hwnd);
-
//Window.maximize(hwnd);
-
EA.startEA(hwnd,EA_SCRIPT_NAME,true);
-
}
-
return(0);
-
}
上面的代码意思主要功能就是把抓取数据的脚本具体attach到行情图表窗口上去,因为每个行情图表都是一个小窗口。
最后看insertMySql脚本,主要功能都在这里面实现
-
int init()
-
{
-
readPropertyFile(properties,getRealtimeConfigFilePath());
-
strTableName = getValueByKey(properties,Symbol());
-
strNewDataTableName = getValueByKey(properties,"newdatatable");
-
connectDB();
-
return(0);
-
}
-
void connectDB(){
-
string host,user,pwd,dbName,port;
-
int socket = 0,client = 0;
-
bool goodConnect = false;
-
host = getValueByKey(properties,"host");
-
user = getValueByKey(properties,"username");
-
pwd = getValueByKey(properties,"password");
-
dbName = getValueByKey(properties,"database");
-
port = getValueByKey(properties,"port");
-
goodConnect = mysqlInit(dbConnectId, host, user, pwd, dbName, port, socket, client);
-
if ( !goodConnect ) {
-
Print("connect DB failed!");
-
return (1); // bad connect
-
}
-
}
-
int deinit()
-
{
-
mysqlDeinit(dbConnectId);
-
return(0);
-
}
-
int start()
-
{
-
string strDateTime = TimeToStr(TimeCurrent(),TIME_DATE | TIME_SECONDS);
-
string strOpen = DoubleToStr(iOpen(Symbol(), 0, 0), MarketInfo(Symbol(), MODE_DIGITS));
-
string strHigh = DoubleToStr(iHigh(Symbol(), 0, 0), MarketInfo(Symbol(), MODE_DIGITS));
-
string strLow = DoubleToStr(iLow(Symbol(), 0, 0), MarketInfo(Symbol(), MODE_DIGITS));
-
string strClose = DoubleToStr(iClose(Symbol(), 0, 0), MarketInfo(Symbol(), MODE_DIGITS));
-
string strVolume = iVolume(Symbol(), NULL, 0);
-
string strBid = DoubleToStr(Bid, MarketInfo(Symbol(), MODE_DIGITS));
-
string strAsk = DoubleToStr(Ask, MarketInfo(Symbol(), MODE_DIGITS));
-
string timeZone = StringTrimRight(StringTrimLeft(getValueByKey(properties,"timeZone")));
-
int adjustTime = TimeGMT();
-
if(timeZone != ""){
-
adjustTime += StrToInteger(timeZone) * 60 * 60 * 1000;
-
}
-
Comment(TimeCurrent()+" ", adjustTime+" ",
-
strBid+" ",
-
strAsk+" ",
-
strHigh+" ",
-
strLow+" ",
-
strVolume);
-
string insertQuery = createInsertQuery(strTableName,Symbol(),adjustTime,Bid,Ask,
-
iHigh(Symbol(), 0, 0),iLow(Symbol(), 0, 0),iVolume(Symbol(), NULL, 0));
-
mysqlQuery(dbConnectId, insertQuery);
-
string updateQuery = createUpdateQuery(strNewDataTableName,Symbol(),adjustTime,Bid,Ask,
-
iHigh(Symbol(), 0, 0),iLow(Symbol(), 0, 0),iVolume(Symbol(), NULL, 0));
-
mysqlQuery(dbConnectId, updateQuery);
-
return(0);
-
}
上面的代码首先连接mysql DB,然后在start函数里面接收tick data,也就是说行情每跳动一次,就会调用一次start方法,这是MT4脚本提供的回调。然后在start方法里,把tick data插入到历史数据表中,接着更新实时行情数据表。历史表和实时数据表是分开的。
上面的过程只是个大概程序,具体代码比这个多多了,这里只是提供个思路,感兴趣的,有需要的,在联系我。
=========================================
这里说一下,不同的外汇供应商提供的数据种类不一样,比如嘉盛提供的外汇种类可能比福汇多,而每家供应商都会对MT4做定制,如果想抓的比较全,需要打开不同供应商的MT4软件,然后执行上面的过程。
所谓的CFD意思是价差合约,背后没有实际的金融资产做支撑,这种玩意在美国是没法交易的,在欧洲可以交易。它往往追踪股指,比如标普500,纳纳斯达克100指数,但是数值不完全一样,因为CFD是5x24小时交易,而对应的股指只有在每天固定的时间交易