http://macy01.blogcn.com/diary,25587290.shtml MT4中如何通过DLL传递汇率数据到外部程序 在Visual C++开发工具中创建一个工程,选择MFC(DLL)类型,假设工程名为demo。创建好工程后,最核心的两个文件为demo.cpp和demo.def。 假设希望开发的dll文件中包含三个功能函数: l double GetCloseValue( RateInfo* rates,int totalRecords, int shift ) 返回收盘价位 l double GetHighValue( RateInfo* rates,int totalRecords, int shift ) 返回最高价位 l void GetSMAArray( RateInfo* rates, int totalRecords, int period, double result[] ) 返回SMA移动平均线值 其中RateInfo被定义为结构类型: struct RateInfo { unsigned int time; //时间 double open; //开盘价格 double low; //最低价格 double high; //最高价格 double close; //收盘价格 double volume; //成交量 }; 比较精妙的是MT4提供了ArrayCopyRates函数用于复制一段走势图上的数据到一个二维数组,并返回复制柱子的总数。其第二维为固定的6个项目,从0到5分别为“时间、开盘价格、最低价格、最高价格、收盘价格、成交量”。 int ArrayCopyRates( void dest_array[], void symbol, void timeframe) 因此这里的RateInfo结构定义正好对应上面二维数组的第二维,MT4程序也是默认通过这种方式来提供二维数组到结构指针(即RateInfo结构数组)的映射的。 在demo.def中定义DLL的输出函数(如下),经过编译后将在指定目录生成DLL文件。 LIBRARY "demo" EXPORTS GetCloseValue GetHighValue GetSMAArray 将生成的DLL文件拷贝到MT4程序的”experts/libraries目录下。在MT4程序中调用引用DLL的代码为: #import "demo.dll" double GetCloseValue( double rates[][6], int totalRecords, int shift ); double GetHighValue( double rates[][6], int totalRecords, int shift ); void GetSMAArray( double rates[][6], int totalRecords, int period, double& results[]); #import 这里引用DLL函数的一个重要的区别在于RateInfo*被映射为二维数组double rates[][6],也就是说MT4调用DLL的时候由操作系统根据内存指针完成了数据的访问,且结构定义中的unsigned int是从double类型转换后得到的。在MT4程序中调用DLL中函数的代码为: int start() { double rates[][6]; int totalRecords = ArrayCopyRates( rates, Symbol(), 0 ); for( int i = totalRecords; i >= 0; i-- ) { ` results = EMPTY; } GetSMAArray( rates, totalRecords, period, results ); return(0); } 示例代码(DLL对应cpp文件中的函数定义和代码): //+------------------------------------------------------------------+ //| MT4调用DLL示例程序 | //| Copyright @2009-2010, 笨蛋学经济 | //| http://macy01.blogcn.com | //+------------------------------------------------------------------+ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define MT4_EXPFUNC __declspec(dllexport) //+------------------------------------------------------------------------------------------------------------+ //| MT4数据结构 | //+------------------------------------------------------------------------------------------------------------+ #pragma pack(push,1) struct RateInfo { unsigned int time; double open; double low; double high; double close; double volume; }; struct MqlStr { int len; char* string; }; #pragma pack(pop) //+------------------------------------------------------------------------------------------------------------------+ //| DLL函数定义 | //+------------------------------------------------------------------------------------------------------------------+ MT4_EXPFUNC double _stdcall GetCloseValue( RateInfo* rates,int totalRecords, int shift ) { return( rates[totalRecords-shift-1].close ); } MT4_EXPFUNC double _stdcall GetHighValue( RateInfo* rates,int totalRecords, int shift ) { return( rates[totalRecords-shift-1].high ); } MT4_EXPFUNC void _stdcall GetSMAArray( RateInfo* rates, int totalRecords, int period, double result[] ) { for( int i = 0; i < totalRecords; i++) { double sum = 0.0; for( int k = 0; k < period ; k++ ) { sum += rates[totalRecords-i-1-k].close; } result[totalRecords-i-1] = sum / period ; } }
除了自制DLL,偶還考慮過以網絡通訊Client/Server端模式交換行情數據,這種數據交換方式可以讓行情端和數據處理端不必局限于同一機本地環境,分布到局域網內也是可行的。 只要在外部程序開發好服務端模塊,響應來自MT4的網絡連接呼叫請求。 客戶端MT4上則調用win32 api提供網絡通訊相關的公共開發庫,比如wininet.dll或winsock.dll等等,實現行情數據的推送。 這里有現成的Http Client代碼。 http://codebase.mql4.com/4428 http://forum.mql4.com/15848 http://msdn.microsoft.com/en-us/library/aa385331(VS.85).aspx