许多年以前,我曾经在
# x |; h3 J7 q3 @( T7 U. k/ O理想公式区发布了+ o, }' [( X5 ^7 Z4 e
"
- r6 y* U$ d7 {3 D* Q8 r& g# x如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)7 p6 }5 Q# j' j
"
! J# h) x% ]4 e3 K7 L; d9 \% i
2 E1 r! I6 _" l% Z现在更新foxtrader(飞狐交易师) 6 {8 x6 E* Y! \
连结 DLL的方法! P6 C" ?4 N3 Z. Y! I7 F+ c
7 q1 w: d0 E, O& vfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
. F6 x7 H, v Z b# t2 }# Hgauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )- {( q6 `! z! m6 W |
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
; m$ X: i' z0 _. e8 ?4 x& q8 ^foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效' {, ^2 \! u& u) s1 [
; ^/ }/ v [& {& q" M# {
也就是这五个结构都能用3 H+ l7 @6 d$ `" A; r* p
typedefstruct tagSTKDATA 1 F1 I0 [8 q N7 \
typedefunion tagSTKDATAEx$ B+ h, a3 h5 m+ _2 w
typedefstruct tagSPLITDATA
' {$ _$ E. R( {, x% h$ |typedefstruct tagCALCPARAM
3 f, Z; x2 z% F, I2 a9 P% G# _typedefstruct tagCALCINFO" V( [) ? O% A7 i' k
7 c% e% y F; v8 Z, t, y/ a自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
1 j: w2 S3 N7 O; n也就是这五个结构中( q+ T- k9 \/ o0 r3 q/ J6 e" l2 u7 D
typedefstruct tagSTKDATA
/ _; I! Y. a6 s& N' r- t% E+ f) c' `typedefunion tagSTKDATAEx
- A3 V7 j: H) V0 b0 Stypedefstruct tagSPLITDATA
! C0 s! t- g+ v; Xtypedefstruct tagCALCPARAM
9 w' ?% O- ~7 }. e3 a' H8 stypedefstruct tagCALCINFO
/ g( Q- Y7 f$ C" T- U只有这两个可以用
# {8 M! f% X# T$ ytypedefstruct tagCALCPARAM
4 ?2 C; Z) q( n" V, etypedefstruct tagCALCINFO
: }. S0 X- A- z0 q. h6 m% _7 C I& N值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个* P7 t" h8 X$ Q0 B# S
typedefstruct tagCALCPARAM
6 l1 h8 K' \1 L- y. f" H例如:在 foxtrader中- h( l; e1 R( l
MA1:=MA(CLOSE,3);. `- R6 s- Q k' m6 W. o
MA2:=MA(CLOSE,6);3 B# ?$ m) O) d( t( d6 ]7 ^& ~5 Y
MA3:=MA(CLOSE,12);
! W# U7 V9 p. ~& F# n) M/ GMA4:=MA(CLOSE,24);% X$ R! O B# j' t7 w
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}- e5 W6 Z+ }2 s' H
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
! I) ~& H! _+ m" t. e下面这两式计算结果相同
+ S* w: ~# b( F# ^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 自行计算}* q# u! `; V& I9 A8 J* Q4 ?8 v
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
: |" U; I! B; O+ x3 w' ~, V/ d) A其他例子
; T- v6 p" ?: n5 Y8 Soooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)% L5 a/ A8 [- x- x0 L: b
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;
/ f! U* t- U8 L% S其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的, A' ]/ Y8 N4 k$ o
fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
" e5 m) o* h6 P+ v% p" n5 Q$ @1 d+ A! `# P
7 Z8 z; z$ y5 M. m- `3 ^7 B% F& u" |
////////////////////////////////////////////////////////foxfunc.h/ ]. \/ l1 T6 D
#ifndef__FOXFUNC_H_INCLUDE
. w' c6 s) P+ P% D1 Z1 ?' U#define__FOXFUNC_H_INCLUDE
- Y5 w: q% y7 { l/*
. }' @0 I' X0 T# S1 {, K9 ~0 i2 z4 X飞狐交易师“C语言接口”扩展程序调用接口规范V3.01 k U3 ~0 F- d! z* P* ^
1.本规范适用于飞狐交易师V3.x公式系统.4 d5 H: {/ R4 o$ J9 g, g5 \
2.扩展函数用于实现系统函数不能实现的特殊算法.# A% L0 H' i3 n$ h1 o8 c" L
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
, L6 a3 D3 ]; o5 P% l4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
2 j3 ?3 d; L5 Q5.动态连接库名称和函数名称可以自己定义.( [, f8 W: S4 P
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.1 m$ S8 r! e; s5 f3 `6 I
*/, D; D: G; _7 L; X. G) k
#ifdef__cplusplus/ a; ?( g. M9 D2 y" X
extern"C"
9 F, b$ a% S, F1 L4 W% C{/ N: \/ j2 ]5 i
#endif//__cplusplus
2 y3 r# |) s* X: _- d///////////////////////////////////////////////////////////////////////////
) t4 B! v4 ]3 g4 M2 C: S//分析周期: m9 v5 S2 Z* e
enumDATA_TYPE. H* K$ z$ F; p b! P/ j. Q
{/ ~! m6 X# z4 \) [; @) {! ]
TICK_DATA=2,//分笔成交- H: n5 O: V% f( g# x0 Z
MIN1_DATA,//1分钟线
6 G& \1 B! ^5 Z+ M7 j! F7 SMIN5_DATA,//5分钟线
' u# V( @: a' J/ c, }5 a$ }MIN15_DATA,//15分钟线
6 y7 Z3 u& e, X1 wMIN30_DATA,//30分钟线( R2 j' w7 ~" @/ q
MIN60_DATA,//60分钟线" d0 T+ v# \% v& `4 A
DAY_DATA,//日线
3 U& Q5 g8 h# p8 G( vWEEK_DATA,//周线
0 `3 V; l& A. P/ AMONTH_DATA,//月线0 t/ l2 d8 y: p& Z. C' l' V) r
YEAR_DATA,//年线& W3 ]0 s6 U7 \/ e) Y6 ^) O
MULTIDAY_DATA,//多日线
& j7 L. _; Y; X: u/ m* [9 QMULTIMIN_DATA//多分钟线$ \* S6 h0 W" }8 w4 i
};+ f$ n$ b( [0 w6 @& ^% v* d
///////////////////////////////////////////////////////////////////////////
+ Y% x8 G8 q* I/ ?4 _0 v4 d//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用
7 S8 R% }4 T9 j8 l( J2 Ctypedefstruct tagSTKDATA
3 A6 X3 q6 ?/ n+ V. [+ P q{
) e' `2 l* {- k5 r% R, f _tm_ ; //时间,UCT
5 y( k9 X! u3 m: T; U+ l y, qfloatm_fOpen; //开盘 open: n7 x7 G5 M# B8 r! l- K
floatm_fHigh; //最高 high
: _& b) |1 v4 ~# Ffloatm_fLow; //最低 low
' t/ x U, _& n B1 Dfloatm_fClose; //收盘 close7 ]7 X- z* V- R; f9 Z3 J( ~
floatm_fVolume; //成交量 Volume; E. A: D0 E$ g
floatm_fAmount; //成交额 amount, W2 e/ S& V8 m$ @5 p2 p" @
WORDm_wAdvance; //上涨家数 仅大盘有效$ F2 f( b& V+ S5 r0 j, A" T
WORDm_wDecline; //下跌家数 仅大盘有效* q* {2 O1 y0 U0 r1 j+ U5 C
}STKDATA;
2 Y4 u9 }8 V6 c: H定义STKDATA为 tagSTKDATA的简单别名,STKDATA
" G0 J4 \& K5 V2 V8 M( V为真正方便使用名称,tagSTKDATA 为定目的的过水名称7 _5 y, L" v* u, [, }
////////////////////////////////////////////////////////////////////////////! J5 E' i3 o! n) a
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
3 f; t3 O+ [! I. p: Stypedefunion tagSTKDATAEx
" c" _6 r/ ~/ g2 {; F: S+ W{' Z2 I( `3 @4 E1 X
struct
- d. Q8 p; t9 Q7 p{6 Z' X' c* F/ {% O5 f
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open
& c. W5 w' @6 g" U9 _floatm_fHigh; //最高 high! u7 W: \& x Q+ u$ p# n* K7 D
floatm_fLow; //最低 low
9 s$ P; F* f2 Q$ p' A, M' l9 i$ Tfloatm_fClose; //收盘 close2 @9 D6 U6 e6 J8 A( L6 n( D( Q( e
floatm_fVolume; //成交量 Volume1 f. L) G, u5 V" i
floatm_fAmount; //成交额 amount
& @) n, A: Z+ yfloatm_fBuyVol[3]; //买1--买3量7 M( X" W9 L' t# E6 m8 d! u6 ~
floatm_fSellPrice[3]; //卖1--卖3价/ S9 m0 J& L! R9 }+ f
floatm_fSellVol[3]; //卖1--卖3量
, C4 H4 T+ U; c: B7 l$ ?: I( w};
3 {1 y4 E! c3 Tfloatm_fDataEx[12];
/ `( H# W* L% `}STKDATAEx;( `9 _: x5 I- M" Y4 ^7 N
////////////////////////////////////////////////////////////////////////////+ h5 g' R: H; y& l& J: w `$ n
//定义取用除权数据的结构6 X+ t. F, |$ Q9 V, Y
typedefstruct tagSPLITDATA
! k, N3 ^# l( U' T" x" z{7 I- w. ]6 y$ ^- T6 i
time_tm_time; //时间,UCT
$ Q' K# `0 Z% M9 w7 ~; ^! dfloatm_fHg; //红股
9 e% u( i# o' S& ^floatm_fPg; //配股
. o& W. @, M1 U+ u( R' hfloatm_fPgj; //配股价( r6 v3 i2 k z6 }
floatm_fHl; //红利
, y6 X+ z3 V2 h* `}SPLITDATA;& y/ l% n) t( e# t/ _
/////////////////////////////////////////////////////////////////////////////
, N* z" X5 q: M* h4 Y/*财务数据顺序(m_pfFinData内容)% ?# Q/ x- A# z( H2 D
序号内容- p, I' u4 q' v
0总股本(万股),1 E: u, V# ?6 T! b2 |
1国家股,2 {# c: A& S. D( E3 j: t# y& c
2发起人法人股,7 W `& M7 H# ?# m# M! ?8 e
3法人股,
# M8 \$ z# ~5 |3 q4B股,
3 A- b9 [. l9 L4 w7 F5H股,9 b" z2 Z/ D. H: `; ~! I& g6 a
6流通A股," ^; _1 o0 {* a1 }9 n5 H6 W* e: X
7职工股,! e. h# f$ [ \" k: a
8A2转配股,
3 c5 t- J) Y% k4 ]: b9总资产(千元),- @3 e/ F9 s) f" x
10流动资产,
. s* \2 S! v& z11固定资产,
9 u! ?/ i/ O& `! r& \. |% w/ B) ^12无形资产,2 H4 r* A4 z. l
13长期投资,
- f- O" b! P4 h( G4 Y14流动负债,
( {- x/ L9 z% n) I% `! P15长期负债,* j8 A! c1 e; c% m, r6 w
16资本公积金,
$ z6 \; f9 z# G# \8 B# i8 V17每股公积金,8 s) N2 j1 e0 q% Z
18股东权益,, P* B/ {' X. F* T/ b
19主营收入,
0 `2 P9 N% Q' a0 J3 c3 S! z: |3 ~. W) a20主营利润,
: m" [5 i; X% l: u% J21其他利润,
2 ?# m) l/ }9 s/ v* L5 E22营业利润,
( N3 E$ V. f. S23投资收益,# Q' a+ l: M. p( g3 \
24补贴收入,
- L( M0 W1 I4 h! K0 v3 p' C/ U25营业外收支,) E( w' D. q4 T7 q
26上年损益调整,& O7 x* N- K! J8 S1 R
27利润总额,
" c9 p+ [( K% H* [3 `28税后利润,4 i7 M, Q7 O! l2 e% `+ P4 H( `( Q
29净利润,
# t0 ^ ?( ~! O f" g30未分配利润,/ D7 i/ _! F3 e, m' E) c @ k
31每股未分配,
/ {4 E: g# {. @! r, C0 s) y5 `32每股收益,0 X+ D$ Z" v1 Z$ ^! U- v: t
33每股净资产,
! }+ N) d. D0 g8 T3 \: j34调整每股净资,
0 ~' B1 M& k# z% L! b0 |2 Y9 L( E# k35股东权益比,5 j/ j2 M6 ? A1 e' {9 d9 G
36净资收益率) W( I9 D6 C# N
*/
! {' i9 I) ~% e3 { A* ^' K. Y. r: Z/////////////////////////////////////////////////////////////
4 \, I" A- d$ T8 o* L//定义取用caller函数传递参数项 的结构! J/ n8 B' O2 R6 U+ S V8 }2 f3 q
typedefstruct tagCALCPARAM
! }3 G( P3 P! B8 x- A{
& w l$ |9 y4 a5 Y+ e" zunion
3 Q0 u% H- T) a% Y) {{
I0 k2 t$ ^3 ~ @6 d; ^3 bconstfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
! L# U' m( w3 k- `' O/ tconstfloat m_fParam; //数值参数 valueof parameter! ~( S8 _- f1 c; I; w4 s
};
( P) h- z/ N. S3 g' \4 \3 Kconstint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
$ J1 [# u4 L# h: S6 K}CALCPARAM;
8 u- i2 N3 R; Q/////////////////////////////////////////////////////////////////////////////& T6 b/ {3 E; W) \6 \+ S* W1 r4 [0 Q
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )0 X; n( y$ s F4 d
typedefstruct tagCALCINFO; a+ B4 g2 s4 g+ k
{) E9 S/ `# E* d: c
constDWORD m_dwSize; //结构大小
0 ^! z$ Q3 }- K' WconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
+ ^, L9 ^/ s! E, w2 V* MconstDWORD m_dwSerial; //调用软件序列号
+ s' j' C* _' E5 pconstchar* m_strStkLabel; //股票代码
: B7 Z! C$ K8 lconstBOOL m_bIndex; //大盘 Y* S6 s7 O; a$ A% r
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度: H! e S& g' f, m$ A) Y
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
0 f! m( I s( j# @$ @ Z! ^constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
% g3 A$ U. J- ~6 \& @9 _2 [# ~constint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter 9 {" g7 C% g, P" N' G
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 6 \; ?2 u4 m' ~+ a, K- p! _. o/ s
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2) L8 H* D; y; K! Z7 ]. c; x# L
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
; N5 j3 M3 e9 \. s& ^. ~; S) Econstfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4) Q, k& ]' C+ `: h5 c/ s
float*m_pResultBuf; //结果缓冲区) Y9 @5 L/ G7 ~+ l) `
constDWORD m_dataType; //数据类型
# B+ T: R9 y: ]% f' N& Wconstfloat* m_pfFinData; //财务数据
0 O' Z4 ]4 p0 w5 [+ O P//以上与分析家兼容,所以沿用其结构和名称
+ Q% t1 E4 d! Q+ q//以下为飞狐交易师扩展(fortagSTKDATAEx)
, ?. |% @; d- z% O/ N& ~# IconstDWORD m_dwReserved; // 保留3 L7 V9 p( J: j/ |2 H
constint m_nNumParam; // 调用参数数量( F; n/ |9 m! j; E' [
constCALCPARAM* m_pCalcParam; // 调用参数数组
( S; }9 h4 E, X! Q4 X7 gconstDWORD m_dwReservedEx[4]; // 保留( S, q* ~. C Y& m O9 b6 N! k
char*m_strStkName; //股票名称8 _( Q$ t( [: J; w, c. m- s: o2 f
SPLITDATA*m_pSplitData; //除权数据
3 U8 q% ~1 \; [% M0 `intm_nNumSplitData; //除权次数
5 X3 E1 t+ D6 ?& C9 F6 ? ^}CALCINFO;
0 C$ l& E" f/ P, D" S' h, c# u+ Q/*: o- ^! N" L5 L% N
注1:(与分析家兼容)
( h; L8 `& n" _. j1 N2 H$ k, F; g1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.4 q9 d+ V# O8 L0 h* H" L/ ~
2.当一个参数无效时,则其后的所有参数均无效.
, D8 c9 y Q% Z' D如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.
* v+ {8 R4 U, A, S$ {3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.! o) [: c6 ~' V0 S0 Y
4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;) H, r5 Z4 { e7 K
5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,4 G0 T+ d5 g1 `
数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
! j& n0 Q% |5 ~9 l+ D8 p2 }: x8 m在时间上m_pData[x]与 m_pfParam1[x]是一致的
$ ?: U- `9 J$ e e. @) M5 O注2:(飞狐交易师扩展)
* A1 A0 d! P% n3 h. P Q1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。
1 t" r! J* u) r# a$ j; d2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.! f( q" a2 j, z6 Y7 P
3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
( u+ `* q# F n' K4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.. N6 w0 Z3 _7 f, ^% D' f
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。
) F( O' j5 ~, J% V6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。# J9 U1 r1 l, |: N
7.经此扩展,对分析家的DLL依然可以调用、兼容。
' J7 n7 q3 K; f4 S# ~4 u*/
5 |0 T5 s* R2 u0 }+ u///////////////////////////////////////////////////////////////////////////////////! l' A, K4 W% H H
/*函数输出
6 g# y9 G8 ]' q! Q4 w4 D' l__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);4 I/ P" e' V# h" x
1.函数名称需全部大写.
/ z' I; X' M/ d/ s2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
8 s& {" a/ l3 a) J7 V7 U5 L对于C++程序还需包括在extern"C" { } 括号中.
2 e) j/ r. J' w8 j" u% D# D1 v5 o3.函数计算结果用pData->m_pResultBuf带回.0 K! w) b- z1 L1 A& G [8 f e7 }/ ]5 v
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:9 K' T4 N/ P2 q2 A+ g+ v
m_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.. U6 ?' t# U6 O# p; y8 Z
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER: H3 z$ X) G9 @) _/ a, h
*/
4 P; Q; G3 A$ |1 Y3 }8 G+ e//示例函数,使用时用实际名称替换1 E2 t- p. A3 h) p: t0 ]& H
__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);
5 x: L# |9 a3 V% x. ?1 |6 y__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
5 X. P9 Y/ c! `//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
0 D6 S2 O8 k* h: E k3 U__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);% Y& R' b; a: ?- C; K! {
//WINAPI = _stdcall
" T6 Y2 m; p2 {#ifdef__cplusplus
6 Y: h! I2 v4 v2 k B# O}$ }6 S' g) o: g) t
#endif//__cplusplus
0 ~8 E+ q/ Y3 k- C! d1 w, c1 P#endif//__FOXFUNC_H_INCLUDE
3 N) s% P* ^# u2 f' G( h- g/ q' y7 _
//////////////////////////////////////////comment 注解- P! ]/ M) R, a0 y! i! E
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)9 z/ J& I# T- i- O$ N: {' Q) K( E
pData是指向 址标总结构 CALCINFO的 总址标
3 ]) D& s/ n& s2 i, U3 O3 W取用第二个参数数值floatfParam = *pData→m_pfParam2
: E& N, y' ] D, T& @# R取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;, ^7 @4 D1 U- T1 a' t3 i p6 ]. g% S
取用股票数据长度intndata = pData→m_nNumData;
. i" `. r" g/ z第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0$ s" b* b& `6 L d9 C* Q8 g7 {( P! z6 k
第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
0 n- c) B n! X; S第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL* [( t+ x+ O0 ]9 l7 O
constfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标7 x" `$ d) Q5 ^' k
取用股票数据结构4 c9 b% a n/ T: ]
pData→m_nNumData= 变数数据长度- S; U; c( T6 [$ Q
pData→m_pData= pointer to struc STKDATA 的址标/ ]' {( w+ x2 O9 u$ I. P2 q) r
pData→m_pData[x]数据结构的第x个数据
" V. m J$ ]5 y0 e* k% {9 tpData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
( ~7 l3 V2 `1 `8 C5 j( E) |# ?* f取用结果缓冲序列
1 s6 c" l# O" j8 H/ Y, g _pData->m_pResultBuf8 w8 s. }4 Q; \2 D
取得第一个序列参数的起始序位,如 2,...5 , . 7.../ I& Y1 ~- [7 y$ c$ i5 }
intnFirst = pData->m_nParam1Start; ' N. c" d# F% c6 y q; I \9 i
for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
8 u: g4 o: O# ?5 u5 y) r取得第二个数值参数的数值
$ P" h, }: l6 pfloatfParam = *pData->m_pfParam2; + w& C; ]! z, m- p. p5 ~) t9 l' l
intnPeriod = (int)fParam;" ?4 S `1 O7 R% _. a7 |8 ?" A
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;: S: W, a2 L1 s! S* W' O
取用序列参数的单个直pValue- @, W- s7 W- w7 K" H c9 Y: b
取用缓冲序列的单个值pData->m_pResultBuf1 }8 m ]/ k9 L0 ]% X$ J7 O1 U
constCALCPARAM* m_pCalcParam; // 调用参数数组# }" ^7 W3 K5 Z6 ^/ a' N8 ]
m_pCalcParam为序列址标,指向各序列参数的指标
3 h9 p$ j( g( {# w第一个序列参数pData→m_pCalcParam[0]
' c& R3 ]2 W' m' d5 {constfloat* m_pfParam; //指向序列参数的址标
! \8 t2 e0 I8 M( b3 K! i第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart: u4 `8 k1 C0 y7 ~8 E6 _9 i* y
第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;$ b; o. v3 S1 y6 Z+ O6 P
取用第一个序列参数的单个直pValue1
5 c. J( P& @* Z3 g7 q$ q/ |第二个序列参数pData→m_pCalcParam[1]$ s: ~' F: Z& ^ \8 @
第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
, Z. {0 F) c. P- j1 j* N' s第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;
$ V( P' d# g/ ?6 ^0 _取用第二个序列参数的单个直pValue2 q+ i7 Z) K$ }' ~4 z
第三个序列参数pData→m_pCalcParam[2]
+ I' [1 O y+ i! o. {( J第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart- Y' i7 S: J' }5 C
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;7 `$ v! p+ m% w$ S6 a B' R" \
取用第三个序列参数的单个直pValue3
+ B! b5 K9 E; J* P+ H第四个序列参数pData→m_pCalcParam[3]
! }( c7 Y" |- H# |& K第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
9 m0 s3 s" f/ [1 F$ q2 I第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;' t% g' I# s0 k2 O$ z
取用第四个序列参数的单个直pValue49 V( A! A0 V6 w, Y/ k% N
如果有四个序列参数,则取用序位最高的那一个序位2 x, p% |6 ?2 j- x3 f
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
/ e& U6 m! v! XpData->m_pCalcParam[1].m_nParamStart>= 0 &&
& M1 g6 Z' x: ^) U0 Z( VpData->m_pCalcParam[2].m_nParamStart>= 0 &&
( |9 i( z: {, g$ Y' dpData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值0 I" J+ k/ p4 b/ D# _3 w1 \6 c
{# m$ c/ N7 g4 r4 }0 n2 o) j* n
//计算返回的序列的第一个有效值位置
3 G9 C" R+ @+ n; e# jintnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
: `. ^ k% u' r//若不知,则- A5 C+ Y9 e, h. D( G) j' q
/** e) P+ w/ N" {9 P- Q' b
intnFirst = pData->m_pCalcParam[0].m_nParamStart;9 ~% Q; p( d8 E
if( nFirst < pData->m_pCalcParam[1].m_nParamStart ) " ~* q* c& Q* }8 O, B' x" v% @
nFirst= pData->m_pCalcParam[1].m_nParamStart;# Z2 W1 S$ v1 Y
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) 5 d: C6 s. @$ g5 D) H, _
nFirst= pData->m_pCalcParam[2].m_nParamStart;4 W2 J2 {$ l4 ^0 l
if( nFirst < pData->m_pCalcParam[3].m_nParamStart )
9 i9 c- f+ C- m/ InFirst= pData→m_pCalcParam[3].m_nParamStart;/ G. z( N D, z8 j6 T9 X
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;. d8 R& n% ~% o \
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
/ n7 y7 h& y. gconstfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
' B9 m7 Y6 m# }( Z: \constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;
( A" K1 n$ E+ E' T( ]' o//-------------------
8 ]; {) f* \! cfloatm_fOpen; //开盘 open
& ~9 N" d) d1 p6 l9 Z/ Xfloatm_fHigh; //最高 high
' H. y. I I. k8 r. cfloatm_fLow; //最低 low/ K/ \ M9 E } [4 w
floatm_fClose; //收盘 close
# |# M% |" C' y! |/ |" s7 z0 `& afloatm_fVolume; //成交量 Volume
/ b$ ? G6 H* R# ]& {floatm_fAmount; //成交额 amount9 o- a+ I9 W1 H# k
调用收盘据
. d5 O3 ^# u; D: b w! \pData→m_nNumData= 变数数据长度
- \) P9 J- R0 {2 J; h9 @pData→m_pData= pointer to struc STKDATA
3 Q9 I% m* V1 S# DpData→m_pData[x]第x个数据
y: N( p' ~" q( p4 V7 v H5 ?3 zpData→m_pData[x].m_fHigh第x个数据中的 High
# B* I" P7 T5 p# S@@@@@@@@@@@important !!!!!!!
7 p$ r( f0 y' ]sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
9 F* f7 |6 S! T' ]0 Z1 [so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct1 M8 ^, W9 M% t0 a9 m; J$ D
pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
1 f6 Q/ Y' Z# O. apData→m_pData[i-j].m_fHighto use high; d/ S8 f3 P9 |
pData->m_pData[i-j].m_fLow
, [6 b6 m7 X G* s. ~7 OpData->m_pData[i-j].m_fClose/ H. a. [$ T, q7 U, z
m_pData= pointer to struc STKDATA) `4 D% Y/ Y/ O2 `
incalling C++ dll function
& b. \3 n r# W+ \) C V4 p) _m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)4 P2 l3 \9 H( L5 K
touse a single value in variable ‘High’
# D6 u; Y. B$ x; B. epData→m_pData[i-j].m_fHighto use high
( U) r, W9 h$ V7 Gconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
7 I" L# P: k) r3 Rconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
8 P* I" {3 q9 O1 fconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
! U7 v: `/ X( D5 ?$ aconstfloat* m_pfParam4;
2 M: h# U. q, a/ Um_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数7 Q5 J; ]+ G# H
pData→m_pfParam1= pointer to 第一个(序列)参数+ y# N- b6 W$ z" ~/ @: _+ Q
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值
6 G/ D4 l6 K, G/ _8 U! s f: C4 R& Tconstfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
) C: _2 Q9 P) B0 o& xcpParam[x] = 取用第一个(序列)参数的第x 个值" U5 ?& M9 L5 A+ @
m_pResultBuf= 结果缓冲列+ W) S' F" B: L) j! D
pData→m_pResultBuf= pointer to 结果缓冲列
" {1 t) T* }% a8 Z3 R- Y$ \pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
4 ?2 H) C6 [) i6 O* @; |//////////////////////////////////////////comment
: Q B1 t3 e! F3 }//////////////////////////////////////////comment 注解% G6 _7 X1 \9 b/ \+ \3 P3 W' K
constint m_nParam1Start; //统杅1衄虴宎弇离( l4 V# u% s* U; O) I
constfloat* m_pfParam1; //覃蚚统杅12 e" W5 H Z0 _: U
constfloat* m_pfParam2; //覃蚚统杅2
% X; F3 Y4 [) t0 P" K' jconstfloat* m_pfParam3; //覃蚚统杅3+ B* v. [8 C9 ]* Y- @6 }
constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4
! u5 u* ~" y; k//const float* m_pfParam5; // parameters must be <= 4
% _. Y) S; X. M8 I) f; o8 r//const float* m_pfParam6; ! D1 m* {4 @2 m- J, X
//const float* m_pfParam7; % R& K* a" [' f ^
//const float* m_pfParam8;
6 H7 T7 w# p$ i$ E" _+ ^2 @ Y//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
. K$ |( ?: q/ T) ?/ M9 |0 {pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0) A# q) r; P* Q8 ]
&&pData->m_pCalcParam[2].m_nParamStart>=0) # B* W r' |4 Z9 t" G5 j
{2 x% M6 R- ]" p7 @( G3 K
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0
* X7 h+ T4 A" q, }% JintnPeriod = (int)fParam; //统杅1
6 o% N4 N" x! @+ [6 G" Y r//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
" {& d8 [/ j2 B0 }+ r' t( F% tconstfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值" m, q o. F) s' t
constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
2 {" N% h2 K% t- J! iconstfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4
5 a I! f, Y$ s+ e1 E; e+ v//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
7 k+ ]5 m; `6 q, `. V* E//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值, w' n3 {( z$ T& Z" n
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA , + N7 D; c2 x% f# l6 Q
touse pData→m_pData[x].m_fClose* w2 W7 D; M9 Y4 P0 P) }& W
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; * ^4 K, y% R6 |) m* |9 t8 k
|1,2,3 , … , m_nNumParam | float m_fOime_t
, ^4 P+ _2 U% q z' g; m|1,2,3 , … , m_nNumParam | float m_fHigh;
2 w7 p: V& z( l0 ^.. .& b& M: j" l& f+ b! e; \) r
|1,2,3 , … , m_nNumParam | WORD m_wDecline;
( L2 s) p$ h! |- t7 L2 t8 u# U# sm_nNumParam= 数据high,close,open,low的长度
' _4 p6 L% {) b# N: ]# Ytouse high:. |# K: T8 W: f! U7 v: F# k- ~
pData→m_pData[x].m_fHigh1 F; y) F; Z) J J5 T& p/ [" \
contentof struct STKDATA
% n( U2 l! k0 }time_tm_time; //时间,UCT
* k- k5 {. x" E9 E0 o4 L. v! rfloatm_fOpen; //开盘 open' U% O* h8 q, W9 a
floatm_fHigh; //最高 high
1 E6 R& ~# X8 I5 K9 s, A' sfloatm_fLow; //最低 low
* r7 S, @4 y7 }4 A- b3 K( [" D( ofloatm_fClose; //收盘 close
& u7 z* t7 I* C" N7 n' _/ D5 Sfloatm_fVolume; //成交量 Volume& l/ z1 Y$ X' r' x8 E) E
floatm_fAmount; //成交额 amount
K, b/ x# N2 |% jWORDm_wAdvance; //上涨家数 仅大盘有效
5 j p! j! _' S/ u1 Z5 e oWORDm_wDecline; //下跌家数 仅大盘有效/ \5 d5 ]% t" M8 Y" Y' o g
调用传递参数及传回结果
( a; h2 u1 F& p7 X* n# A调用传递参数
4 s) M( Z! T7 T) ?$ _: K(pData->m_pfParam1 && //参数1有效Param1exists c) f! N9 }( y; F
pData->m_nParam1Start<0&& //参数1为常数# }* {! Q, u0 s- r2 ?: M
pData->m_pfParam2==NULL) //* I+ I- X$ T c2 F+ p# T
localprocedure 定义使用变数4 E' {" u$ @* r% m+ `9 h. ^5 w3 H$ j
onstfloat* pValue = pData→m_pfParam1; //use constant参数1
: x/ X/ t. V' ]+ z9 a YintnFirst = pData->m_nParam1Start; //use 参数1效值起始位
6 z$ b, a8 n- H( mfloatfParam = *pData->m_pfParam2; //use 参数2" T0 {, w6 R5 \6 a% F
intnPeriod = (int)fParam; ! l6 V4 k* j' x& ?! \' Q
传回结果
, a0 o" N5 W! f0 m* m" ufTotal+= pValue[i-j];
! P( X6 n# k4 d0 X7 ?pData->m_pResultBuf4 z0 Z! ]& F0 P# V7 t
//////////////////////////////////////////comment |