许多年以前,我曾经在
4 Z; T0 O$ o w; j3 n7 t理想公式区发布了
2 _* S( H- e; Y0 I# V6 f6 }% p- J( G"
3 [* U4 L( H6 R2 B d8 X w如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
, ?* y7 T( r9 ?9 b9 w. u7 Z: W6 o"
. i( M3 n" I0 ]+ q5 I' G. D) i8 _- Q- s, u/ X
现在更新foxtrader(飞狐交易师)
F+ T; [" R- T5 B) X连结 DLL的方法- `" S# z; _1 F) y( ~
( Q/ G) c0 m) o
foxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )% M9 Y( i3 T9 H: [% W9 Z
gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )" _$ @+ r% J' I
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
/ Z" ]* Q) y, @4 xfoxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效: c" @& M* z4 _! X
3 _5 h' P( M. U& u+ V也就是这五个结构都能用$ B! c* T d# B6 N% N
typedefstruct tagSTKDATA ( r' f* \6 j4 `1 [# |
typedefunion tagSTKDATAEx
6 `/ f* j! A- ~7 |typedefstruct tagSPLITDATA 3 q- @) ]( K' C* `! a! a
typedefstruct tagCALCPARAM
; v0 I6 q9 m! f2 R% l- Y( Utypedefstruct tagCALCINFO
! K! @4 B& n k( ~) V
5 J( p. I& t! H2 z# a. c t! S$ p自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C$ U* s- H, o: |( Q# \+ H9 M6 }9 x
也就是这五个结构中
4 l$ q4 p1 D6 k q. j( n- vtypedefstruct tagSTKDATA
/ m* o" V& N% F' H' ] |typedefunion tagSTKDATAEx# C# L; s N; Z8 b
typedefstruct tagSPLITDATA ! @. O. E6 O. f% e- G, A" c) {
typedefstruct tagCALCPARAM
5 s/ r5 l3 p( j5 L" ^: ]! ~typedefstruct tagCALCINFO9 E5 k0 s# c+ Q+ n" @% u9 Z5 S0 }
只有这两个可以用/ |/ ]3 L+ _1 [+ O
typedefstruct tagCALCPARAM( L3 x" E- Q$ }. B, ]
typedefstruct tagCALCINFO
O0 V8 X8 A; X值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个4 x6 O1 u7 N T! G) P
typedefstruct tagCALCPARAM/ u5 \- c. s- }
例如:在 foxtrader中
( X1 q7 P- P: C* e* h! dMA1:=MA(CLOSE,3);# h/ W4 ~7 B3 h* d
MA2:=MA(CLOSE,6);1 X* }7 z. h7 m2 n
MA3:=MA(CLOSE,12); {8 w+ M) l% T) T D# ^
MA4:=MA(CLOSE,24);/ z. W/ B/ s0 t& d3 U- V, v
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
# s: X) S) O7 n6 i1 j/ }* d( ]; M e其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
' c: V; q9 o- U% W下面这两式计算结果相同; M+ ? C0 E: ]' `3 V
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 自行计算}1 L6 I( s) p- ?7 ^
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
' o7 U* e, ^' @其他例子; L9 z! G6 C& s# |4 v5 r1 E6 H
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)( u9 \) Z7 R8 E
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;1 l. ]# E7 L. p
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的% l6 w0 [' b6 Z, A- o& b
fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误* c% ]: D- a* X! B
4 a( F0 _) o- v% u& p' B0 ^ q
% ?8 C0 T* y& M; D////////////////////////////////////////////////////////foxfunc.h
5 |" V1 O6 ]. h#ifndef__FOXFUNC_H_INCLUDE2 @1 l) v5 b' V+ F- T
#define__FOXFUNC_H_INCLUDE
- e! D2 \1 J" z$ ?8 z/*1 Y3 f! ^/ b# F
飞狐交易师“C语言接口”扩展程序调用接口规范V3.0$ m1 V4 a) t0 [* P% X. g
1.本规范适用于飞狐交易师V3.x公式系统.
1 i( C- I5 X9 ]. N2 d. V0 y4 q2.扩展函数用于实现系统函数不能实现的特殊算法.6 G6 k1 Z& I! R3 E. G
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
+ n Q( A( q8 X' [: h1 [0 S8 g- @4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)8 d- L) n d* G! q: @& r' h
5.动态连接库名称和函数名称可以自己定义.
7 \/ A" s0 Q8 J' ?/ c6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.+ a3 N: f. G j% y- v' q. V
*/" g) ~) N, T. t; j2 F- G
#ifdef__cplusplus
6 _: T# Z7 g$ I- B2 U& I- qextern"C"
# J+ R4 X3 ?: q& o$ q5 ~{
Y* [+ W ^$ p m% e#endif//__cplusplus
* n0 L2 l, q. ^5 ^2 B g///////////////////////////////////////////////////////////////////////////) M8 _$ c. U7 `7 V5 q
//分析周期
) K" \" d& `- zenumDATA_TYPE
5 v3 D! y7 A( [ Y; g( {{
9 W* }/ U8 U* ?6 ZTICK_DATA=2,//分笔成交
. ~- o: G! c' j6 J( Q; DMIN1_DATA,//1分钟线7 S' d+ E; F% U+ {9 x- g! h" F
MIN5_DATA,//5分钟线
) J. i" X) i* M! n% xMIN15_DATA,//15分钟线9 O2 s" j. |) Y- V3 w" U/ b
MIN30_DATA,//30分钟线 m: C" K% Z) X# l( ?$ \: E
MIN60_DATA,//60分钟线* j' [. M2 M; {. O7 }
DAY_DATA,//日线
; ^6 d# K, q' C! MWEEK_DATA,//周线
* U) ^! a6 `; _9 t! U3 C2 B3 ?) fMONTH_DATA,//月线- A W% O' l0 g1 t. M- {, W
YEAR_DATA,//年线
f6 G7 h- r8 K8 W% w' r6 KMULTIDAY_DATA,//多日线/ `( D8 {8 s. b4 k3 C' ^
MULTIMIN_DATA//多分钟线" H# b9 B R% A i3 t
};
0 Q2 d3 M: z* I1 L1 I* E) H///////////////////////////////////////////////////////////////////////////
' \* r1 ?/ Y% H+ S9 e# H' e( f//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用0 C: r9 g: |/ }6 X2 d" l
typedefstruct tagSTKDATA
! W. ?4 L& w7 L( }! ]: h' `: i3 b{$ D. Z2 v, E( j6 t6 k% p' T
_tm_ ; //时间,UCT- S( J- G7 n3 L: X- ]3 ^& u. Z& V
floatm_fOpen; //开盘 open4 y; X3 i& y1 i4 a' Y. J
floatm_fHigh; //最高 high
- d2 {% |3 ~9 T5 B8 I6 z% u7 ~floatm_fLow; //最低 low7 \( N; P5 B0 p0 x7 I7 h
floatm_fClose; //收盘 close7 K& M8 l* R/ B; p' Z, f
floatm_fVolume; //成交量 Volume- T9 e6 B5 F7 u
floatm_fAmount; //成交额 amount
* _# e8 W* |" mWORDm_wAdvance; //上涨家数 仅大盘有效
( E& v+ x& v$ A; EWORDm_wDecline; //下跌家数 仅大盘有效- v3 f& A+ _# R1 |& q- K
}STKDATA;5 P; \$ T* c! z% Q1 U
定义STKDATA为 tagSTKDATA的简单别名,STKDATA # ~% f+ V# G$ C. X9 i8 r
为真正方便使用名称,tagSTKDATA 为定目的的过水名称 f+ F# f8 y2 T5 X( D4 ^! o, B5 ]
////////////////////////////////////////////////////////////////////////////& R" i; H7 C) r/ \0 u; ]6 D4 l
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
! ?, q8 J+ P2 P. n }/ ]typedefunion tagSTKDATAEx
. O) s! L6 j& T7 C9 V/ k& ~{, v5 c5 H* }. }8 t0 c1 h
struct
- j3 Z# ]; b3 U: i( H% s5 [* p{+ S( p/ z2 j+ G* [5 s) n- S5 w
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open
3 N) B* J3 J2 D; Afloatm_fHigh; //最高 high" s P, ]: P m8 P% d+ ^" e
floatm_fLow; //最低 low
2 j. P9 D; w' ~7 M/ g7 |4 l2 ofloatm_fClose; //收盘 close
% V5 |0 E/ l+ N( p. t7 zfloatm_fVolume; //成交量 Volume& V% y9 l6 G9 P6 P6 ]* p
floatm_fAmount; //成交额 amount2 ~, d r0 O% V; |% q" U8 U5 x
floatm_fBuyVol[3]; //买1--买3量% l8 U- Y' O, h1 ~4 N% ]6 S
floatm_fSellPrice[3]; //卖1--卖3价
0 f/ Y; x( l/ u% H4 Y8 U) f" T% Ffloatm_fSellVol[3]; //卖1--卖3量, Y0 z# T& y4 @9 ?( A5 {5 R' k
};% h0 w0 r+ Z* M) r6 X
floatm_fDataEx[12];
: i4 x3 F! o# I' n t}STKDATAEx;; E- s6 m: j. N4 ~' {, V+ r
////////////////////////////////////////////////////////////////////////////- Q$ t9 v8 L# E8 j3 f3 p
//定义取用除权数据的结构2 n2 Z8 k# P1 S1 G
typedefstruct tagSPLITDATA $ h4 \3 V2 s* u# U( R
{
( D% }3 a( [% G _3 D& r2 Ptime_tm_time; //时间,UCT
+ O& \* n# l, \/ \floatm_fHg; //红股
; N- C* O/ ?# }1 Q& Q1 q0 xfloatm_fPg; //配股
' N4 R9 I8 `% ~ P' U0 zfloatm_fPgj; //配股价& v# @& l" ^" ~5 [8 N
floatm_fHl; //红利8 K8 s% W7 C: `1 x! A# g+ K
}SPLITDATA;
5 `, c4 I I7 O/////////////////////////////////////////////////////////////////////////////3 F- w9 o) }1 z' {9 Z+ i
/*财务数据顺序(m_pfFinData内容)
# \* F5 x2 @$ ^& C序号内容* b3 J; @+ u; U, Q
0总股本(万股),& u8 X3 ]/ t6 G. n8 u# v
1国家股,
' h6 H2 x: a' d7 p2发起人法人股,' u# s; s/ e0 }; z% V
3法人股,
8 w( O: X" \- g/ n, Q7 o4B股,! i. d$ t5 M" h
5H股,
+ g0 Q, m$ M( |( D. _/ l6流通A股,
, p2 L) m+ M; d7职工股,' o$ P r* Z' o" ?; N2 U6 l
8A2转配股,
5 y6 W8 |# f/ g; m7 \1 G$ K8 ?9总资产(千元),) r: d1 y; `5 R$ x
10流动资产,
5 G$ m" r1 e. g, t) g11固定资产,
' ^0 }6 s# }( F# J% r8 [12无形资产,- Q; V. j, K P$ z
13长期投资,! N$ n9 @/ b% \8 b# ]6 `
14流动负债,
; U) O2 |& W. N9 R7 z- R15长期负债," Z$ i% e- _9 A: Y1 s; y7 E
16资本公积金,+ W. d' A& l% s0 a; Q3 c E- j
17每股公积金,; w3 V; ?$ a, Z, C, N/ E
18股东权益,
% z) |# T/ W) F% f# C- u19主营收入,
6 h) S+ y# v+ _' B! N, A20主营利润,& T6 ]" F5 M1 N7 \; X @
21其他利润,5 F; q: _ J7 f- I
22营业利润,! [; H4 S6 g9 V- P; t6 ^! u4 Q
23投资收益,
' t5 s4 b+ G4 h4 T24补贴收入,9 f% e4 ?6 ?, h) j2 x0 K- k
25营业外收支,
1 i# p! {1 ?$ F) {26上年损益调整,
% b8 n7 z5 X0 ^6 l! m: d27利润总额,
5 M) h# ?9 y6 `- c! ^- U# q5 c; b28税后利润,
4 t5 Z3 b* S/ g& @1 z5 b. _0 X: _5 j2 z, M29净利润,
& w J$ C& [+ i* n6 O; c30未分配利润,& E0 E+ S8 V3 B- j* ~& A
31每股未分配,7 B. P7 L. P" q, G" [0 U4 V
32每股收益,
, h* D: Z: N/ C- ~' J" T33每股净资产,
. W/ p9 Z4 G2 v: F. c7 K34调整每股净资,- J2 c+ |: p! {
35股东权益比,
& p0 c" t) h# U5 f) V: O2 p36净资收益率# z) @% C7 Q6 I# @* J% z
*/, L# o. v* i) \+ c% Q
/////////////////////////////////////////////////////////////
& U* d' U" i. ~% c8 {//定义取用caller函数传递参数项 的结构% e* Z6 D$ Y9 Q G
typedefstruct tagCALCPARAM
) ~0 M8 h7 Z* d4 M3 z{) H+ p/ g( Y$ F) b
union0 |* s0 V4 ^; Q* o6 m( f1 J5 j- H
{0 W+ s/ z7 P- `3 H
constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/21 Z/ u2 N( l' N: F
constfloat m_fParam; //数值参数 valueof parameter t3 Q' n$ E9 Y. E% S0 k
}; v/ H2 ?, p' a& D" s% G) _5 n
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
/ N& e) A8 G+ u& i, @}CALCPARAM;
* f( j5 A5 q; J8 }5 |/////////////////////////////////////////////////////////////////////////////! X. R$ L6 r* K9 k
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )4 H' \5 l8 o" C J, Z
typedefstruct tagCALCINFO; r; H6 m9 x& [. a
{
* N& R- E/ q4 o4 S0 G0 Z. ~constDWORD m_dwSize; //结构大小
5 o6 r/ x0 ^0 ]* g6 X% ?constDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
! X6 @* r f" W( _- |constDWORD m_dwSerial; //调用软件序列号
, C1 Z5 \. C7 N( S. Rconstchar* m_strStkLabel; //股票代码( z S) J W- ]
constBOOL m_bIndex; //大盘
, Q2 U$ m R0 bconstint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度+ t. m5 B( m ?/ H& e. [: n, {. ]
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
+ E5 {: T" l4 Q. c2 k8 r& B# C1 N5 \7 IconstSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
+ Y4 Z; ]* B& n3 O0 Kconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
3 K3 e. ~% Q+ rconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 + T E5 u# ^1 r, p2 G. G8 b1 J0 j
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2$ e) e& J( _/ p& [ s
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
! c% k; j/ n9 s3 ]3 a) pconstfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
/ E& F/ Q! Z# f/ B5 d1 ^# ffloat*m_pResultBuf; //结果缓冲区
" O0 ~6 W5 ~, R( m, h( sconstDWORD m_dataType; //数据类型. q" H$ V; P0 f8 n& n
constfloat* m_pfFinData; //财务数据
1 o {$ l4 ~6 j( e* \" L//以上与分析家兼容,所以沿用其结构和名称
: g2 T0 v: y, j7 M. R, j2 d//以下为飞狐交易师扩展(fortagSTKDATAEx)
/ d, A( X r# V. yconstDWORD m_dwReserved; // 保留
$ d/ K* w% [4 }) K) Z3 }constint m_nNumParam; // 调用参数数量
* b' M, s. h4 Y( X0 d6 n' _/ zconstCALCPARAM* m_pCalcParam; // 调用参数数组; _6 G9 }- X1 @/ Z- U2 }( u
constDWORD m_dwReservedEx[4]; // 保留7 w; L! w$ U! _# C
char*m_strStkName; //股票名称
! l' S6 n4 e8 J; dSPLITDATA*m_pSplitData; //除权数据+ e* H8 X2 Z% {9 R4 ]
intm_nNumSplitData; //除权次数5 `8 T0 M" Y1 _3 g
}CALCINFO;
- f% c7 t! f. [. @; ~/*
: M8 m7 c+ P; m# X5 w4 N% W注1:(与分析家兼容)
( o& S7 n$ {* I+ F1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效." X2 B3 v% I: [6 U
2.当一个参数无效时,则其后的所有参数均无效.
0 n: W8 l1 L8 Q6 n* x9 K如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.( U! L) x( L2 |
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.4 f' {" C6 A Q
4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
7 D1 R- g- s8 F: O% n* a5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
( E+ V0 H# B! n! \4 P3 L- G数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
1 P3 j" N% o1 Z7 [在时间上m_pData[x]与 m_pfParam1[x]是一致的' A, b# B5 a% l& A+ w
注2:(飞狐交易师扩展)4 h6 P4 y9 h; Q# M( L
1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。
& Q1 F2 U3 v9 ^$ |( J3 w* @7 Q6 G2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.: w+ r0 z# i6 u$ |6 z" C
3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。! O! o, P5 y9 N8 m" `4 E/ n
4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.$ M; d) B7 M! U& U( w- f1 U ?! T
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。
+ Q h% Z' I. J6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。6 M! b. r7 A; k w7 g
7.经此扩展,对分析家的DLL依然可以调用、兼容。4 u" F6 \! P* h* M
*/
$ C$ |7 ^1 q9 H- T( \/ D4 w///////////////////////////////////////////////////////////////////////////////////. ]% ~ X6 e, G! A6 M: b
/*函数输出1 T# G' b6 ~! }2 Q0 M
__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);5 M& @* F; G9 g
1.函数名称需全部大写.2 E, H* ~% U4 V3 K' H/ G
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
, g) j7 M. g( I- C# ?; }对于C++程序还需包括在extern"C" { } 括号中. W3 C, Y& }! u7 V
3.函数计算结果用pData->m_pResultBuf带回.9 { T6 o/ i$ n- y" v
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:$ d2 h! d, i9 V$ Y2 A4 I6 d
m_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.6 ~3 W; |/ c" v# f2 n
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
+ q S6 e( T1 }+ D" I- c*// C+ U1 `7 T3 |% Q+ t0 N
//示例函数,使用时用实际名称替换+ `5 G7 N) O2 H+ q5 `5 A
__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);/ A, ` Z$ Q: N2 p3 a9 A4 E% u5 z
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData); p' S ^+ |# A5 K
//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
# k' Z9 r- \5 `& w__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
/ {6 |1 ]2 f h6 }//WINAPI = _stdcall
0 B3 ^) i& U, |4 \% ~0 N#ifdef__cplusplus
+ \! V6 b" r* H- N2 \}
( x* {, t, Z* K# L( Z#endif//__cplusplus* [& b0 W" N0 ~3 C# U
#endif//__FOXFUNC_H_INCLUDE; c8 M/ ~+ `' F/ f
; h/ ~/ U& i3 ~6 E3 h+ l6 w//////////////////////////////////////////comment 注解
5 P0 T# K1 I3 Y+ G) [, h__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
! k4 `+ r3 ], P5 dpData是指向 址标总结构 CALCINFO的 总址标
( C6 y1 I' q9 T8 r/ O% T取用第二个参数数值floatfParam = *pData→m_pfParam2 - {' N2 i K/ F* d% V7 K- e& W& Z
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;
5 I% @4 m! c- g+ }取用股票数据长度intndata = pData→m_nNumData;
9 Y% E6 H# u o g第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
) F+ `3 q6 S: C: r: V# f2 w8 F第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=06 E0 t- B0 }( j! ?" u
第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
_8 ?* D/ C: e$ M3 S2 Pconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
5 r, p! R6 V4 c7 T& Q- [取用股票数据结构( u& ^$ F$ ?1 D) A- a
pData→m_nNumData= 变数数据长度
" N; u: X* g. W; F. H. a# wpData→m_pData= pointer to struc STKDATA 的址标
/ p; m( t0 O) q4 ^' ~pData→m_pData[x]数据结构的第x个数据
* p3 E" o8 m! g4 C3 Y! tpData→m_pData[x].m_fHigh数据结构的第x个数据中的 High4 a2 k+ O8 N9 v1 F$ s
取用结果缓冲序列, ]5 T7 m1 R1 e& D2 ?
pData->m_pResultBuf! ]) ~$ e( r+ g7 [( y
取得第一个序列参数的起始序位,如 2,...5 , . 7...3 r& B0 K5 S' L5 s* N
intnFirst = pData->m_nParam1Start; * j5 Z% d* x6 m; |$ v
for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )3 s+ k3 D# A, s( Q b0 t4 @% B
取得第二个数值参数的数值1 M* k; d* ~: B. F) N2 R# c5 D
floatfParam = *pData->m_pfParam2;
# W5 \$ A6 w; x( f9 F7 QintnPeriod = (int)fParam;; U7 x6 V0 T& M; b; t5 d
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;) C/ `. E: I9 s; c3 ^
取用序列参数的单个直pValue2 u% U, ^+ B! I o9 k+ B$ o
取用缓冲序列的单个值pData->m_pResultBuf, [3 U6 }5 M0 H, D. s2 q) P
constCALCPARAM* m_pCalcParam; // 调用参数数组+ o3 [/ O) i! a" q
m_pCalcParam为序列址标,指向各序列参数的指标) F' q) E% ?) D. V: e' N
第一个序列参数pData→m_pCalcParam[0]
2 ^, u- W. i) Y' hconstfloat* m_pfParam; //指向序列参数的址标
3 B/ e ]* S' t第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
' W/ u$ ~. H0 _* L6 @% h* A7 ~第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
& j; P1 q/ _5 X6 q取用第一个序列参数的单个直pValue1. u" ^) @6 r* Y8 S: ~
第二个序列参数pData→m_pCalcParam[1]
! O$ m7 I5 F; M9 }7 g( f第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
& h: F1 D V4 Y+ W5 D; A# l第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;
/ L J2 L* ?0 L9 N* u取用第二个序列参数的单个直pValue20 l3 L; S3 k2 t% {, k& w* Y2 h! D
第三个序列参数pData→m_pCalcParam[2]
; q7 Q* n6 R. l' `5 Q, c第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart% t4 b& D( z! U/ j
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;. {' L4 @- V) F) }% a; S2 @* I
取用第三个序列参数的单个直pValue3
6 b* v" ~5 m% Z; f3 u0 D; d第四个序列参数pData→m_pCalcParam[3]
, z# T: @" |9 D7 I8 X* ^第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
3 y& \4 ]1 s3 U+ `第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;
@% k7 B! E$ o取用第四个序列参数的单个直pValue48 L; r' ?7 B% j7 P- ]
如果有四个序列参数,则取用序位最高的那一个序位- Q6 F. i4 L% S; H# E
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
* P/ B- O, T4 @, U! ]0 npData->m_pCalcParam[1].m_nParamStart>= 0 &&
4 a6 U9 A1 Z0 H3 [3 ]pData->m_pCalcParam[2].m_nParamStart>= 0 &&* u5 c. n3 l6 ?# \
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值
+ ^8 Y( `! U, m l1 H$ u{
e- p( X" m( d//计算返回的序列的第一个有效值位置$ q- d) h& e1 \/ q; C
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
" D/ [: j3 U; j7 Y3 ]//若不知,则 ~; g* k! |9 C) w3 I7 O
/*1 G6 R0 T$ ~1 t1 V+ P# S* K8 \
intnFirst = pData->m_pCalcParam[0].m_nParamStart;
: p ?+ p& m8 ^9 }if( nFirst < pData->m_pCalcParam[1].m_nParamStart ) , c" j6 z7 `" T; P5 ?
nFirst= pData->m_pCalcParam[1].m_nParamStart;; S0 Q7 u x# u; _, w
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) 7 l4 G" ~: d) L1 {; A- \0 Z7 }8 ~
nFirst= pData->m_pCalcParam[2].m_nParamStart;' p& D) }* v, ?/ I7 S; A
if( nFirst < pData->m_pCalcParam[3].m_nParamStart )
. ^6 R# S1 O; OnFirst= pData→m_pCalcParam[3].m_nParamStart;
* j& m3 I3 l% }3 e+ o- ~6 Z+ bconstfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;0 |* \) X7 J( [/ G; V; t. L1 U
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;" p+ m4 q4 T" W" f1 G
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;: N8 q/ }# `, v1 ~' D. Q
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;: L" C0 H, T0 u
//-------------------
2 Q' l: s( r% z8 q8 X) Z) v% ifloatm_fOpen; //开盘 open
. W5 N% B5 Z! P5 q/ k! P3 Ofloatm_fHigh; //最高 high* d9 n A4 Z- o) w- ^
floatm_fLow; //最低 low8 k% L" i+ H/ J! N
floatm_fClose; //收盘 close8 _& _7 ^, z, S5 P
floatm_fVolume; //成交量 Volume
. ?% O- O1 s; a2 `0 K/ Mfloatm_fAmount; //成交额 amount6 ^ W$ y$ o+ x3 P. ]
调用收盘据
+ _& t. m! c$ zpData→m_nNumData= 变数数据长度
' P) C5 `5 S! H- W' @% L: k7 _7 s8 MpData→m_pData= pointer to struc STKDATA
+ N+ S# d8 ^# \& _0 ^pData→m_pData[x]第x个数据" Q; J7 I5 D. e3 [4 ^# ]
pData→m_pData[x].m_fHigh第x个数据中的 High
0 Y& ~7 e2 Y4 [, H4 i6 h@@@@@@@@@@@important !!!!!!!5 X6 q/ s4 a8 a' p1 p
sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror7 d1 f3 l" c0 l/ n6 T( N
so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
( ^8 w$ y- K& Q0 M! g BpData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader* {( l8 w0 C) P+ V) z9 i' ?6 x" J
pData→m_pData[i-j].m_fHighto use high) b) D, `- e$ V/ U) f+ j# I' c2 j6 Q2 p
pData->m_pData[i-j].m_fLow
' k3 c2 t5 I, l7 h% S, a$ g" mpData->m_pData[i-j].m_fClose3 j. {; R1 h5 ^! i. o4 O- r1 h
m_pData= pointer to struc STKDATA
0 c) `' Z2 j; o# ]( o! pincalling C++ dll function4 x {/ H; X) T( `; K* b) z! f
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)* ]9 m, `$ F% E! v6 {8 X7 h
touse a single value in variable ‘High’: g( u- g' E" Y! N* M9 m( s
pData→m_pData[i-j].m_fHighto use high% h8 F# T0 X( G% w
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
7 K8 X3 {) s8 F- C: Qconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
6 }# \+ b' H; e* m9 S6 c. zconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3. M- H2 l/ G" `
constfloat* m_pfParam4;
- q3 R7 ~$ V7 L1 ~) zm_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
9 F+ n3 c$ O1 zpData→m_pfParam1= pointer to 第一个(序列)参数
' C2 G2 S6 n9 i4 i( a C, a( U* H3 ~% o# qpData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值# \, k- o3 P4 `8 z9 k) g
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数0 J F3 Q5 d1 q" v i1 R
cpParam[x] = 取用第一个(序列)参数的第x 个值* p& c/ H; E9 h1 Y, r! w; H
m_pResultBuf= 结果缓冲列
5 ~. O" L F0 c8 ^3 q/ j0 @" ApData→m_pResultBuf= pointer to 结果缓冲列
. x! S6 [7 z7 T! m) ZpData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
6 `. a# r$ z. K) Y//////////////////////////////////////////comment
5 {9 c; u6 x) ~) Q, C//////////////////////////////////////////comment 注解
" Q$ z4 }: c! i% H+ zconstint m_nParam1Start; //统杅1衄虴宎弇离6 g, C& q8 m. {
constfloat* m_pfParam1; //覃蚚统杅1
! o4 w6 ` z, Zconstfloat* m_pfParam2; //覃蚚统杅2
$ n# k/ M' V5 L! M. yconstfloat* m_pfParam3; //覃蚚统杅32 T# [6 J/ o- F- ]% a
constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4; Z7 L: H0 D D" l' C+ i# R
//const float* m_pfParam5; // parameters must be <= 4
8 _" V/ b1 P* Q//const float* m_pfParam6;
, ]- U" X1 s/ T) O- E- q//const float* m_pfParam7; 5 h- Z/ A# L! N% j7 q* P
//const float* m_pfParam8;
9 ]* f% b6 p, n; j/ n$ q3 l//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 && Q7 w& V' }5 ]
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
+ @0 n1 w" O( b&&pData->m_pCalcParam[2].m_nParamStart>=0)
" k3 G4 x5 |* o{
; U1 l( c1 F9 \7 H4 F, S/ E' EfloatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 02 K& o, n- T5 z
intnPeriod = (int)fParam; //统杅1) L* s$ P) p# _$ O( i% t
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
6 S/ B+ F& ~7 g2 M( B/ u% L, T0 [constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值/ o6 a& Y$ N, ?! D2 c# m. {
constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值; E }; C2 F9 h
constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4
6 b8 u: t+ H2 L6 r8 V" Z# H//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值7 ]0 C4 R- e, x! j7 a: g
//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值9 }2 m; |3 t! a" f' g# c8 _9 m/ c
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA , # D- ]' F3 O7 v7 V
touse pData→m_pData[x].m_fClose
# \5 w6 p) h1 X3 i( SpData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time;
! g+ r6 z+ {: U% N5 K|1,2,3 , … , m_nNumParam | float m_fOime_t # z( b4 _: |7 [/ [* s* Q9 w
|1,2,3 , … , m_nNumParam | float m_fHigh;
: i3 O3 t- M+ v$ N4 h8 C.. .
, W, V& Y( \; \9 U/ n|1,2,3 , … , m_nNumParam | WORD m_wDecline; u5 `& ^8 n) E4 t0 W% Y
m_nNumParam= 数据high,close,open,low的长度* J" a; G- D8 k% l1 s; S
touse high:
- U- ?8 V" m ]pData→m_pData[x].m_fHigh
+ L: \- h p& jcontentof struct STKDATA
' x3 |" {! i8 r7 _9 M Gtime_tm_time; //时间,UCT* E+ ^% G; k D- ~% ?2 H8 H& _+ n
floatm_fOpen; //开盘 open
+ d% {; G$ Y$ ffloatm_fHigh; //最高 high! F! W6 R3 T9 N% |
floatm_fLow; //最低 low' ~, _, \( F9 ?
floatm_fClose; //收盘 close0 {* o' I% K, e. e( y/ [, M
floatm_fVolume; //成交量 Volume
5 j9 W2 L) ^+ d' C( y! e* U vfloatm_fAmount; //成交额 amount
# ^7 l7 q; k: a7 X/ J1 p2 wWORDm_wAdvance; //上涨家数 仅大盘有效
( A$ k' d/ ~- ~/ O# IWORDm_wDecline; //下跌家数 仅大盘有效% T; [4 |& K( `# `( I6 ~
调用传递参数及传回结果
: ]! R, m8 b, S) }7 b$ c6 J# q调用传递参数% C5 V9 F. K7 s! M' _7 K- J
(pData->m_pfParam1 && //参数1有效Param1exists
* b1 z; K/ P/ r2 MpData->m_nParam1Start<0&& //参数1为常数2 Q5 }# E; q/ z% t2 j! g
pData->m_pfParam2==NULL) //5 ^+ H+ `. f4 @0 E; j
localprocedure 定义使用变数
3 R$ G9 @ j; |% v6 vonstfloat* pValue = pData→m_pfParam1; //use constant参数1
# a. G c' z1 n$ ^3 @intnFirst = pData->m_nParam1Start; //use 参数1效值起始位
3 F$ ~0 B/ e' H) r+ T, W; D9 _2 tfloatfParam = *pData->m_pfParam2; //use 参数2
6 Z2 l0 p& j% _4 b: U) v) KintnPeriod = (int)fParam;
1 q& y) L, X" t$ x$ \1 q传回结果5 D5 T0 K2 L" D- t8 z
fTotal+= pValue[i-j];3 o7 G+ z5 g; v5 g! m1 F( w
pData->m_pResultBuf% c7 f9 L9 m! g# _
//////////////////////////////////////////comment |