许多年以前,我曾经在
1 a/ j! |* u8 A- ?2 d$ y0 ?: a1 e: s理想公式区发布了& _9 y% X. j* y4 t; j/ G w+ v
"2 c4 u% G- U' [1 u$ Y& i/ d
如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言), Q5 `% d- a/ }0 u4 Z- [
"+ }$ n2 _: O: I0 p' Q% G8 h
0 m4 Y! `7 {2 ?% E" @) Z
现在更新foxtrader(飞狐交易师) . B" R* X3 E, ^0 u
连结 DLL的方法
: J- W! w4 J$ `' V9 h/ _9 H$ U
9 u3 Z+ J3 O- L" L2 jfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
A! g/ t6 r* ]; |gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
' M; \2 k2 p, a M% P" ]. Ugauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
. v# L `6 @, \8 jfoxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
) Z; e9 G* L: T2 [# y
' I" q1 B+ x" d% X; M( k1 x也就是这五个结构都能用
' ~! x, I' Z" [( r4 J$ f5 v) Atypedefstruct tagSTKDATA
- E5 K! R- r+ b: jtypedefunion tagSTKDATAEx7 k" v- w9 k" t
typedefstruct tagSPLITDATA 0 B' _' F. z% e s+ I4 {
typedefstruct tagCALCPARAM2 M/ X8 C9 q- L' e" `/ C l
typedefstruct tagCALCINFO3 F3 B' Q l F
9 l& F& Z; Y9 ?3 F# c; |, I自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
; e9 _, X( P& V5 S! N0 R, q% l- g也就是这五个结构中' K8 A! r t: {4 r; X1 r1 U
typedefstruct tagSTKDATA 1 |" D, T0 M( R2 a3 h' @
typedefunion tagSTKDATAEx; N" T! f4 l) Z5 s L- F# Y
typedefstruct tagSPLITDATA 8 @; e9 ]. P1 G' S7 X9 D2 H- S
typedefstruct tagCALCPARAM# a' d# I6 ?7 v) ?# j* n
typedefstruct tagCALCINFO
) T) u. v6 [; I" D: \2 W只有这两个可以用! j$ d5 z7 P+ f" ^6 F
typedefstruct tagCALCPARAM% N/ }0 H" l2 J4 O* b6 g
typedefstruct tagCALCINFO
4 W1 p m5 O# r5 ^- X' [. U值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
6 ~2 {9 j( n4 [1 I$ c6 Jtypedefstruct tagCALCPARAM
* L k) M" |- j7 Q4 V( a$ ^4 j例如:在 foxtrader中
& J7 o: Q* g! A5 K/ z2 V* _; sMA1:=MA(CLOSE,3);
' I1 `* ?) r: ]* G _MA2:=MA(CLOSE,6);
) a* F+ s' Z5 W6 uMA3:=MA(CLOSE,12);
" Z3 \% u- K& V9 A- s& C9 qMA4:=MA(CLOSE,24);
; i( w$ {/ Z2 u* S. NMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
4 e8 _6 h& |& L其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个, [+ H& F: C$ c
下面这两式计算结果相同% F$ J h. a3 \5 F1 { B& g. q, R
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 自行计算}/ L, u; P! X& ]6 C/ a/ Y
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
& k( G" E, w$ Z4 D* M" t其他例子# x0 k% p- X( Q: c0 J j
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm), Y/ f+ g1 f+ M9 k% `+ l
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;7 J# g% x. N7 u- O
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
: S* G) y u! ZfTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误6 x/ P$ k, M% u' |
[! S9 o8 A1 s3 ~5 P# a @
9 W5 l& O+ S8 J& @1 g; S5 p" k////////////////////////////////////////////////////////foxfunc.h9 E5 V V: V" }" Y5 K
#ifndef__FOXFUNC_H_INCLUDE
& f2 B; c! }$ X% p" {" O. `) P* j5 {#define__FOXFUNC_H_INCLUDE
8 x. G& Z/ x5 D+ A. O; R# E$ A( F: T/*
1 O8 O. B* D( M" z- d2 L飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
2 h" [$ J( n* Z! H& P1.本规范适用于飞狐交易师V3.x公式系统.' \; p( f7 H9 v6 w
2.扩展函数用于实现系统函数不能实现的特殊算法.# l* _5 n- v9 I- n! J
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
; W2 P/ l! P. d7 L8 F# f% M! @) @- L9 N3 o4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)- {9 }" q: Z) G* \ b4 A
5.动态连接库名称和函数名称可以自己定义.$ n9 Z4 ]# n4 f. ?* ?8 j G
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.6 a& O" I5 _7 h" ~
*/8 y5 q! C( S- k5 ?; `/ l
#ifdef__cplusplus
/ W( t. Q/ [5 G, I4 jextern"C"
' e) d) N+ N4 | s{
; n$ t6 g# l. P% I4 Z( k9 {#endif//__cplusplus. Q% B2 `0 I. o* e$ E
///////////////////////////////////////////////////////////////////////////" |' q j) j( _: i# f3 ]7 w0 }
//分析周期
E3 \: E# m$ e6 J+ u/ \; }enumDATA_TYPE
" Y& g1 q+ t& Y7 N9 e2 X{
# r. j% v" y" Q, JTICK_DATA=2,//分笔成交' ^+ d9 z' n H2 C/ S
MIN1_DATA,//1分钟线
( m+ T8 F1 U5 {" C, \MIN5_DATA,//5分钟线 0 k. B& H% M \! \
MIN15_DATA,//15分钟线0 \# j3 P1 F8 `; o5 g/ S6 a
MIN30_DATA,//30分钟线
! u, \% s* v, ^MIN60_DATA,//60分钟线
9 y5 k2 ~# T2 d' v0 C/ P9 GDAY_DATA,//日线8 X( N% D) a3 y% C- o
WEEK_DATA,//周线" p; y7 M( I2 t8 N( z- w8 q5 ]% K
MONTH_DATA,//月线, i( ^6 z7 \7 g$ ~5 w6 l; D
YEAR_DATA,//年线
! O* u7 M1 A4 B- D, X) x4 uMULTIDAY_DATA,//多日线
1 `9 o2 a% K1 c# F6 PMULTIMIN_DATA//多分钟线+ A, h ?2 ]' S
};! d! }# |, E7 b
///////////////////////////////////////////////////////////////////////////
/ J+ ?( x: r' Z$ n+ \/ ^0 k- z; Y//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用$ k2 d, U4 P! e9 ]6 A: d* @1 Y, R' w$ f
typedefstruct tagSTKDATA
: u" k/ i: }9 Z/ K{
, `+ G; f, F5 {* n/ ` _tm_ ; //时间,UCT
& A* p. E. G7 o; @floatm_fOpen; //开盘 open: R4 r; I. n; v0 | ~) i' o$ j
floatm_fHigh; //最高 high( M- l) E$ H6 Z: Z
floatm_fLow; //最低 low3 T p" K4 c" a' \
floatm_fClose; //收盘 close; g6 R6 w3 i; a1 P" a4 u: ]% _" `
floatm_fVolume; //成交量 Volume) s$ w( G" M* t
floatm_fAmount; //成交额 amount
/ G" Q% G2 E' n* c; rWORDm_wAdvance; //上涨家数 仅大盘有效
6 F1 ~ Y0 L" J |& V2 i) sWORDm_wDecline; //下跌家数 仅大盘有效& M- d2 |7 v$ v3 Y- g" c3 u
}STKDATA;4 [6 e" n6 \& E; Z* Y+ ]$ ^
定义STKDATA为 tagSTKDATA的简单别名,STKDATA
. {7 H( Y2 w: ]+ b5 P' O为真正方便使用名称,tagSTKDATA 为定目的的过水名称! N. ~8 b1 t- `
////////////////////////////////////////////////////////////////////////////* E3 T) n* L. |2 i
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构* f3 _% a& j6 c! g7 d# I/ Y
typedefunion tagSTKDATAEx
1 g n7 D a% N9 \0 r{
* L" Q: h, b8 v$ r: Kstruct
5 T4 C$ ?! k/ F* k: R$ E7 h{" h- x6 X& U( O& i6 R: H
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open8 J: s0 r& {4 I
floatm_fHigh; //最高 high3 V( `7 a% Q0 c. v$ ^* @' g; h' S
floatm_fLow; //最低 low
9 t. V6 f* ?- u, w7 G0 C3 zfloatm_fClose; //收盘 close
) l" V! [# s8 H' @' xfloatm_fVolume; //成交量 Volume
x) C4 d& g( G- r$ Ofloatm_fAmount; //成交额 amount; s+ ?% x5 \9 J: b0 r7 c
floatm_fBuyVol[3]; //买1--买3量
+ N, p8 i. r3 O6 kfloatm_fSellPrice[3]; //卖1--卖3价
5 C- k: r; B9 X' jfloatm_fSellVol[3]; //卖1--卖3量
1 @. a$ x9 c: p U [/ i, k};
0 _* M* }. r/ L/ i% W$ hfloatm_fDataEx[12];
' f* y; p s% }4 M}STKDATAEx;
3 j. B4 N; W: Z$ S0 g8 L////////////////////////////////////////////////////////////////////////////' l. ^) D3 F% A1 H7 ]
//定义取用除权数据的结构; ~; p5 H- e: [0 y8 p: c. u
typedefstruct tagSPLITDATA
- c' k/ l& n& L; ] I, h" k{/ { @, @6 D/ q6 U
time_tm_time; //时间,UCT
( D9 [# F s9 t4 M( zfloatm_fHg; //红股) Q1 o3 P, j a- `/ e9 {& m4 W
floatm_fPg; //配股
( Q2 q( h% o: gfloatm_fPgj; //配股价
+ U3 i) p1 |/ ?$ B& M, n; o$ {floatm_fHl; //红利
0 r: \% X( c, r u3 A( K0 R}SPLITDATA;5 e& m X0 {) b
/////////////////////////////////////////////////////////////////////////////
' ?* \+ ^% I3 r. u; R5 x/*财务数据顺序(m_pfFinData内容)
# W' Q' o4 F8 j序号内容
0 ]5 \% ^5 u0 S1 y# _- D0总股本(万股),
, j, V4 _: n2 D9 f9 P9 c0 p! _/ l1国家股,
2 V' ~( [* w4 m/ |" ?! _; M- l2发起人法人股,1 G9 {6 e& V1 W+ O6 y, Q# Y
3法人股,
* l ^5 i7 U; ]! W' g6 q5 C4B股,: W1 U/ T" p$ ^3 v& I3 ^
5H股,# s X' l8 p5 }- @, ]0 q
6流通A股,
: K5 _. T% h5 K* Z" W: ~- ~7职工股,
* J3 i$ q+ G9 E8A2转配股,4 w0 n1 l7 c# n& m
9总资产(千元),1 m8 ^" l2 t. i7 L9 |4 A+ T3 ~# A
10流动资产,! Z2 C& s |$ N6 h
11固定资产,& B/ T5 \8 j' v2 w* ?4 S: m9 A
12无形资产,
% u/ Y4 u' e1 z4 l6 v13长期投资,
7 [5 z1 m! g$ \14流动负债,4 H, ^. x# f$ ]1 W5 N1 _2 q, h
15长期负债,) K: E& g; U6 `4 o) | e' ^4 }1 O# x2 y
16资本公积金,
6 M! T% o' ]- H6 _17每股公积金,
6 p8 I% ^8 b2 c4 q. A, ^! L! N$ X: b18股东权益,
) n: M% I" N6 Y19主营收入,
% j: e0 k7 G$ F: O2 X; b20主营利润,+ g9 U6 l* N8 |+ R
21其他利润,; W% h; x: r! z5 `4 i7 i1 c! g9 Q( J4 s
22营业利润,
( L. N3 }0 [) P+ K: |3 f/ d4 M23投资收益,
( u! o8 J' U/ h4 O24补贴收入,. ~! K! I: y. O& H
25营业外收支,
2 e4 h" c9 U- s26上年损益调整,
5 Y9 d( K2 g! H. I" E; b/ ^27利润总额,( A ^& c. X; J( n* ?
28税后利润,
4 F$ W) r" b2 s5 @8 ?29净利润,1 O$ I9 a% J6 z# Z
30未分配利润,
3 V( ^3 C! w; u3 w31每股未分配,
4 D1 s7 O9 h: a+ A1 Y: H) g32每股收益,$ s& o* ]7 q+ P7 f: x, U: |
33每股净资产,
0 _+ a. B5 I6 y34调整每股净资,: Q/ H3 u, W) P, D, X7 v& N
35股东权益比,
3 f r8 y* T6 i- z) G& x3 T4 k36净资收益率' x8 [; ?$ H6 j, j
*/
$ z5 v- ^+ H) Y6 M! k/////////////////////////////////////////////////////////////
2 c U# ]9 ~8 P: G//定义取用caller函数传递参数项 的结构
8 h" _+ H7 h8 i, N9 }typedefstruct tagCALCPARAM
1 J6 X' i/ g, b3 Q8 ?{; w( r' @" z7 U* g& T* [* m
union
+ O7 H2 [! ?* ~+ m{
# R, I( m3 ^) v1 L1 t: oconstfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2% P3 Y; C/ M" u, X6 Q4 k
constfloat m_fParam; //数值参数 valueof parameter
4 X" @' x* W7 r};
* E* j: K7 n9 z: }1 g3 Fconstint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2....., b: u n. E* B- y; S$ J
}CALCPARAM;
/ W% V) O p; Z, v& g- w! ~/////////////////////////////////////////////////////////////////////////////
r2 N8 H6 S) Q k9 J* X" x% {+ q//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )3 R0 Q4 [0 k+ u+ i9 @2 I
typedefstruct tagCALCINFO# ]% K1 I* X) S, j& z0 P
{
- H0 W% Q1 G+ Z2 O1 u: fconstDWORD m_dwSize; //结构大小+ k1 N) k t8 L) A! d' D
constDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)6 r) W+ a) r0 ]& a- x' Y: h
constDWORD m_dwSerial; //调用软件序列号8 e. Z8 ~6 R( d, f
constchar* m_strStkLabel; //股票代码
' ^" Z! G1 b- i- u' wconstBOOL m_bIndex; //大盘
- k* S+ ~$ j4 rconstint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度1 t0 R. Z* d4 e: b: j+ B" D' K* d" p
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
/ L+ Z, g$ a9 G6 ]constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
% A9 N4 N+ w2 @1 k' Hconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
' G7 b% ?2 V0 [" Q9 U$ ~constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 . m- f( q( V ^1 c' d
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
' I8 N. T, {3 i: d" @3 d5 r- \% q7 r4 Dconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
2 |2 u/ w; J/ r/ e. ~8 q! b6 ~constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
: n+ ^ l& L8 c/ o9 bfloat*m_pResultBuf; //结果缓冲区
: w/ z6 I5 w, ]constDWORD m_dataType; //数据类型- x \- ~ a* D- K2 p
constfloat* m_pfFinData; //财务数据
8 U( U; H7 U/ V/ Q- h% H* o//以上与分析家兼容,所以沿用其结构和名称
' n9 e5 z" d/ A: Q0 l8 K//以下为飞狐交易师扩展(fortagSTKDATAEx)
3 N) }" Z$ P$ }6 [# `/ o( _constDWORD m_dwReserved; // 保留
3 O; r! b+ B9 I& F; c5 [constint m_nNumParam; // 调用参数数量 O# S2 _& p; g9 _* I, i
constCALCPARAM* m_pCalcParam; // 调用参数数组5 [3 U3 G8 q0 _: M5 H: p/ o
constDWORD m_dwReservedEx[4]; // 保留: L2 z, e8 A+ f5 B6 J; k
char*m_strStkName; //股票名称
% @6 b, B% Q8 M# S2 z x( RSPLITDATA*m_pSplitData; //除权数据
/ M! W* e; r1 k) Y* s0 P* wintm_nNumSplitData; //除权次数' b. { M" R& m" H( y
}CALCINFO;
( p5 a0 k3 N& N& C/*9 }, r: U% ?( j
注1:(与分析家兼容)* D$ `, v4 W9 \: B
1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.( d1 U, e& N- ~/ ^. _. C- l) @
2.当一个参数无效时,则其后的所有参数均无效.
5 c) Q+ E. ^7 ^如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL." G8 Q6 J+ \6 k
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数. q# p4 P$ D C0 }3 U- C/ e
4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
- Q: t: j( c- Z9 {) L9 d+ X# {! |7 I5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,$ }+ D; o& U, z9 S, h+ b
数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
1 z9 n& f! |/ z: l! X在时间上m_pData[x]与 m_pfParam1[x]是一致的
- ]* Q) ^. }8 k4 [8 L注2:(飞狐交易师扩展)
8 P M6 L6 T N% m/ g3 T1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。# V8 v- b/ f' d. U9 q
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
: F0 E5 N+ |3 e3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
" }$ b, f' E; E# X; [; S4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.% m0 Z3 D. Z0 ^# h& k2 N, {: r
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。
, Q O9 L4 |" V( \/ _- s6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。+ G) ]8 ]1 d+ J
7.经此扩展,对分析家的DLL依然可以调用、兼容。. o3 Q/ a5 l- ^% o1 z: ]
*/
/ |- J$ s7 C; C4 v" R///////////////////////////////////////////////////////////////////////////////////
! ~9 k' n7 F- c7 |/*函数输出
) X) Z2 J9 M$ J__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);9 U1 f U2 b- ]+ R+ @2 a3 p: O
1.函数名称需全部大写.+ S' g3 V/ U! }6 M9 j
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;' z/ P* I: N" s& S3 m( d
对于C++程序还需包括在extern"C" { } 括号中. C6 R! k; @( R
3.函数计算结果用pData->m_pResultBuf带回.
# X) L/ H+ M# u% a+ X9 A; ^4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
* O1 x5 R ], y4 ?/ p0 I& dm_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.
! c4 e8 B. `1 Q5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
9 b, v; {: H- Q9 D*/
# Z' n3 m3 z1 o% Q" g* @//示例函数,使用时用实际名称替换
' j& h! g* a- o; o__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);
- J* J, D+ u, e* t$ G: R7 e__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
' X" \% v; F' |9 l2 d//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
- \$ @& Z5 [! a0 ___declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
0 t# h/ b2 f: o1 @9 @//WINAPI = _stdcall5 s& R, E$ [8 q( W0 I0 W
#ifdef__cplusplus1 n( f+ t7 n/ Z* N
}
2 `! I* A+ S0 Z; H+ S#endif//__cplusplus# I8 ]" u2 j3 b9 |
#endif//__FOXFUNC_H_INCLUDE
; K$ ?3 y8 r% F- n+ }
1 s4 \. x. D3 F//////////////////////////////////////////comment 注解" o# o' W- |+ S, A$ q0 Y7 o+ {" W3 b
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)* G# P- z! b; s/ F
pData是指向 址标总结构 CALCINFO的 总址标
: F2 y1 B7 O& Y. p取用第二个参数数值floatfParam = *pData→m_pfParam2 ) i* U: _4 F Y& q2 M$ C T/ Y; _( d
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;2 i! T# d3 I4 \9 R/ o2 b
取用股票数据长度intndata = pData→m_nNumData;- i% a+ U+ N% {
第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0) K9 ?+ T; H' ^! [; e/ u2 Z
第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
4 ^4 [* a( p, v4 B第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
2 r. H, S7 i1 k3 t, aconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
" `. a$ @, G8 P6 ^* Q% t取用股票数据结构/ D4 p7 Z' i! u, T1 l& V& i
pData→m_nNumData= 变数数据长度$ J0 T" y4 G4 \: o& q0 w
pData→m_pData= pointer to struc STKDATA 的址标
) O; t1 E; d' [; M0 s: NpData→m_pData[x]数据结构的第x个数据0 `- i/ r+ w: Q
pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High* |3 r8 ]9 N6 T U5 }$ q
取用结果缓冲序列
1 |% q0 Q% b3 ]/ g) ?% B2 E% p8 e8 fpData->m_pResultBuf `; @: N8 s. L8 K, S8 J
取得第一个序列参数的起始序位,如 2,...5 , . 7...
( `2 l' Z! Q$ s: vintnFirst = pData->m_nParam1Start;
" ~% u0 a @. }for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ ); G/ d4 J. e1 P6 }* b( e' y2 i2 u
取得第二个数值参数的数值
8 d7 R0 m% Z8 Z7 a; I5 ?0 V' b) @floatfParam = *pData->m_pfParam2; 0 R/ c/ C3 p) t8 C: U& Z
intnPeriod = (int)fParam;% H5 |1 y9 D: a' A
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;. c G$ T. m* r2 Y* H
取用序列参数的单个直pValue
) u" J* {, s; \3 @# E" J取用缓冲序列的单个值pData->m_pResultBuf* x$ n; ^4 a$ g* C# [9 j) \/ m* H
constCALCPARAM* m_pCalcParam; // 调用参数数组& ?2 |8 |& d4 H4 R* |4 c3 K
m_pCalcParam为序列址标,指向各序列参数的指标+ l% _ O" Z B9 r/ ^0 O
第一个序列参数pData→m_pCalcParam[0]
' Y6 M( B2 a7 [9 f8 O9 e9 Hconstfloat* m_pfParam; //指向序列参数的址标
+ k: @& y1 {2 ^9 f; _第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
1 g- |* I' ^0 m. y0 w4 W/ y第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
7 g2 d; [3 l% y' J; K4 U, w取用第一个序列参数的单个直pValue1
5 R2 }) k+ w! u3 m6 A第二个序列参数pData→m_pCalcParam[1]
$ y$ f, F4 I: U' l% p第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
4 }) b5 e% u' i1 k) P第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;
/ Z' o% p! P- K+ G3 K4 }取用第二个序列参数的单个直pValue2' k" h& I7 L6 m/ Q
第三个序列参数pData→m_pCalcParam[2]
8 \; [/ E& s6 T第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart( d+ ]; B( n9 v$ ?9 x1 P
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;" t- G- U: H- p
取用第三个序列参数的单个直pValue3" T0 E. W! J! o4 j/ ]6 H4 r$ Q. r
第四个序列参数pData→m_pCalcParam[3]: _% t5 R6 w4 k4 d: `9 f$ C# J
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
) p3 Z0 h3 `' w' A第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;
8 W5 X8 I4 z+ D9 ?3 z& r取用第四个序列参数的单个直pValue4
5 u; A, X$ f; Y8 F) f ]* A如果有四个序列参数,则取用序位最高的那一个序位( T( s1 [ @% C) {2 c
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&: o: q" o; z, Z0 N$ w
pData->m_pCalcParam[1].m_nParamStart>= 0 &&3 F. u( n5 @' s
pData->m_pCalcParam[2].m_nParamStart>= 0 &&
- N: Y$ C- p7 d2 m: L/ P# \. n, UpData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值; t' K& u' n% `' [- x1 Q! Z
{, F' f* C5 A. W7 b! N
//计算返回的序列的第一个有效值位置
c) J. N9 Q* T |, BintnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致& H! A8 O, T4 W( H
//若不知,则/ V+ t+ I/ Z6 b% I( L3 Z# s
/*
2 `8 Z2 x; M9 R6 T. a8 H4 P5 I8 EintnFirst = pData->m_pCalcParam[0].m_nParamStart;
2 H5 G" r4 K! D: ?6 t" Q% fif( nFirst < pData->m_pCalcParam[1].m_nParamStart ) 9 s, [4 @6 H) Z0 @" P+ s- d- S- O. z
nFirst= pData->m_pCalcParam[1].m_nParamStart;: D g4 p5 A* L" R" E
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) ; q* _, J# N; d
nFirst= pData->m_pCalcParam[2].m_nParamStart;& c# \' b' T$ ]3 I
if( nFirst < pData->m_pCalcParam[3].m_nParamStart ) : S6 Z( \% p6 R; k- E6 m
nFirst= pData→m_pCalcParam[3].m_nParamStart;
) E% x( n/ p. x2 gconstfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;& w6 @# Z+ d+ F9 r2 ^/ F
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
# s& C8 l2 r' Yconstfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
+ C. T& L# l3 `; d0 d3 o, Bconstfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
8 N3 Z. y7 }6 w0 [# I( O& K' x//-------------------# C) b: J& f7 D+ V y7 f( ]& {
floatm_fOpen; //开盘 open0 n/ c1 J$ Q' Q4 I# |( L: ]* f
floatm_fHigh; //最高 high& a+ ~0 `, f& `" U2 R; t
floatm_fLow; //最低 low
' @, z N) o5 P/ u+ R, T9 Afloatm_fClose; //收盘 close
" B v5 i; l5 ^' z6 Wfloatm_fVolume; //成交量 Volume
1 }. P) t# ?( Ifloatm_fAmount; //成交额 amount, E, H7 ~. D+ z
调用收盘据. o. ~( h4 ^& {( k* ?5 I
pData→m_nNumData= 变数数据长度
% v+ o/ ?. _& s# opData→m_pData= pointer to struc STKDATA0 ?6 |' {9 S$ z" w' T% M* p, R1 Y) L
pData→m_pData[x]第x个数据
- y; [( e* h- WpData→m_pData[x].m_fHigh第x个数据中的 High
$ e; X" U! W/ B# M, Y, g@@@@@@@@@@@important !!!!!!!
6 D Q, ^2 W, U# ]sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
; ]: N5 ^# @! B' ]so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
( z1 }0 B- [* _pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader6 O6 _- x7 N+ K, b J, h
pData→m_pData[i-j].m_fHighto use high" K% e: w t' @2 {$ C
pData->m_pData[i-j].m_fLow; g3 E% Y/ \2 c% K% O' H5 v0 V+ {8 I! x
pData->m_pData[i-j].m_fClose
! r; j5 A( Q0 r) ?' m, Nm_pData= pointer to struc STKDATA
7 ~; O/ Z7 o9 Q7 |0 f& Sincalling C++ dll function6 _7 }7 i* L5 k; ~! [6 k0 \" R5 M
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)% z5 I* x. @9 o8 F M3 x$ Z
touse a single value in variable ‘High’: o2 g6 L8 T9 c: N4 I) Y) V
pData→m_pData[i-j].m_fHighto use high% H) e& B& ?( \7 {5 m `: I; c. l. H
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 ; {9 U }2 p) e3 s4 G& G' ]
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2, E9 \2 L( [) s! D( F# Y6 a; F
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 31 ]6 J. D' D# d, J w- H' o& ^: E- q
constfloat* m_pfParam4; 2 Q* ~0 \- A# S
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数) s% M7 ]. K2 ^9 I$ J+ y& H
pData→m_pfParam1= pointer to 第一个(序列)参数0 I0 W+ A6 w* z; h) R$ ~& \9 x5 H8 o
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值4 L! {6 k1 N) [' k$ X8 q
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
+ E4 E. ~: \' J" R* U# ^. p: _! N% h& KcpParam[x] = 取用第一个(序列)参数的第x 个值
2 r! z" j8 E5 Mm_pResultBuf= 结果缓冲列- f( |. q5 F& O0 v+ p; ~
pData→m_pResultBuf= pointer to 结果缓冲列) H) A) S- |# I) k' L
pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值8 i1 w$ n& }5 [, `% t) r
//////////////////////////////////////////comment% n0 G. a" s+ z; _0 [
//////////////////////////////////////////comment 注解
4 Q% E/ u0 [" a* R2 i. O' k) @" [0 sconstint m_nParam1Start; //统杅1衄虴宎弇离/ A1 j. [: T! T( {, B* }" x
constfloat* m_pfParam1; //覃蚚统杅1
9 E w s/ S; } u! |+ U* G2 Q. \" bconstfloat* m_pfParam2; //覃蚚统杅2) H' y) J7 j( t e: Q) D5 l
constfloat* m_pfParam3; //覃蚚统杅3
' Z# c# J( C( K- O, j7 _constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4& N& V; ?- H* L+ A4 |" T& l
//const float* m_pfParam5; // parameters must be <= 40 I) @. F/ ?7 }5 h- @5 J& c
//const float* m_pfParam6;
0 N' W8 d( S7 ?1 Z6 ~1 s& k0 g8 w; Q//const float* m_pfParam7; + M! ]5 F' J3 C# h0 U0 E* ]
//const float* m_pfParam8;
8 u' ~% h- M$ P, M* U, f8 y8 h: Y//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&. X4 M5 b5 O/ q
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
- k3 E g5 i$ `&&pData->m_pCalcParam[2].m_nParamStart>=0)
0 z0 q; \6 f: g7 M{ a! n e9 s6 {: S* `9 a
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0
- e/ c- C' a& rintnPeriod = (int)fParam; //统杅1; g' O; I8 i1 O( U& [
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值9 @% h5 j- g, t0 Q! N
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
8 J5 v6 b8 ^2 @! fconstfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
; h( j, S( @# Econstfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4
& o/ G8 @- W X6 v//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值# N' ]0 t9 }$ ? ~
//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值# S( k) b" \1 ^7 Q4 \
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA , : K+ z6 L- f0 w6 T. v# j0 j! Q* B
touse pData→m_pData[x].m_fClose
[7 R. F/ p e5 _; }9 NpData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; # J; A* {, P* n$ [/ o0 p6 X& Z4 @& @
|1,2,3 , … , m_nNumParam | float m_fOime_t 7 W9 t+ p; l1 E. _6 C3 p
|1,2,3 , … , m_nNumParam | float m_fHigh;
0 |( P$ Y( k5 F) P/ Z9 N" Z6 v.. .! g8 K1 U0 i5 f9 u6 F* Y
|1,2,3 , … , m_nNumParam | WORD m_wDecline;. s7 W8 q$ \: r# q
m_nNumParam= 数据high,close,open,low的长度0 }6 A8 U0 G, f' V5 g* z
touse high:" x; I. S" s5 M; X0 U: H l
pData→m_pData[x].m_fHigh% j" {2 D3 D+ }/ a
contentof struct STKDATA
7 c3 F1 ^8 Z& |time_tm_time; //时间,UCT" E4 S' S! w7 [2 _# M4 ]
floatm_fOpen; //开盘 open
# O# p! X. \0 S: n7 ]% Sfloatm_fHigh; //最高 high, e' q' W* q& E: ]0 g
floatm_fLow; //最低 low% X! S2 x' b. C$ w9 s: V
floatm_fClose; //收盘 close: u0 B1 e8 K9 g1 t5 _2 z: d
floatm_fVolume; //成交量 Volume$ p. h+ m. u7 o4 W
floatm_fAmount; //成交额 amount" ]& X7 w4 P/ c
WORDm_wAdvance; //上涨家数 仅大盘有效8 G: X& x3 l( n! C& W5 o
WORDm_wDecline; //下跌家数 仅大盘有效
, j# p/ I& G( t. E& @. Z# R8 w9 C调用传递参数及传回结果
. X2 @ i, T7 a4 O6 a$ v调用传递参数( ]1 i2 W0 y$ q- g
(pData->m_pfParam1 && //参数1有效Param1exists% @1 f/ [: `$ d# B) P; Z$ s2 w
pData->m_nParam1Start<0&& //参数1为常数8 S" \- h& }# P* [5 [
pData->m_pfParam2==NULL) //* \# L0 o! B: \' l" h8 D
localprocedure 定义使用变数1 X) w4 I/ A! p; v! o
onstfloat* pValue = pData→m_pfParam1; //use constant参数1, Z$ k$ z6 y6 d& y
intnFirst = pData->m_nParam1Start; //use 参数1效值起始位
5 l6 v n" j( e+ M& l8 n0 wfloatfParam = *pData->m_pfParam2; //use 参数2# |8 ~) l |2 j
intnPeriod = (int)fParam;
! Z4 C7 z' s0 T7 M传回结果
+ K& E0 @1 Q: i5 `fTotal+= pValue[i-j];- o# [( x8 I" c1 @
pData->m_pResultBuf! O2 L0 ~$ }# D! l+ w8 ?- {: k
//////////////////////////////////////////comment |