国庆奉献:简单支持大智慧公式dll接口 这次源自客户定制需要,考虑再三,决定支持大智慧公式dll接口 大智慧公式dll语言规约和分析家一样. 算是给大家的国庆节礼物 调用大智慧/分析家公式dll接口函数 在调用函数之前要创建缓冲区,并从对应历史数据接口填充k线数据 这个与历史数据接口对应的缓冲区,数据长度固定为480,配有10个输入输出缓冲区, 用作调用dll具体公式函数是时输入输出缓冲区 XDll_Free(Dll相对路径文件名);//释放动态链接库 XDll_Load(Dll相对路径文件名);//加载动态链接库 功能:释放或加载动态链接库 参数:Dll相对路径文件名 例如:XDll_Load("autop\qml\xxxxx.dll"); XDll_Exec(Dll相对路径文件名, 函数名,K线缓冲区序号,输出缓冲区序号, 参数1有效位置,参数1,参数2,参数3,参数4);//调用库函数 功能:调用库函数 参数: 1.Dll相对路径文件名 2.函数名(dll完全出口函数名,例如在大智慧中是macd,一般完全函数名是_macd) 3.K线缓冲区序号 指的是与历史数据库接口相对应k线数据缓冲区的序号0,1,2 4.输出缓冲区序号(可省) 指定调用库函数的输出缓冲区的序号,为0--9(可以是10个输入输出缓冲区中的任何一个) 默认为0 5.参数1有效位置(可省) 当有参数1时设定参数1的性质,<0时指定参数1是常数输入,这时参数1就是输入数据 当其>=0时,参数1就是选定做输入缓冲区的输入输出缓冲区序号,在库函数调用前一定要设置好预定数据 本参数值指定该系列输入数据的有效起始位置 6.参数1 输入参数,当其明确输入时,与上一参数配合,省略时,库函数调用输入参数为空 6.参数2,参数3,参数4 输入参数,当其明确输入时,将作为库函数调用参数,省略时,库函数对应调用参数为空 例如:XDll_Exec("autop\qml\xxxxx.dll","_kxian",0,0);//调用库函数 XDll_DBufDelete();//删除历史数据接口对应k线数据缓冲区 XDll_DBufCreate(开始位置,结束位置);//创建历史数据接口对应k线数据缓冲区,并调入数据 XDll_GetKXData(数据索引,k线数据编号0.t.1.o.2.h.3.l.4.c.5.v);//获取历史数据接口对应k线数据缓冲区数据 XDll_GetIOData(输入输出数据缓冲区号0..9,数据索引);//获取历史数据接口对应数据缓冲区数据 XDll_SetIOData(输入输出数据缓冲区号0..9,数据索引,数据);//设置历史数据接口对应数据缓冲区数据 XDll_CopyIOData(源缓冲区号,目的缓冲区号);//拷贝历史数据接口对应数据缓冲区数据 XDll_ClearIOData(缓冲区号);//清除历史数据接口对应数据缓冲区数据 功能:历史数据接口对应k线数据缓冲区操作,具体功能看上面标示 参数: 1.开始位置 对应历史数据接口中的数据开始位置 2.结束位置 对应历史数据接口中的数据结束位置,-1时将直接取值为最后位置 当开始与结束位置的k线根数大于480时,系统会自动将开始位置裁剪为结束位置-450 3 数据索引 等同历史数据库接口索引 4.其他参数同表面意思 注意: XDll_DBufCreate函数可以连续调入,并填入数据,其返回值为新的数据根数 在程序中可用 if(XDll_DBufCreate(0,-1)) { XDll_Exec("autop\qml\xxxxx.dll","_kxian",0,0);//调用库函数 // ..... } 简单测试代码为: OpenLsLib("m1005",64,4,0); XDll_DBufCreate(0,-1);//创建历史数据接口对应k线数据缓冲区,并调入数据 XDll_Load("autop\qml\xxxxx.dll");//加载动态链接库 XDll_Exec("autop\qml\xxxxx.dll","_kxian",0,0);//调用库函数 ...................... int m_daya=XDll_GetIOData(0,m_dsp_dir);
#ifndef __DzhFUNC_H_INCLUDE #define __DzhFUNC_H_INCLUDE /* /////////////////////////////////////////////////////////////////////////// 大智慧扩展函数规范V1.10 1.本规范适用于大智慧1.10标准版和专业版公式系统. 2.扩展函数用于实现系统函数不能实现的特殊算法. 3.扩展函数用windows 32位动态连接库实现,建议使用Microsoft Visual C++编程. 4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"DZHFUNC@MYCMALOSE"(5) 5.动态连接库名称和函数名称可以自己定义. 6.使用时可以将动态库拷贝到大智慧目录下使用. */ #ifdef __cplusplus extern "C" { #endif //__cplusplus /////////////////////////////////////////////////////////////////////////// //分析周期 enum DATA_TYPE { TICK_DATA=2, //分笔成交 MIN1_DATA, //1分钟线 MIN5_DATA, //5分钟线 MIN15_DATA, //15分钟线 MIN30_DATA, //30分钟线 MIN60_DATA, //60分钟线 DAY_DATA, //日线 WEEK_DATA, //周线 MONTH_DATA, //月线 MULTI_DATA //多日线 }; /////////////////////////////////////////////////////////////////////////// //基本数据 typedef struct tagSTKDATA { time_t m_time; //时间,UCT float m_fOpen; //开盘 float m_fHigh; //最高 float m_fLow; //最低 float m_fClose; //收盘 float m_fVolume; //成交量 float m_fAmount; //成交额 WORD m_wAdvance; //上涨家数(仅大盘有效) WORD m_wDecline; //下跌家数(仅大盘有效) } STKDATA; //////////////////////////////////////////////////////////////////////////// //扩展数据,用于描述分笔成交数据的买卖盘 typedef union tagSTKDATAEx { struct { float m_fBuyPrice[3]; //买1--买3价 float m_fBuyVol[3]; //买1--买3量 float m_fSellPrice[3]; //卖1--卖3价 float m_fSellVol[3]; //卖1--卖3量 }; float m_fDataEx[12]; //保留 } STKDATAEx; ///////////////////////////////////////////////////////////////////////////// /*财务数据顺序(m_pfFinData内容) 序号 内容 0 总股本(万股), 1 国家股, 2 发起人法人股, 3 法人股, 4 B股, 5 H股, 6 流通A股, 7 职工股, 8 A2转配股, 9 总资产(千元), 10 流动资产, 11 固定资产, 12 无形资产, 13 长期投资, 14 流动负债, 15 长期负债, 16 资本公积金, 17 每股公积金, 18 股东权益, 19 主营收入, 20 主营利润, 21 其他利润, 22 营业利润, 23 投资收益, 24 补贴收入, 25 营业外收支, 26 上年损益调整, 27 利润总额, 28 税后利润, 29 净利润, 30 未分配利润, 31 每股未分配, 32 每股收益, 33 每股净资产, 34 调整每股净资, 35 股东权益比, 36 净资收益率 */ ///////////////////////////////////////////////////////////////////////////// //函数数据结构 typedef struct tagCALCINFO { const DWORD m_dwSize; //结构大小 const DWORD m_dwVersion; //调用软件版本(V2.10 : 0x210) const DWORD m_dwSerial; //调用软件序列号 const char* m_strStkLabel; //股票代码 const BOOL m_bIndex; //大盘 const int m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量) const STKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为 NULL const STKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为 NULL const int m_nParam1Start; //参数1有效位置 const float* m_pfParam1; //调用参数1 const float* m_pfParam2; //调用参数2 const float* m_pfParam3; //调用参数3 const float* m_pfParam4; //调用参数3 float* m_pResultBuf; //结果缓冲区 const DATA_TYPE m_dataType; //数据类型 const float* m_pfFinData; //财务数据 } CALCINFO; /* 注: 1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效. 2.当一个参数无效时,则其后的所有参数均无效. 如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL. 3.参数1可以是常数参数或序列数参数,其余参数只能为常数参数. 4.若m_nParam1Start<0, 则参数1为常数参数,参数等于*m_pfParam1; 5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组, 数组大小为m_nNumData,数据有效范围为m_nParam1Start--m_nNumData. 在时间上m_pData[x] 与 m_pfParam1[x]是一致的 */ /////////////////////////////////////////////////////////////////////////////////// /* 函数输出 __declspec(dllexport) int xxxxxxxx(CALCINFO* pData); ---------- A __declspec(dllexport) int xxxxxxxxVAR(CALCINDO* pData); ---------- B 1.函数名称需全部大写. 2.函数必须以上述A,B两种形式之一声明,请用实际函数名称替代xxxxxxxx; 对于C++程序还需包括在 extern "C" { } 括号中. 3.上述形式A用于声明不带参数或全部参数为常数的函数; 形式B用于声明参数1为序列数的函数;两种函数的区别在于后者以VAR结尾. 4.函数计算结果用pData->m_pResultBuf带回. 5.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即: m_pResultBuf[返回值] -- m_pResultBuf[m_nNumData-1]间为有效值. 6.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER 7.编译时请请选择1字节对齐 */ //示例函数,使用时用实际名称替换 __declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData); __declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData); __declspec(dllexport) int WINAPI MYMACLOSE_CALC_PREV(CALCINFO* pData); __declspec(dllexport) int WINAPI MYMAVAR_CALC_PREV(CALCINFO* pData); #ifdef __cplusplus } #endif //__cplusplus #endif //__DZHFUNC_H_INCLUDE
// FxjFunc.cpp : Defines the entry point for the DLL application. // #include "stdafx.h" #include "FxjFunc.h" BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } //计算收盘价的均价,一个常数参数,表示计算周期 //调用方法: // MYMACLOSE(5) __declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData) { float f,fTotal; int nPeriod,i,j; if(pData->m_pfParam1 && //参数1有效 pData->m_nParam1Start<0 && //参数1为常数 pData->m_pfParam2==NULL) //仅有一个参数 { f = *pData->m_pfParam1; nPeriod = (int)f; //参数1 if(nPeriod>0) { for(i=nPeriod-1;i<pData->m_nNumData;i++) //计算nPeriod周期的均线,数据从nPeriod-1开始有效 { fTotal = 0.0f; for(j=0;j<nPeriod;j++) //累加 fTotal += pData->m_pData[i-j].m_fClose; pData->m_pResultBuf = fTotal/nPeriod; //平均 } return nPeriod-1; } } return -1; } __declspec(dllexport) int WINAPI MYMACLOSE_CALC_PREV(CALCINFO* pData) { if(pData->m_pfParam1 && pData->m_nParam1Start<0) { float f = *pData->m_pfParam1; return ((int)f) - 1; } return 0; } //计算均价,2个参数,参数1为待求均线的数据,参数2表示计算周期 //调用方法: // MYMAVAR(CLOSE-OPEN,5) __declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData) { float f,fTotal; const float* pValue; int nPeriod,nFirst,i,j; if(pData->m_pfParam1 && pData->m_pfParam2 && //参数1,2有效 pData->m_nParam1Start>=0 && //参数1为序列数 pData->m_pfParam3==NULL) //有2个参数 { pValue = pData->m_pfParam1; //参数1 nFirst = pData->m_nParam1Start; //有效值 f = *pData->m_pfParam2; nPeriod = (int)f; //参数2 if(nFirst>=0 && nPeriod>0) { for(i=nFirst+nPeriod-1;i<pData->m_nNumData;i++) { fTotal = 0.0f; for(j=0;j<nPeriod;j++) //累加 fTotal += pData->m_pData[i-j].m_fClose; pData->m_pResultBuf = fTotal/nPeriod; //平均 } return nFirst+nPeriod-1; } } return -1; } __declspec(dllexport) int WINAPI MYMAVAR_CALC_PREV(CALCINFO* pData) { if(pData->m_pfParam2) { float f = *pData->m_pfParam2; return ((int)f) - 1; } return 0; }
参数一般不超过四个.少于四个是可以的.本软件只是调入公式dll.他原来有几个参数就是几个参数. 公式dll的配置和使用,可以根据实际需要来.假如你多于四个参数,就应当分拆,通过生成中间指标来转接. 再复杂的系统也不难.