许多年以前,我曾经在! o* K/ g1 Y* T) C7 @0 L
理想公式区发布了
f2 [8 r1 m; L; ]- k6 x' W"/ L, y" F% F$ I3 q" w
如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)+ h9 m( J! T7 x" d
"
( d7 S: d) u5 U1 j$ \( x+ \# l) P
}1 }. i/ J# w/ W$ m4 j现在更新foxtrader(飞狐交易师)
; M" X9 B3 `0 Q& g9 f7 v连结 DLL的方法+ @, \. m5 Y. f2 F% V8 H
3 J# J: R$ D. N1 d: ], F0 j0 yfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )5 q, _8 ?8 E; {3 h9 R
gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )0 J& s0 U8 X; F; R. ~
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响) ^/ K- b( J- M% ]( a7 `
foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
( h4 d% u- M6 G% m- i7 i8 H$ t& }5 v4 t; c" Z
也就是这五个结构都能用
0 O6 U' r/ ?, a5 [typedefstruct tagSTKDATA 2 W( I, d/ ]+ B" b3 K% f# s) ~4 k9 F
typedefunion tagSTKDATAEx
, a) o4 X4 Z& a* I7 utypedefstruct tagSPLITDATA
2 { b1 {4 Y, S- |typedefstruct tagCALCPARAM
9 E5 m- [* i- m( d2 [typedefstruct tagCALCINFO
: k: ^' J" _: t5 t' S4 P5 A7 u8 w: {6 ~ G5 d
自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
* u& P8 i: T2 h1 w7 j+ o' W8 r也就是这五个结构中
- }% q9 L' f, H4 Z! }1 |typedefstruct tagSTKDATA
" a w9 y( E' i- k7 R: Ltypedefunion tagSTKDATAEx
3 l# j. r" [" |2 P$ Y) stypedefstruct tagSPLITDATA
$ _' p, @) M# ttypedefstruct tagCALCPARAM
6 P; ^* S, I9 s: ^typedefstruct tagCALCINFO
* ~3 |5 n8 x" `. b* Y& h+ n只有这两个可以用
. }+ Y' C2 a; e/ a* ^/ ptypedefstruct tagCALCPARAM/ `/ y. |. c' b
typedefstruct tagCALCINFO
8 F+ o" k/ b6 e, w) Y1 I: N+ `值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
% p6 \7 J1 ?4 Q. z l9 @typedefstruct tagCALCPARAM( @+ `% Z+ K: w' `
例如:在 foxtrader中
2 b2 |5 x* m9 K) X' mMA1:=MA(CLOSE,3);
1 j2 ], j2 c0 V8 ?. ^. kMA2:=MA(CLOSE,6);- I% T {/ a0 h. n5 W: C) Y2 ]' _7 J
MA3:=MA(CLOSE,12);. d7 U+ L: X, `* L$ H+ \
MA4:=MA(CLOSE,24);/ Q& ?$ |: g$ v* r
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}% V- E1 Y8 \! y, m" d9 M! d3 a
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
9 B5 A6 d3 O3 s# `5 u) P1 T下面这两式计算结果相同$ O, p. p& Z7 |, j( y
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 自行计算}
. m; G6 K) e; W3 F) R y: bMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}8 v% V% s# b1 H( X% ]/ x9 x" k
其他例子2 |! ~9 Q( ]& O) X: Q3 w# y4 ?5 Z
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
6 ?, S$ z; o8 ^ ]) `( {oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;
2 ?! R3 u) C' N0 N+ s其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的- _/ g+ n X4 W8 }
fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
' w% w1 {6 Y7 [" B' ~$ t7 C
9 O! m3 }, W1 Q$ T8 y n
8 |# e4 [0 D/ `8 i4 Z////////////////////////////////////////////////////////foxfunc.h
8 w4 Y0 ?0 D) Y9 T9 H3 m) b#ifndef__FOXFUNC_H_INCLUDE$ Z* [! O( a6 t& f( [* G
#define__FOXFUNC_H_INCLUDE
! n3 V; h6 K) l+ x0 Q* x/*. C2 g7 }- |1 o$ N3 w* Y) X
飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
3 b2 W* {0 y6 u- {: b1.本规范适用于飞狐交易师V3.x公式系统.
- d/ I5 W& ^# a! Y2.扩展函数用于实现系统函数不能实现的特殊算法.0 S t. Q0 K/ h0 x' \# z) M
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
" Q" J/ D0 J: P4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5) C9 A5 O9 w: Z2 s
5.动态连接库名称和函数名称可以自己定义.
' p6 i+ i" h: q; E! q$ I( ~6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
/ ^9 j7 d% g3 M*/
5 M: T( d5 O' M+ h! r#ifdef__cplusplus
, ^, }0 q9 X/ \% cextern"C"4 y3 F# _3 [8 P6 ^8 ^2 E( K
{3 u9 s+ F1 z/ @7 H! Z
#endif//__cplusplus
9 ~( J" u( Y6 P' c' G! A E///////////////////////////////////////////////////////////////////////////
. \2 `0 k/ O4 ?7 a! z5 ]* o//分析周期' n) N1 n/ w) @$ v
enumDATA_TYPE
4 Z' Y- X! b4 p# S6 S m P" s3 x{
' K0 H5 M, @& v9 [1 ZTICK_DATA=2,//分笔成交
7 i% u- k: `2 s, w: `5 y" e4 M6 bMIN1_DATA,//1分钟线
' y1 l! t* @' U% T* cMIN5_DATA,//5分钟线 : w5 E1 a3 Q7 q- ` P
MIN15_DATA,//15分钟线4 o5 `1 z' \; X9 a+ s: v
MIN30_DATA,//30分钟线6 h6 Q3 e/ g0 Z# Y$ A! L
MIN60_DATA,//60分钟线
# T$ w6 F, a9 [$ P7 `" Y. g8 UDAY_DATA,//日线2 W" G5 g8 S) v. C5 } |3 V. p
WEEK_DATA,//周线# c- y+ i+ O: {
MONTH_DATA,//月线
6 V. b1 t& q3 o0 Y' ZYEAR_DATA,//年线7 C# ]0 T2 u/ x: j5 z# @
MULTIDAY_DATA,//多日线
& Z/ S3 I* Y- V8 uMULTIMIN_DATA//多分钟线
0 Z8 S( _, n. o};
+ }% F* Q" z' Z- X3 F" Y) h0 m///////////////////////////////////////////////////////////////////////////% |1 C4 A8 B- d7 v0 H1 f/ S
//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用
$ Y, J; z9 Z8 L! ptypedefstruct tagSTKDATA
( H# x9 P" y8 m n V{
. g: K# G: I6 Z9 C/ H# N! Z5 M _tm_ ; //时间,UCT
! h1 a' ] `/ e+ wfloatm_fOpen; //开盘 open
: ~9 D9 r9 R, S& w/ pfloatm_fHigh; //最高 high( r! m0 q2 v5 r- Y) J) b4 X
floatm_fLow; //最低 low7 n; _" @) X! [6 m
floatm_fClose; //收盘 close2 v- k" L2 X* C7 y% g1 z1 z
floatm_fVolume; //成交量 Volume! y$ t- P# D' Y7 Z
floatm_fAmount; //成交额 amount
4 N* E/ U( v8 A5 f( WWORDm_wAdvance; //上涨家数 仅大盘有效
" k# L! C* r% [. o% TWORDm_wDecline; //下跌家数 仅大盘有效. D# \. x* r2 H4 h8 z
}STKDATA;
3 ?# }6 ]- l/ p# i: N7 ]/ c定义STKDATA为 tagSTKDATA的简单别名,STKDATA / m* e5 @# A5 Q! F2 A
为真正方便使用名称,tagSTKDATA 为定目的的过水名称 n6 ^/ g' j$ `5 |, `9 q
////////////////////////////////////////////////////////////////////////////# q- g* o6 o8 Q# r( T9 R4 `
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
6 D+ K, W1 ~9 @' e2 d }typedefunion tagSTKDATAEx/ I8 }6 ~8 {7 J5 C* M, s! T
{4 L+ L D; A# c1 H2 y
struct r1 |* t9 i1 H& ^+ m' \
{
3 Y) l+ D5 `7 qfloatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open# ?/ L$ Z: z) G$ o
floatm_fHigh; //最高 high
& y4 g$ H& I$ Q }& m3 P/ _floatm_fLow; //最低 low
: R+ _. u# H. {2 U; Efloatm_fClose; //收盘 close+ N- f8 s4 n9 Z1 `" B) R
floatm_fVolume; //成交量 Volume7 h' \, ^' g5 n* n! |# W
floatm_fAmount; //成交额 amount
7 \5 Y# h( M2 p) H0 z# q3 Xfloatm_fBuyVol[3]; //买1--买3量: M# B* W R( ^' e/ [) Y4 _
floatm_fSellPrice[3]; //卖1--卖3价; c, s, d' J, G9 e
floatm_fSellVol[3]; //卖1--卖3量
( N8 m" v/ M# h& y1 n- S" Y3 S};
" }( H5 b+ s' X+ Lfloatm_fDataEx[12];3 K+ u( d8 v! S% |% [# x( e- ^
}STKDATAEx;! \. h# {; ]$ e; d
////////////////////////////////////////////////////////////////////////////
- q* ?( y% n" Q//定义取用除权数据的结构
* I. s! R4 k) ktypedefstruct tagSPLITDATA 2 T$ h, R+ G4 ^
{% G7 Y: _# v7 C3 b! G, V
time_tm_time; //时间,UCT. [, V$ d& S5 y+ P- J
floatm_fHg; //红股
" r8 c+ N; {! @! e- }3 Wfloatm_fPg; //配股2 v) M# Z5 o0 C E
floatm_fPgj; //配股价) U$ N5 f P- q) i; v; Y
floatm_fHl; //红利+ j; }6 Q# P2 X3 i
}SPLITDATA;" E% S, f& ?+ P% U" E* [
/////////////////////////////////////////////////////////////////////////////
; I* q$ T8 U* j- ?* Q% |3 t/*财务数据顺序(m_pfFinData内容)
; d1 g4 g* O; p2 j) \* J序号内容
; E1 A6 R" t5 I: q0总股本(万股),
/ V6 {. r6 w q1国家股,+ u( ^" `( I( N9 r9 D
2发起人法人股,% N- D: Y, B3 b3 n/ ~$ O
3法人股,
* x( T* w, F# a: t4B股,
0 Q6 G: u1 L6 O: N7 }5H股,; [' c' O$ U/ e
6流通A股,9 K% D1 I% y( U
7职工股,5 V( A* w; i- D# s' F/ \8 E- }2 {( i
8A2转配股,2 G1 K& Z( o+ [$ @5 V$ Q% Z
9总资产(千元),( K l1 L9 T! ^4 A
10流动资产,3 p' G% X6 K0 R
11固定资产,
- X5 X$ W2 c; F2 X( K12无形资产,9 U) _7 y7 t; R4 z) ^8 G( d
13长期投资,! O! t: B/ z! V* ?5 C9 V
14流动负债,
& U. S- Q# p, e5 H. t15长期负债,4 D9 c# K1 O9 |# ?
16资本公积金,
! f6 S0 a* s& U! g% V17每股公积金,6 O2 G4 T5 L4 ]% r4 g* ~! \6 U
18股东权益,
' n. h N7 ?) B19主营收入,
) I0 n) Z( k8 g! S" R20主营利润,
2 l; d4 ^0 C& B/ \. J1 } i4 ?' l21其他利润,
! u' @. L$ W! J: x7 L, @22营业利润,, t5 R* A( w1 m- {
23投资收益,1 T: g# E0 `4 u! a3 z
24补贴收入,$ \" ?1 O& `" v) G
25营业外收支,
8 i: d3 {# x% A26上年损益调整,
! ^* @& N3 ^ ?% y. N27利润总额,1 w& _8 d/ C) [$ _) T2 S
28税后利润,4 S% r6 F0 A% P( A+ {; ^$ J9 t& d
29净利润,, ?" X- L5 x# Z# I% E* A/ i5 s
30未分配利润,
3 C7 U1 O' g/ o7 i31每股未分配,; @1 n: ~5 F: K$ s4 R) V
32每股收益,1 v0 o4 W B: P$ N& U; q) e
33每股净资产,
% u2 V, H: E3 T$ _% W2 o2 _34调整每股净资,
" X( S" a0 e6 w" s( n35股东权益比,
9 s5 a% p- u& D! A. [# t% Y: w36净资收益率2 a4 X, Z0 _. i0 c* s3 K& J
*/
1 z; U/ m: f9 m% T$ f7 M8 M7 e/////////////////////////////////////////////////////////////9 X% i$ t) i1 j* }
//定义取用caller函数传递参数项 的结构9 a3 l- s( ` e! M0 V8 d' s
typedefstruct tagCALCPARAM6 ]2 t; b) z! r! d
{
; Y+ A# Z$ X, q- f4 eunion
# M9 ?9 i/ A9 q- _3 e5 U{; u3 E3 _4 T( a' e* c: L% A0 {
constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
/ O7 t+ {2 U4 x! q) l7 Gconstfloat m_fParam; //数值参数 valueof parameter
% S! R0 G4 H' T7 p: C0 i5 }};7 w, ?0 a8 d; G$ a
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
+ F$ ^. G! d3 L6 _}CALCPARAM;- z2 n, V2 @9 P! t" p. Q7 q
/////////////////////////////////////////////////////////////////////////////
* `4 m* w& k* }, m//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )$ L. m1 S9 ^) U/ S9 \5 I
typedefstruct tagCALCINFO
+ V' T' ^# H# G{
% r# F) [" o3 b8 |8 z7 pconstDWORD m_dwSize; //结构大小9 e' }6 e- I( A: R# a ]
constDWORD m_dwVersion; //调用软件版本(V2.10: 0x210); S: }: U9 M2 r( [0 P; P' J
constDWORD m_dwSerial; //调用软件序列号
; E: E- g& l2 Q; M1 J" Q, ], y+ Q: Uconstchar* m_strStkLabel; //股票代码& _ m( e1 Q4 x
constBOOL m_bIndex; //大盘( x3 P& r0 @9 j8 k
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度
0 Y# l! b/ h: ~& ~& econstSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL* m* f, D4 k$ o% r0 q% s$ L' J
constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
/ o. x, q' H/ {6 X. L/ @constint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter - K1 f5 V% K+ r/ y# h
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
" t2 G% D' E& t7 d5 f4 z6 ^constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
. T4 L* c' D, m n- } Vconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
- @0 q# w/ M {constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
?0 C: c1 j: q! @) Hfloat*m_pResultBuf; //结果缓冲区
v2 s# q& Q( K6 MconstDWORD m_dataType; //数据类型
# z! }# T1 r$ wconstfloat* m_pfFinData; //财务数据
- M5 F6 M- m' J2 ~! D//以上与分析家兼容,所以沿用其结构和名称
/ c' ? P; D! X. N5 R7 U: n% _//以下为飞狐交易师扩展(fortagSTKDATAEx), U% g0 Z. V8 |" U q
constDWORD m_dwReserved; // 保留
& Y5 Q8 H8 ^7 Q) N) wconstint m_nNumParam; // 调用参数数量- Q1 R$ X- K0 G3 s) h
constCALCPARAM* m_pCalcParam; // 调用参数数组
5 E# S3 f3 `& ]: \( w4 b' dconstDWORD m_dwReservedEx[4]; // 保留' {9 g$ C/ J3 I
char*m_strStkName; //股票名称
2 i m t6 i8 Y0 W1 USPLITDATA*m_pSplitData; //除权数据
# d& z6 { ?3 r; S Uintm_nNumSplitData; //除权次数3 a( Z: ~+ w4 {$ h- I1 a8 [
}CALCINFO;
' E6 P3 M# ] j+ U' F' Z/*+ f6 c; o3 t# r
注1:(与分析家兼容); v7 {2 F7 y' R* x
1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.: r" J) `9 |/ d! B5 @* J
2.当一个参数无效时,则其后的所有参数均无效.3 {6 W7 L! B5 e4 v& R
如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.
1 G8 U2 T0 h _3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
7 G0 [! `7 ?) G6 x4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
5 z. N: s F9 Q4 `1 m5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,+ g( r. \$ O& n0 D" T
数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.5 R! Q2 o m; L8 X, N, {, Y f2 f
在时间上m_pData[x]与 m_pfParam1[x]是一致的& A' h; o8 \3 Z v
注2:(飞狐交易师扩展)
g- X/ {5 ?: r( ^2 l; o: a3 b1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。
5 v A; M2 N: |2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1. z& f; M7 H p3 D/ I4 ]
3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
' H2 \6 L g9 f* {# i1 `: l4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.
2 `" W+ j: ?8 r; |5 z8 |5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。+ q1 W1 _4 ]) i
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。1 c) |/ ?& d# P9 Y6 J
7.经此扩展,对分析家的DLL依然可以调用、兼容。/ O0 l$ R2 Y2 M8 u A H- R# ]
*/* @0 A7 G) S; P
///////////////////////////////////////////////////////////////////////////////////7 g. }+ c& C2 {
/*函数输出
4 U* `) X. L7 i4 s: k6 M__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);. d7 s9 }9 k" E
1.函数名称需全部大写.* ^/ h* p, Q) O7 z( V. m2 k* o3 G
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
6 a5 s. Q1 ^' O对于C++程序还需包括在extern"C" { } 括号中.. y0 Y; g2 W: ]; Y5 H0 z' t2 s9 r, X
3.函数计算结果用pData->m_pResultBuf带回.9 Z2 T2 K- `% R$ y( J
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
; ?) C4 p, n, A7 U$ @" g2 bm_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.
. z5 u- v: h$ n# Z8 h5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER2 M1 y9 S7 y0 ?
*/
, U V( M/ [1 U% u! k//示例函数,使用时用实际名称替换, Q) J B$ b- S+ L
__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);
( t4 v( S, c* { X" g' `__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
% K- W( ?$ X& B//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
7 Q$ K" z5 R7 g- ~ v__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
% j6 `& e3 Y+ k//WINAPI = _stdcall
! \$ q) d3 A- i# e! _#ifdef__cplusplus2 a7 @. L) g' e1 c* W3 g
}
% [# R, |: T4 ]' { O0 T#endif//__cplusplus
" p7 q# J5 |* H% P# i+ j0 B3 b#endif//__FOXFUNC_H_INCLUDE
7 {8 e$ A- d: x3 V2 F! ^5 U' V" z$ X
- j5 ]) p6 e# h( v4 J) @3 r! w% g, s//////////////////////////////////////////comment 注解% I$ f* l9 Z& x+ B9 h
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)0 f8 l) I) p. O- {$ j
pData是指向 址标总结构 CALCINFO的 总址标( j" h( g! U- f" K7 k0 d
取用第二个参数数值floatfParam = *pData→m_pfParam2 2 d, }: ]- ~% F, z3 |! f+ W+ L
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1; o M! K3 d7 n
取用股票数据长度intndata = pData→m_nNumData;
, _- m0 U+ M( q( V7 l. l第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
p3 I3 p0 P9 _: t% H; V# S3 Z第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
; C/ H- T& O6 p- C第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
' A, _7 `' |: L& L) @, Nconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标/ e( F1 ^6 I- p7 j, \. P
取用股票数据结构# \; R) G/ x6 M# W
pData→m_nNumData= 变数数据长度
4 G- [$ d' Z+ U% I. F$ z$ _pData→m_pData= pointer to struc STKDATA 的址标8 I" F" N" c, H9 f* c9 {$ w0 ]4 S
pData→m_pData[x]数据结构的第x个数据
0 V7 S; g" R- r1 G `pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
Z4 o1 l9 n. Y+ W) k取用结果缓冲序列4 {6 ?2 v) ~$ _! _( l+ J
pData->m_pResultBuf
& }1 B% `5 g4 \: o n取得第一个序列参数的起始序位,如 2,...5 , . 7...
- n) h# }4 c" W7 c) V, CintnFirst = pData->m_nParam1Start;
. |, |* F* t) `9 _9 L- U2 f Ufor( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ ): Y! `% J! t1 M
取得第二个数值参数的数值6 p( u$ e5 _8 K
floatfParam = *pData->m_pfParam2;
# e# [, y: k7 q9 uintnPeriod = (int)fParam;' }: x0 q8 i2 S- n! r
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;
. b5 @+ z. E0 A) O. y6 b% y取用序列参数的单个直pValue* R5 U& z$ j. _4 W5 y6 x$ {$ v9 M
取用缓冲序列的单个值pData->m_pResultBuf; F1 Q4 G1 q6 x0 L1 ?
constCALCPARAM* m_pCalcParam; // 调用参数数组
- ^) E3 U9 A f5 S" L0 a9 ?3 P& ?m_pCalcParam为序列址标,指向各序列参数的指标
6 e4 G" r" y- n/ J5 c7 Z第一个序列参数pData→m_pCalcParam[0]
/ ^% b7 w3 U3 G7 @- z0 lconstfloat* m_pfParam; //指向序列参数的址标# Q+ S# h% Y6 u) d1 }* `. n
第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart& V7 }, s1 g& O
第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;; w- E& Y# c# R. ]4 W, ~
取用第一个序列参数的单个直pValue1
/ k. t/ p1 t/ X9 u. S( }) P N第二个序列参数pData→m_pCalcParam[1], d3 Q& N9 d* p7 @' s: N
第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
) W+ U+ H4 _$ _$ m9 ~第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;+ K5 v/ ^8 m, D3 G
取用第二个序列参数的单个直pValue2
! s2 R$ D5 w$ v* B) y- `1 b第三个序列参数pData→m_pCalcParam[2]
: D. X% F) G) }7 ]6 h+ p' m第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart
( N' X/ W8 U9 y1 j, i. z* _第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;
' u r; o% X1 E N( e* b) o取用第三个序列参数的单个直pValue3+ C5 ^7 \$ {2 ?* ^: l5 [' Y
第四个序列参数pData→m_pCalcParam[3]2 X; l3 j L0 O% @3 u
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
4 P1 |# A6 K9 J4 ]: `; X h4 O第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;5 r6 p! u/ }. G! O
取用第四个序列参数的单个直pValue4
) Q7 ~1 O+ X1 Q, @/ l如果有四个序列参数,则取用序位最高的那一个序位
5 @5 R O& A2 W$ i: B4 ?if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&8 o; J7 ^7 Y- t7 |
pData->m_pCalcParam[1].m_nParamStart>= 0 &&
2 Z9 J R+ v5 X6 [, y: QpData->m_pCalcParam[2].m_nParamStart>= 0 &&
( a/ Z6 z2 x* z: NpData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值
# x: C9 [1 @1 W+ G B{
( M- U6 {- n& K% U//计算返回的序列的第一个有效值位置, v* X! w* Q/ b
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
! E# P4 f3 j' a5 e. Z//若不知,则
8 N& H8 z8 Y4 T2 i3 a/*
6 S+ F/ P0 O; @# {intnFirst = pData->m_pCalcParam[0].m_nParamStart; x0 s% M! L: Z! X8 U: h* Y7 T% O
if( nFirst < pData->m_pCalcParam[1].m_nParamStart ) $ I- w+ I/ | t( J$ t% h
nFirst= pData->m_pCalcParam[1].m_nParamStart;
9 h5 n1 W$ _1 kif( nFirst < pData->m_pCalcParam[2].m_nParamStart ) ) K% B! X2 c& ?, D
nFirst= pData->m_pCalcParam[2].m_nParamStart;
' l7 }" X$ x' k& zif( nFirst < pData->m_pCalcParam[3].m_nParamStart ) / @" N; }4 K% e
nFirst= pData→m_pCalcParam[3].m_nParamStart;
( f4 G$ P) P+ |constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;
. z" X* o3 S. X1 D5 C/ bconstfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
: [5 ]- J7 ~7 R6 Wconstfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
* @. Q& T4 [- ]* |. J Cconstfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;9 ?. G8 d" }3 i9 @5 ?0 H
//-------------------! ?' J' T# K5 l" {6 ^" b1 t; W6 U; x
floatm_fOpen; //开盘 open
% w: {' M2 ^2 C, ^$ ufloatm_fHigh; //最高 high8 ?# \1 m) t, Y: v
floatm_fLow; //最低 low
/ {% v$ E9 Z2 Y6 o* Ffloatm_fClose; //收盘 close4 T" k* s3 Z. A1 s# j2 i
floatm_fVolume; //成交量 Volume, P: u s$ |6 Q$ Q) _7 K+ P% ^( @
floatm_fAmount; //成交额 amount! b$ W/ W! r1 Q" G: `$ Z
调用收盘据0 [$ d: Q! U( S9 m
pData→m_nNumData= 变数数据长度
- q2 Z) S; L/ b1 Y! r% a8 P8 v; _pData→m_pData= pointer to struc STKDATA- Y& T7 T' O4 I7 d
pData→m_pData[x]第x个数据
# E4 Z8 |; K- } i" ?pData→m_pData[x].m_fHigh第x个数据中的 High
7 @+ z4 x. R0 \+ i/ A+ r@@@@@@@@@@@important !!!!!!!; a u& S1 Q6 B" D) l
sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
/ V2 i. c" C: j) b2 Bso,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct' X( `! b1 F$ e) o' Q. P
pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
2 f! z1 r- T2 `7 O1 hpData→m_pData[i-j].m_fHighto use high
4 A0 z# {% ]$ G4 FpData->m_pData[i-j].m_fLow
. t8 h4 M* A$ I+ K$ A5 NpData->m_pData[i-j].m_fClose' R C) x4 e5 f# M
m_pData= pointer to struc STKDATA# |" x$ o% h R: f! h
incalling C++ dll function- I# k$ g z! K& G( d8 E5 g0 ~; `
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer), _4 t- d- \8 M9 w7 S
touse a single value in variable ‘High’" l* w7 |. {/ d% k
pData→m_pData[i-j].m_fHighto use high
, D- C: n- h1 y3 b3 X! l* S/ ]constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 " c/ R$ Z' P7 o: G F8 }( R0 ]; [
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
( v( @' L _- L9 O7 j* Qconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
6 {& \9 N% d" k8 P# H7 yconstfloat* m_pfParam4;
1 A6 N& J1 x+ c' C! Y9 j% k. \: R8 qm_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
0 X4 `) i" @, l, MpData→m_pfParam1= pointer to 第一个(序列)参数1 B. V& F1 u- J2 D9 p( W
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值. C! ?! t, H6 b8 ^/ F% Y4 W
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
9 x. [! p! I7 y& W+ O0 `" J# b zcpParam[x] = 取用第一个(序列)参数的第x 个值& _: D3 P- B% M2 @; M; d' x
m_pResultBuf= 结果缓冲列) m3 K* L) Y# ]- N- l) X
pData→m_pResultBuf= pointer to 结果缓冲列& S+ K- v% ?5 K3 x
pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值( L5 x+ p" ]. F
//////////////////////////////////////////comment
9 G8 q; S7 k/ B( [9 P) W8 p/ g g//////////////////////////////////////////comment 注解4 H3 U7 q/ A9 v, S
constint m_nParam1Start; //统杅1衄虴宎弇离4 y+ H2 |# L' _, ^, k" P
constfloat* m_pfParam1; //覃蚚统杅1
9 R3 n M( _' S4 s* Bconstfloat* m_pfParam2; //覃蚚统杅2
( D& J. Z) s. H* Fconstfloat* m_pfParam3; //覃蚚统杅3
- l' o; O2 M* @+ C: Zconstfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4# k' y/ G" |. X
//const float* m_pfParam5; // parameters must be <= 4
4 R: W8 C, ^5 b4 J9 v; F1 ^//const float* m_pfParam6;
& p1 Q9 \1 ^9 [/ t1 w//const float* m_pfParam7;
/ q: T* Q* y0 G9 U3 W$ f//const float* m_pfParam8;* x2 f/ w; |. y4 l$ ^
//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
4 }1 I1 U" q0 }, g3 B' G" U& BpData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0$ [. D4 u% `9 ^2 U0 f7 S7 {9 @
&&pData->m_pCalcParam[2].m_nParamStart>=0) " u: c- _# s( Q8 h5 D) G
{
& k+ K5 E4 H# |# Q- u# n' }9 \floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0
: d1 @+ I# Q! `, J0 EintnPeriod = (int)fParam; //统杅1) K. x5 [/ k/ Q. j. e$ w1 `; k% O! k# H
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
6 Z. |6 g5 b9 c$ jconstfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值2 R' i$ S8 `2 O' B' m8 y
constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值3 ~3 k6 u7 P4 M/ J
constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4& J/ g* X7 w/ K8 T. }
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
7 L1 b5 x; b7 Y: K//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值2 v# X3 u9 t" |
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA , . t/ P0 f( j1 ]$ Y
touse pData→m_pData[x].m_fClose |2 R2 G& o2 e; ~+ \
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; 4 |- F7 U& x( Z r
|1,2,3 , … , m_nNumParam | float m_fOime_t
3 A$ x8 j8 g K z|1,2,3 , … , m_nNumParam | float m_fHigh;
: ]) x5 Z" Y# w; j4 S% t.. .
# q( `! S% m; `4 P' e5 E|1,2,3 , … , m_nNumParam | WORD m_wDecline;
7 W1 J( m" a m( B8 D$ wm_nNumParam= 数据high,close,open,low的长度6 U* p4 h+ w: H8 x( w
touse high:
5 G" J" n" ?4 npData→m_pData[x].m_fHigh
# K6 _6 `; x7 t$ H! v3 y; zcontentof struct STKDATA" _* }/ }7 w4 W+ z" B5 k5 B1 t
time_tm_time; //时间,UCT
& A E+ I, q( j: ?( H, Z5 A! wfloatm_fOpen; //开盘 open: [: \4 l8 {, Z. T
floatm_fHigh; //最高 high
7 U, P4 C: w, Jfloatm_fLow; //最低 low1 i: ^- M% A; J' G- E7 f( J
floatm_fClose; //收盘 close
9 Y S1 E3 G6 ?floatm_fVolume; //成交量 Volume
" {* M( V: l5 _& t: ~, y! Afloatm_fAmount; //成交额 amount
+ u" D# e0 K7 \WORDm_wAdvance; //上涨家数 仅大盘有效
; F% e* B6 y) Q- B0 Z1 K5 R: @9 UWORDm_wDecline; //下跌家数 仅大盘有效
" W: | I$ e: q5 X- |7 d( P调用传递参数及传回结果' h4 ^1 L- b7 F/ e) B9 w7 P
调用传递参数/ E0 ?# Z& w* d; f4 S; z0 z
(pData->m_pfParam1 && //参数1有效Param1exists
: o4 {; G7 }9 o* dpData->m_nParam1Start<0&& //参数1为常数$ s1 {# H% O% V2 e
pData->m_pfParam2==NULL) //. y j- g3 \3 d4 ~- w3 ]
localprocedure 定义使用变数6 r7 f( o+ g7 ?1 Q( t3 Y
onstfloat* pValue = pData→m_pfParam1; //use constant参数1
" q0 J y$ p' `# |- eintnFirst = pData->m_nParam1Start; //use 参数1效值起始位# m2 J+ q8 \: |$ v3 L7 t' S
floatfParam = *pData->m_pfParam2; //use 参数2
. B% |1 H) _6 U- u7 o, Z- E+ PintnPeriod = (int)fParam;
: y0 @4 e7 w, e/ F6 p4 d* U" _传回结果
; w2 x4 D2 r: m0 O) `9 G8 ~" VfTotal+= pValue[i-j];+ G* p; i# S% e4 f+ s' g/ t, J: f5 F
pData->m_pResultBuf5 k/ T T# }% d& Z6 [
//////////////////////////////////////////comment |