许多年以前,我曾经在
' ^5 k# }) L7 u- r$ _理想公式区发布了' |6 T1 c0 b9 ~# x3 b! A) z& v& t
"
6 J. |) ^6 m. |& k5 b, Z; E/ s% `如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
9 X1 w1 A: s/ P4 }4 K1 _6 C0 o"9 R$ x* t* m! {) C8 O
4 A- }" H, w7 j# x9 z. q5 O
现在更新foxtrader(飞狐交易师) ' ^" C/ Y8 B" l$ w: s+ a! Y
连结 DLL的方法
, Z, o2 F- y# n4 B1 M, ^& Q* C" X* J/ o7 G
foxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
9 k, H2 f8 ^0 M& Q9 k. Sgauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
% s" J \( X0 i. q% V- T& ygauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响2 p7 {# |: E3 O; d
foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
8 i7 `; p( l) J' @! v2 |% ^
& D4 H- e0 p- t# p+ q% o9 W也就是这五个结构都能用4 b3 {2 r+ d" D
typedefstruct tagSTKDATA 5 D& O" q" K c& A! f3 Q
typedefunion tagSTKDATAEx3 ?% I: b' \4 |! a* |$ R1 S/ f6 B
typedefstruct tagSPLITDATA
& J0 b: H L e2 ktypedefstruct tagCALCPARAM0 V$ k6 ?( w& o& q0 S4 M5 M: X
typedefstruct tagCALCINFO, m/ F9 g w3 H8 P, u
' X' L7 U2 c: [( l
自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C4 W: ^! B- N" N7 d5 W
也就是这五个结构中$ ]& W% C& x" v9 t {! o+ D6 N
typedefstruct tagSTKDATA
9 W5 D" J& q$ H# u: l! stypedefunion tagSTKDATAEx
4 Z/ M. R6 A$ ]) j8 A/ M, Xtypedefstruct tagSPLITDATA
" X1 I+ {1 @3 J8 H# N: `typedefstruct tagCALCPARAM# [* d" Q$ t. J$ ~* f
typedefstruct tagCALCINFO3 n! Q7 E- x& W- d& r
只有这两个可以用/ ~; x7 h* J% x) [
typedefstruct tagCALCPARAM
7 U: e7 Z- o. P% G; Q, L7 P5 H' Dtypedefstruct tagCALCINFO# \/ c# ~: G9 F- a1 }3 ^
值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个7 T# S, F4 h+ [2 i; k7 {6 e
typedefstruct tagCALCPARAM
: X: q2 e9 g7 O4 F例如:在 foxtrader中
5 [! m& V; k' f" v# R5 @MA1:=MA(CLOSE,3);
1 T6 d G; n- T. L5 ^MA2:=MA(CLOSE,6);% r# f O5 p& R. V
MA3:=MA(CLOSE,12);
3 y/ A4 O$ U5 ]8 c: {MA4:=MA(CLOSE,24);
- H+ z1 |2 m2 g# FMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}* ~; o) G. _( }
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个: X3 s% `9 y& Y, V2 T/ A( H! }
下面这两式计算结果相同
; b5 @; T8 J6 Z% `* ^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 自行计算}
7 D g j1 @/ j! n5 U( u6 Z/ {MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
/ y9 d$ d8 p' i8 K9 }9 m其他例子0 I& a4 }8 s8 Y! @5 I$ p6 X
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)% K: p8 k0 `* s7 t
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;4 l1 b" C& R, j5 p& F, h
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的/ `. W k. R1 P7 I( b
fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
' K0 W4 | u2 y1 Q0 u. K( E
' `8 q Z1 x* @9 ^( @' b
' h7 }6 w/ Y7 T. o6 q3 X: G////////////////////////////////////////////////////////foxfunc.h
1 X' |. \1 c/ W/ ]#ifndef__FOXFUNC_H_INCLUDE
) Q2 Q. L, D t6 R- Z7 \: h#define__FOXFUNC_H_INCLUDE
- M9 m( q6 N/ N8 i Y/*! G( L- v0 d9 k# c! \ ^
飞狐交易师“C语言接口”扩展程序调用接口规范V3.0; \% Y% O$ J' Y
1.本规范适用于飞狐交易师V3.x公式系统.
6 \ b/ g2 _" L$ r" E9 y% `9 x2.扩展函数用于实现系统函数不能实现的特殊算法.9 Y$ W' s3 X K7 [3 n0 z
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.5 o* q2 Z3 D& o5 x) }; A
4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
) T( {( ~# e# F5.动态连接库名称和函数名称可以自己定义.- B% u0 C# [, f- [
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
7 ?; M2 P$ Z# Y. V*/, F- b' @8 |9 x7 Y
#ifdef__cplusplus
/ x- w8 J5 ~9 E$ f" m, C4 v" Wextern"C", a R9 d* l' R {) l: f
{
; E# ^- r. ]9 m; g$ F1 {6 _#endif//__cplusplus
4 `: a$ Y; O: X/ o: U9 x. Q& z///////////////////////////////////////////////////////////////////////////
% M) u) G# S* f: n/ [7 z//分析周期) X/ p# q6 P) R4 i' [
enumDATA_TYPE: J% T6 w; Q: E
{
( B! v* ^: R& N7 D( V% j1 `( bTICK_DATA=2,//分笔成交
, w; {2 L( [ e- T& x8 PMIN1_DATA,//1分钟线3 i, ~0 W! d8 Z) V
MIN5_DATA,//5分钟线 1 P$ Q* f9 s- ~) N# e# T1 \- D
MIN15_DATA,//15分钟线
" S$ l' F9 a1 v) L- f" B$ ?% N: ZMIN30_DATA,//30分钟线8 }4 Q/ g/ U: n9 u% N2 T7 }: L8 R
MIN60_DATA,//60分钟线7 V6 z! V. A, J4 h% M" j. N" h
DAY_DATA,//日线
4 P) D* l V2 e( Y/ ?( EWEEK_DATA,//周线( `+ [8 Q0 p k& W
MONTH_DATA,//月线# B! ^( j! O" q' O) I+ `+ Y9 c
YEAR_DATA,//年线2 Y6 Y5 [- w! C/ K, w1 d& B' o" d
MULTIDAY_DATA,//多日线
. }( L3 ]0 |' ? F$ hMULTIMIN_DATA//多分钟线
" Z- y$ O6 f8 C' W) h};6 d; M* K& ^7 p( E$ A
///////////////////////////////////////////////////////////////////////////
$ n/ g4 s6 T3 [4 @$ q( t# ]8 p//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用
, e& ~, n7 ^# }, P8 R2 atypedefstruct tagSTKDATA . i/ q3 H8 r) H. `( h; D
{
$ q* ]0 K0 Y D* H, P( x+ a _tm_ ; //时间,UCT
. a# ^8 J6 K) x2 K1 f7 A9 ifloatm_fOpen; //开盘 open
9 z. N. v9 o$ J$ G$ y( ] }floatm_fHigh; //最高 high/ D5 v7 a1 \+ f0 {
floatm_fLow; //最低 low
3 w0 V2 t7 B" Q" P% e4 ^. ~7 y0 s/ dfloatm_fClose; //收盘 close
, L1 K( G2 F, t* b3 }; k7 dfloatm_fVolume; //成交量 Volume5 ^) ?% h( Y5 w. Z9 G. x) z* v* ~
floatm_fAmount; //成交额 amount
: I( y* g9 t0 T0 D3 G$ H0 HWORDm_wAdvance; //上涨家数 仅大盘有效
8 n/ q3 I7 ^# N. z: [: uWORDm_wDecline; //下跌家数 仅大盘有效" T5 a7 \. T) ^5 `; I# h
}STKDATA;
5 }" F2 c6 i5 _定义STKDATA为 tagSTKDATA的简单别名,STKDATA " o: q9 `. @: J! ?1 D9 ^. K
为真正方便使用名称,tagSTKDATA 为定目的的过水名称4 G5 }. }& D- L" P# F7 Y
////////////////////////////////////////////////////////////////////////////; L) l: F: u( H% T
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
) {# `5 V( r& b' ]typedefunion tagSTKDATAEx0 W8 F2 x! B: `
{) e: c2 H* v$ [3 b* o# \# e+ o; i
struct
7 T N& ^ F3 r# P{- E) C: k4 k+ m8 ^8 {- X
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open( T$ i2 ^& S9 J z# v
floatm_fHigh; //最高 high1 i- ~0 b, Z. j8 q6 @& O8 D
floatm_fLow; //最低 low
! \8 [5 s* x+ r _+ l4 Mfloatm_fClose; //收盘 close" k+ T! l* H; _0 x& K
floatm_fVolume; //成交量 Volume
$ h& ~* {% [) Ifloatm_fAmount; //成交额 amount; M7 ?' |- y4 d. g A- x. {2 j
floatm_fBuyVol[3]; //买1--买3量
. w( k# M- I8 G3 \* A' D/ Ffloatm_fSellPrice[3]; //卖1--卖3价
5 f) T7 p/ k& |7 X3 @floatm_fSellVol[3]; //卖1--卖3量
) Y' W4 ]" d' w& T};
4 O$ n8 G7 {/ x2 y1 }floatm_fDataEx[12];
* B6 b% N% ], L4 O7 q6 ~}STKDATAEx;
# F# Q% [2 D1 P, z////////////////////////////////////////////////////////////////////////////) E! H+ z) Y. U3 k" Q0 i
//定义取用除权数据的结构: F" k9 m9 h2 q$ H9 l, d+ ]
typedefstruct tagSPLITDATA ) y2 H, i$ k9 L0 W
{+ p( |3 K2 k' }* Z! m7 U, w0 r" L
time_tm_time; //时间,UCT
; {/ h4 Y( e# T" e( R9 q5 D* Wfloatm_fHg; //红股
- G! O' S) i$ K7 ]! P( v9 Tfloatm_fPg; //配股
8 X# g0 s. R' Yfloatm_fPgj; //配股价
3 j& X" {' |1 d! H6 y5 P6 { {floatm_fHl; //红利% o: y& S# n0 D
}SPLITDATA;
- x* S0 k0 K) D$ P) B( Y2 n# l/////////////////////////////////////////////////////////////////////////////- `2 {" u3 h3 v0 e5 }
/*财务数据顺序(m_pfFinData内容)
% N$ b8 C7 v7 T a序号内容% N: `" y! g+ {1 g+ e
0总股本(万股),
5 |* P/ j# n# l* m, t* W, m1国家股,8 y4 O2 h+ t4 y* x
2发起人法人股,5 n/ a! k) y4 @- p* g
3法人股,# Q4 c" I, m9 _, U( q/ U- m# \
4B股,& K+ W1 A; {2 a9 `! N$ D* T
5H股,9 G- O/ V* a" }( g( I
6流通A股,8 O! _% B# G1 ^- E/ J' u0 h
7职工股," y+ K9 V% ^3 J) W3 G& K" \
8A2转配股,/ ?9 L$ ?# }) _1 ~; Q% O7 P
9总资产(千元),. u# [9 y: o9 o! f& Z4 S: Z- o
10流动资产,7 s% h* ` i. P" g+ g4 X
11固定资产,0 }% G R% k0 [ @% w* |
12无形资产,% N: `& {; U/ m h: E; k6 {
13长期投资,# u! H. y& S) ?% C
14流动负债,
% b4 u0 Q4 n. l- R, \7 [! G5 u; }15长期负债,2 n* Q& O) n7 O- R4 ^! s
16资本公积金,
( l! }; w" Q8 @1 Q6 L& X- r! O0 e17每股公积金,
. S$ `: o% o3 O- a2 u f8 {18股东权益, [: h6 O" E" |) l
19主营收入,
. p+ B+ A- J c20主营利润,
& x+ ~' N: C0 |$ t21其他利润,
/ G" k. M/ z& ^& k" v" K22营业利润,
0 u/ t9 v: F+ n( }23投资收益,0 X4 B& W9 A# n9 j! R* L1 E
24补贴收入,! a1 g" M4 h4 V6 P- p, }0 C
25营业外收支,
. U' j) [5 s+ F9 \9 ^& B$ W @26上年损益调整,$ f* S5 F9 u1 [9 E, R5 K
27利润总额, v a: k$ K/ [: d y2 L1 l
28税后利润,
/ m% j, e2 H; r0 O% A29净利润,
a# |6 q1 ?5 O' |: b9 `: ^30未分配利润,3 P! b% _( N. B
31每股未分配,! [9 m! ^9 u4 G$ A; |4 E
32每股收益,
% y+ t' e) j1 c8 z) h33每股净资产,6 K$ p0 X* O1 {% f: V; [) m& n4 z1 G; L
34调整每股净资,
, ^6 F& V; A2 u/ s' d6 s35股东权益比,
; G3 _; w" A! O36净资收益率
8 d2 d5 r3 f# M2 L*/
1 j$ [' l+ W4 d& ^/////////////////////////////////////////////////////////////+ j. K5 d; \2 S* x( ]
//定义取用caller函数传递参数项 的结构5 k+ S, _0 F6 B# s* M5 E. s
typedefstruct tagCALCPARAM z! y: x& R% j4 P1 C$ O
{
+ C+ M* s l& H* W, {5 tunion
5 C3 `7 A, K. }3 I1 B1 E/ H: d{
4 N; `# p, F7 } Xconstfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2* X5 S% [8 b- m' N8 M" l6 R( L
constfloat m_fParam; //数值参数 valueof parameter$ a j- u4 o4 a$ b& F3 |
};
$ a7 k/ A( D/ T9 t, `' fconstint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
1 @) I1 T" x- H' Q}CALCPARAM;
2 j7 a9 a$ L7 l* {/////////////////////////////////////////////////////////////////////////////8 o* H7 ]# v1 F$ Y& `- v2 D
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )
. f% C5 h( S/ v. g1 |typedefstruct tagCALCINFO) [. n3 a+ [: m8 i) J& E( T, L% _4 u- q
{
- P! d3 f8 s- ~! V* \$ ZconstDWORD m_dwSize; //结构大小
- f1 Z' w+ Q4 ?& M, ]constDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)7 x/ B3 j A0 u! h2 q: W# J
constDWORD m_dwSerial; //调用软件序列号
; }& J" r& f" Y1 D' k. kconstchar* m_strStkLabel; //股票代码2 D( R k% K0 {$ s* F8 z8 A: G% Z
constBOOL m_bIndex; //大盘( @) T! U" `+ h- Z1 s9 k; r3 H4 t, T
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度5 o! w4 l3 Q- \; \- e! z
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL& S- x9 y7 j* _$ d( i: T1 H( t, a
constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
/ l9 V" C# f9 E$ }% Rconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
3 k. G% [. f' b: ]; K9 Yconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
+ n: T3 Q( e- E1 b; H4 vconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
) _ u- R8 r# z8 Bconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3% S. h7 ?0 b/ i0 j& q1 v
constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
Q& L3 e$ Q- H3 t) {4 G) bfloat*m_pResultBuf; //结果缓冲区7 |2 t2 F5 W8 P! O0 C
constDWORD m_dataType; //数据类型
$ n* L6 H0 a! u$ zconstfloat* m_pfFinData; //财务数据3 K$ v2 S! X. d0 e- y
//以上与分析家兼容,所以沿用其结构和名称8 x2 m. ~! z4 i2 ?$ o8 W8 g
//以下为飞狐交易师扩展(fortagSTKDATAEx)) K) u! A' \* Z& {) H
constDWORD m_dwReserved; // 保留3 }, N' M! L( m0 |" X1 W
constint m_nNumParam; // 调用参数数量# i9 p3 Y) V: g4 T) A/ {* Y* S8 m
constCALCPARAM* m_pCalcParam; // 调用参数数组; L: Q5 y( y' O" E
constDWORD m_dwReservedEx[4]; // 保留- l- n# n9 A! X/ _
char*m_strStkName; //股票名称
j: i! n; v; h6 K+ |7 ~+ @( i/ `, eSPLITDATA*m_pSplitData; //除权数据
' }/ M% I+ r" k k7 W; Y4 nintm_nNumSplitData; //除权次数
. j$ a B$ a( S& S}CALCINFO;- |# W& f/ ]3 G4 Z+ s
/*
5 p8 I* D* B" |* F+ ]2 z注1:(与分析家兼容)4 w! U$ s1 e7 [9 x1 `
1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.
4 Z0 E+ c, `0 Q# W2.当一个参数无效时,则其后的所有参数均无效.$ n; O1 n0 G- k& L. u4 d8 w
如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL. X0 L. l4 _, W+ _/ c' M+ T ^ j
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
/ G: V; I9 w L3 ]( t, C/ y4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;# t$ X. O" y0 ~/ Z7 H, f( b+ R% K8 b
5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,+ a% F: f! ^. h- T5 E
数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.$ p8 i8 D% v: P) ?# M
在时间上m_pData[x]与 m_pfParam1[x]是一致的
0 R1 k: c# c0 ^! v0 S) j注2:(飞狐交易师扩展)
1 P6 R, p% u* k+ y1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。, o. z8 e& ]3 X" e# J/ `: D2 i
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
( Q T; l) f7 d0 P$ y1 h3 T3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
7 J- M5 D5 r5 |+ R3 x4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.6 f) L% V' G* Z7 n+ l) z( K
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。, z6 d/ H% b9 ?$ a y- n
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
) y5 ^) k, P6 {7.经此扩展,对分析家的DLL依然可以调用、兼容。' e. o7 a, |5 _2 `
*/9 w; J. j4 _' s- f. j
///////////////////////////////////////////////////////////////////////////////////& g8 `. I! I6 w$ x+ `) v+ W, w
/*函数输出; C: A) n1 \; t2 ?6 d. V d3 f/ q
__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);
1 `* a+ I7 }4 n- O( h2 Z" j: t% ~6 B1 G: V1.函数名称需全部大写.' r I# n4 r/ C8 }5 O7 ]# Y
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;+ \% T+ |/ w9 r' ~+ E6 \1 B
对于C++程序还需包括在extern"C" { } 括号中.' C6 @6 y; X; m8 O5 c
3.函数计算结果用pData->m_pResultBuf带回.4 [) w5 T. ^# k% x8 h
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:4 \, Z$ i2 a& t$ g
m_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.9 A' f+ ^5 o( |! `" |" H
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
9 X+ F- v: n: a7 J*/7 E X( [* L& `! q
//示例函数,使用时用实际名称替换+ V$ f; W2 K- Q8 b; n
__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);, c; D+ P3 B4 v9 Z. b' o
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
' Y3 c' m) u% [: ^# p//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);- Z, c/ G- A9 x5 m
__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);& k5 b5 q9 }% w9 |$ c
//WINAPI = _stdcall8 W. N% I) t# W( i: u
#ifdef__cplusplus! W7 L, K0 I4 ?4 P/ P
}
) j; D' A6 f: e8 ]' k1 t; o#endif//__cplusplus0 L; |* h- X c
#endif//__FOXFUNC_H_INCLUDE
; m! f6 ?/ b: L2 [$ j7 |; e! P' C+ r) s! Z" {
//////////////////////////////////////////comment 注解
% t/ H1 b, {* H+ }1 ?1 J__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)9 ~8 Q( s& [& _4 B6 ~# u: `. w& t
pData是指向 址标总结构 CALCINFO的 总址标
: g4 G1 e: Z3 W7 h; |取用第二个参数数值floatfParam = *pData→m_pfParam2
" s4 |0 R7 o- U9 h+ R: `' ?, K. D# T5 P取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;7 l/ E% C$ y y1 E+ N
取用股票数据长度intndata = pData→m_nNumData;$ L$ ]3 g5 z: O" C% h j" J$ b
第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
# t' |0 r' d- w. O第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
1 N: J. Y# u: I- n, P( d第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
) F- J) i* n1 f2 cconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
( \7 e( r; |% }9 C, j; q' l取用股票数据结构5 N, {0 ~4 Q$ J9 C* b. A
pData→m_nNumData= 变数数据长度
. n7 [& f7 J2 m4 BpData→m_pData= pointer to struc STKDATA 的址标
1 i- B+ b% B1 d7 k/ P" \4 X6 N6 DpData→m_pData[x]数据结构的第x个数据
* S. E) }( V* }# f9 O8 bpData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
" i! ^5 O& f& @2 N; { V. u取用结果缓冲序列0 A. ^! h3 v, }: T! x2 ~6 B# n
pData->m_pResultBuf
' F8 \& V4 T M0 n取得第一个序列参数的起始序位,如 2,...5 , . 7...+ F( o5 q. R% r
intnFirst = pData->m_nParam1Start;
; v8 |! ^) t- z$ t V+ S) F+ Ufor( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
6 x4 L8 V j Y6 [取得第二个数值参数的数值
2 U( S3 F( G. _) M% XfloatfParam = *pData->m_pfParam2; 2 ^! t2 u4 r5 Y3 c+ ~! f$ [# o! d
intnPeriod = (int)fParam;
: m3 w( P! a3 |( E取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;
( ^% \9 s; P% v" M* Q; h取用序列参数的单个直pValue
$ {/ O6 s# t; v取用缓冲序列的单个值pData->m_pResultBuf
8 A8 y0 p2 y9 T, WconstCALCPARAM* m_pCalcParam; // 调用参数数组
3 X4 T+ d0 `- y; c3 om_pCalcParam为序列址标,指向各序列参数的指标! I |7 L8 k! j8 N$ W0 j0 d
第一个序列参数pData→m_pCalcParam[0]# }: w) F$ p9 `0 }; ^: n
constfloat* m_pfParam; //指向序列参数的址标
, A( y' \+ l! l; l) p第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
7 h9 B: v& i1 \$ N第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
4 E% ?% [$ q$ _8 i! Q0 u取用第一个序列参数的单个直pValue11 D1 M, j# M& y, l1 f
第二个序列参数pData→m_pCalcParam[1]
/ t' Y4 V2 s6 ?' y0 b第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
& l: b- C8 ]0 d7 u- ~, j" _第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;! R% D- F( q) F2 X; o, l3 z
取用第二个序列参数的单个直pValue2% i4 o- m4 K0 i3 {7 {1 G) Z
第三个序列参数pData→m_pCalcParam[2]4 B8 D$ S$ i# L; y: q" |% T
第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart3 ?7 U0 A5 L# N6 @
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;
9 I0 r# z( N& f' I6 E1 k取用第三个序列参数的单个直pValue3, y3 _% N1 O: J( R! e; a: k2 N
第四个序列参数pData→m_pCalcParam[3]+ S* [% Q9 B% o9 M; ]: `% D
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart$ X2 w" q# r0 ~1 ]% j! z8 C
第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;: L- m+ q7 I, x3 @3 k W
取用第四个序列参数的单个直pValue44 G" L. ^- U5 {# [
如果有四个序列参数,则取用序位最高的那一个序位
' ^$ C# x# S# T; i( j. V# zif( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
) U* R! S/ v) _0 l7 U: |pData->m_pCalcParam[1].m_nParamStart>= 0 &&
0 @& p2 W W( T0 G+ y* ypData->m_pCalcParam[2].m_nParamStart>= 0 &&
: O H/ h! W L+ a, S* D3 c4 LpData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值# F- S* ^8 B1 d
{
7 K9 a# M) o4 K. q* ~//计算返回的序列的第一个有效值位置
+ i3 q1 W: y6 E0 l. mintnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
) P( E& G* ~$ b' T0 c//若不知,则& X& T9 O3 F8 T8 O
/*
1 }. b2 X9 h5 H) yintnFirst = pData->m_pCalcParam[0].m_nParamStart;$ h- n" n5 P6 ]
if( nFirst < pData->m_pCalcParam[1].m_nParamStart )
; k; K q1 V; X, r4 i, SnFirst= pData->m_pCalcParam[1].m_nParamStart;' `( s, d5 N9 l1 s0 X5 M
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) + |* G, k3 ?( W# i' S
nFirst= pData->m_pCalcParam[2].m_nParamStart;
% G8 `$ R! ?) e% Dif( nFirst < pData->m_pCalcParam[3].m_nParamStart )
1 t8 Y! p1 t6 EnFirst= pData→m_pCalcParam[3].m_nParamStart;
$ B9 F, n' e0 `$ K# T9 Tconstfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;; J9 y2 B9 a+ L* o5 S* V9 n
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;' H6 \% f3 r4 s: }$ t- ?
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;8 i" p* B S+ h" ~& f
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
. H% L5 i( j. p, j//-------------------% Q4 l: G" R. u; }/ e/ W {
floatm_fOpen; //开盘 open& a' B0 w0 k4 z" X; n
floatm_fHigh; //最高 high
. k- g: E2 v9 o' q% dfloatm_fLow; //最低 low
; ^* n% L) j* W7 H: Q, u8 C" x; I* Jfloatm_fClose; //收盘 close
6 D. i: d: ^/ q) |floatm_fVolume; //成交量 Volume; l3 e1 C5 G, p! e' K- \" m
floatm_fAmount; //成交额 amount; [2 { W/ N9 H4 u/ }
调用收盘据
/ S% n) F$ ]: ^8 R! N w* ipData→m_nNumData= 变数数据长度1 L' u% G' S5 k* L# e+ R
pData→m_pData= pointer to struc STKDATA
+ U1 i0 j, ]9 a) F, x/ {4 wpData→m_pData[x]第x个数据
7 h f+ Y% D+ m& BpData→m_pData[x].m_fHigh第x个数据中的 High
. H) y6 q# H3 X9 ?$ u5 B5 j+ h@@@@@@@@@@@important !!!!!!!
; S- N1 Q8 [! w1 t& }( p) lsinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror! ] W$ c3 L. U* b" I7 _1 Y$ M# i
so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
& C0 w* Y( M- x6 Q9 @pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
4 l" O7 i0 [" V9 t9 n- `) E. f6 D% epData→m_pData[i-j].m_fHighto use high
! l% q2 n j) lpData->m_pData[i-j].m_fLow
, ~: {% R3 m+ o' R3 M, \' Q+ }pData->m_pData[i-j].m_fClose) H7 c/ X& ^4 _" s
m_pData= pointer to struc STKDATA
c- L+ u$ N! q. W1 yincalling C++ dll function! { N( u% [1 s
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer): w9 B+ Q2 n/ Y2 m/ e2 t, x+ N9 N
touse a single value in variable ‘High’/ F+ h8 F; i, Z! [( T6 d8 c% x: }
pData→m_pData[i-j].m_fHighto use high
9 z' l- I2 Y6 O& F$ Uconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 + U2 ^& h+ a/ u8 r# M
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2: `4 U0 j/ |; v
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
. R7 Z* [' z0 G& [constfloat* m_pfParam4; . q% S9 x: {' b C. p$ n3 I
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数9 t; _5 e0 l5 {
pData→m_pfParam1= pointer to 第一个(序列)参数# a. a1 u6 X7 L1 N* x0 N
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值
$ Y& j3 }) ~. x/ n" G* o2 S" vconstfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数5 I/ C( Q8 `3 N+ h3 _
cpParam[x] = 取用第一个(序列)参数的第x 个值% w/ G1 @2 F9 P7 @
m_pResultBuf= 结果缓冲列5 U5 E5 G8 _8 ?$ `/ M
pData→m_pResultBuf= pointer to 结果缓冲列3 t+ J4 \$ d- U" f1 T8 f$ t
pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值0 K9 M: a" H9 a- l4 n5 O. _
//////////////////////////////////////////comment( l, _7 ~5 R* g
//////////////////////////////////////////comment 注解
6 k5 }4 ^: b; B# |" kconstint m_nParam1Start; //统杅1衄虴宎弇离
' g C+ c: I' K2 r: k3 v9 w- H( a3 ?constfloat* m_pfParam1; //覃蚚统杅16 E! @$ u' M! _4 |/ S
constfloat* m_pfParam2; //覃蚚统杅2- h4 y8 a2 L' X0 [
constfloat* m_pfParam3; //覃蚚统杅3
, |4 M) Q% `2 _- O! D$ T* ^& s" oconstfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4) ?: X6 }2 N9 b: i: ]. p* k0 @
//const float* m_pfParam5; // parameters must be <= 4. {! ? p9 C$ r' ~) C
//const float* m_pfParam6; 5 ^: w3 |# k" z
//const float* m_pfParam7; 5 A, Y4 Z9 S" M! N8 I
//const float* m_pfParam8;
: ~1 l' \* J- a( b; w( U//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&6 c7 v% S; |1 C3 g8 V
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
( N8 |; G$ r* j- B/ R# R! N&&pData->m_pCalcParam[2].m_nParamStart>=0)
, H% q% @( R" ]{
- i5 v% }3 s( e$ }floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0' \' \4 q. `0 z. M
intnPeriod = (int)fParam; //统杅1
& g9 L0 y) V+ u7 S ?. a//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值' Q- T4 C$ c- m, j7 R$ v
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值! C2 ~3 G- }$ `
constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
6 `# V% n* v, f' \' y- K% h, Mconstfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 43 J" \4 d# t$ c# X0 \& m; I
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值& A( C$ _5 }5 f @7 I
//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
# G3 j# K0 c: }, j: F. M6 `3 Z//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
) |4 f2 `( _: {! Ztouse pData→m_pData[x].m_fClose
* c- U! D. X( D" u7 [pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time;
$ l4 J; {! }2 @1 y' n8 B/ ]|1,2,3 , … , m_nNumParam | float m_fOime_t
) j6 q8 {0 R9 G|1,2,3 , … , m_nNumParam | float m_fHigh;# _1 N1 [* ?7 N
.. .
; G( A" S. c7 V/ b|1,2,3 , … , m_nNumParam | WORD m_wDecline;& M% D- @+ g5 w5 @- g1 k1 o
m_nNumParam= 数据high,close,open,low的长度
( O* \$ A" g* S& [- N, j2 C0 mtouse high:% c1 ?9 s5 E% k) U
pData→m_pData[x].m_fHigh
* |5 F8 u0 ^8 F$ _5 {contentof struct STKDATA
2 K& _! l6 E# g& z) |time_tm_time; //时间,UCT7 w( x9 a! `+ b1 `2 k- O) \$ z! @) |
floatm_fOpen; //开盘 open W* i8 A9 _. I2 g2 z9 f
floatm_fHigh; //最高 high# r, S3 h$ N" I! O& g
floatm_fLow; //最低 low2 |1 o0 O- |: x8 b* _/ m9 W
floatm_fClose; //收盘 close
: O* w3 C! M) R& e9 Nfloatm_fVolume; //成交量 Volume% m( ?* z/ x$ K' J
floatm_fAmount; //成交额 amount
" }: H4 G6 O( B: P( pWORDm_wAdvance; //上涨家数 仅大盘有效/ t7 w& ~$ v$ M6 ?4 C4 t3 k& I- i
WORDm_wDecline; //下跌家数 仅大盘有效4 |: B+ b/ ^7 m( Z# H# R8 V
调用传递参数及传回结果1 ?" ?. I* m* M5 t
调用传递参数. [- l, S' v2 t' L
(pData->m_pfParam1 && //参数1有效Param1exists0 R& D) Q" c- _
pData->m_nParam1Start<0&& //参数1为常数 S& R4 ~" s4 y0 C$ C0 G: C% \
pData->m_pfParam2==NULL) //( Z* L; T, A( }* u6 U, l, J+ _# G- f3 Y$ a% ]
localprocedure 定义使用变数$ N9 _1 R5 \& ]( l$ [, t I; ~
onstfloat* pValue = pData→m_pfParam1; //use constant参数1
7 V$ A W( R$ S5 x1 UintnFirst = pData->m_nParam1Start; //use 参数1效值起始位
/ T0 ` ~' n5 r4 S4 D- e+ O3 ZfloatfParam = *pData->m_pfParam2; //use 参数2
0 `) s1 P) ? r \intnPeriod = (int)fParam; ) c3 {2 u0 G6 ]
传回结果
( r6 g" t+ a. MfTotal+= pValue[i-j];( V( o" ?) V$ _ h6 a& r, Q' P9 e
pData->m_pResultBuf
4 N+ b6 D2 }. z. n5 r7 X* j//////////////////////////////////////////comment |