许多年以前,我曾经在
- P' o1 t% y# i: F# c( O) }7 {理想公式区发布了
2 X' H9 w: ]4 a/ C7 ~"
, A% j# T7 X! c, X- I. ]如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
6 p# }7 O- H' j4 J"' I; V0 H6 Q! e
) s( {% K$ a, L: b2 v! r4 z. A$ o
现在更新foxtrader(飞狐交易师)
9 [/ A: M: l" X3 h0 n! M2 }连结 DLL的方法' a# U" A; V% G
# K' W N0 f1 ] t. ~- b0 Lfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm ), n1 g, Y6 s- x2 Z& s
gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm ), |' _7 q. X$ ?0 f! m4 ~0 L0 V
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
0 ?/ H- j3 M/ c: t: h. wfoxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效" q& s j" F/ n9 {/ x0 `
4 e+ u2 J6 d2 `& Y1 D- M" P) w* L也就是这五个结构都能用8 _: p7 s0 j0 J7 C: f, \' }
typedefstruct tagSTKDATA
% x9 j( u: a" S. F N0 z; H' Ytypedefunion tagSTKDATAEx1 D( a B7 O3 A; T+ \. I
typedefstruct tagSPLITDATA
8 K: L9 o% M5 w. L& L% o ?* wtypedefstruct tagCALCPARAM
' n' Z# J' q" ttypedefstruct tagCALCINFO' t9 b, @0 Z" i6 i- Y
7 V; u; w- j E. N u" ]) w7 Q% q自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C- b: I* _" d) s5 {# l
也就是这五个结构中6 D z1 S3 q' S' T$ z
typedefstruct tagSTKDATA 7 D( W* w& I- n
typedefunion tagSTKDATAEx
( t) E$ o& c; o$ O$ \; X6 X0 w) Ptypedefstruct tagSPLITDATA 0 H) [4 J4 i, m. d/ l
typedefstruct tagCALCPARAM
% C% m" P$ x: \5 l$ o6 Ctypedefstruct tagCALCINFO
4 T8 b0 v) s6 U只有这两个可以用9 a8 Z% _' Y7 O4 B) @( y, A! M0 r
typedefstruct tagCALCPARAM0 @8 p/ u3 x' d. i; G5 Z& K
typedefstruct tagCALCINFO
/ c P5 I$ k; W! I8 {值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个# N( K# ^! h3 R: M+ j
typedefstruct tagCALCPARAM
Z. y4 r0 @9 d' p' y6 G例如:在 foxtrader中& H1 H" J0 x$ S/ q
MA1:=MA(CLOSE,3);0 {6 ]' n5 L/ L$ m" I# e
MA2:=MA(CLOSE,6);
8 t- N7 U' F5 g7 }MA3:=MA(CLOSE,12);
# M' h2 W) T# e; n0 _. g. t$ H3 g8 JMA4:=MA(CLOSE,24);
: \# x( Y4 Y7 _) rMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}$ x. p# Q6 v% F8 Q1 i
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个+ T2 r5 K* e0 V: ~
下面这两式计算结果相同
& g5 L! O& ?. R8 t' ?/ W/ w/ ~4 Oxx:(MA(CLOSE,3)+MA(CLOSE,6)+MA(CLOSE,12),MA(CLOSE,24),MA(CLOSE,12),),MA(CLOSE,24)/6*0.95,color0000ff,linethick2;{foxtrader 自行计算}! C' ?& `3 |& _, k! {7 a
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
) d. }; x$ [% o: N, {4 y其他例子
7 E" u; J# a! K. v- Q+ U) [oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
& _; }# b. d2 B( w& u6 ]- woooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;* C7 E) h4 f3 U# u2 L! B
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的6 J3 X) }2 z/ `, r* o* b: B
fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
. S8 g5 r! h& i8 S. i
+ W/ C% c1 T7 ~# ~
h* s( Z% g: ?: t////////////////////////////////////////////////////////foxfunc.h8 L* _0 F) T' B
#ifndef__FOXFUNC_H_INCLUDE
; I8 W% W8 d' @' @& H3 K#define__FOXFUNC_H_INCLUDE
& e$ ]1 Y& ^6 C4 G$ X3 J6 k$ \/*
. @4 [- ~$ H2 U+ i飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
5 G, G" E( k" ?( G! U1.本规范适用于飞狐交易师V3.x公式系统.5 ]1 g. \3 Q+ ]/ F5 e; C, x
2.扩展函数用于实现系统函数不能实现的特殊算法.0 @$ ~% B9 {" J' f; C/ y" M
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
( h7 x8 z& Y6 e" W& g N( R: K' K4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
1 `( E- q4 E; N/ x, U5.动态连接库名称和函数名称可以自己定义.2 c! R& e6 B, V
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
' A$ Y- H3 O R" T( D) L1 F*/ C0 o; Z) E- S, o+ m
#ifdef__cplusplus& T: [# W. e6 u9 y. Q" h) K ~
extern"C"' m# Y j0 K1 z1 t* v
{; x5 |1 @- i* ` E2 x' W% k
#endif//__cplusplus
: W' n0 X; ]5 B: ^( k" I- e/ u/ i///////////////////////////////////////////////////////////////////////////
, k* N1 e3 y( I) j" k+ c//分析周期$ G; Z% y) L" W, t- U+ @
enumDATA_TYPE
5 Z2 k9 k( g8 q8 c+ l2 m1 d5 ?{2 j- {9 l" w4 A* @8 g
TICK_DATA=2,//分笔成交
( {' h1 l/ [" r* W: aMIN1_DATA,//1分钟线
* l) o; L4 t$ X! h5 l2 SMIN5_DATA,//5分钟线 , A2 [5 h" a' U
MIN15_DATA,//15分钟线! f: u/ O9 i$ |! T5 F5 l6 D6 M
MIN30_DATA,//30分钟线4 v( M& z! b$ v0 h- @
MIN60_DATA,//60分钟线
. q! i3 V- f- ]; k& i, iDAY_DATA,//日线$ _( R- \5 B7 I9 q1 s- o* x
WEEK_DATA,//周线5 @3 _! F* j* Z
MONTH_DATA,//月线+ a5 \1 O! d# Q7 r, Q' {2 O. O
YEAR_DATA,//年线
( a$ v$ N. Q |" BMULTIDAY_DATA,//多日线
& U+ L9 y) U3 E! _5 L) A7 i: WMULTIMIN_DATA//多分钟线
! g" Q8 i6 A; x3 G/ k, T" |" U};
# H% {6 z: W! M. n" N5 [& `- m///////////////////////////////////////////////////////////////////////////
. |2 L7 J/ E$ T' H. V$ x' B7 A//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用6 I. d; g5 N0 k
typedefstruct tagSTKDATA
% U( [& }4 b% [8 M{
$ U5 r4 u; A/ z* O$ u7 r _tm_ ; //时间,UCT
t- B4 E8 i: `6 Kfloatm_fOpen; //开盘 open6 S% N4 C+ k1 `4 o) ]
floatm_fHigh; //最高 high
3 R# g5 Q1 L# L& U. sfloatm_fLow; //最低 low
4 s* H% N" g; D& x; x5 ifloatm_fClose; //收盘 close
8 C2 p& K4 {0 @floatm_fVolume; //成交量 Volume3 H* W* D6 Q+ e9 H
floatm_fAmount; //成交额 amount
8 z r! D" n. ]0 J" L: vWORDm_wAdvance; //上涨家数 仅大盘有效4 _& \ L& O) E5 E" h z# g
WORDm_wDecline; //下跌家数 仅大盘有效
6 L4 ^' D3 V. a- D}STKDATA;: [" n, W5 B5 E: O
定义STKDATA为 tagSTKDATA的简单别名,STKDATA
2 J2 M! l3 D& F为真正方便使用名称,tagSTKDATA 为定目的的过水名称
1 h }5 [3 V8 k2 ^' a5 C1 F [. I////////////////////////////////////////////////////////////////////////////
1 J' x/ ?/ k2 r. H//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
) G8 q0 [1 V! [( Wtypedefunion tagSTKDATAEx
' Y6 M9 b, p3 j{
2 p+ H8 E. }' L+ W0 fstruct# b; w. }7 S- a `* k6 l9 a' L# j3 r
{. l) Q# Q9 o0 Q- [; b2 R4 m9 `
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open
" j4 Q8 M: V; X0 l5 a# s x. Ofloatm_fHigh; //最高 high
6 V& d8 A) W5 Y6 j5 }floatm_fLow; //最低 low( r- y7 U& g' F! E
floatm_fClose; //收盘 close
9 m) e" \8 H% c1 S9 y$ `. \floatm_fVolume; //成交量 Volume) F: c, _1 o6 A
floatm_fAmount; //成交额 amount: A" Y Y7 @' ]$ T$ K
floatm_fBuyVol[3]; //买1--买3量2 B" q9 E" ~- R" G' v
floatm_fSellPrice[3]; //卖1--卖3价
0 U4 }. f1 h3 N' R# _9 o% Wfloatm_fSellVol[3]; //卖1--卖3量
3 ~) X. h5 d* Q. B. A: F};& y1 C% {5 I2 n; P9 x. {2 w- g7 M9 k
floatm_fDataEx[12];
9 e+ o- a/ b# b% |. S}STKDATAEx;0 |- X, T3 P) s. a. q& o0 z7 a( f
////////////////////////////////////////////////////////////////////////////
1 b6 j! u4 \1 B$ I" \& G0 Z8 x8 z* F//定义取用除权数据的结构( x( v' l3 O( C( C# T
typedefstruct tagSPLITDATA
0 b4 @! I# B8 v% m }{
: g4 k, `- E$ F4 i. |time_tm_time; //时间,UCT1 H) ] \6 a. E9 }
floatm_fHg; //红股
# d0 F6 D( p! e# _- d6 K; j$ Afloatm_fPg; //配股
+ o& U+ `8 h' D8 u- Y# |, Q+ ?; dfloatm_fPgj; //配股价; h, ~* ^0 l v) b1 {# S5 n$ ]
floatm_fHl; //红利
6 H2 ]" _1 k8 b2 O4 F' H) e}SPLITDATA;
: n2 s2 b. v% s/////////////////////////////////////////////////////////////////////////////- p7 q+ D7 o2 p R' g \5 }+ m5 n
/*财务数据顺序(m_pfFinData内容)! f3 P' L. T) I6 |/ B7 ]
序号内容
: ]- |6 n9 V* ]0 y8 c0总股本(万股),9 J5 x0 w4 N( r6 H. Z- M9 H/ O4 a
1国家股,
8 V+ ]$ k4 ^: H! x; H' c! B7 Z2发起人法人股," E; z; L. q+ T( V9 x, x, A0 D( x
3法人股,$ V3 s7 e9 A$ \! Q4 ]2 u1 B% |
4B股,$ F5 @! x: u1 n
5H股,; C' l8 F" A$ Z8 s6 q5 X! C
6流通A股,! N7 W. l: R1 |/ A% R
7职工股,8 P- n6 A O8 a& z
8A2转配股,& |6 q# G1 ]/ r! ?
9总资产(千元),
5 G# k8 Y1 \3 T+ M10流动资产,# d0 @8 z& Q. i+ g# X
11固定资产,4 Y P) ]4 J+ N4 W8 W" k
12无形资产,
0 U" V! O2 ~: C13长期投资,
: ^3 O) p2 n: g14流动负债,
/ K; c# L/ |; g. A15长期负债,% c F( O) n, c6 O8 K; }
16资本公积金,/ D' n! Z0 w9 Z; K( m9 O
17每股公积金,
3 I& N0 M. l* A4 X7 M% Y18股东权益,
- M2 m6 H& D5 A# [- L19主营收入,3 ?7 h) z3 U9 {2 }
20主营利润,+ p" @2 a D8 |' s
21其他利润,
( c# t: H$ }. y5 o; g9 W2 d22营业利润,
* Q3 M+ }" k1 V2 s9 H' p23投资收益,
' g3 W/ J; J* u! r24补贴收入,
% Y' Z0 D& j9 @9 i+ A25营业外收支,5 z3 }- Z) h% j4 f1 f' m0 S
26上年损益调整,
. g/ M6 i) n* t27利润总额,
# t7 I) b, b, L7 p/ ~" T28税后利润,( G# \ s. Q8 Q2 v% z
29净利润,
( {* A* P2 w, C. A7 Y8 N) T+ l30未分配利润,2 J7 U( a5 F4 y5 A
31每股未分配,) Y9 Y! w0 |9 ^+ x3 D2 [: K
32每股收益,
* e5 ?% g! |: v$ ~8 H! b( S33每股净资产,
3 J) U1 a+ P- I9 j8 s6 t9 k# z34调整每股净资,
! O) e9 v$ N( [ y; j9 d35股东权益比,4 T; n/ b4 e' s ^# t9 g& T
36净资收益率' \# j+ R4 n( a+ V0 _ h
*/7 q; l2 g \( c
/////////////////////////////////////////////////////////////- g1 L9 |9 f. G! F1 k
//定义取用caller函数传递参数项 的结构
) O5 e5 F1 _' g+ }" }1 ctypedefstruct tagCALCPARAM" U# G) V5 Q4 Q! S2 \2 w6 i0 S4 W
{
% s3 N9 d- p+ \union
9 w5 T" d' G5 b: s! K{' M. f/ `% O- Y: _
constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/22 w P2 K) @( M7 e7 V7 o8 i
constfloat m_fParam; //数值参数 valueof parameter6 S5 e0 E5 |9 n/ \& Q' E$ W) D
};
' M" u6 Q- V/ v3 B. Econstint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2...../ W3 {4 c3 Q+ t2 p; @
}CALCPARAM;
" n% }' |' s: E, r, J# r F/////////////////////////////////////////////////////////////////////////////" P4 y% w0 j5 O4 N: }& a$ R' p
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )
: v& N0 V/ w8 j# Utypedefstruct tagCALCINFO
4 ] b* B& I5 i7 u1 z4 y4 W{- M6 {/ ~2 L% u3 _: |$ F- u
constDWORD m_dwSize; //结构大小
. I4 G0 V9 ~) HconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
$ C3 B; c) b- K) L5 rconstDWORD m_dwSerial; //调用软件序列号
$ \8 B3 v; w1 V% y3 Oconstchar* m_strStkLabel; //股票代码
5 j, N3 I+ @) @2 i" w6 p' u6 o5 {7 nconstBOOL m_bIndex; //大盘
8 X" T* t) M4 C5 I( }4 Zconstint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度' K* D$ T b$ d3 A# Q7 I+ F
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
, l1 S t9 y$ `3 ?% c& XconstSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
; B; {& b3 }' a) pconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
: _! q& L" k2 T8 @- O. R: o" zconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 ! q0 O6 T. ^3 ]( B r$ F" \, Q1 R5 D
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
H* C6 b, Y- \# N8 t2 Aconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3" M0 H; J6 I' a
constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4* i# J7 t$ @! }+ w6 T: _3 x
float*m_pResultBuf; //结果缓冲区7 A0 {! {7 h: |. l7 {* N
constDWORD m_dataType; //数据类型% r, o+ k, R. I6 U/ I L
constfloat* m_pfFinData; //财务数据: h5 G& y5 u* `: [4 O
//以上与分析家兼容,所以沿用其结构和名称
2 |- |* t6 W0 l ], V& r//以下为飞狐交易师扩展(fortagSTKDATAEx)
2 V/ c) e9 J' ]1 b5 QconstDWORD m_dwReserved; // 保留4 j! t9 k7 Y: y
constint m_nNumParam; // 调用参数数量
6 W" J. x3 g1 |9 wconstCALCPARAM* m_pCalcParam; // 调用参数数组
0 {. R4 [8 g2 pconstDWORD m_dwReservedEx[4]; // 保留& x2 ^- {" T5 Y8 q' N7 L2 X
char*m_strStkName; //股票名称
M/ a% b8 K& l2 ^5 R0 D- O2 jSPLITDATA*m_pSplitData; //除权数据2 S, H1 }7 [# w
intm_nNumSplitData; //除权次数
5 F* C. E- z, @, u% I}CALCINFO;5 V; a" c' h3 }6 o4 c! I) \
/*
; s& M6 m0 j6 D% L" y$ f$ p$ h注1:(与分析家兼容)
! F3 H/ n+ L* a+ ?, [) Z) U1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.
3 T5 a! ~" W! P1 ]6 n2.当一个参数无效时,则其后的所有参数均无效.
" u( V/ c( X+ W; [" P如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.! f* S# o3 w. |
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.; |; k, p% E- k `( Y
4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
% u* r1 y* q$ c5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
# c- {8 l% [/ x, J数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.% F2 K3 U4 c+ y7 w; `
在时间上m_pData[x]与 m_pfParam1[x]是一致的
t9 c3 Y+ Y+ ]1 _9 H. Y: H注2:(飞狐交易师扩展) M' ]' D3 R P8 w0 b
1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。
7 {2 y. `! v5 G) ~. q @2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
# ]+ e) d$ s/ R2 [6 N+ h: L3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。$ y3 k: g, T; z+ r
4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.( w* N7 g! g9 n/ q5 |0 `
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。. h4 z5 Y. `' z0 T- e+ ]
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
# l- f( Y6 o n% |7.经此扩展,对分析家的DLL依然可以调用、兼容。
; G! l6 R3 i" f1 a: P _, E3 l*/
5 U5 s8 v; @! D9 A( f6 }- Q///////////////////////////////////////////////////////////////////////////////////3 H( y9 v7 n C ?4 L$ c
/*函数输出
8 u6 ~: [1 t. U5 e__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);
0 F1 {# G E# `3 N1.函数名称需全部大写.
) ? y( U: I0 z/ c9 D) q' Y1 H+ {2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
o# z4 @8 B: x8 b对于C++程序还需包括在extern"C" { } 括号中.
: `+ s5 O" _0 R* x K) E" m, B. c3.函数计算结果用pData->m_pResultBuf带回.
4 A* f' T" W8 A: w8 g- Y P& R8 k6 r, t4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
9 F0 {+ T3 k# S8 U$ F! mm_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.4 V6 M% `; H5 v2 N+ X. ?
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
' C. i7 T! I+ i2 w5 r0 t! P6 n*/7 a# ~/ L1 e" K# G1 P
//示例函数,使用时用实际名称替换
, ^/ F' l7 P. x2 a+ G__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);
0 L3 D2 i) S0 D" y$ u9 L/ V" _/ P__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);7 d! N+ }8 Y6 r
//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);2 Y7 s4 k$ n% `+ o5 i0 F5 ^! X
__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
6 k# K/ H" B6 ]0 ~9 O: n//WINAPI = _stdcall
; W& O, _* m) _#ifdef__cplusplus
" d* E K8 A v. ]# m/ `0 ~ s& _}
; _! ?3 }( T) j! e( M! i* c#endif//__cplusplus
8 @; q+ \) ]0 Z% a: X, ?#endif//__FOXFUNC_H_INCLUDE+ Z. j1 _# }: F0 s5 D8 |
! X& D2 r9 m+ I+ N1 n& ?+ y, H//////////////////////////////////////////comment 注解* v& M/ O* H5 b/ d1 u9 l4 o' C8 G
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)/ G. x" ~1 y9 Z8 c( K( \1 C# l2 v
pData是指向 址标总结构 CALCINFO的 总址标
( Z! O3 @4 }" H取用第二个参数数值floatfParam = *pData→m_pfParam2 ' d+ W0 [# I2 X$ ~- k b. B
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;' O( r& M2 m6 @: }
取用股票数据长度intndata = pData→m_nNumData;4 W% z0 M- P( d: [8 P* v
第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0+ p# r, |7 ?1 s9 D* K& r6 ]) R- g
第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
n4 S1 \" y* a K2 k1 X/ U第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
p2 d" Q9 A' o2 Zconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
+ s+ f6 S n4 E' w' O0 B取用股票数据结构
8 n7 y7 h( t) k( zpData→m_nNumData= 变数数据长度* R, J* z! a9 W4 a! `
pData→m_pData= pointer to struc STKDATA 的址标
. J) e5 g& V! N4 d; p( HpData→m_pData[x]数据结构的第x个数据
- _8 ~* V7 E, I* r, _+ }pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
5 `" s/ i$ m9 v- f' E4 G7 h5 n4 n$ H取用结果缓冲序列
0 x" o2 x+ X6 a6 I7 U' x" x; k/ JpData->m_pResultBuf
/ }" }1 v6 q7 r9 M( F! }) p, ~取得第一个序列参数的起始序位,如 2,...5 , . 7...
; K& c% ^! U& UintnFirst = pData->m_nParam1Start;
* }+ a& I/ F/ A. ?for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
; }0 _4 b5 l) i取得第二个数值参数的数值/ Y5 s; _) ^& `5 G: }: h
floatfParam = *pData->m_pfParam2;
) Q n$ C8 A& y4 IintnPeriod = (int)fParam; L; w( l) E5 T) D0 n, f5 F/ W3 V7 v
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;
$ Q& A7 u/ ]/ j" p% K取用序列参数的单个直pValue
$ T6 U# {! _& v6 N( f; f取用缓冲序列的单个值pData->m_pResultBuf* j- N# K8 e4 {7 S/ |3 c0 M1 U
constCALCPARAM* m_pCalcParam; // 调用参数数组
+ y$ O( [6 D4 K4 J Ym_pCalcParam为序列址标,指向各序列参数的指标) j e2 n5 o! u1 h" m8 V
第一个序列参数pData→m_pCalcParam[0]
) O w2 J* X* p0 O: Bconstfloat* m_pfParam; //指向序列参数的址标
6 p' O: @+ F$ j1 x: @' N+ q第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
' J) p0 k3 F6 ?2 x* z, v8 Z0 S第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;7 t1 ]: [0 T6 C, \
取用第一个序列参数的单个直pValue1
- T9 _9 I0 X9 W$ X m+ m第二个序列参数pData→m_pCalcParam[1]- H: X& `$ O" H5 U! u
第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart7 u% y1 t) p4 C
第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;& K3 u( S: c, x2 ?$ x, x4 K
取用第二个序列参数的单个直pValue22 y3 i+ I& E0 A
第三个序列参数pData→m_pCalcParam[2]
. \, g/ g7 ?) X# z; R& V- a1 N% s. k T第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart/ D; w' k8 L/ [9 M7 M3 ]2 N, k
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;( h( B$ w4 H. E
取用第三个序列参数的单个直pValue3
2 @# k, l5 f- q: @3 s第四个序列参数pData→m_pCalcParam[3]
1 p) c4 B! M7 C$ |1 l7 H; R第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart' A* v. h, v% p2 H j$ }1 r# q; o
第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;9 T8 }, |# ?0 s6 g# ]7 m# s! x2 G
取用第四个序列参数的单个直pValue4$ X5 l6 S# v, n$ Q/ m8 h
如果有四个序列参数,则取用序位最高的那一个序位
/ N" y" e& q' U# e2 H2 Oif( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
0 N, x( A* j. p }' wpData->m_pCalcParam[1].m_nParamStart>= 0 &&1 k1 E" a1 x. _) [- |) V
pData->m_pCalcParam[2].m_nParamStart>= 0 &&- J' ?- t+ M8 n( F/ m
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值9 A. M9 O! H( N- a/ z/ \! G+ ~
{
* W$ |2 g6 J! g. t//计算返回的序列的第一个有效值位置( x( n/ w. b ^% j/ }
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
- G; ?8 l* s* {# r! P% H, H5 U' O8 c//若不知,则
. j, B0 n7 U7 Y% z# @6 H/*1 I6 l7 U2 F: w: q8 X
intnFirst = pData->m_pCalcParam[0].m_nParamStart;. o% f) {3 a3 R4 Y) `
if( nFirst < pData->m_pCalcParam[1].m_nParamStart )
5 t9 l0 f2 N2 e' w2 W5 D! xnFirst= pData->m_pCalcParam[1].m_nParamStart;9 }, K6 P2 O% p q
if( nFirst < pData->m_pCalcParam[2].m_nParamStart )
& L) i. m8 L! i+ G" `& P8 CnFirst= pData->m_pCalcParam[2].m_nParamStart;
; _8 @- a7 n2 x# gif( nFirst < pData->m_pCalcParam[3].m_nParamStart ) - d3 |+ _, t8 i# z( Y
nFirst= pData→m_pCalcParam[3].m_nParamStart;: ~: Z% A" [4 h& f' [- S- i
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;0 I; s9 M1 i9 c- [
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;8 J: R' G5 P* }: m: h
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
1 p1 O5 H6 R6 e7 i2 hconstfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
! O- J9 r1 }% ]7 `5 R! H//-------------------
0 `. l5 a* X, Z0 Q8 l3 S' c1 lfloatm_fOpen; //开盘 open
& s* e d! _# j; x" t9 P7 j3 Hfloatm_fHigh; //最高 high
" l! y& A' h- v# B& @. [floatm_fLow; //最低 low$ ^) J! V7 t: c! H9 Y* b
floatm_fClose; //收盘 close
, J- z% S1 e, g& a4 Hfloatm_fVolume; //成交量 Volume
" f* g& A; \" u6 O" E6 _0 x$ c% F, Hfloatm_fAmount; //成交额 amount
9 K* F) r1 d3 _9 ~调用收盘据
$ t! c9 ^0 R+ _. ^) K7 RpData→m_nNumData= 变数数据长度
( i1 k/ h; U2 Z9 ~pData→m_pData= pointer to struc STKDATA
- c0 a# M$ w* U$ upData→m_pData[x]第x个数据' L4 n/ G% L5 p, g: O' S' C$ P
pData→m_pData[x].m_fHigh第x个数据中的 High
$ ?2 f+ R9 O' C2 c@@@@@@@@@@@important !!!!!!!' k/ d/ E$ X9 w4 d' p
sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
2 Q+ u- Y. Y; P" i% s2 Eso,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
' J( L9 y6 k" L+ W9 A+ opData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
9 b8 v( k, t. g" spData→m_pData[i-j].m_fHighto use high
/ D/ e v% j& j9 ^0 N. C+ R6 x* epData->m_pData[i-j].m_fLow9 i: ]3 p: T* Y7 D8 I4 j
pData->m_pData[i-j].m_fClose
. f& F m% ~( ^0 ~" w em_pData= pointer to struc STKDATA0 u; d! c& b5 x9 J
incalling C++ dll function
- E6 \7 B+ l. b7 z5 R: Sm_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)
# s, E' d1 _( k6 \! Vtouse a single value in variable ‘High’, Y7 U! F6 w: T9 |) Q# L/ c
pData→m_pData[i-j].m_fHighto use high+ h/ @8 Y, t' S/ m+ M1 H* l+ C
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
8 J5 A& N% X0 Mconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2' W& E0 J$ [# O/ B& O% M y
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3: u! |' {5 [+ l R
constfloat* m_pfParam4; 4 c7 A4 o. R3 h0 g
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
3 p( h3 D1 R9 R4 _7 s( qpData→m_pfParam1= pointer to 第一个(序列)参数
' T9 }1 E) A5 j9 J+ u4 p9 Z2 H, _% QpData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值# w, f, ?8 V& V; a" o! p
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
1 a7 F9 M- d2 w, K- e- UcpParam[x] = 取用第一个(序列)参数的第x 个值
8 I. g8 C# O) Z$ ?0 S! b7 b& um_pResultBuf= 结果缓冲列3 Q5 o( ?: U6 @2 Y$ D+ C
pData→m_pResultBuf= pointer to 结果缓冲列
4 ?% S1 k- P- M7 j3 y* T8 ppData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
; G: e. a! s8 G# e! ?! F//////////////////////////////////////////comment' P) K0 N) P. x9 H0 d
//////////////////////////////////////////comment 注解
# o+ {& I+ N) h; Hconstint m_nParam1Start; //统杅1衄虴宎弇离
- M% c5 G) s0 M/ m" | Kconstfloat* m_pfParam1; //覃蚚统杅1
6 {9 c3 P1 o5 ]+ Y* j1 o" D- |constfloat* m_pfParam2; //覃蚚统杅2
* C% c; x3 ~1 jconstfloat* m_pfParam3; //覃蚚统杅3
; j; t4 C# q* _' p1 {8 U1 Sconstfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 48 C# r4 s3 V5 l
//const float* m_pfParam5; // parameters must be <= 4
8 m1 n' x! U. b9 r4 G5 E//const float* m_pfParam6; , l7 D$ \+ t& [; U4 b/ \4 A
//const float* m_pfParam7; 5 Y. K) |4 [8 A% F
//const float* m_pfParam8;% }" J2 E. y. k! b9 ~ ^
//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&6 Q5 T# V: ~! p2 _
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
* w: E% {/ c% s4 ]: w& i* L3 @, R$ R&&pData->m_pCalcParam[2].m_nParamStart>=0) Q, S9 Z) n( T" j+ e4 R
{: z4 |- b1 @% r- f' Q" ^
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 07 g! k2 t5 {0 e; C% I! {7 v5 ^8 i' w
intnPeriod = (int)fParam; //统杅1
4 c1 I3 x, g8 [$ A( `1 v2 p; N) B//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
: i( c7 A7 _) N# V$ O( C7 O( ^constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
! j: X3 s/ l2 v& c' c2 F, }constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值/ s6 A) L! u H9 q2 Q$ n6 L3 e6 f8 T7 J
constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4* s- a. U) A& a; x8 z6 H
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值. {% f; Z; } [, }: N
//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值4 }3 @8 p$ U, c& I* m8 k$ |- l
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA , $ G5 I: i$ L ~) f; T8 u8 _% \
touse pData→m_pData[x].m_fClose3 D* L% v. X9 I4 h, E0 w
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; H0 _. O0 q9 v, E6 Q& P
|1,2,3 , … , m_nNumParam | float m_fOime_t ^& n* ~/ {' _, g) F' a1 w$ x
|1,2,3 , … , m_nNumParam | float m_fHigh;
( A! e; J; _! ~; v/ @8 p.. .% `( m. `9 G& {! Q$ ?& E3 G
|1,2,3 , … , m_nNumParam | WORD m_wDecline;
( M$ F) U& }: v. c8 h: Xm_nNumParam= 数据high,close,open,low的长度! Z/ c1 y! Z8 o& `* @% X) o
touse high:- h8 e8 ?% D5 x4 U3 J3 S
pData→m_pData[x].m_fHigh0 [: ~- i+ V: q7 u
contentof struct STKDATA
& l2 {# X. e0 _! Utime_tm_time; //时间,UCT$ G/ b; w" q T# n3 \* c
floatm_fOpen; //开盘 open) q s; ]6 v: s( | y) }
floatm_fHigh; //最高 high1 {2 m: X v: ^8 i
floatm_fLow; //最低 low* G* _. O& B5 x$ b6 e
floatm_fClose; //收盘 close
- \! q$ {3 i* lfloatm_fVolume; //成交量 Volume
; m8 }- h7 t/ O9 w2 Tfloatm_fAmount; //成交额 amount
9 B2 X" ~2 ?& u1 [# W0 n8 GWORDm_wAdvance; //上涨家数 仅大盘有效
) z+ N3 _5 P3 p3 O& [( U/ C* xWORDm_wDecline; //下跌家数 仅大盘有效; m h! A8 ^& \. t: c$ d
调用传递参数及传回结果( \' E7 m/ A" y# Q5 \
调用传递参数
0 k3 M) f" h& ?, _5 @: l* T2 ~$ w: p7 u(pData->m_pfParam1 && //参数1有效Param1exists
/ Z2 p1 L2 i7 l7 [pData->m_nParam1Start<0&& //参数1为常数+ Y6 {0 D# l3 D( ?$ V# J+ O
pData->m_pfParam2==NULL) //
) }' c- F8 {4 v* @% Ulocalprocedure 定义使用变数
4 e' P* }+ F! {onstfloat* pValue = pData→m_pfParam1; //use constant参数16 m1 m w; _2 n6 `% j8 ?
intnFirst = pData->m_nParam1Start; //use 参数1效值起始位
( w5 h* x3 u2 ?1 G+ CfloatfParam = *pData->m_pfParam2; //use 参数29 `- U5 H& j# A/ E" _
intnPeriod = (int)fParam;
" }9 z! `$ D' j7 m" R! `3 `传回结果9 x' Y$ c. O( x; K ?
fTotal+= pValue[i-j];
3 o, ?& _- I" |7 z2 HpData->m_pResultBuf$ {3 i% A; A r; ~* m! o
//////////////////////////////////////////comment |