许多年以前,我曾经在
( }# N/ w* z8 \) E: r; Z2 I& e理想公式区发布了
6 K" [4 ~( ^3 U$ y7 p"# W+ a* F" d' }! e2 j
如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
3 u/ |- r2 f* }9 O; @0 U( _ F"
- g# o- ^7 t) v9 v- K
! I$ X3 \8 k1 b1 L现在更新foxtrader(飞狐交易师)
. U# o5 {- w2 y连结 DLL的方法3 W: z8 D% U' l' ]' [1 S) ~: Y
- ~+ d- c& }$ ?! O. Q
foxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
# d8 w7 x6 \3 |# |* T2 ~gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
8 ^' o$ J5 _( B$ {+ D( e3 r4 ^5 Sgauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
# k& x) O: J+ S$ r0 @foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
/ B- |1 }, x4 b. [( [( G7 z6 d" m
- t0 o$ E: w5 W) P; d也就是这五个结构都能用
2 D6 i' W, Y C( ^typedefstruct tagSTKDATA
+ A; b* t9 R' U/ L% ?' s' xtypedefunion tagSTKDATAEx
' S @% B6 \! g. r6 dtypedefstruct tagSPLITDATA - O# d# d* w+ u5 ~9 |
typedefstruct tagCALCPARAM
. r. w) Y5 P$ c6 p5 j& [typedefstruct tagCALCINFO
3 h/ A Q$ c9 {/ N \
* q2 m2 l% n. ^/ V8 y; q自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C0 x) t& `) ^4 P Q- a
也就是这五个结构中, C: u: F" T4 Q; P! p0 ?8 b
typedefstruct tagSTKDATA
c5 E2 e* V" N/ i6 r' x( Dtypedefunion tagSTKDATAEx6 q$ p0 ^ A: I
typedefstruct tagSPLITDATA 0 d+ K7 L) S6 ^4 j( k
typedefstruct tagCALCPARAM4 z) ~2 I4 s5 m T
typedefstruct tagCALCINFO" V( W& v$ s2 m/ B+ ^
只有这两个可以用
8 d! Q6 b2 u8 T5 w: ~1 i" x- qtypedefstruct tagCALCPARAM3 U1 s; c% R t7 j0 H) `% V
typedefstruct tagCALCINFO4 T# z, N" B- t! F5 A
值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
5 B+ j! ?- [3 U/ L( g3 g( Ntypedefstruct tagCALCPARAM
! w4 E E2 _) x; a例如:在 foxtrader中
2 U" }5 T4 x/ l0 K3 hMA1:=MA(CLOSE,3);
) a* @4 t# A% j: c& b% S' {: WMA2:=MA(CLOSE,6);6 s4 L: V' _% r. o. Q6 Q- P2 l
MA3:=MA(CLOSE,12);9 j: d \. \: o8 `* V9 P
MA4:=MA(CLOSE,24);
$ b% {, w) [( V. x( ]6 P" RMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0} s7 z* M* y8 T8 O8 v$ W
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
, _' _) y0 }3 h- e下面这两式计算结果相同" V) H0 e' y) S3 B# j
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 自行计算}
9 R& j: A7 E. G7 ]; A. fMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
" q$ @0 }& N: ?8 \其他例子
; a: R0 t( J8 J& Z* f/ l# soooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)! ]0 d1 ^# T) j1 q `! w E5 A7 Z
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;- r" D- S. v! ~5 F5 S7 F
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
' i3 M( H, ?6 E, u: D3 E2 mfTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误+ n+ e4 ^/ S/ y# U
" m& c& t- x+ f b
* y; G* X& c, }////////////////////////////////////////////////////////foxfunc.h
9 ^& \3 A& b% x$ D#ifndef__FOXFUNC_H_INCLUDE" Z& f5 S y, j9 T# `
#define__FOXFUNC_H_INCLUDE- S* t9 }: a5 p$ P$ r
/*) T/ a# J& @( L. e5 i
飞狐交易师“C语言接口”扩展程序调用接口规范V3.0# K& ~1 ^1 B" ?, B
1.本规范适用于飞狐交易师V3.x公式系统.% u( F ]. [- V& I* L
2.扩展函数用于实现系统函数不能实现的特殊算法.
- y0 j; @6 U" `9 l7 \. e- o3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
8 d: a/ h( B) f; K7 v( U1 ~4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
8 a, |8 I7 N, g, m: s5.动态连接库名称和函数名称可以自己定义.+ N u L/ ~" [0 S1 m3 l- q6 n
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.$ P; ?- p8 m9 p' w. @
*/" w4 N* t* ^5 Z2 o; Z
#ifdef__cplusplus8 V. g7 c6 \, m* G; F5 {
extern"C"
7 `& X6 F" J* a0 r' J B* W{
C2 X" t' L0 c/ b o#endif//__cplusplus9 Q7 F7 m( i! v. y+ ~
///////////////////////////////////////////////////////////////////////////5 Z( J% _0 A% k; ~* Z3 I! S7 _" l% `
//分析周期
2 \/ p. |, h. VenumDATA_TYPE
9 C$ ~6 x# @+ [, J; ?{
# W$ a* Y1 I' X! C6 f. HTICK_DATA=2,//分笔成交
* j; T/ l9 J: p; k5 |# j: IMIN1_DATA,//1分钟线
' I( P( C* `, ?! A+ FMIN5_DATA,//5分钟线 k. [: n" T5 @! A- c8 V/ Q3 m, B+ u! B- c
MIN15_DATA,//15分钟线
Z' o9 f' W$ y9 B4 C1 k2 jMIN30_DATA,//30分钟线3 D& \) X; j6 R! s, l ^$ R/ V4 \
MIN60_DATA,//60分钟线
2 N" M* A2 u8 L, uDAY_DATA,//日线3 S( z9 @& X! k' f' t
WEEK_DATA,//周线
8 t3 |: _. G6 K/ q! W0 ZMONTH_DATA,//月线
0 V8 E5 b: Q; k" f1 S; XYEAR_DATA,//年线
1 v* v9 x5 a1 q3 t: mMULTIDAY_DATA,//多日线
( u8 I& r( o i n* IMULTIMIN_DATA//多分钟线+ y+ V6 N( p0 `. e7 }
};' |2 e. I, ]0 ^. P( c
///////////////////////////////////////////////////////////////////////////
$ d2 c6 A3 f" t//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用: d, }' V' l5 A- d( j6 U
typedefstruct tagSTKDATA
( j) I3 {* O- V( z9 B# x{% k. Y5 |$ P I9 V
_tm_ ; //时间,UCT
9 l% y, L7 V& m( |1 sfloatm_fOpen; //开盘 open7 E; t0 V4 e# E( P# U, d1 v+ ^
floatm_fHigh; //最高 high
+ A8 c* h8 V' S4 ~floatm_fLow; //最低 low! Z: F, ^" J; ~4 F* c+ s: y
floatm_fClose; //收盘 close
y+ u& N7 O) H- u2 X5 Y2 lfloatm_fVolume; //成交量 Volume% M" T" y; X& X
floatm_fAmount; //成交额 amount& C1 w$ t8 c& g5 d) l: V* ~7 \1 {& p
WORDm_wAdvance; //上涨家数 仅大盘有效6 W6 X' p) y8 |' u
WORDm_wDecline; //下跌家数 仅大盘有效
6 w1 k$ {- A* s: \}STKDATA;
. M, F6 |/ }, j/ f y2 k0 Z& l定义STKDATA为 tagSTKDATA的简单别名,STKDATA
$ M3 W( O; F7 Q* J2 k& w为真正方便使用名称,tagSTKDATA 为定目的的过水名称
! i4 c6 J+ c- |# E" x////////////////////////////////////////////////////////////////////////////2 I1 a* u$ J2 t }2 z1 n6 M
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构& w2 i ^- K- H+ z5 x2 m
typedefunion tagSTKDATAEx! a5 R# K2 }+ Q0 Q: R. q4 U/ P/ L
{# R# I1 X, i" g! b' `
struct
: B8 T7 t& H4 j' f( f{
# l' G9 F- {5 r Z* ofloatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open
: V7 b5 q& ?$ f% ~9 A8 }& sfloatm_fHigh; //最高 high
! O; S6 f% G. c9 zfloatm_fLow; //最低 low
* b+ Y V6 k, j; Y& }0 Ifloatm_fClose; //收盘 close3 Z# R, w3 B. F! I9 m1 w, V- f
floatm_fVolume; //成交量 Volume
# |. x' V! B: ^" l" mfloatm_fAmount; //成交额 amount
3 `( B) n2 t) n( V5 Ufloatm_fBuyVol[3]; //买1--买3量
+ M4 q) F% x+ Y e, \/ Efloatm_fSellPrice[3]; //卖1--卖3价
( ?0 l1 V; A. jfloatm_fSellVol[3]; //卖1--卖3量% I3 `$ g% s! K9 j6 ^' _6 v6 R
};( ~, d. B* P" k
floatm_fDataEx[12];
9 ?3 Q5 [' N( ^6 S' @; L}STKDATAEx;
Z" q6 h, o% v X$ x' j* l////////////////////////////////////////////////////////////////////////////
9 G- M- {! L+ }, I1 D2 l- y//定义取用除权数据的结构
3 [% M/ u, w3 q: z+ t5 Ltypedefstruct tagSPLITDATA 6 C R2 B$ U, P5 d2 J$ O
{& Y5 {; ^4 J4 f; s4 I/ O
time_tm_time; //时间,UCT6 ?) k/ w! A$ d) w$ m {% K
floatm_fHg; //红股
& k# z" z5 S0 z E- ]6 i/ Hfloatm_fPg; //配股
7 }' T+ u5 w7 h6 U' L; R: Pfloatm_fPgj; //配股价
9 m2 ]7 c, F% H+ t. x/ C7 m$ S- Gfloatm_fHl; //红利
2 T$ `% I2 _( J" E% N}SPLITDATA;
" L; k! L7 f( v' W/////////////////////////////////////////////////////////////////////////////
$ v! N4 O$ N' V' J* L/*财务数据顺序(m_pfFinData内容)* U5 o2 H3 A( W% L3 [
序号内容+ L# w1 J k) {
0总股本(万股),% o) s' a- _% m! O! Q' B, z
1国家股,+ e+ h7 v" W" c. d- ~/ b+ }% [
2发起人法人股,
0 C6 X8 m8 R5 }! m3法人股,' v5 `/ s8 p# x% L
4B股,
- Q: A$ w3 v& n- Y- r6 Q a5H股,& _# {# M2 I% i0 T! b3 V
6流通A股,
2 ?" t2 V) i* k7职工股,+ K' }+ V1 I* U" i: V
8A2转配股,
( _6 S% m- C. J' S" B; G9总资产(千元),+ v2 u# x. ]4 B% ^+ j$ R
10流动资产,
3 P4 F* K) F" Z11固定资产,
9 Y; ]3 k, U6 L" x12无形资产,3 V# p! m& `% X# F+ X4 w& w
13长期投资,
$ r. {/ R# j, S' L( [14流动负债,8 ?% g$ ?+ V n7 P( w
15长期负债,9 @, E6 P" G0 U f% g0 ~- |
16资本公积金,
) p8 `6 Z& i6 i7 [( v17每股公积金,
4 _; T0 F& L9 {' W* v18股东权益,1 d/ F9 b: w% |( x! e6 f( \
19主营收入,
- {; j+ |1 j) f20主营利润,
+ Q9 _1 c) K1 G! _* O- O% X21其他利润,( C+ |7 ] `. `8 R* R
22营业利润,9 X0 w1 G7 L6 F- y/ B4 V
23投资收益,
9 j2 J; N1 u/ u# y% M0 z24补贴收入,
4 W% c( H; U9 @: N( U; |25营业外收支,
8 U8 P+ w- b, b1 i7 ?/ c" N$ |7 e$ x26上年损益调整,
, o! V0 _% j' t27利润总额,
( `2 J% K' F3 q1 h+ N, `28税后利润,
& l; g: p0 }& P, o. x29净利润,1 j# d/ R Q! q$ d0 Y
30未分配利润,: ?; t8 ?# I: A
31每股未分配,
' C9 i, s8 `: J) O Q* _32每股收益,; L6 f6 y4 J4 @' V4 z+ D( I" x% q
33每股净资产,
8 t. D. U3 t: l' F! {34调整每股净资,
+ l; X# p0 ]5 D: C4 m4 |2 n35股东权益比,
0 |( e" `/ g& a0 j36净资收益率! R! S( _, ^6 E7 g% \2 W
*// T* [7 Z- ^6 t: v; d! W/ {
/////////////////////////////////////////////////////////////
; Q, I( \. d! A$ l& g" n//定义取用caller函数传递参数项 的结构+ T2 U0 ^' t: |$ H! w! m0 ^: r
typedefstruct tagCALCPARAM
7 A1 ~5 ^+ |% `) ?5 W% b' p{3 P) Z+ V+ ?/ d/ @2 N
union
8 |/ }& i9 C$ V5 Z{/ U' W+ L7 I+ A
constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
( t p( n' d& V5 E) a2 mconstfloat m_fParam; //数值参数 valueof parameter, R* g8 l9 a4 Z3 Q
};- N: t0 t+ z# @0 S
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
) K* o' @ ]- T9 y$ E0 u9 C}CALCPARAM;. Q2 ^5 z* t1 x) c- z
/////////////////////////////////////////////////////////////////////////////
( Z; m3 z- {5 c4 D+ H# T p" }//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )8 c* c2 w- A) ~" f5 R" c
typedefstruct tagCALCINFO
- S" s. J T1 O, D" u{ L& u! X$ p0 [8 g: Y
constDWORD m_dwSize; //结构大小' P$ @! @/ V1 v+ s/ E
constDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)4 a. |, M8 J0 D
constDWORD m_dwSerial; //调用软件序列号
y* j# b* b* wconstchar* m_strStkLabel; //股票代码
5 R4 v' _' t' I$ s: zconstBOOL m_bIndex; //大盘
, {: a2 e: r- `3 |6 G. I( @constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度# @+ d: W+ }& p6 _6 F
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL( k- P/ y0 U& z- Y( c" X9 u) o/ C* @
constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
/ j& C5 D1 L8 J9 @0 |$ wconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
* D2 E7 |9 H4 v: m7 [1 y9 C2 Nconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
. o Y3 Y; ^/ _5 Q& z- zconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
" `/ d+ O' H" q3 k& Q5 P+ Z! k& Wconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3- ]' ~7 q3 L5 H9 ^1 I$ S* L- N* i% A- \
constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
; H" T' O5 i8 w6 F! gfloat*m_pResultBuf; //结果缓冲区, b9 h' X5 f2 i8 b
constDWORD m_dataType; //数据类型
2 g, P) e) C/ e8 y& Yconstfloat* m_pfFinData; //财务数据
+ S4 T' y. v. l# K/ Y- R; O6 [//以上与分析家兼容,所以沿用其结构和名称
% n0 f9 a+ B& l& N. _//以下为飞狐交易师扩展(fortagSTKDATAEx) u) g7 D9 f) B6 P. q# A/ T4 G
constDWORD m_dwReserved; // 保留% t# q9 R; G+ ~% g; S
constint m_nNumParam; // 调用参数数量
& T( h. K5 `; z# sconstCALCPARAM* m_pCalcParam; // 调用参数数组
0 k% Y/ R+ w) ?& g- d3 HconstDWORD m_dwReservedEx[4]; // 保留
+ x: i, Y: Q' E& pchar*m_strStkName; //股票名称$ F B$ Y* Y1 ^
SPLITDATA*m_pSplitData; //除权数据( z8 r: R# @0 {5 x* w w- D" t; v
intm_nNumSplitData; //除权次数
& }* d% A+ P9 g" T" _' A' }. L}CALCINFO;
4 n [; o% I- \1 B" c- w" O/*
* K/ Q# P( k/ |5 G# G注1:(与分析家兼容)
9 F! W/ c$ o4 _. Y5 j# }1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.1 `* A' O# c0 _0 o4 \- c
2.当一个参数无效时,则其后的所有参数均无效.
; P/ P) Q& w5 q) d. J* _; L如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.
% `( N! k+ M3 X1 f2 Q' p' w3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
$ c1 p) s X( c9 e0 F0 n$ `4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
2 ^. p q" P) y+ T$ Z; r5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
" P- O# ^6 @9 r4 V数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
0 L1 a3 K3 d" r( Y6 ~9 u在时间上m_pData[x]与 m_pfParam1[x]是一致的/ y5 |5 [+ i; ]* C+ f
注2:(飞狐交易师扩展)
7 |% Q1 w6 \: A- r+ D, b1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。
0 A f S+ `" q- ?" I5 F' h2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.7 _ T3 ?, o2 F1 y5 R
3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
' B) P) w" M5 i/ A$ E+ e7 Z; v* Y; e4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.8 Z; d. g7 W& \8 f; ?
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。 r2 f# q1 `/ p4 j4 ]+ ], A+ e
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
6 g% a/ K, U$ d6 d7 f& G7.经此扩展,对分析家的DLL依然可以调用、兼容。
; J/ K0 e( `( j1 L*/2 y, A" \# A H6 _/ U
///////////////////////////////////////////////////////////////////////////////////
. `3 l r9 R: X" h& p& ~3 ^& U- ^/*函数输出2 N& w0 [" a3 z
__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);
9 ~ M( g3 r! \0 u' M9 @1.函数名称需全部大写.
]3 C5 z, o0 \" ?+ [+ i; E2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
# U/ @9 e1 j+ j$ z" I: B' }. n对于C++程序还需包括在extern"C" { } 括号中.! u" ^+ d3 H$ B. e
3.函数计算结果用pData->m_pResultBuf带回.) |' R3 Q0 T; n+ |- w0 N, m
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
: v! P( Q; O" ] sm_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.( `8 l* X& S# k. E
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
4 {+ J+ G+ k% C F- I' x*/# _: u2 T) T2 A$ x
//示例函数,使用时用实际名称替换
$ O& k8 Q* y) n4 J__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);1 V- u; C8 \. S
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
/ ?% R3 b, H @8 W. W( b/ g//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);. L8 ~9 H) H3 j& H' g7 I# X; b5 w
__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
. S* [9 p8 w) S$ g//WINAPI = _stdcall
, e! H' R5 }0 D, ]! y#ifdef__cplusplus
6 A6 O8 h3 M$ T% U}3 Q$ H% ~) c$ M$ _1 K+ r
#endif//__cplusplus; O. Z, }/ a; z( J# \+ S6 }. p
#endif//__FOXFUNC_H_INCLUDE+ r9 [6 K. M; K% F
8 _ _5 ~( M' A! |//////////////////////////////////////////comment 注解# ~2 U- s3 W" j w M x
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
7 Z5 V" f; Z Q6 N4 ~& M- d' S; w6 r- [pData是指向 址标总结构 CALCINFO的 总址标
: _% V8 Y0 Q" _* i取用第二个参数数值floatfParam = *pData→m_pfParam2
& |; Y0 K1 J/ [1 K/ W0 l取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;# \* E y2 l9 y
取用股票数据长度intndata = pData→m_nNumData;( r0 z6 [$ ?, _$ O- B& l
第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
0 J5 T% x5 Q" I3 m) O* G第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
d" G/ J! K: G& ~第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
* p% y7 y K+ H6 pconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标! ~+ S2 q$ x, _' x
取用股票数据结构% w# N/ I$ Z7 O" x, k
pData→m_nNumData= 变数数据长度$ }# Z" W/ W$ n5 }
pData→m_pData= pointer to struc STKDATA 的址标5 u) I3 ? W5 `0 a7 F; s
pData→m_pData[x]数据结构的第x个数据
' F: t0 p$ y2 O0 g: f `( Q' opData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
+ Y: y/ N2 [8 L3 I, ]2 H+ O5 ]( Y取用结果缓冲序列6 k- `6 U# }: c+ D2 D
pData->m_pResultBuf
$ P7 _* s+ {- t% E取得第一个序列参数的起始序位,如 2,...5 , . 7...
( C9 R! L% X3 ]0 e! y4 h1 m- qintnFirst = pData->m_nParam1Start; 5 j& a6 ]) p1 e4 t
for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
% u: [7 L7 C1 d7 z7 l取得第二个数值参数的数值
3 w* n j6 J" P4 y+ Q3 ofloatfParam = *pData->m_pfParam2; : K4 }8 M- d: l+ K! d
intnPeriod = (int)fParam;
: z" [, h4 l7 c4 u# u) F+ K% D3 O7 I取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;6 }3 O3 M& ]3 J
取用序列参数的单个直pValue
7 s/ p- U( o8 K6 [0 L取用缓冲序列的单个值pData->m_pResultBuf
* H# h% z2 E1 {$ SconstCALCPARAM* m_pCalcParam; // 调用参数数组6 U5 B7 T5 U/ Q, W* J% L4 O) D
m_pCalcParam为序列址标,指向各序列参数的指标; ]! @3 L" K/ f) L+ T
第一个序列参数pData→m_pCalcParam[0] j3 D: ~* Y/ q" L2 V: J- @' U
constfloat* m_pfParam; //指向序列参数的址标
) U& L( K6 c5 V6 K* k+ u: b第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart; A$ y1 r2 b& q* i2 I7 L/ {: S
第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
' N6 }, m) ~; _1 {( i7 r) J* ~取用第一个序列参数的单个直pValue1' c' q" A$ R' z
第二个序列参数pData→m_pCalcParam[1]8 J4 \" M8 h4 E8 P' w6 H$ {
第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
& v% Y& g( x7 z7 R第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;
" B3 e! p/ W: Y& \, M取用第二个序列参数的单个直pValue2' v0 E- r, V# @2 U0 s
第三个序列参数pData→m_pCalcParam[2]2 T* S) \+ r) F6 {0 r& ?
第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart
3 A5 n9 L4 i- {) |第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;3 J2 o8 z9 e# F1 w" v5 S# f
取用第三个序列参数的单个直pValue38 y* d/ q! z4 u3 V& P
第四个序列参数pData→m_pCalcParam[3]& d4 F" _* r) D/ \9 Z8 n' k
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
{4 r, J- C7 m, z5 r9 G第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam; |) i* L/ ~. S2 v
取用第四个序列参数的单个直pValue45 Z- u6 n C T, H, J5 f
如果有四个序列参数,则取用序位最高的那一个序位* Q: N& w1 N/ R e/ ?5 a
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&0 b! @ U6 W* T- |" [
pData->m_pCalcParam[1].m_nParamStart>= 0 &&2 @) g# h ?: l( K) w5 `
pData->m_pCalcParam[2].m_nParamStart>= 0 &&
8 X0 c; u% v" ^, ypData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值$ H E7 s# @2 V7 `% b" r
{6 k$ q; A" J8 Z* I7 O
//计算返回的序列的第一个有效值位置
6 F5 k; b& ` o- zintnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
9 C' N2 x2 m8 k' j//若不知,则
+ e3 B2 L" m2 B7 V# w+ K/*% W! _' W. a0 [% I: P6 d
intnFirst = pData->m_pCalcParam[0].m_nParamStart;7 |- r: }! @% e$ Q. e C
if( nFirst < pData->m_pCalcParam[1].m_nParamStart )
; F- t- F5 [7 `4 vnFirst= pData->m_pCalcParam[1].m_nParamStart;) }, q, c7 v; T* |
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) ; x# o" |0 e/ e- X
nFirst= pData->m_pCalcParam[2].m_nParamStart;
" [. P& m9 z9 n2 Wif( nFirst < pData->m_pCalcParam[3].m_nParamStart )
1 x \2 m, h; t% \nFirst= pData→m_pCalcParam[3].m_nParamStart;
0 M# t3 u+ y/ s: Z" M; z% U- Y# Qconstfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;, ]. l/ A b# n0 U7 `, v8 Z- N
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;. |: [# G# H7 W; F8 _4 o
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
- j# ~% }2 \/ Lconstfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
; h ?' w" a7 V! h! D3 }. h//-------------------
) R; w" `! C$ d, dfloatm_fOpen; //开盘 open1 `0 G4 S# V% H; P. J; _. n, ^/ S
floatm_fHigh; //最高 high
+ a0 ]0 B/ `5 A7 h0 |" xfloatm_fLow; //最低 low
/ }+ L Z: n8 Bfloatm_fClose; //收盘 close- o% A: H4 C4 q2 }* j* U( ^* N
floatm_fVolume; //成交量 Volume
) m; o0 h8 n3 [' V, ~ M, afloatm_fAmount; //成交额 amount
! T2 l! F& M2 V' u; i. a调用收盘据
" T$ w0 j; m6 U3 B/ ~9 upData→m_nNumData= 变数数据长度
8 U7 n( ]1 x- `1 b7 DpData→m_pData= pointer to struc STKDATA0 a7 o- b+ z/ r* X: }: S
pData→m_pData[x]第x个数据% ?/ D3 R1 c2 o, j7 C
pData→m_pData[x].m_fHigh第x个数据中的 High
6 X/ S+ U# T ]- d# }@@@@@@@@@@@important !!!!!!!
y! D: ~, M4 a: r3 CsinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
+ k# m8 `5 ]$ i( D$ I, j; Zso,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
* X3 N9 @$ D& n* Q, u" Z; IpData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
6 S& _( S$ x" A# K' E+ S; r0 fpData→m_pData[i-j].m_fHighto use high3 r7 v$ S5 [' ]) F
pData->m_pData[i-j].m_fLow' H0 e% z7 M! v( q; r& W+ s
pData->m_pData[i-j].m_fClose% K5 B: P6 z0 p' c5 B
m_pData= pointer to struc STKDATA! ~, P, ]4 q$ @
incalling C++ dll function' E! D/ r- \* l) N4 _' i* D% x
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)
& Q2 z% }7 o0 J; h, ` x7 X% d5 `touse a single value in variable ‘High’
, D* `. O2 C- opData→m_pData[i-j].m_fHighto use high' o% Q( y' u5 `3 h$ s
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
* z* d% p$ {3 ^) sconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 24 H7 I5 m. B/ G5 e2 z
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 33 g V* {+ \4 \2 N
constfloat* m_pfParam4;
5 I1 H2 L7 ?3 x4 x. [5 km_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数9 L' j h0 X$ z* `3 B; J
pData→m_pfParam1= pointer to 第一个(序列)参数* R! A$ X7 e; _. W+ ]6 B
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值, l6 G, H, e) p1 k0 c
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
7 U9 O- {$ V: Q& Z! JcpParam[x] = 取用第一个(序列)参数的第x 个值
# [8 ]; {+ M" r: t( m. x! Tm_pResultBuf= 结果缓冲列
) R( h! O9 m0 W9 Z- epData→m_pResultBuf= pointer to 结果缓冲列% u, ?8 P# f% d' ?9 p9 o
pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值3 A$ H0 Q5 x% B& B3 f
//////////////////////////////////////////comment# z4 ^% ~& z$ [3 O O$ j) B( |
//////////////////////////////////////////comment 注解
; q$ q& ~' C- Z7 ?6 u0 aconstint m_nParam1Start; //统杅1衄虴宎弇离
, P8 [4 ]$ l6 \' g& _. Y; Nconstfloat* m_pfParam1; //覃蚚统杅1
* K! N9 w5 j. @6 o p. L- Y4 Mconstfloat* m_pfParam2; //覃蚚统杅2- R! w# K4 P( @! A6 A
constfloat* m_pfParam3; //覃蚚统杅3) S, |! T) J2 G* h& G2 W7 v+ p
constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4
9 H4 V9 P0 x( X5 M0 K. ?//const float* m_pfParam5; // parameters must be <= 4. A0 H* ^7 B5 `
//const float* m_pfParam6; + p8 V* y7 z% x8 @6 o# y
//const float* m_pfParam7; ; O* F% f' w8 d0 ?& p1 v
//const float* m_pfParam8;
" b0 h# p1 T G. Z' [//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
& x" Y* D, a% l$ e1 T$ [pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
7 }9 q; H* h3 T5 T- r- B&&pData->m_pCalcParam[2].m_nParamStart>=0) + K$ L1 \7 y2 o$ s6 I8 C' v- C5 i' h! S
{
5 a, j( G1 g7 c5 _, ofloatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0& n; ~: T. `# \ H* d( `/ i0 Y; e. t
intnPeriod = (int)fParam; //统杅1
. T- v' ^& x1 \0 y! U) c; t' m% a! w//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值2 P# t, U5 J8 ? s/ r
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
7 J' W8 B8 }2 |- y S$ ~constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
8 ] r, b1 A6 ?& l7 \( Uconstfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4
. P* H. e4 C7 Q//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
1 ^; f& X- v0 Y: A//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
" U, I! g2 n% M: A, j//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA , 6 l' A3 a1 g1 @+ j2 W
touse pData→m_pData[x].m_fClose
0 {) l8 p# \; u& Y3 ]pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time;
) M1 @. e& V6 k. {0 N% t/ ~|1,2,3 , … , m_nNumParam | float m_fOime_t
0 v$ K4 ]3 X! K3 \( e, {|1,2,3 , … , m_nNumParam | float m_fHigh;& [$ a/ P9 p/ h9 I
.. .& G$ X- K |& }# u
|1,2,3 , … , m_nNumParam | WORD m_wDecline;
( Z# R7 h/ ~* \" }; \m_nNumParam= 数据high,close,open,low的长度
3 I$ |3 U/ W0 d* ?touse high:1 `6 E/ E; ^! _5 k; f; U9 ?
pData→m_pData[x].m_fHigh
% t, n, Q0 V) @, M8 M" u: M9 Tcontentof struct STKDATA4 \( R, ^7 X" o7 Y* G
time_tm_time; //时间,UCT+ Z }$ @1 `# q2 n
floatm_fOpen; //开盘 open* n6 |2 T' A$ C# t0 ^1 y% M. c! T
floatm_fHigh; //最高 high3 a7 V1 i3 C) W$ X& o; s" C
floatm_fLow; //最低 low- c8 l1 C: _0 c
floatm_fClose; //收盘 close
/ v6 P# P- P+ @floatm_fVolume; //成交量 Volume. \4 Y, B. R6 Z, c6 Z0 t
floatm_fAmount; //成交额 amount8 `: ^8 ?5 E+ k7 F, e: V
WORDm_wAdvance; //上涨家数 仅大盘有效% O8 K0 C* P* i% A" `; B T
WORDm_wDecline; //下跌家数 仅大盘有效
2 |8 E; L% U& A- J" C* U调用传递参数及传回结果
' |( c' c$ }9 @* C5 o调用传递参数
' K# ^ I2 H' \1 k(pData->m_pfParam1 && //参数1有效Param1exists# B* b0 x8 W2 |
pData->m_nParam1Start<0&& //参数1为常数+ |! V& f) Y/ c% u# y
pData->m_pfParam2==NULL) //
8 s+ @( u+ \. Y" Vlocalprocedure 定义使用变数
; C, X+ m: y ^: c$ w+ N5 p. Aonstfloat* pValue = pData→m_pfParam1; //use constant参数1- z8 k4 @( \" M- s+ W: b
intnFirst = pData->m_nParam1Start; //use 参数1效值起始位* R, g. ?! a1 z9 n
floatfParam = *pData->m_pfParam2; //use 参数2( x1 @9 e3 L0 G" q6 A; ?
intnPeriod = (int)fParam; / T) _) F2 W- D: ~% L: O% V
传回结果; v- {9 G4 ^: M
fTotal+= pValue[i-j];
) c0 n1 @) W/ i4 ^0 J* {' UpData->m_pResultBuf/ a: F# A9 }3 ~$ b9 Y
//////////////////////////////////////////comment |