大智慧DLL资料

关于证券软件大智慧的数据输出的一个dll文件,它导出的是二进制文件。我想求助如何改写该dll输出txt供matlab读入,再用dll读入matlab计算后的数据。抑或有达人有matlab直接读入该二进制文件的方案?dll源码以下。
头文件如下:
#ifndef __FXJFUNC_H_INCLUDE
#define __FXJFUNC_H_INCLUDE

/*
//////////
分析家扩展函数规范V3.10
1.本规范适用于分析家3.10标准版和专业版公式系统.
2.扩展函数用于实现系统函数不能实现的特殊算法.
3.扩展函数用windows 32位动态连接库实现,建议使用Microsoft Visual C++编程.
4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FXJFUNC@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 WRITE(CALCINFO* pData);
__declspec(dllexport) int WINAPI READ(CALCINFO* pData);


#ifdef __cplusplus
}
#endif //__cplusplus


#endif //__FXJFUNC_H_INCLUDE
===============================
// FxjFunc.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "FxjFunc.h"
#include
using namespace std;
#include
#include


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;
}

string DzhCode(string dm , const BOOL bIndex)
{
string mydm=dm;
if(bIndex && mydm.substr(0,3)=="000")
{
mydm="1";mydm=mydm.append(dm);
return mydm;
}
else
{
return mydm;
}
}

string int2Code(int iCode)
{
char strvar[20];
itoa(iCode,strvar,10);//指标序号,第三个参数10表示十进制
string mydm(strvar);
if(iCode>1000000)//沪市指数1000001...
{
return mydm;
}
else
{
//char s[20];
//sprintf(s,"00000%d",iCode);
//return string(s);
string zeros="";
for(int j=strlen(strvar);j<6;j++) zeros.append("0");
mydm=zeros.append(mydm);
return mydm;
}
}

string DzhDataType(DATA_TYPE datatype)
{
switch(datatype)
{
case TICK_DATA: //分笔成交
return "TICK";
break;
case MIN1_DATA: //1分钟线
return "MIN1";
break;
case MIN5_DATA: //5分钟线
return "MIN5";
break;
case MIN15_DATA: //15分钟线
return "MIN15";
break;
case MIN30_DATA: //30分钟线
return "MIN30";
break;
case MIN60_DATA: //60分钟线
return "MIN60";
break;
case DAY_DATA: //日线
return "DAY";
break;
case WEEK_DATA: //周线
return "WEEK";
break;
case MONTH_DATA: //月线
return "MONTH";
break;
case MULTI_DATA: //多日线
return "NDAYS";
break;
case 12:
return "YEAR";
break;
case 13:
return "QUARTER";
break;
case 14:
return "SEMIYEAR";
break;
case 15:
return "15";
break;
case 1:
return "1";
break;
default:
return "NA";
}

}

string fileName(string dm , const BOOL bIndex,int varid,DATA_TYPE datatype)
{
char strvar[20];
itoa(varid,strvar,10);//指标序号,第三个参数10表示十进制
string filename ="FMLDATA\\";
filename.append(DzhCode(dm,bIndex));
filename.append(".");
filename.append(strvar);
filename.append(".");
filename.append(DzhDataType(datatype));
return filename;
}


__declspec(dllexport) int WINAPI WRITE(CALCINFO* pData)
{
float f ;
int nVar,nFirst,i;
string code="";
if(pData->m_pfParam1 && pData->m_pfParam2 && //参数1,2有效
pData->m_nParam1Start>=0 && //参数1为序列数
pData->m_pfParam3==NULL) //有2个参数
{
nFirst = pData->m_nParam1Start; //有效值
code.append(pData->m_strStkLabel);
f = *pData->m_pfParam2; nVar = (int)f;
if(nVar>0)
{
struct recordStruct{int dt;float value;} record;
string filename=fileName(code,pData->m_bIndex,nVar,pData->m_dataType);
ofstream fout(filename.c_str(),ios::binary);
if(fout)
{
for(i=0;im_nNumData;i++)
{
record.dt=pData->m_pData[i].m_time;
record.value=pData->m_pfParam1[i];
fout.write((char*)(&record),sizeof(record));
pData->m_pResultBuf[i]=pData->m_pfParam1[i];
}
}
fout.close();
return 1;
}
}
return -1;
}

__declspec(dllex

port) int WINAPI READ(CALCINFO* pData)
{
float f;
int nCode,nVar,i;
string code="";

if(pData->m_pfParam1 && pData->m_pfParam2 && //参数有效
pData->m_nParam1Start<0 && //参数为常数
pData->m_pfParam3==NULL) //2个参数
{

nCode=(int) *pData->m_pfParam1; //参数1
if(nCode==0)
code.append(pData->m_strStkLabel);
else
code=int2Code(nCode);

f = *pData->m_pfParam2;
nVar = (int)f; //参数1
if(nVar>0)
{

struct recordStruct{int dt;float value;} record;
string filename=fileName(code,pData->m_bIndex,nVar,pData->m_dataType);
ifstream fin(filename.c_str(),ios::binary);
if(fin)
{
record.dt=0;record.value=0;
fin.read((char*)(&record),sizeof(record));
for(i=0;im_nNumData;i++)
{
int dzhrq = pData->m_pData[i].m_time;
while(!fin.eof() && dzhrq>record.dt )
{
fin.read((char*)(&record),sizeof(record));
}
if(!fin.eof() && dzhrq==record.dt)
//if(!fin.eof())
{
pData->m_pResultBuf[i]=record.value;
}
if(fin.eof()) break;
}
}
fin.close();

return 1;
}

}
return -1;
}
==================
二进制格式文件,一个文件由多个记录组成,每个记录两个字段,第一个字段为DZH时间,为INT型,保存的是与1970-1-1 00:00:00间隔秒数,第二个字段为指标/序列值,为Float型,保存具体数值,注意Float型的数据范围!文件要求每个记录的时间由小到大顺序排列。
例如,文件中有8条记录:
1174435200 0.05
1174521600 0.003
1174608000 -0.029
1174867200 -0.011
1174953600 - 0.009
1175040000 0.005
1175126400 0.004
1175212800 -0.015
第一列是日期/时间,第二列是数值,把第一列转换一下可得:
2007-03-21 0.05
2007-03-22 0.003
2007-03-23 -0.029
2007-03-26 -0.011
2007-03-27 -0.009
2007-03-28 0.005
2007-03-29 0.004
2007-03-30 -0.015

其中,1175212800 是2007-3-30 0:0:0与1970-1-1 0:0:0间隔的秒数,etc...。

相关文档
最新文档