以下全部精采内容: ---------------------------------------------------------------------------------------------- 飛狐dll文件數學例子 这是飞狐接口的标准C++引入档,Foxfunc.h,可在飞博廷站下载 这几行需修改MYMACLOSE, SMOOTH, MYBBI是宣告外部DLL函数 __declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData); __declspec(dllexport) int WINAPI SMOOTH(CALCINFO* pData); __declspec(dllexport) int WINAPI MYBBI(CALCINFO* pData); ------------------------------------------------------------------------------------------------- 公式開始: ------------------------------------------------------------------------------------------------- #ifndef __FOXFUNC_H_INCLUDE #define __FOXFUNC_H_INCLUDE /* /////////////////////////////////////////////////////////////////////////// 飞狐交易师“C语言接口”扩展程序调用接口规范V3.0 1.本规范适用于飞狐交易师V3.x公式系统. 2.扩展函数用于实现系统函数不能实现的特殊算法. 3.扩展函数用windows 32位动态连接库实现,建议使用Microsoft Visual C++编程. 4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5) 5.动态连接库名称和函数名称可以自己定义. 6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用. */ #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, //月线 YEAR_DATA, //年线 MULTIDAY_DATA, //多日线 MULTIMIN_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; //////////////////////////////////////////////////////////////////////////// //除权数据 typedef struct tagSPLITDATA { time_t m_time; //时间,UCT float m_fHg; //红股 float m_fPg; //配股 float m_fPgj; //配股价 float m_fHl; //红利 } SPLITDATA; ///////////////////////////////////////////////////////////////////////////// /*财务数据顺序(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 tagCALCPARAM { union { const float* m_pfParam; //序列参数,指向一个浮点型数组 const float m_fParam; //数值参数 }; const int m_nParamStart; //序列参数有效起始位置 }CALCPARAM; ///////////////////////////////////////////////////////////////////////////// //调用接口信息数据结构 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 DWORD m_dataType; //数据类型 const float* m_pfFinData; //财务数据 //以上与分析家兼容,所以沿用其结构和名称 //以下为飞狐交易师扩展 const DWORD m_dwReserved; // 保留 const int m_nNumParam; // 调用参数数量 const CALCPARAM* m_pCalcParam; // 调用参数数组 const DWORD m_dwReservedEx[4]; // 保留 char* m_strStkName; //股票名称 SPLITDATA* m_pSplitData; //除权数据 int m_nNumSplitData; //除权次数 } CALCINFO; /* 注1: (与分析家兼容) 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-1. 在时间上m_pData[x] 与 m_pfParam1[x]是一致的 注2: (飞狐交易师扩展) 1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。 2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为 0 至 m_nNumParam-1. 3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。 4.若 i位置的参数为数值,取用m_pCalcParam[i].m_fParam. 5.若 i位置的参数为序列,取用m_pCalcParam[i].m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam[i].m_nParamStart 至 m_nNumData-1. 若m_pCalcParam[i].m_nParamStart<0, 则此数组中无有效数据。 6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。 7.经此扩展,对分析家的DLL依然可以调用、兼容。 */ /////////////////////////////////////////////////////////////////////////////////// /* 函数输出 __declspec(dllexport) int xxxxxxxx(CALCINFO* pData); 1.函数名称需全部大写. 2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx; 对于C++程序还需包括在 extern "C" { } 括号中. 3.函数计算结果用pData->m_pResultBuf带回. 4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即: m_pResultBuf[返回值] -- m_pResultBuf[m_nNumData-1]间为有效值. 5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER */ //示例函数,使用时用实际名称替换 __declspec(dllexport) int WINAPI MYMACLOSE(CALCINFO* pData); __declspec(dllexport) int WINAPI SMOOTH(CALCINFO* pData); __declspec(dllexport) int WINAPI MYBBI(CALCINFO* pData); #ifdef __cplusplus } #endif //__cplusplus #endif //__FOXFUNC_H_INCLUDE ------------------------------------------------------------------------------------------------- /公式結束 ------------------------------------------------------------------------------------------------- 这是DLL程序的主体,其中这句提醒已忘记用在那里了 “””””””””””””// !!!!!!!! use "C" for Microsoft visual C++ compiler””””””””””””” ------------------------------------------------------------------------------------------------- 公式開始: ------------------------------------------------------------------------------------------------- // FoxFunc.cpp : Defines the entry point for the DLL application. // #include <string.h> #include <stdio.h> #include <io.h> #include <math.h> #include <iostream.h> #include "stdafx.h" #include "FoxFunc.h" float y[15000]; float yy[15000]; 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; } //计算收盘价的均价,一个常数参数,表示计算周ヽ //调用方法: // "FOXFUNC@MYMACLOSE"(5) float smoothb(int ,int ); float realft(int, int ); int fourit(int , int ); // !!!!!!!! use "C" for Microsoft visual C++ compiler // !!!!!!!! use "C" for Microsoft visual C++ compiler // !!!!!!!! use "C" for Microsoft visual C++ compiler // !!!!!!!! use "C" for Microsoft visual C++ compiler // !!!!!!!! use "C" for Microsoft visual C++ compiler __declspec(dllexport) int WINAPI SMOOTH(CALCINFO* pData) { if(pData->m_pfParam1 && pData->m_pfParam2 && //参数1,2有效 pData->m_nParam1Start>=0 && //参数1为序列数 pData->m_pfParam3==NULL) //有2个参数 { const float* pValue = pData->m_pfParam1; //参数1 int nFirst = pData->m_nParam1Start; //有效值お始位 float fParam = *pData->m_pfParam2; //参数2 int nPeriod = (int)fParam; int nndata =pData->m_nNumData; float aa=(float)0.0; if( nFirst >= 0 && nPeriod > 0 ) { // float fTotal; int i; for ( i =nFirst; i < pData->m_nNumData; i++ ) { y[i+1] = pValue[i]; //Ⅸ均 } for ( i = 0; i <15000; i++ ) { yy[i+1]=(float)0.0; } aa=smoothb(nndata,nPeriod); for ( i =nFirst; i < pData->m_nNumData; i++ ) { pData->m_pResultBuf[i]=y[i+1]; //Ⅸ均 // pData->m_pResultBuf[i]=aa; //Ⅸ均 // pData->m_pResultBuf[i]=nndata; } return 0; } } return -1; } //计算均价,2个参数,参数1为待А均线的数据,参数2表示计算周ヽ //调用方法: // "FOXFUNC@MYMAVAR"(CLOSE-OPEN,5) float smoothb(int ma,int pts) { int m,n,k,j,n1,nmin,mo2,no2; float y1,yn,rn1,fac,cnst,aa,bb; m=2; n=ma; nmin=n*2+(pts*2+1); while (m < nmin) { m=m*2; } cnst=((float)pts/(float)m); //!!!!!!!!! don't use cnst=pts/m; //!!!!!!!!! don't use cnst=(double)(pts/m); bb=cnst; // cnst= cnst*(float)pts/(float)n; cnst=cnst*cnst; y1=y[1]; yn=y[n]; rn1=(float)1.0/((float)n-(float)1.0); j=1; while (j<= n) { y[j]=y[j]-(y1*((float)n-(float)j)+yn*((float)j-(float)1))*rn1; j=j+1; } n1=2*ma; // yy=zeros(n1,1); // j=1; // while (j<=n1) { // yy[j]=0.0; // } j=1; while (j <= n) { yy[2*j-1]=y[j]; j=j+1; } // e=zeros(m-n1,1);yy=yy|e; // j=n1+1; // while (j<=m) // { // yy[j]=0.0; // } //!!!!!!!!! yy=[n1+(m-n1),1] //!!!!!!!!! yy=[n1+(m-n1),1] //!!!!!!!!! yy=[n1+(m-n1),1] //!!!!!!!!! yy=[n1+(m-n1),1] //!!!!!!!!! yy=[n1+(m-n1),1] mo2=m/2; no2=(n/2); aa=realft(m,1); yy[1]=yy[1]/(float)mo2; fac=((float)1.05-(float)0.25*(float)pts*(float)pts)/(float)mo2; if (fac < (float)0) { fac=(float)0; } yy[2]=yy[2]*fac; fac=(float)1.0; j=1; while (j < mo2) { k=2*j+1; if (fac != (float)0) { fac=((float)1.05- cnst*(float)j*(float)j)/(float)mo2; if (fac <(float) 0) {fac=(float)0;} yy[k]=yy[k]*fac; yy[k+1]=yy[k+1]*fac; } else { yy[k]=0; yy[k+1]=0; } j=j+1; } aa=realft(m,-1); j=1; /* even is image of complex */ while (j <= n) { y[j]=yy[j*2-1]; j=j+1; } j=1; while (j<= n) { y[j]=y[j]+(y1*((float)n-(float)j)+yn*((float)j-(float)1))*rn1; j=j+1; } // retp(y); return bb; } /* ** Purpose: To get fourier transform of a real data array, ** transform rows(y)/2 obs. ** ** Format: y = realft(y,isign); ** ** Input: y -- vector, real data array. ** isign -- 1, Fourier Transform of real data array. ** -1, Inverse Fourier Transform of complex ** data array. ** ** Output: y=realft(y,isign); ** y -- vector, real data array. ** ** Note: call fourit(data,1); ** Globals: None */ float realft(int ma,int isign) { int n,m,i,i1,i2,i3,i4,np3,aa; float h1r,c1,c2,h1i,h2r,h2i,wr,wi,wpr,wpi,wtemp,theta; m=ma; n=m/2; c1=(float)0.5; theta=(float)3.141592653589793/(float)n; if (isign == 1) { c2=(float)-0.5; aa=fourit(m,1); } else { c2=(float)0.5; theta=-theta; } wtemp=(float)sin((float)0.5*theta); wpr=(float)-2.0*wtemp*wtemp; wpi=(float)sin(theta); wr=(float)1.0+wpr; wi=wpi; np3=m+3; i=2; while (i <= m/4) { i1=i+i-1; i2=i+i1; i3=np3-i2; i4=1+i3; h1r=c1*(yy[i1]+yy[i3]); h1i=c1*(yy[i2]-yy[i4]); h2r=-c2*(yy[i2]+yy[i4]); h2i=c2*(yy[i1]-yy[i3]); yy[i1]=h1r+wr*h2r-wi*h2i; yy[i2]=h1i+wr*h2i+wi*h2r; yy[i3]=h1r-wr*h2r+wi*h2i; yy[i4]=-h1i+wr*h2i+wi*h2r; wtemp=wr; wr=wtemp*wpr-wi*wpi+wr; wi=wi*wpr+wtemp*wpi+wi; i=i+1; } if (isign == 1) { h1r=yy[1]; yy[1]=h1r+yy[2]; yy[2]=h1r-yy[2]; } else { h1r=yy[1]; yy[1]=c1*(h1r+yy[2]); yy[2]=c1*(h1r-yy[2]); aa=fourit(m,-1); } // retp(data); return 1; } /* ** Purpose: To do Fourier Transform of a real data array ** by decimation-in-time or Cooley-Tukey FFT. ** ** Format: y = fourit(data,isign); ** ** Input: data -- vector, real data array. ** isign -- 1, Fourier Transform of real data array. ** transform rows(data)/2. ** -1, Inverse Fourier Transform of complex ** data array. ** ** Output: y = fourit(data,isign); ** y -- vector, complex data array. ** ** Globals: None */ int fourit(int ma,int isign) { int mmax,m,o,j,istep,i; float wtemp,wr,wpr,wpi,wi,theta, tempr,tempi; m=ma; j=1; i=1; while (i < m) { if (i < j) { tempr=yy[j];yy[j]=yy[i];yy[i]=tempr; tempr=yy[j+1];yy[j+1]=yy[i+1];yy[i+1]=tempr; } o=m/2; while (o>=2 && o<j) { j=j-o; o=o/2; } j=j+o; i=i+2; } mmax=2; while (mmax < m) { istep=mmax*2; theta=(float)6.28318530717959/((float)isign*(float)mmax); wtemp=(float)sin((float)0.5*theta); wpr=(float)-2.0*wtemp*wtemp; wpi=(float)sin(theta); wr=(float)1.0; wi=(float)0.0; o=1; while (o < mmax) { i=o; while (i <= m) { j=i+mmax; tempr=wr*yy[j]-wi*yy[j+1]; tempi=wr*yy[j+1]+wi*yy[j]; yy[j]=yy[i]-tempr; yy[j+1]=yy[i+1]-tempi; yy[i]=yy[i]+tempr; yy[i+1]=yy[i+1]+tempi; i=i+istep; } wtemp=wr; wr=wtemp*wpr-wi*wpi+wr; wi=wi*wpr+wtemp*wpi+wi; o=o+2; } mmax=istep; } // retp(data); return 1; } //计算多个序列的均值,5个参数,参数1-4为待А多个序列,参数5用于举例说明数值参数的用法,实际在此例中无需该参数 /* 调用方法: MA1:=MA(CLOSE,3); MA2:=MA(CLOSE,6); MA3:=MA(CLOSE,12); MA4:=MA(CLOSE,24); MYBBI: "FOXFUNC@MYBBI"(MA1, MA2, MA3, MA4, 4); */ __declspec(dllexport) int WINAPI MYBBI(CALCINFO* pData) { if ( pData->m_pCalcParam[0].m_nParamStart >= 0 && pData->m_pCalcParam[1].m_nParamStart >= 0 && pData->m_pCalcParam[2].m_nParamStart >= 0 && pData->m_pCalcParam[3].m_nParamStart >= 0 ) //4个序列都含有效数值 { //计算返回的序列的第一个有效值位置 int nFirst = pData->m_pCalcParam[3].m_nParamStart; //已知返回的序列的第一个有效值位置与第4个序列一致 //?不知,则 /* int nFirst = pData->m_pCalcParam[0].m_nParamStart; if ( nFirst < pData->m_pCalcParam[1].m_nParamStart ) nFirst = pData->m_pCalcParam[1].m_nParamStart; if ( nFirst < pData->m_pCalcParam[2].m_nParamStart ) nFirst = pData->m_pCalcParam[2].m_nParamStart; if ( nFirst < pData->m_pCalcParam[3].m_nParamStart ) nFirst = pData->m_pCalcParam[3].m_nParamStart; */ const float* pValue1 = pData->m_pCalcParam[0].m_pfParam; const float* pValue2 = pData->m_pCalcParam[1].m_pfParam; const float* pValue3 = pData->m_pCalcParam[2].m_pfParam; const float* pValue4 = pData->m_pCalcParam[3].m_pfParam; int nNum = (int)(pData->m_pCalcParam[4].m_fParam); //实际上该例中已知nNum=4,在此用于说明数值参数的用法 for( int i = nFirst; i < pData->m_nNumData; i++ ) { pData->m_pResultBuf[i] = (pValue1[i] + pValue2[i] + pValue3[i] + pValue4[i])/nNum; } return nFirst; } return -1; } ------------------------------------------------------------------------------------------------- /公式結束 ------------------------------------------------------------------------------------------------- 这是飞狐如何调用,MYFUNC4是DLL的档名 ------------------------------------------------------------------------------------------------- 公式開始: ------------------------------------------------------------------------------------------------- oooo22:"MYFUNC4@SMOOTH"(c,5)*1,linethick3; {ma(c,3);} cc11:c,colorred; aa:fft(c,3),colorgreen; ------------------------------------------------------------------------------------------------- /公式結束 ------------------------------------------------------------------------------------------------- |
|