【阳光飞狐__与财富同行】
标题:
飞狐交易师 (foxtrader) 连结 DLL 的方法
[打印本页]
作者:
ycng
时间:
2019-8-11 16:09
标题:
飞狐交易师 (foxtrader) 连结 DLL 的方法
许多年以前
,
我曾经在
理想公式区发布了
"
如何用
Foxtrader(
飞狐
)
连结
C++
动态程式库
DLL
及
80x86Macro Assembly (
组合语言
)
"
现在更新
foxtrader(
飞狐交易师
)
连结
DLL
的方法
foxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
gauss
只用到函数参数传递
,
所以使用新的
c++compiler,
不受影响
foxtrader
的
foxfunc.h
宣告的结构型态
(struct)
在
2004vc++ 6.0
全部有效
也就是这五个结构都能用
typedefstruct tagSTKDATA
typedefunion tagSTKDATAEx
typedefstruct tagSPLITDATA
typedefstruct tagCALCPARAM
typedefstruct tagCALCINFO
自
2008
年起
,vc++ 2008, vc++ 2010, vc++2017
对
struct
的编译
,
已经完全
c++
化
,
不再相容于
C
也就是这五个结构中
typedefstruct tagSTKDATA
typedefunion tagSTKDATAEx
typedefstruct tagSPLITDATA
typedefstruct tagCALCPARAM
typedefstruct tagCALCINFO
只有这两个可以用
typedefstruct tagCALCPARAM
typedefstruct tagCALCINFO
值得庆幸的是
,
下面这个结构的函数参数传递个数可以有无数个
typedefstruct tagCALCPARAM
例如
:
在
foxtrader
中
MA1:=MA(CLOSE,3);
MA2:=MA(CLOSE,6);
MA3:=MA(CLOSE,12);
MA4:=MA(CLOSE,24);
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
其中
MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll
中的
MYBBI
函数
,
这里
MYBBI
函数传递的参数共有
7
个
下面这两式计算结果相同
xx:(MA(CLOSE,3)+MA(CLOSE,6)+MA(CLOSE,12),MA(CLOSE,24),MA(CLOSE,12),),MA(CLOSE,24)/6*0.95,color0000ff,linethick2;{foxtrader
自行计算
}
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll
计算
}
其他例子
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;
其中
pow10.asm
里面有很多不同定义或宣告被注解不用
,
那是因为后来在逐步侦测法修改语码中才发现在
foxfunc.cpp
主程式中
,
下面这行错误
,
也就是新的
compiler
不再相容于
C,
因此在
pow10.asm
里面被注解不用的定义或宣告中
,
有些应该是可以用的
fTotal= pData->m_pData
.m_fClose; // @@@@@@@ vc++ 2010 cl.exe
使
pData->m_pData[i-j].m_fClose
错误
////////////////////////////////////////////////////////foxfunc.h
#ifndef
__FOXFUNC_H_INCLUDE
#define
__FOXFUNC_H_INCLUDE
/*
飞狐交易师“
C
语言接口”扩展程序调用接口规范
V3.0
1.
本规范适用于飞狐交易师
V3.x
公式系统
.
2.
扩展函数用于实现系统函数不能实现的特殊算法
.
3.
扩展函数用
windows32
位动态连接库实现
,
建议使用
MicrosoftVisual C++
编程
.
4.
调用时在公式编辑器中写
"
动态库名称
@
函数名称
"(
参数表
)
即可
,
例如下面函数可以写为
"FOXFUNC@MYMACLOSE"(5)
5.
动态连接库名称和函数名称可以自己定义
.
6.
使用时必须将动态库拷贝到飞狐交易师安装目录下的
FmlDLL
子目录下使用
.
*/
#ifdef
__cplusplus
extern"C"
{
#endif
//__cplusplus
///////////////////////////////////////////////////////////////////////////
//
分析周期
enumDATA_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//
多分钟线
};
///////////////////////////////////////////////////////////////////////////
//
定义取用股票基本数据的结构 只有
VC++ 6.0
能
compile
成功使用
typedefstruct tagSTKDATA
{
_tm_
; //
时间
,UCT
floatm_fOpen; //
开盘
open
floatm_fHigh; //
最高
high
floatm_fLow; //
最低
low
floatm_fClose; //
收盘
close
floatm_fVolume; //
成交量
Volume
floatm_fAmount; //
成交额
amount
WORDm_wAdvance; //
上涨家数 仅大盘有效
WORDm_wDecline; //
下跌家数 仅大盘有效
}STKDATA;
定义
STKDATA
为
tagSTKDATA
的简单别名
,STKDATA
为真正方便使用名称
,tagSTKDATA
为定目的的过水名称
////////////////////////////////////////////////////////////////////////////
//
扩展数据
,
用于定义取用分笔成交数据的买卖盘 的结构
typedefunion tagSTKDATAEx
{
struct
{
floatm_fBuyPrice[3]; //
买
1--
买
3
价
floatm_fOpen; //
开盘
open
floatm_fHigh; //
最高
high
floatm_fLow; //
最低
low
floatm_fClose; //
收盘
close
floatm_fVolume; //
成交量
Volume
floatm_fAmount; //
成交额
amount
floatm_fBuyVol[3]; //
买
1--
买
3
量
floatm_fSellPrice[3]; //
卖
1--
卖
3
价
floatm_fSellVol[3]; //
卖
1--
卖
3
量
};
floatm_fDataEx[12];
}STKDATAEx;
////////////////////////////////////////////////////////////////////////////
//
定义取用除权数据的结构
typedefstruct tagSPLITDATA
{
time_tm_time; //
时间
,UCT
floatm_fHg; //
红股
floatm_fPg; //
配股
floatm_fPgj; //
配股价
floatm_fHl; //
红利
}SPLITDATA;
/////////////////////////////////////////////////////////////////////////////
/*
财务数据顺序
(m_pfFinData
内容
)
序号内容
0
总股本
(
万股
),
1
国家股
,
2
发起人法人股
,
3
法人股
,
4B
股
,
5H
股
,
6
流通
A
股
,
7
职工股
,
8A2
转配股
,
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
净资收益率
*/
/////////////////////////////////////////////////////////////
//
定义取用
caller
函数传递参数项 的结构
typedefstruct tagCALCPARAM
{
union
{
constfloat* m_pfParam; //
指向序列参数的址标,指向一个浮点型数组
pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
constfloat m_fParam; //
数值参数
valueof parameter
};
constint m_nParamStart; //
序列参数有效起始位置
thestart address of variable parameter / ex. c,h,l,o,co2.....
}CALCPARAM;
/////////////////////////////////////////////////////////////////////////////
//
定义全部取用址标 的总结构
(
各指标指向前述各结构以便取的各结构的数据
,
接口信息数据的结构
)
typedefstruct tagCALCINFO
{
constDWORD m_dwSize; //
结构大小
constDWORD m_dwVersion; //
调用软件版本
(V2.10: 0x210)
constDWORD m_dwSerial; //
调用软件序列号
constchar* m_strStkLabel; //
股票代码
constBOOL m_bIndex; //
大盘
constint m_nNumData; //
数据数量
(pData,pDataEx,pResultBuf
数据数量
)
数据长度
constSTKDATA* m_pData; //
常规数据
,
注意
:
当
m_nNumData==0
时可能为
NULL
constSTKDATAEx* m_pDataEx; //
扩展数据
,
分笔成交买卖盘
,
注意
:
可能为
NULL
constint m_nParam1Start; //
参数
1
有效起始位置
<0/ constant parameter >0 /variable parameter
constfloat* m_pfParam1; //
调用参数
1/pointer to variable parameter 1
constfloat* m_pfParam2; //
调用参数
2/pointer to variable parameter 2
constfloat* m_pfParam3; //
调用参数
3/pointer to variable parameter 3
constfloat* m_pfParam4; //
调用参数
4/pointer to variable parameter 4
float*m_pResultBuf; //
结果缓冲区
constDWORD m_dataType; //
数据类型
constfloat* m_pfFinData; //
财务数据
//
以上与分析家兼容,所以沿用其结构和名称
//
以下为飞狐交易师扩展
(fortagSTKDATAEx)
constDWORD m_dwReserved; //
保留
constint m_nNumParam; //
调用参数数量
constCALCPARAM* m_pCalcParam; //
调用参数数组
constDWORD m_dwReservedEx[4]; //
保留
char*m_strStkName; //
股票名称
SPLITDATA*m_pSplitData; //
除权数据
intm_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
.m_fParam.
5.
若
i
位置的参数为序列,取用
m_pCalcParam
.m_pfParam
,数组大小为
m_nNumData,
数据有效范围为
m_pCalcParam
.m_nParamStart
至
m_nNumData-1.
若
m_pCalcParam
.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 MYMAVAR(CALCINFO* pData);
__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
//WINAPI = _stdcall
#ifdef
__cplusplus
}
#endif
//__cplusplus
#endif
//__FOXFUNC_H_INCLUDE
//////////////////////////////////////////comment
注解
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
pData
是指向 址标总结构
CALCINFO
的 总址标
取用第二个参数数值
floatfParam = *pData→m_pfParam2
取用第一个序列参数的址标
constfloat* pValue = pData->m_pfParam1;
取用股票数据长度
intndata = pData→m_nNumData;
第一个参数存在且为数值
pData->m_pfParam1&& pData→m_nParam1Start<0
第一个参数存在且为序列
pData->m_pfParam1&& pData→m_nParam1Start>=0
第一个及第二个参数存在且为序列
,
第三个参数不存在
pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
constfloat* cpParam = pData->m_pfParam1;
定义
cpParam
为第一个序列参数的址标
取用股票数据结构
pData→m_nNumData=
变数数据长度
pData→m_pData= pointer to struc STKDATA
的址标
pData→m_pData[x]
数据结构的第
x
个数据
pData→m_pData[x].m_fHigh
数据结构的第
x
个数据中的
High
取用结果缓冲序列
pData->m_pResultBuf
取得第一个序列参数的起始序位
,
如
2,...5 , . 7...
intnFirst = pData->m_nParam1Start;
for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
取得第二个数值参数的数值
floatfParam = *pData->m_pfParam2;
intnPeriod = (int)fParam;
取用第一个序列参数的址标
constfloat* pValue = pData→m_pfParam1;
取用序列参数的单个直
pValue
取用缓冲序列的单个值
pData->m_pResultBuf
constCALCPARAM* m_pCalcParam; //
调用参数数组
m_pCalcParam
为序列址标
,
指向各序列参数的指标
第一个序列参数
pData→m_pCalcParam[0]
constfloat* m_pfParam; //
指向序列参数的址标
第一个序列参数的起始序位
pData->m_pCalcParam[0].m_nParamStart
第一个序列参数的址标
constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
取用第一个序列参数的单个直
pValue1
第二个序列参数
pData→m_pCalcParam[1]
第二个序列参数的起始序位
pData->m_pCalcParam[1].m_nParamStart
第二个序列参数的址标
constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;
取用第二个序列参数的单个直
pValue2
第三个序列参数
pData→m_pCalcParam[2]
第三个序列参数的起始序位
pData->m_pCalcParam[2].m_nParamStart
第三个序列参数的址标
constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;
取用第三个序列参数的单个直
pValue3
第四个序列参数
pData→m_pCalcParam[3]
第四个序列参数的起始序位
pData->m_pCalcParam[3].m_nParamStart
第四个序列参数的址标
constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;
取用第四个序列参数的单个直
pValue4
如果有四个序列参数
,
则取用序位最高的那一个序位
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
个序列都含有效数值
{
//
计算返回的序列的第一个有效值位置
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//
已知返回的序列的第一个有效值位置与第
4
个序列一致
//
若不知,则
/*
intnFirst = 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;
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
//-------------------
floatm_fOpen; //
开盘
open
floatm_fHigh; //
最高
high
floatm_fLow; //
最低
low
floatm_fClose; //
收盘
close
floatm_fVolume; //
成交量
Volume
floatm_fAmount; //
成交额
amount
调用收盘据
pData→m_nNumData=
变数数据长度
pData→m_pData= pointer to struc STKDATA
pData→m_pData[x]
第
x
个数据
pData→m_pData[x].m_fHigh
第
x
个数据中的
High
@@@@@@@@@@@important !!!!!!!
sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
pData→m_pData[i-j].m_fHighto use high
pData->m_pData[i-j].m_fLow
pData->m_pData[i-j].m_fClose
m_pData= pointer to struc STKDATA
incalling C++ dll function
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)
touse a single value in variable ‘High’
pData→m_pData[i-j].m_fHighto use high
constfloat* m_pfParam1; //
调用参数
1/pointer to variable parameter 1
constfloat* m_pfParam2; //
调用参数
2/pointer to variable parameter 2
constfloat* m_pfParam3; //
调用参数
3/pointer to variable parameter 3
constfloat* m_pfParam4;
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function
的参数
pData→m_pfParam1= pointer to
第一个
(
序列
)
参数
pData→m_pfParam1[x]=
取用第一个
(
序列
)
参数的第
x
个值
constfloat* cpParam = pData→m_pfParam1;
=定义
cpParam
为
pointerto
第一个
(
序列
)
参数
cpParam[x] =
取用第一个
(
序列
)
参数的第
x
个值
m_pResultBuf
= 结果缓冲列
pData→m_pResultBuf= pointer to
结果缓冲列
pData→m_pResultBuf[x] =
取用结果缓冲列的第
x
个值
//////////////////////////////////////////comment
//////////////////////////////////////////comment
注解
constint m_nParam1Start; //
统杅
1
衄虴宎弇离
constfloat* m_pfParam1; //
覃蚚统杅
1
constfloat* m_pfParam2; //
覃蚚统杅
2
constfloat* m_pfParam3; //
覃蚚统杅
3
constfloat* m_pfParam4; //
覃蚚统杅
4,parameters must be <= 4
//const float* m_pfParam5; // parameters must be <= 4
//const float* m_pfParam6;
//const float* m_pfParam7;
//const float* m_pfParam8;
//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
&&pData->m_pCalcParam[2].m_nParamStart>=0)
{
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0
intnPeriod = (int)fParam; //
统杅
1
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to
第一个序列参数
,cpParam
=
取用第一个序列参数的第
i
个值
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to
第一个序列参数
,cpParam
=
取用第一个序列参数的第
i
个值
constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to
第一个序列参数
,cpParam
=
取用第一个序列参数的第
i
个值
constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to
第一个序列参数
,cpParam
=
取用第一个序列参数的第
i
个值
//parameters must be <= 4
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to
第一个序列参数
,cpParam
=
取用第一个序列参数的第
i
个值
//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to
第一个序列参数
,cpParam
=
取用第一个序列参数的第
i
个值
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
touse pData→m_pData[x].m_fClose
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time;
|1,2,3 , … , m_nNumParam | float m_fOime_t
|1,2,3 , … , m_nNumParam | float m_fHigh;
.. .
|1,2,3 , … , m_nNumParam | WORD m_wDecline;
m_nNumParam=
数据
high,close,open,low
的长度
touse high:
pData→m_pData[x].m_fHigh
contentof struct STKDATA
time_tm_time; //
时间
,UCT
floatm_fOpen; //
开盘
open
floatm_fHigh; //
最高
high
floatm_fLow; //
最低
low
floatm_fClose; //
收盘
close
floatm_fVolume; //
成交量
Volume
floatm_fAmount; //
成交额
amount
WORDm_wAdvance; //
上涨家数 仅大盘有效
WORDm_wDecline; //
下跌家数 仅大盘有效
调用传递参数及传回结果
调用传递参数
(pData->m_pfParam1 && //
参数
1
有效
Param1exists
pData->m_nParam1Start<0&& //
参数
1
为常数
pData->m_pfParam2==NULL) //
localprocedure
定义使用变数
onstfloat* pValue = pData→m_pfParam1; //use constant
参数
1
intnFirst = pData->m_nParam1Start; //use
参数
1
效值起始位
floatfParam = *pData->m_pfParam2; //use
参数
2
intnPeriod = (int)fParam;
传回结果
fTotal+= pValue[i-j];
pData->m_pResultBuf
//////////////////////////////////////////comment
欢迎光临 【阳光飞狐__与财富同行】 (http://bbs.88158.cn/)
Powered by Discuz! X3.2