许多年以前,我曾经在
: k+ f) x! Z6 @! v理想公式区发布了$ J6 Z# V% R: f. x
"
4 h# q: r+ s/ E' d) n8 y如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
1 I0 J6 J2 u* E* r: c8 G"
, y# }# l) k8 t3 v5 `: r: q
" q: J1 t9 j* l现在更新foxtrader(飞狐交易师) 5 a+ A7 `) Z0 _" O9 {0 |5 Y
连结 DLL的方法& l( v) Y% o# K) x/ Y
" ]0 [5 k, a& Z( Bfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
3 l3 C, q s! `5 \gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm ) Q5 R" j* S/ P9 B
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响' [8 c! A. W! G) m9 }! d$ _% v) p
foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
! P- s, p# `0 p% z7 U2 o1 j. j6 _0 m* R% E* a4 T+ C5 w
也就是这五个结构都能用
( [9 ]: X5 V/ N& _$ L8 utypedefstruct tagSTKDATA
" J4 Q$ p5 ?5 y0 btypedefunion tagSTKDATAEx
$ B# J6 w m8 etypedefstruct tagSPLITDATA
7 J8 R4 Q* t1 L# j4 Wtypedefstruct tagCALCPARAM
* J) q6 R0 ~9 X6 v3 Stypedefstruct tagCALCINFO
) x8 @$ b9 z% n1 b' w3 p( |. {
0 F. g; @3 ?: L* h5 ]6 y自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
- `- c# w0 T; p T7 ]- I; W" V也就是这五个结构中
" f. E/ Q" ^: B( p6 p% `) ftypedefstruct tagSTKDATA & m4 ?% {) M0 o' j- q+ W- W; X" ?
typedefunion tagSTKDATAEx
5 ?6 N' `# C7 I6 mtypedefstruct tagSPLITDATA
0 I7 S" S4 v ^, s2 H* Qtypedefstruct tagCALCPARAM
# _* j j0 z1 x$ e. |! dtypedefstruct tagCALCINFO9 ]; `3 o. S, s! {, ^
只有这两个可以用1 ~/ y( @5 G) ^$ e6 t8 i
typedefstruct tagCALCPARAM
& M% |/ ]5 W, z& b2 F; Ttypedefstruct tagCALCINFO
! x) i& K) _/ L# v' J值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
& o* o) w5 `3 N+ y6 P9 {( P9 W+ [1 ptypedefstruct tagCALCPARAM
$ }) v" b4 z1 [, ]1 ~例如:在 foxtrader中7 Z" g& z( R) h( |3 l
MA1:=MA(CLOSE,3);
/ a3 q: d: b! f* T7 I5 {4 R$ }+ WMA2:=MA(CLOSE,6);# W, B* I4 r) y: T
MA3:=MA(CLOSE,12);4 }! p, L9 k0 s6 a
MA4:=MA(CLOSE,24);
2 l4 E3 c5 N% ~6 w0 z Y) o0 HMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}; \% w- Q6 E2 \ u" P* m
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
! [5 B0 [( M% e. u4 O下面这两式计算结果相同
2 u8 e4 F( F3 d2 Txx:(MA(CLOSE,3)+MA(CLOSE,6)+MA(CLOSE,12),MA(CLOSE,24),MA(CLOSE,12),),MA(CLOSE,24)/6*0.95,color0000ff,linethick2;{foxtrader 自行计算}" d w) K& b/ T& Z( O. f
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}8 x9 Q3 ~/ |/ O5 G1 W* F, T
其他例子& n! R/ t$ J. e
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
y. t* I+ }" M, A3 m/ b; O) toooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;! H: v( y! V4 C! E6 q* B. J
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
4 f! s C( ^5 j# {( q8 c: |fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误" ?4 B8 l8 f' H0 N8 @2 R- ^& ^
, Y8 C. L w/ p6 |2 S) g# \9 t! y7 z1 C+ c5 E( W: T
////////////////////////////////////////////////////////foxfunc.h
# a9 Y) M" m; d9 H; V& ^" ?#ifndef__FOXFUNC_H_INCLUDE
6 M0 w. }3 J5 j/ z9 j. J1 }% F#define__FOXFUNC_H_INCLUDE
) L2 d/ V& u: u$ }4 j/ R' G9 ?/*+ j3 f+ V9 w8 ^4 k5 m0 f
飞狐交易师“C语言接口”扩展程序调用接口规范V3.08 J9 d { |# m' H, y$ q( ]4 Q
1.本规范适用于飞狐交易师V3.x公式系统.
* B- n8 i, E$ c. l! r& _# J2.扩展函数用于实现系统函数不能实现的特殊算法.% E# g" S' h& K5 G% \2 k7 Q
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.+ c. L6 t9 O0 b: s3 o) d
4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
5 I g2 F9 |- z5.动态连接库名称和函数名称可以自己定义.
: v- R$ B9 g+ ?/ M. l3 W6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
. Q, h8 m% C' [4 S' _. p*/
1 f! P* }* w0 w& p6 x0 R) N& F$ W#ifdef__cplusplus [# y& ?3 p/ F: }2 Q
extern"C"
; I* [5 [0 _; w' U# `5 t* ?{
* T: T1 F( E; I) h0 _#endif//__cplusplus
% |6 h# ~1 ]# {///////////////////////////////////////////////////////////////////////////7 Y0 S* N5 P3 F L
//分析周期) |( X8 `. s: J. `5 u
enumDATA_TYPE1 d3 l, b. a7 h
{. C* @# G3 A- g
TICK_DATA=2,//分笔成交
6 w& q' J: b7 j4 J4 XMIN1_DATA,//1分钟线1 s# b5 x' [: Z8 P% ~9 w
MIN5_DATA,//5分钟线
( _! O5 ?2 n9 s0 W+ VMIN15_DATA,//15分钟线
3 H0 h: y5 k% W; a& ~ c% z% TMIN30_DATA,//30分钟线" F3 f0 R/ t Y" C. |5 Q9 k- y
MIN60_DATA,//60分钟线
) `! m4 P! |5 ]5 ?7 ` A3 ]# CDAY_DATA,//日线) u/ b7 O. @: T$ n
WEEK_DATA,//周线
2 r; j2 a1 }. [7 L; ~: W) v8 {MONTH_DATA,//月线- X, A9 m0 j: p# W
YEAR_DATA,//年线4 y8 b. }! u& M8 j+ ^/ B
MULTIDAY_DATA,//多日线5 V& E4 _# H4 E0 x9 D6 Z
MULTIMIN_DATA//多分钟线$ [7 l+ m/ f9 k: F
};8 `0 @+ w$ T4 t* x; l
///////////////////////////////////////////////////////////////////////////
% O7 K- b. e% W y//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用/ t) u. [& I& H& r! {
typedefstruct tagSTKDATA
+ |# F) ^1 C3 j{
6 V; ^' E, V9 w" c' | _tm_ ; //时间,UCT9 z. I/ ~; {0 d {& J) E
floatm_fOpen; //开盘 open
5 B: b2 H4 g' @6 ~floatm_fHigh; //最高 high
8 R+ L" w3 @) X+ |3 W% lfloatm_fLow; //最低 low
( d+ l7 |: o6 D+ Vfloatm_fClose; //收盘 close
- D5 P6 g9 r" q* w5 H, e' \$ tfloatm_fVolume; //成交量 Volume
7 E0 o: y" {! W, X& n! ?floatm_fAmount; //成交额 amount
4 ^) ?! b: r8 v4 h0 QWORDm_wAdvance; //上涨家数 仅大盘有效$ p! ]9 g% M0 Y/ k6 t
WORDm_wDecline; //下跌家数 仅大盘有效
6 U0 X0 S2 ?0 k}STKDATA;
' R% s# V1 d/ }; n6 ]7 r定义STKDATA为 tagSTKDATA的简单别名,STKDATA
, T0 J$ S( e& w# }为真正方便使用名称,tagSTKDATA 为定目的的过水名称8 W5 F, p8 J( o5 D# k
////////////////////////////////////////////////////////////////////////////
+ M$ z* W( E! Z7 n//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构0 [* L, F; @& K: b. b" I3 L0 n
typedefunion tagSTKDATAEx
$ |; K7 e0 [: w4 C{2 g& M) S- p( | @$ w C1 ~$ u+ |
struct
2 Z: X( I o7 [' d" k{
, L: P Z( S9 w8 p' qfloatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open7 ]; F- @5 I ~; u) _* X. Z
floatm_fHigh; //最高 high
! t6 H7 Z" S: O, y$ mfloatm_fLow; //最低 low
1 K) I3 D( _3 h/ X& F, }1 ofloatm_fClose; //收盘 close( ~7 z1 h3 N: y( ]# u1 d! s
floatm_fVolume; //成交量 Volume
1 \) {0 j# s" J7 B7 y* h: pfloatm_fAmount; //成交额 amount" v/ G* h% z) W) h
floatm_fBuyVol[3]; //买1--买3量! q6 l3 M7 K. @% b6 [
floatm_fSellPrice[3]; //卖1--卖3价
) e( Z2 C& u+ p( a7 ofloatm_fSellVol[3]; //卖1--卖3量! v4 S- f0 y- t* z( B& K
};
& l% h" \/ C8 F8 E0 I. o' {floatm_fDataEx[12];1 k* X( @1 e3 k: U: b
}STKDATAEx;
% [7 ?" h: ` L+ L: x: o$ @8 n) A////////////////////////////////////////////////////////////////////////////4 ?9 N+ ]& |& V* L4 W
//定义取用除权数据的结构
; N) a- J- x: a9 F% e7 ytypedefstruct tagSPLITDATA
3 D) a: U/ |0 Q+ _% m7 b, P! j{- k# `% V' E7 I# _# m
time_tm_time; //时间,UCT
" y4 Y8 O% I( Qfloatm_fHg; //红股" m- V/ {2 J+ [3 c
floatm_fPg; //配股: p8 ?) p) N, a$ E7 e1 P4 A$ K
floatm_fPgj; //配股价
& S9 S. ?- c: G4 n. u S: {3 h# @* _! gfloatm_fHl; //红利
) |- p; ]& z! V) k) f}SPLITDATA;
' s: z- m5 { N( I$ u/////////////////////////////////////////////////////////////////////////////
! w4 Q F+ F, K0 D' E/*财务数据顺序(m_pfFinData内容)
M& @9 U. l9 h$ T3 A3 q: A2 X序号内容' ^# k; x8 J$ `1 @9 o) P
0总股本(万股),
3 _' c2 P- v" ?1国家股,9 p* O/ @( I5 L' R
2发起人法人股,
% x8 h) t5 a! X; g" D3法人股,+ }) d: Q) a) X8 o4 h
4B股,: S; m6 a8 f+ C' s# M5 [
5H股,% I& b, t8 |6 h4 i
6流通A股,
; w8 }. W! ?" Z7职工股,
: B3 A' J. Z5 g8A2转配股,2 K' u8 W, O7 {6 h1 B2 O, U8 H
9总资产(千元),
& e# Z& Q7 P8 E; V" v* d% S6 l* M10流动资产,
( G: V- R: ~: q8 D* s11固定资产,) J& {9 E4 G9 B( m* X
12无形资产,
4 @, E# |( z# M% }7 e' p13长期投资,
$ @' Y; m9 \9 v/ U14流动负债,2 _ w8 b w2 f( ~- S) s
15长期负债,: w. `' ~0 l @& E( p
16资本公积金,) r" c) }! m# | h- t0 P
17每股公积金,
2 m6 e8 c$ z/ R1 h$ e18股东权益,' X% f% ?6 O& `4 }' k8 r9 M' g
19主营收入,2 Q4 H ?5 D8 p9 ?
20主营利润,
: g3 o- \7 @- [* ~21其他利润,) G4 D) t( ]( x G+ N6 u) c
22营业利润,
2 I. ]7 t8 h. g) s) p1 g23投资收益,
, G8 l& }' v& H7 ~24补贴收入,
7 ~* G3 J! o( U5 ]& y25营业外收支,! a% t) ~5 H# S! h3 k; H
26上年损益调整,
/ t% G3 {+ |; L& l" h# k# y! W27利润总额,
0 _/ y# n1 o# C7 _2 U28税后利润,1 e$ ^+ ?' U' x7 i
29净利润,) f& F- S# K4 v8 c! {: j
30未分配利润,
( \# v8 @- h) N9 ~1 [% J6 ^31每股未分配,) Y+ e+ C8 a- d& M# k( P$ m9 R* e
32每股收益,3 w' L8 [' T( H2 B# Z* L( w
33每股净资产,+ d2 c: g6 t# I7 M2 o4 n
34调整每股净资,* L. J& C% C% [% K7 K
35股东权益比,
, Z, j5 v' u& R+ K# g2 ]* Z36净资收益率# N2 J4 _7 x, {
*/) Y; d" m+ f: Q$ U
/////////////////////////////////////////////////////////////0 [4 S( \" p1 G1 e- O0 A6 r
//定义取用caller函数传递参数项 的结构3 K$ B9 a5 I0 W* \% A- Q
typedefstruct tagCALCPARAM3 j& u9 X% u w+ {1 Y: N9 A
{" t" o! D X3 l3 R
union' l+ q& P8 w' K" I+ w0 y3 W. u5 Q" A
{) z2 g! q/ k; Q; R
constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
3 b; e1 @+ c- a( i. p8 jconstfloat m_fParam; //数值参数 valueof parameter
0 R! C6 c/ Y3 t, U* Y5 G};8 y, a! R. c3 q# p2 q
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
) I, e% i& u' u! H2 D* G) O}CALCPARAM;
7 G' n7 E$ Z$ A% w3 ~/////////////////////////////////////////////////////////////////////////////) w# x7 V- c9 c
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )
( e9 L1 a Y/ R7 Z* @typedefstruct tagCALCINFO
F) g- e9 ^7 M6 q; U: R' L{0 H& u3 u$ `. P8 X, T# K% u
constDWORD m_dwSize; //结构大小
. R7 p) Y6 A- Q, J+ p8 Q7 JconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)( U" m1 F* t: z B
constDWORD m_dwSerial; //调用软件序列号
$ L# P* N6 b: t* q6 z/ W5 {constchar* m_strStkLabel; //股票代码
3 C& g! Y- i( y/ gconstBOOL m_bIndex; //大盘, ~7 s/ ^# I' \! g
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度: b$ ?% g* e' t
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
& a; ~& [' T9 r% H- D: FconstSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
/ a' o$ A* G4 A' F. L4 Vconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter 9 S2 J( y9 S& \+ j c
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 , R3 I0 r; f3 }9 O8 e
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
& H* c' s8 ]0 ?3 tconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 39 O$ k" K( M& p/ B
constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 43 I% _$ c' M- s d; s* m9 Y
float*m_pResultBuf; //结果缓冲区
: T' h" l2 G9 E2 h- Y0 bconstDWORD m_dataType; //数据类型$ K, m0 D O; E1 _
constfloat* m_pfFinData; //财务数据
, {3 E- Q [, X2 i' ~//以上与分析家兼容,所以沿用其结构和名称3 s( B1 S5 l; Z4 r' p
//以下为飞狐交易师扩展(fortagSTKDATAEx)( y' O' s: s# F1 W" c
constDWORD m_dwReserved; // 保留. e3 _5 W' G$ w: h4 \
constint m_nNumParam; // 调用参数数量
: F& B$ Z' y& x/ ZconstCALCPARAM* m_pCalcParam; // 调用参数数组" T) ^/ D* S0 b
constDWORD m_dwReservedEx[4]; // 保留- @' T8 J" H" Z; N7 K
char*m_strStkName; //股票名称: \* J/ n- E) f8 E
SPLITDATA*m_pSplitData; //除权数据# ?! c9 U5 a. D o8 |
intm_nNumSplitData; //除权次数) C- l8 P) `# d3 Q, C, |( M1 X
}CALCINFO;! @0 Z' f8 ^1 g+ s* X
/*
+ S& L4 b9 u7 E1 M2 L注1:(与分析家兼容)7 N: i6 K1 n3 T8 B2 w2 e
1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.
5 N% b7 R4 n0 @- X2.当一个参数无效时,则其后的所有参数均无效.% j. U9 ?/ k( |7 i+ @5 H2 \& E0 \
如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.
8 x* Z5 [& h5 v7 H- E+ G3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
# S& A G+ G6 O z2 z9 R/ _4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;, K. D: ~& i/ N. C6 K
5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,6 r7 a) C% l. h/ v6 {% n# U3 X N
数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.6 s, L& G6 Q% W0 a# Y* s
在时间上m_pData[x]与 m_pfParam1[x]是一致的$ }$ G1 W8 ]% @1 }
注2:(飞狐交易师扩展)9 p2 y7 @+ k1 g$ m' W( }; z$ Q
1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。. a+ A/ w) }$ @: ]
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
# ?9 `5 j$ Z- X+ N* x1 W, O- U4 ~2 B3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
/ V+ {) M6 I& x1 Y5 r. r7 B w. P4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.
1 s# {7 o: L2 c) k( E& e1 \* Y5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。. p4 ]+ Y2 ^! b) y# n- u
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
; j1 Z$ V9 m: R# T+ Z d. v1 {7.经此扩展,对分析家的DLL依然可以调用、兼容。( H X [2 P4 n! r$ c* Z; ?
*/. K; @) N3 ?) v/ n3 q
///////////////////////////////////////////////////////////////////////////////////
7 J+ p5 l8 c6 G- v0 {5 K, T6 _% s/*函数输出
* C( K& V, f' D/ [, b__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);8 M. a, ~ t/ X9 R6 _# `* F
1.函数名称需全部大写.# L$ t$ x% G+ B6 W# N* [7 f
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
) J8 Z' L2 E. m1 h对于C++程序还需包括在extern"C" { } 括号中.6 O/ y' x6 Q: t; h
3.函数计算结果用pData->m_pResultBuf带回.. C" g, I: a6 G% k4 e
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:* H+ D; _7 F- ~/ }
m_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.
5 b) D0 u- v2 e3 k" e- u& M5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER8 h1 Z! _, P6 L, e5 }
*/: ?3 l" z+ S$ U% A2 g% V
//示例函数,使用时用实际名称替换
, C3 m. t! m: w3 f" c8 o: x* G__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);' V. r- {. g: x- j
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);& J- J1 @9 A* ^! L0 `; H
//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);+ P9 I8 |; d4 K' i4 w
__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
- a0 X) G- k8 T: X//WINAPI = _stdcall
5 E' |, o, L$ H2 `; S#ifdef__cplusplus9 J! L* b9 c' f) j
}
8 e: J3 V* c# p$ R- ^7 J#endif//__cplusplus
- q0 a" }4 f3 k2 Z: Q. G#endif//__FOXFUNC_H_INCLUDE
8 W% R; [+ q* V. o9 c7 n" [1 L& D6 J- H
//////////////////////////////////////////comment 注解" f0 b6 g1 h4 Q
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
$ \9 C( o' }/ q+ ~/ LpData是指向 址标总结构 CALCINFO的 总址标0 B0 {. `! x6 R( n5 m% i
取用第二个参数数值floatfParam = *pData→m_pfParam2 + O/ B' m* A$ m% e3 ]6 U( {
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;/ G8 o, i+ ]; t7 y7 q, c9 k3 Q
取用股票数据长度intndata = pData→m_nNumData;+ _! y- O3 R8 H, W; X
第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
; w6 U" K4 O# E" G) E第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
: P4 H) A6 q% M' {( ^- L第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL- j8 E2 U! H; P# g9 D# m
constfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标) w8 P, s0 i7 O" M5 _$ ]6 l
取用股票数据结构
$ k: Q0 }9 P, dpData→m_nNumData= 变数数据长度3 j) [4 h2 [* E9 [/ [6 i
pData→m_pData= pointer to struc STKDATA 的址标
; i/ N' I# p npData→m_pData[x]数据结构的第x个数据
# t; J4 z4 R) B) s* m: i: LpData→m_pData[x].m_fHigh数据结构的第x个数据中的 High7 E9 u: k4 f1 p2 K$ x4 i
取用结果缓冲序列
- e2 L' g3 }5 v- k' d) O# kpData->m_pResultBuf
/ e4 A8 O0 D1 Q6 c取得第一个序列参数的起始序位,如 2,...5 , . 7...
- Z; U- F1 N' b! x% m$ FintnFirst = pData->m_nParam1Start;
& F, w( F6 H. ~+ dfor( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
, m( _1 w0 t1 e取得第二个数值参数的数值
5 V6 ~/ w: w. O$ G8 H8 F: C: `8 |floatfParam = *pData->m_pfParam2;
# l1 t2 _- i2 X8 W' K/ {; LintnPeriod = (int)fParam;+ J7 @4 f5 ?3 o3 S( r9 k) A# k: u
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;
% t& h- b- O+ Q! C- b取用序列参数的单个直pValue! d C# ?$ O. R |$ t
取用缓冲序列的单个值pData->m_pResultBuf& G1 `; V- U G1 B
constCALCPARAM* m_pCalcParam; // 调用参数数组' W. M7 {8 O7 I1 k0 d) U( O6 n
m_pCalcParam为序列址标,指向各序列参数的指标' v2 d; U4 ]4 v) G! s; H- e
第一个序列参数pData→m_pCalcParam[0]
! q7 g( c0 S1 \% W4 A/ A W$ O- Zconstfloat* m_pfParam; //指向序列参数的址标3 a$ f" u: c; s5 U9 y
第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
. @4 ~- X9 w1 B7 h5 ?1 W第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;4 L- p3 N: I1 A, \) N+ N
取用第一个序列参数的单个直pValue1
( |/ ]& V& A8 _9 X* _" `% ^, `/ S第二个序列参数pData→m_pCalcParam[1]$ G- H) y* t6 s! t4 x: y! p
第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
" m" L6 W" ~+ G# J8 t% G第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;
' o7 t6 U' E7 O" U: j取用第二个序列参数的单个直pValue2
' t( \: V% F! u ~3 x! G* F f第三个序列参数pData→m_pCalcParam[2]
f6 B: w% ]# |0 N第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart& y" m5 n" H8 ~) O
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;
3 v: b& c# H& p( k取用第三个序列参数的单个直pValue3
8 e- i# v! f+ m' \: H第四个序列参数pData→m_pCalcParam[3]
' c% c5 e+ g+ g2 K, O! }3 O第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart( G/ D$ O, p3 j/ |1 ^
第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;0 S2 B1 L; }1 `7 H$ U: Q
取用第四个序列参数的单个直pValue4) c: N' o; i# n% f( c; `# q
如果有四个序列参数,则取用序位最高的那一个序位5 ~$ B( x# a4 n/ H' [, y( ?
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&0 s8 |+ m5 j- F
pData->m_pCalcParam[1].m_nParamStart>= 0 &&: g' g5 X5 Z9 N1 C
pData->m_pCalcParam[2].m_nParamStart>= 0 &&( v5 b: g/ x8 D( R' E ^: w' U- ]! ~
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值: J+ _5 W; ]; J
{& |4 Z- S4 r! \) H( a- x, g) e6 u) ^; K
//计算返回的序列的第一个有效值位置
) W/ W6 N' d, A2 WintnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
7 L$ X9 j. R9 _//若不知,则2 w# @. Z' ^ i; ^- `
/*2 a" t: j& y) v* X# L5 v* e
intnFirst = pData->m_pCalcParam[0].m_nParamStart;
/ e7 R: H; x' {1 K3 [; N4 c! q8 o# pif( nFirst < pData->m_pCalcParam[1].m_nParamStart ) ' m: G0 ~5 F8 j. }: U
nFirst= pData->m_pCalcParam[1].m_nParamStart;
% O. Y( w6 u" E* @. Uif( nFirst < pData->m_pCalcParam[2].m_nParamStart )
4 `! F% ^% X2 vnFirst= pData->m_pCalcParam[2].m_nParamStart;" D0 W' h& h8 i' b/ f% n* z
if( nFirst < pData->m_pCalcParam[3].m_nParamStart )
2 c& Z [% F8 i- }/ |3 S7 LnFirst= pData→m_pCalcParam[3].m_nParamStart;* m7 y$ H( \) P9 _- d
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;+ w! D# r L+ \7 G) h7 ?1 m7 m
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
. p1 J" `6 r6 j4 \3 E oconstfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;. t; S/ Y. Z4 U" ?' b
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
2 B; c! {1 d" d) q6 V$ O R//------------------- D. n: `+ X0 }6 g
floatm_fOpen; //开盘 open2 X" [. m- x1 y: m9 ~" |( }- G9 ^
floatm_fHigh; //最高 high e2 C4 V6 ~( Q) K$ L1 k) o1 j7 y
floatm_fLow; //最低 low+ H8 V2 z9 H/ I3 k7 |9 G
floatm_fClose; //收盘 close
" o& ?( h. ~- u. e/ gfloatm_fVolume; //成交量 Volume2 a' o8 v2 ^/ ?. ]4 C% }
floatm_fAmount; //成交额 amount" R8 n, A1 |5 k% L6 b( ~2 o R# ^/ S2 R
调用收盘据) c2 d/ E5 J. E1 a0 n' p
pData→m_nNumData= 变数数据长度
6 C1 w& R% D" l9 ], Y/ C. Q2 Z: upData→m_pData= pointer to struc STKDATA
# Q) B- E4 D1 G# n6 ~pData→m_pData[x]第x个数据, l- O+ a# `. t/ y- G
pData→m_pData[x].m_fHigh第x个数据中的 High! p- \0 ]; f3 b& o- t! I; {1 m
@@@@@@@@@@@important !!!!!!!1 \1 ]# z% N& T+ s- x2 W
sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
* j1 y4 H: B' Z5 l& {so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
3 q! u8 Q$ ~; L0 a9 O RpData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
( n# ^) n0 E# w4 f h: lpData→m_pData[i-j].m_fHighto use high
1 @; D* x0 L4 P# N! [1 V7 F+ vpData->m_pData[i-j].m_fLow
z( {; ^& a3 b& Y$ }pData->m_pData[i-j].m_fClose
0 x8 O2 X9 F$ e- g5 n+ i1 Lm_pData= pointer to struc STKDATA) @3 b- d: Q* i. E
incalling C++ dll function# N$ _! E2 o1 H7 v8 X# ]
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)
; i, g5 I) D2 Mtouse a single value in variable ‘High’* C; P1 y* \& C
pData→m_pData[i-j].m_fHighto use high
) P" ]7 ]6 ]) }$ _& ~( Rconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 6 z& d1 p& k v! V2 ~9 w
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
z1 K# q+ P) ? F' Tconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 35 T: g4 R9 B/ ^) g0 N9 S' y
constfloat* m_pfParam4;
4 Y, N9 Q z. x2 |- O, v# cm_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
1 h% g: l1 W' u1 K! P4 h) NpData→m_pfParam1= pointer to 第一个(序列)参数; C: ]6 B, S1 q* H) X8 ^
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值: X6 D2 X. E3 R& |
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数6 F& k$ f. k7 b0 K- S
cpParam[x] = 取用第一个(序列)参数的第x 个值8 }& t! y, y0 ]! i
m_pResultBuf= 结果缓冲列* G Y+ X' m7 f( b% w* d, c/ y
pData→m_pResultBuf= pointer to 结果缓冲列
+ k7 y5 z+ ]' SpData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
& @9 [+ `. O+ U4 n1 u% v2 n//////////////////////////////////////////comment; _/ w, K) R2 I1 K9 i
//////////////////////////////////////////comment 注解9 h+ H+ z0 A- U {9 S" D
constint m_nParam1Start; //统杅1衄虴宎弇离! M3 _$ B2 W& ~+ N$ v% H
constfloat* m_pfParam1; //覃蚚统杅1
, l5 _0 U& c0 K I8 W/ kconstfloat* m_pfParam2; //覃蚚统杅2& W: V# D6 n, e: e b9 n
constfloat* m_pfParam3; //覃蚚统杅3
) b. t8 {. B. n" Zconstfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4# e# s' Y0 ? ]1 X0 n ^* O- n' A
//const float* m_pfParam5; // parameters must be <= 4
+ B; g6 b+ J, u//const float* m_pfParam6;
* V5 B1 D# e" u# j7 @; u3 a- k//const float* m_pfParam7;
8 V% }' c- h) \. k o: W//const float* m_pfParam8;+ j5 R8 N5 }& D" y* M6 C
//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&9 G `' W, x3 ?4 x, v6 d$ m; b1 S; |
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
9 F C2 X+ @. y0 L! e1 \ k. E) [% _$ t&&pData->m_pCalcParam[2].m_nParamStart>=0)
+ ]/ R- t8 e& X9 L8 Y" r{6 v6 ?1 x) e u- l% f
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 06 ~3 x% S. H3 @$ I! A( D& |* ?
intnPeriod = (int)fParam; //统杅1
/ I0 }# k& _# x7 i8 X$ d+ f//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
# O) i* U# k) |constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
. Y4 L! z. g" n$ T) g) j- Fconstfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
/ Q1 |8 [5 ~) b; @- Rconstfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 44 m1 N$ A6 V% i6 Q* b. `
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
1 N- H, _% d* J1 ]' N( C//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值9 t$ l3 K4 _" c: X
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
/ U! J; F* a# Z0 g' y4 Btouse pData→m_pData[x].m_fClose
9 o$ l/ n$ F- ^6 F2 s9 kpData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; 8 \, V2 |( g+ \' s
|1,2,3 , … , m_nNumParam | float m_fOime_t
9 Z. N# Q3 S+ O' T- u|1,2,3 , … , m_nNumParam | float m_fHigh;
1 f3 Y" e; M2 \.. .. x+ p. Z/ l3 N9 y1 o2 ?( U
|1,2,3 , … , m_nNumParam | WORD m_wDecline;# J. Q& E) N/ l& l, e& ~! k
m_nNumParam= 数据high,close,open,low的长度0 G0 m6 M: {; l
touse high:
1 B/ @: g9 n! _6 `pData→m_pData[x].m_fHigh
2 E' P$ f) C3 e3 {contentof struct STKDATA
: X }5 u" A2 c5 b- w9 F% Ntime_tm_time; //时间,UCT" S, S: G) B6 V/ h. s- U
floatm_fOpen; //开盘 open
# S- h6 m6 M2 z! Yfloatm_fHigh; //最高 high! N0 w( z9 I3 H# l
floatm_fLow; //最低 low
! G, f( a* l" ]- ], q, Kfloatm_fClose; //收盘 close. |$ x3 ^! ^; i: N# b! n; Q
floatm_fVolume; //成交量 Volume
/ b: u5 l! G3 U% jfloatm_fAmount; //成交额 amount5 N" c- N" G7 I/ t) N1 x' ~ d8 Y4 `
WORDm_wAdvance; //上涨家数 仅大盘有效( e) I. V% q0 w' e* Q% a
WORDm_wDecline; //下跌家数 仅大盘有效9 G9 Y& y: Q1 _# s3 h: ]/ P4 t
调用传递参数及传回结果
6 b# D* k4 }7 M8 S: }调用传递参数
, M. _7 B- z# f/ N( L. }4 o+ R4 j- s8 h(pData->m_pfParam1 && //参数1有效Param1exists, I4 o3 e) D* N$ u; e( x
pData->m_nParam1Start<0&& //参数1为常数6 f. f( s# X% `+ \
pData->m_pfParam2==NULL) //
. j. {$ W! v6 _+ w& k* q" jlocalprocedure 定义使用变数; i0 a& p1 w1 p! v
onstfloat* pValue = pData→m_pfParam1; //use constant参数11 i6 l' P: ?. k6 M
intnFirst = pData->m_nParam1Start; //use 参数1效值起始位& U: V9 D3 V& j1 [2 S
floatfParam = *pData->m_pfParam2; //use 参数2
/ B/ Q7 o% S( ointnPeriod = (int)fParam; 9 j5 J- ^3 a+ W
传回结果
! b7 a ]5 t* n- h. p% k* EfTotal+= pValue[i-j];
3 I$ {' D$ W# I- W1 X% y* w) rpData->m_pResultBuf
6 g+ }9 t& n! R! N% L$ e//////////////////////////////////////////comment |