许多年以前,我曾经在4 r+ _7 a: B) Z: _/ H9 i5 D+ H! B
理想公式区发布了7 E+ H6 Y! Y/ O# }" Y
"5 J. D- [+ i4 B1 A0 k9 \& w
如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
$ ~/ c8 M3 Z2 U; q6 i9 O/ `"+ d6 H l$ w5 h: u/ D- r* i
4 k$ h4 ?4 N% s( N) [2 K现在更新foxtrader(飞狐交易师) : d" m- q7 g' z8 C
连结 DLL的方法9 x4 y- s7 J/ ?9 P
2 X! X% d/ V% L2 y& V. r' wfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
; f a6 a5 f- _2 a) T- o2 b; fgauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
6 {! Y. S5 [0 w, ygauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响- a9 M% v8 S$ j9 U2 H0 n
foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
! F- |# i% t9 f* b
7 l+ F: J* z: {" D0 a: H也就是这五个结构都能用% C- R4 O" C# o) B& i( x, b
typedefstruct tagSTKDATA & M( ?$ _$ X _2 {' _% N+ X
typedefunion tagSTKDATAEx
6 Y1 ?5 }: u9 |5 D. R G; Xtypedefstruct tagSPLITDATA
$ ] V) s" `4 }' t8 vtypedefstruct tagCALCPARAM, s3 V% b8 I- j( Z/ k _. m p
typedefstruct tagCALCINFO/ |. F6 D3 g" s3 w7 d5 ]
" H% f" O- Y6 ~; i4 C/ g2 }! p
自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
9 v; V6 s: S& B" ]$ S也就是这五个结构中
4 P/ Y( d e& Wtypedefstruct tagSTKDATA 4 D7 b& c% n; P0 [
typedefunion tagSTKDATAEx# J7 o) v) x0 f% ?) Q
typedefstruct tagSPLITDATA 7 L: o# U* s7 w0 d. a8 w
typedefstruct tagCALCPARAM e* S% m; R. K c, `7 _4 x0 p( n% D
typedefstruct tagCALCINFO! u% X% }/ \3 {0 B" L7 v8 M
只有这两个可以用
5 C( \5 z6 Q& f4 t4 atypedefstruct tagCALCPARAM
, y) Y. O8 m& [ G; f/ s- I f8 G$ ztypedefstruct tagCALCINFO
* d* n3 I) G- l值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个& x3 Z, ^! H( @. C9 D
typedefstruct tagCALCPARAM
+ n; D' |+ A) Q l6 [. q, `$ w. B, a例如:在 foxtrader中+ D3 t5 V" \. Z, l
MA1:=MA(CLOSE,3);9 M7 ^! Q2 ^ w1 q# W+ n
MA2:=MA(CLOSE,6);6 N1 [% n' _; [9 b. k* }
MA3:=MA(CLOSE,12);
& c C7 L8 H. u& h6 vMA4:=MA(CLOSE,24);; L9 R8 q6 c' ~
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
) Y$ U2 ]3 x8 J9 g0 s! G* f$ U其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
! v0 r. g! m) r1 p下面这两式计算结果相同! r/ m8 w J( N8 G7 c; O X$ `) w+ B
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 自行计算}
- n/ G% j9 j: }- yMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
: e( w4 w N2 q0 k, Q3 p) ^: @其他例子
: `& K# h7 m! B- U- f+ {oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
3 L) A4 f( v d2 M( |* s- f- ]oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;
& `, B/ U+ d8 E/ }1 u* ]% t其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
, Y) o6 M5 O& FfTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误2 J+ f" s" z7 H/ o9 _* Y1 q
+ x) B$ @6 k. T+ s
5 W+ ^& A; I g: u3 [" f////////////////////////////////////////////////////////foxfunc.h
+ y$ ]. B; Z# l/ C2 R) h: x#ifndef__FOXFUNC_H_INCLUDE: R4 F7 _ j. z' C( m, n
#define__FOXFUNC_H_INCLUDE
: _7 c# S c& y$ T& m8 G/*
0 c4 E8 X- }, k4 v* E1 H飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
" n% T* i- e+ _' u7 p1.本规范适用于飞狐交易师V3.x公式系统.
9 N8 M3 s+ J0 i U. t# ^5 g6 S2 r2.扩展函数用于实现系统函数不能实现的特殊算法.
- G J. n3 g4 L5 F, k V3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
) }9 p2 T, s+ ~0 n1 B4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
4 E4 ?" u, X, ~$ N! O# Q5.动态连接库名称和函数名称可以自己定义.; ^" k$ J3 O, k( u. H( A
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用." M6 |" H5 w& Y6 N3 e* o; ?
*/' { g# w1 ^! S& e, F# Y
#ifdef__cplusplus3 }. r( I) m' g( s9 \- g
extern"C"
) f: O' ^% {8 a{- Q+ d; y: c1 J. k3 F V
#endif//__cplusplus; F S3 y, @# A/ t
///////////////////////////////////////////////////////////////////////////
) _+ h- N$ R9 [' Q//分析周期5 P3 ]* y& e3 c5 p: z
enumDATA_TYPE+ E* O& g& r2 N l3 X6 t
{
_- c/ w8 U% w' Y) eTICK_DATA=2,//分笔成交& S/ ]. g) M7 A- D
MIN1_DATA,//1分钟线
6 ?, t5 T+ o* sMIN5_DATA,//5分钟线
/ Z- y8 z: G* M+ t- C' VMIN15_DATA,//15分钟线' Z' }3 `: I0 @$ Z3 E
MIN30_DATA,//30分钟线
4 P5 ]$ o7 \+ O% n, Y3 HMIN60_DATA,//60分钟线; M1 b0 [" M- t. O5 c
DAY_DATA,//日线 |8 l, A7 t% F3 E& y A
WEEK_DATA,//周线' j# M+ A' i) i; H" o. k& K
MONTH_DATA,//月线
# a, |* @: e0 }$ ZYEAR_DATA,//年线
?7 y$ R& H, ?- e5 cMULTIDAY_DATA,//多日线 r9 G* _4 V- q. a
MULTIMIN_DATA//多分钟线
9 W6 @. z# Y5 u; p3 k7 @" A g};
) X) o' r5 _. u. {3 ?/ J# b* a: I///////////////////////////////////////////////////////////////////////////: O# D3 r' v' Y$ J* m7 y+ y
//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用1 s5 a' O+ t8 l5 @- l0 a* M7 ~( |
typedefstruct tagSTKDATA & J$ ]+ c! Q$ u# a
{
8 F+ n4 }! r6 y% ?! A _tm_ ; //时间,UCT( X9 v7 `7 }. s* c6 [/ C' \& Y
floatm_fOpen; //开盘 open. m' M1 P' r7 ^- x- k) R& V" s
floatm_fHigh; //最高 high
) h# T" g4 w% }2 ?7 v' Cfloatm_fLow; //最低 low
, q$ f! \+ u4 T: q5 w& ~floatm_fClose; //收盘 close
3 h1 z% j4 H9 M. hfloatm_fVolume; //成交量 Volume
2 C+ |9 T7 Z2 a/ m( y' B( l* nfloatm_fAmount; //成交额 amount4 }* b' L- Q' n3 P( L# i, K
WORDm_wAdvance; //上涨家数 仅大盘有效( U2 c5 F& t) e2 {9 F
WORDm_wDecline; //下跌家数 仅大盘有效3 ]% X' r% Y+ F: Y! b
}STKDATA;
5 r; ]2 f# o2 ^定义STKDATA为 tagSTKDATA的简单别名,STKDATA 1 }/ }' V3 a0 {+ k: g7 m, b* O
为真正方便使用名称,tagSTKDATA 为定目的的过水名称# ?* E$ s- o, A( W3 O4 Z
////////////////////////////////////////////////////////////////////////////
# h1 Z8 G' k# e1 {. D//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构& Q7 _1 O$ U' D; R7 Y- L5 o, }
typedefunion tagSTKDATAEx
( @ T7 H8 s9 }{0 c; y2 n) s& s+ C- Q; c4 ~
struct9 w. j! z3 o o. m! B8 _4 j8 U
{" g0 p1 P: N8 P6 R
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open/ }! n+ Z) g8 `# I1 O
floatm_fHigh; //最高 high
" o+ Q; I# m* R! w. c1 r( ~floatm_fLow; //最低 low, \8 o; n- J7 ~, ^4 b3 p6 m
floatm_fClose; //收盘 close
) t# t! z5 o9 |3 q4 h" ^floatm_fVolume; //成交量 Volume
% s% L3 a8 R b% T0 Kfloatm_fAmount; //成交额 amount0 U. V3 J4 n5 G# X) W. f4 p+ A3 O
floatm_fBuyVol[3]; //买1--买3量
5 p) l# `/ h. o) j. Bfloatm_fSellPrice[3]; //卖1--卖3价' y6 l& j8 ?3 Z e+ x C
floatm_fSellVol[3]; //卖1--卖3量
z9 }; @ L" H8 s6 [};
' u% M! u) Z) R3 dfloatm_fDataEx[12];
8 R5 I% \$ v7 ?}STKDATAEx;
% @# R9 Q$ B* R% h. f: P% d////////////////////////////////////////////////////////////////////////////
1 g4 ]2 V( U3 T# K: ~9 B//定义取用除权数据的结构
/ C+ `' T h& J1 Atypedefstruct tagSPLITDATA , u, n* D& S% A$ Q; j F
{, m8 N2 R. ^, h1 i& G2 ^
time_tm_time; //时间,UCT
4 E: T' x# n, f9 L8 p% ifloatm_fHg; //红股
& K0 U, W6 N5 [, g( efloatm_fPg; //配股: k6 i) c/ U$ s+ I# C/ Z
floatm_fPgj; //配股价
0 y9 |- ?/ M1 I" F1 Zfloatm_fHl; //红利5 K" e7 C9 X6 G' }) k
}SPLITDATA;
" T6 ?8 q" V: J& P; l/////////////////////////////////////////////////////////////////////////////9 {6 ?- E" s8 W2 M, I* F+ O
/*财务数据顺序(m_pfFinData内容)/ ]4 Q% {0 Y( H6 g9 g) ^2 ]5 C
序号内容
% z- T& k0 S! E- J, E+ y0总股本(万股),
' @7 r- v; [: E/ U6 O& s+ I1 V) J1国家股,
9 J3 W" \3 e9 X1 f2发起人法人股,- X9 b+ ?- h% P0 W$ s/ w
3法人股,
, x4 b. r* X, `9 G! v, \4B股,6 Y: b3 H: O. ?) K+ S; D
5H股,
+ q. [$ i; r$ V; X6流通A股,
& S1 f3 U7 P4 _! u7职工股,
. [8 f8 M' T" C& c* W9 v8A2转配股,
5 K: @6 p( a, M; ?9总资产(千元),8 R1 x( B: u, d: H1 S3 z2 n1 x
10流动资产,
$ Q' N- v3 t$ @) p0 N& B11固定资产,9 l* w) d( r2 ^1 N* o& c8 ]
12无形资产,
3 ?2 S% g2 l, N/ S13长期投资," U: s$ G; @5 ?6 ], |" u
14流动负债,' _% x/ k$ Q6 s& U
15长期负债,
5 H& H7 n. Y+ ^* r5 R. K16资本公积金,2 n1 j& r$ [5 Y5 w# w' d
17每股公积金,
+ F5 V2 L: |" h; B' m/ x18股东权益,
, W z- ?& C6 e$ U$ y3 F$ \' G6 }4 a19主营收入,
0 `. j( i; f1 E, |( S20主营利润,
9 J( s1 V1 g9 \21其他利润,, P, Y; e/ Z# [+ \& g! B! ?7 T
22营业利润,4 e: O. Z: u* L0 n3 [$ X' a
23投资收益,
# g* k& N" j/ R$ p" ~5 ~24补贴收入, S- l3 v- }# ^, [* A
25营业外收支,6 D5 a5 ]# s% Y. Y) w
26上年损益调整,
* ?* {% Q1 I( o3 n5 n% {+ L27利润总额,' n3 \ p( j- f# u+ v1 p
28税后利润,
% h! l5 f+ u$ H2 o! H/ e29净利润,1 v$ O: e [; y' M2 N z$ S- F) D
30未分配利润,
. L( [! O3 j8 R, H* h8 L31每股未分配,9 N2 k8 |# u/ B9 Q, @
32每股收益, h# K' f9 l$ |( h" C. A
33每股净资产,2 k: `' h# [0 X* r* L; q+ W. V
34调整每股净资,4 O4 A; P& k! Y7 s
35股东权益比,. R! Q7 I# V3 m6 u- H$ p" a
36净资收益率
8 P+ Z2 |; d+ M) j+ N) o- @*/9 [$ K2 }$ S9 S
/////////////////////////////////////////////////////////////
+ Z* Y% Q$ B7 Y I2 P//定义取用caller函数传递参数项 的结构( w( d* t& v) K2 L
typedefstruct tagCALCPARAM) t5 I6 m& J, I" Q* d
{
: E% U. W) x$ u6 `% Y( Qunion
# I: ~9 X9 R/ B{
; q! V4 W1 U9 e! r. F6 b# Kconstfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
% z+ s/ r5 j# X% J8 j3 Sconstfloat m_fParam; //数值参数 valueof parameter7 R+ [! t) m* C) Q' `5 S: ]3 F D' A
};
" W1 X- z. d. H# Aconstint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....1 t% Z& v$ W% J o0 V1 H
}CALCPARAM;
. C5 W( \$ g* E O# a" q/////////////////////////////////////////////////////////////////////////////, E z4 m6 g: P
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 ); Q8 ~0 y9 v6 h% R6 r: c- N
typedefstruct tagCALCINFO% q8 V9 c# J* r" a( ?3 k9 k
{* F' U! R6 i+ L3 H) Q) `# T: G( \
constDWORD m_dwSize; //结构大小
! ?# }1 v V9 \4 U! K, z! g! J4 W6 H5 tconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
7 R. R7 Q: C; Q% n$ zconstDWORD m_dwSerial; //调用软件序列号
I( ]8 j4 W% Yconstchar* m_strStkLabel; //股票代码
) B. H7 [9 {$ U1 H1 wconstBOOL m_bIndex; //大盘; j5 l8 K% [' ^/ s& b& {
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度
2 l; U6 j$ t1 t4 `constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
4 J' n; ]& |9 L- i- w+ f& B5 U( k; ^constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
) _! X# f" e2 B. u7 f9 J. q% cconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter 6 h$ w5 R; R: O
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
9 s, E' K3 I" `1 M3 v% sconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2) ^1 b* _9 n3 u) Q" F7 D
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 36 }9 I$ D0 `: a Y5 G& @* g% G4 F
constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
" R% X0 i- j6 R. }float*m_pResultBuf; //结果缓冲区5 m1 e: M( E, |* K" a% A7 p4 O
constDWORD m_dataType; //数据类型
- z! _5 f4 F/ c# nconstfloat* m_pfFinData; //财务数据 E/ E% K! s q c( A
//以上与分析家兼容,所以沿用其结构和名称. Y" g$ e/ C: C0 |1 @
//以下为飞狐交易师扩展(fortagSTKDATAEx)
" o7 s4 X( g& ~( j5 V! uconstDWORD m_dwReserved; // 保留
( J5 U" N) ?- g, j5 {2 K; a5 `constint m_nNumParam; // 调用参数数量
U v2 k+ q! E6 `constCALCPARAM* m_pCalcParam; // 调用参数数组
/ H1 Z+ ]1 c( t& b! V+ QconstDWORD m_dwReservedEx[4]; // 保留
4 R* X7 ?8 {# M, l2 Cchar*m_strStkName; //股票名称/ d- I3 L5 z- l0 i' y% Q
SPLITDATA*m_pSplitData; //除权数据
9 y, n' l* [# E! l1 l2 wintm_nNumSplitData; //除权次数4 i: k% G' V* g' i1 x* Q
}CALCINFO;
& q& R a) J/ g' g w/*: B1 X! b; B5 z! x6 ?+ w( C2 t t0 f
注1:(与分析家兼容)
+ w, z, b/ q8 Q/ z1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.+ H) C; d, ?* @( y/ a& R+ L5 G
2.当一个参数无效时,则其后的所有参数均无效./ D' k5 L: T) L1 D0 S! |* d/ \
如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.4 E9 h3 F, N- X _; J
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
- P7 k1 s# @& z8 g+ `3 [+ U7 w) S/ d- g- T4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
9 u( a% b3 P) J8 K" C3 \4 e5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
& Z$ x' d8 ]" h2 a2 Q1 H数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
% y+ ^2 } E. v/ E在时间上m_pData[x]与 m_pfParam1[x]是一致的
$ h! V0 g5 d6 R" {3 V注2:(飞狐交易师扩展)
" Z6 l9 ]5 Y* L0 H1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。7 D8 y; e& U. Z6 d3 [0 J8 P
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.! Y9 ^# v$ x* e4 ?$ S, b2 d* q! Y) ^
3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。) T' |* ]" U' y; W( u2 [; J
4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.& w. ~$ O, L8 `2 \8 v* v( u' U! K
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。' s" x) s9 W+ v# ^
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
/ n: c- I" e, @! ~5 y. s7.经此扩展,对分析家的DLL依然可以调用、兼容。( i3 L j. {4 R5 }- f9 A& l
*/
6 N, G# B2 c/ ^2 M, J///////////////////////////////////////////////////////////////////////////////////1 `5 d$ [2 \% ?" K% Z0 f& w
/*函数输出" d2 d) s# p* N; b1 R
__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);5 b* P, P* j" b. e2 e4 f
1.函数名称需全部大写.# t+ \& j! {7 V# T1 D/ ^
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
% ^5 Y" N+ ]) [对于C++程序还需包括在extern"C" { } 括号中.5 | C7 N! ~3 T- B
3.函数计算结果用pData->m_pResultBuf带回.
# }; o' J7 M- C' S: d4 v2 W4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
) k2 ]# D3 W8 E T5 O- fm_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.5 l1 Q) v# F$ U; Q; M: J6 A
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
- K/ P" |5 `! d, x C*/$ v( c" Z' b* m+ J
//示例函数,使用时用实际名称替换
& v% V+ z' a7 x( Y9 S__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);3 K, H% A" H3 w- F* N5 r. C
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
/ {5 s( m5 H$ [6 F _; T9 z8 _9 g//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
% d, P' X) v% @- ^& }# O8 a__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
& \ L4 R% b% |' D//WINAPI = _stdcall
$ g0 n8 p, r$ [/ {3 I$ r. x( @#ifdef__cplusplus
- h5 m P$ u. {; d( f}
2 L/ D3 D/ g0 P" [#endif//__cplusplus
" o: @* M" a" A3 Q P; v#endif//__FOXFUNC_H_INCLUDE
. _# O4 B& m/ T4 U7 U3 t9 g, m0 z8 d9 P8 w! a( Y A( _; K: I
//////////////////////////////////////////comment 注解$ ^; |& I _5 G4 ^
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)/ }7 f$ d! k( N5 \0 }( ~# V
pData是指向 址标总结构 CALCINFO的 总址标6 t/ \8 t- l; K
取用第二个参数数值floatfParam = *pData→m_pfParam2
! s- E" ^9 ]# L- l5 d7 p取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;( a) ?6 x7 L d5 ~/ ?) g2 B. G
取用股票数据长度intndata = pData→m_nNumData;
% ~6 U9 ^) b0 q第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
3 X( Y" A: O/ |0 _- L* q7 ]7 m( l第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0( m! c w7 {* Z
第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL$ N9 @2 C1 R. u* y8 `2 @
constfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
7 f# b6 R2 p1 a/ C5 l取用股票数据结构3 O: Z4 Y) k( k* J d% A
pData→m_nNumData= 变数数据长度
1 M* E! W, y/ g% g/ S1 r' M6 E0 ~pData→m_pData= pointer to struc STKDATA 的址标* J0 `/ G7 R" ]" k) d" p: S G
pData→m_pData[x]数据结构的第x个数据6 Q, W( I5 l& H7 p
pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
' ?; O# m5 l8 Y& g取用结果缓冲序列
# t9 \% d a+ b0 upData->m_pResultBuf
$ B: L0 s7 {# j6 V" v+ k; C取得第一个序列参数的起始序位,如 2,...5 , . 7...
3 Q1 n! R( R$ }* A, ?* UintnFirst = pData->m_nParam1Start; , q, h, ?( @- |: |& t5 H
for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )9 R9 U2 W v: x) c; m# s
取得第二个数值参数的数值9 u2 v0 Q# O7 E
floatfParam = *pData->m_pfParam2; 5 R. a4 R/ }3 p$ `
intnPeriod = (int)fParam;( W9 |" a5 i! u" c3 U
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;6 u4 o2 w& b' o( e4 l0 j: N
取用序列参数的单个直pValue
( Q6 I! {: C1 y3 k$ B$ r取用缓冲序列的单个值pData->m_pResultBuf
. s0 _" Q& W% w$ ~, _constCALCPARAM* m_pCalcParam; // 调用参数数组, m' k; @% d' q. w
m_pCalcParam为序列址标,指向各序列参数的指标2 ?( [5 ^ N9 T
第一个序列参数pData→m_pCalcParam[0]
5 {' D+ A4 @1 q# `* P% M: X) uconstfloat* m_pfParam; //指向序列参数的址标
- p/ T$ h, I7 u5 P' C( _; x第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
7 a/ x3 Z1 q/ f: a( H第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;- T9 y3 f& j; _* Z
取用第一个序列参数的单个直pValue1
. y3 p6 c% V+ g3 j* L3 z0 k7 b. A第二个序列参数pData→m_pCalcParam[1]
' A6 a+ V4 o4 \+ H' J+ V7 R第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart( X: W# g9 \" b; ~3 Z
第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;3 r# `8 E' O3 F ^1 n. P* p3 u
取用第二个序列参数的单个直pValue2
8 M- J; Z5 k+ S第三个序列参数pData→m_pCalcParam[2]
; v2 L( Q0 W6 b$ @' k( S( G: T第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart
2 s3 z$ I0 _$ F第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;6 o3 n$ h2 i! n2 Z/ I/ F5 }$ m& d
取用第三个序列参数的单个直pValue3
/ y7 m: {6 C: k1 | w3 W第四个序列参数pData→m_pCalcParam[3]
& a6 U7 w7 b& |6 e! W3 O$ b第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
( F* S5 e& G6 Y8 Q% w第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;
( r& D+ U% z8 s; P' B取用第四个序列参数的单个直pValue4
" I1 s+ h0 e) ?0 M+ f- S! d E- G如果有四个序列参数,则取用序位最高的那一个序位! V; G5 o& i2 d$ _
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
7 L. v% T" N1 \+ q7 C9 E% KpData->m_pCalcParam[1].m_nParamStart>= 0 &&0 _3 s, x% ~- T
pData->m_pCalcParam[2].m_nParamStart>= 0 &&; K# k1 K6 |, R# j$ A% ]
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值6 {, W! w i& x9 }2 @5 h# @8 t
{# s5 T _6 k$ @9 p5 r
//计算返回的序列的第一个有效值位置: f, Z4 F/ Z. Y
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致% R$ S% V' h0 ]
//若不知,则# d2 W+ R0 @1 ?
/*
# h) t0 R' N. |' A6 ~intnFirst = pData->m_pCalcParam[0].m_nParamStart;
! E0 `' k, I tif( nFirst < pData->m_pCalcParam[1].m_nParamStart )
0 j4 c( }+ d( {- [% J; anFirst= pData->m_pCalcParam[1].m_nParamStart;1 z, ]* c+ E$ J) y; f
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) 8 x, u: [; e0 p. S4 ?6 \3 z2 V3 K
nFirst= pData->m_pCalcParam[2].m_nParamStart;2 r. Y' e6 x) q3 K' p5 M+ Q
if( nFirst < pData->m_pCalcParam[3].m_nParamStart ) 3 m m/ H; G" O$ }+ P& ~
nFirst= pData→m_pCalcParam[3].m_nParamStart;* {, [8 \2 ?, S8 u) A0 Y
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;
# ?6 o! F! P% f. r8 `3 G# nconstfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;" t8 x2 F, k1 |. w' I
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
4 @/ q4 r8 {! Nconstfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;! u2 p5 M( M, S9 w( Q
//-------------------) x* @ I% o, d1 w7 ]
floatm_fOpen; //开盘 open6 z1 _ _; e$ A, X5 g @
floatm_fHigh; //最高 high$ M$ e* T% P, ^3 I) ?" {
floatm_fLow; //最低 low
} k. q b' g1 W: d& ffloatm_fClose; //收盘 close$ l8 b/ t- U6 k {7 }7 E- x5 Z
floatm_fVolume; //成交量 Volume
* y5 z4 ]' s3 f7 k- f; Yfloatm_fAmount; //成交额 amount0 Q+ u* S5 q! q$ y7 R
调用收盘据2 c/ [3 a1 [9 r! b0 q
pData→m_nNumData= 变数数据长度( h4 w6 @, }5 j
pData→m_pData= pointer to struc STKDATA
: ^+ q; s4 K4 f: {0 A2 }6 _pData→m_pData[x]第x个数据
7 N3 P5 V3 ? F9 vpData→m_pData[x].m_fHigh第x个数据中的 High2 i0 {' O( ~4 H( z" i) ?( h+ {; K
@@@@@@@@@@@important !!!!!!!% m, X+ z# h# B5 }
sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
3 R3 Z: V" `6 U) p5 @9 Bso,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
. {$ I, b8 }: O% e+ P4 ypData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
* C* h `1 s+ G5 E' G1 ~pData→m_pData[i-j].m_fHighto use high: C. i2 H6 N; E6 v$ F0 \
pData->m_pData[i-j].m_fLow
) A# c8 S. d& f- f, ]. o, ~: UpData->m_pData[i-j].m_fClose
% b+ a) \1 Y* Gm_pData= pointer to struc STKDATA3 x% Q, k F9 N. g
incalling C++ dll function1 ~5 j5 k6 p! B4 t* B9 @; j8 U1 v
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)3 g+ U$ n2 [4 x, o) H* h* e
touse a single value in variable ‘High’: [. |# W U- _4 [) S6 X6 N) E
pData→m_pData[i-j].m_fHighto use high# Z" d1 g3 K5 ^2 }0 d
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 & O6 Z [% w% l r" Y
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
+ e& v+ @1 c, x/ o7 Qconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
8 |+ ], m( B4 D6 c0 Z( e4 l! E5 ~constfloat* m_pfParam4; 7 F" s" W$ D8 k1 ^: S
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
1 j: \; X$ ]: R5 {9 e1 }" LpData→m_pfParam1= pointer to 第一个(序列)参数/ G( d, E3 j8 E, s
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值( F$ D$ }# N" b) K- S4 P
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数 C- d2 Q! v4 a2 T. _8 [( \
cpParam[x] = 取用第一个(序列)参数的第x 个值
" B f1 M( ^3 ^) j: U* d. \8 Dm_pResultBuf= 结果缓冲列
* z& `, r# U3 {: d: RpData→m_pResultBuf= pointer to 结果缓冲列, s; D5 i9 k; y
pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
* r. Y# g8 q( [. e( m, [//////////////////////////////////////////comment) u; W7 u& x* o8 A
//////////////////////////////////////////comment 注解
& [* ^0 d7 E# ~/ `% |constint m_nParam1Start; //统杅1衄虴宎弇离; B' y# V+ H$ c3 o* C7 u# ~
constfloat* m_pfParam1; //覃蚚统杅1+ a7 C9 Z. k" c
constfloat* m_pfParam2; //覃蚚统杅2
2 V7 _# K/ N- w J. {9 |constfloat* m_pfParam3; //覃蚚统杅31 k/ q$ F5 [( W# N+ R% t8 e
constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4
E! X4 g0 h# V2 m9 b" j3 G1 Z3 e//const float* m_pfParam5; // parameters must be <= 4
+ h: P: l( u/ S2 y3 n+ W1 T//const float* m_pfParam6; . q% d8 @* v0 F! q, T3 v
//const float* m_pfParam7; - s& p) r+ w$ h; ?2 |8 n# s
//const float* m_pfParam8;" ]. E6 G* n( E* p: t. `: ^
//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&' K+ y2 b F& \2 F
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0* J& g0 a( r* d0 D! Z* g9 t
&&pData->m_pCalcParam[2].m_nParamStart>=0)
# H" r$ i$ K# R; j+ Y{
- Z( ^2 E: y( l+ x efloatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0
- O6 i# ], B' v# R" h, X) d! `intnPeriod = (int)fParam; //统杅1
: |2 Z* G v' Y" [8 N; f$ i. i! q( }! @//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
6 A, l+ \ i8 _" j* |4 }constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
# l( h$ }1 V- C% Y+ S1 C- u' T7 |2 B6 `constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
$ I* g, U3 C( F! G- D) Y) Dconstfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4
8 W+ d T3 p2 C//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
! c/ V0 L" @" M9 B9 C//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
. H* U: S3 D+ ]& |//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
% B) N+ o, P+ a! U/ |touse pData→m_pData[x].m_fClose% [; v7 Z: `( o
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; 9 I$ B" ? f) i; Q* A) U |8 M# j
|1,2,3 , … , m_nNumParam | float m_fOime_t
R, ]2 R2 p7 A) D7 S. L* I|1,2,3 , … , m_nNumParam | float m_fHigh;
/ \5 W1 ?8 d5 d8 D2 q8 R- K.. .* K0 t# `8 I; B% e3 L6 L# S
|1,2,3 , … , m_nNumParam | WORD m_wDecline;
% f4 O2 A8 g; T3 V" Qm_nNumParam= 数据high,close,open,low的长度
7 d3 e( D) W2 W6 q" J4 e# @6 O+ ztouse high:/ M$ d4 F7 ]) Z" T4 b# c. d
pData→m_pData[x].m_fHigh0 U" u2 z9 _3 M& T3 l
contentof struct STKDATA: k% h3 k% b; d$ v/ G7 o
time_tm_time; //时间,UCT
8 e s9 k9 v& G' |& wfloatm_fOpen; //开盘 open
7 D. o1 p8 p" J: f( Lfloatm_fHigh; //最高 high
* G E" x' E+ x) Q3 Ifloatm_fLow; //最低 low
( g- @8 r9 w0 t1 G- Q7 i' u1 @0 Q# Nfloatm_fClose; //收盘 close0 z8 e& J. b) `# e5 _
floatm_fVolume; //成交量 Volume
: h5 d+ W% k2 K. z4 w* ^4 Q3 sfloatm_fAmount; //成交额 amount0 U: O0 Z9 }7 a. M& C7 z$ W. a8 ?
WORDm_wAdvance; //上涨家数 仅大盘有效
1 E, C: m: ~/ k: E0 nWORDm_wDecline; //下跌家数 仅大盘有效
' P! P. c5 E# T/ m5 o调用传递参数及传回结果
$ ?2 C3 X/ k! ]+ m+ V) _7 o调用传递参数
& z, b2 q- e" F! o) _7 R% D9 X+ m(pData->m_pfParam1 && //参数1有效Param1exists% w& E. H4 u0 }6 ~3 H4 |
pData->m_nParam1Start<0&& //参数1为常数8 L$ O; b3 o( s7 J9 T
pData->m_pfParam2==NULL) //
4 v+ S+ N2 ?5 Z6 k1 Dlocalprocedure 定义使用变数
9 _9 |) n6 [4 p0 v+ I- qonstfloat* pValue = pData→m_pfParam1; //use constant参数1
! q) W/ q# h9 i4 \! |intnFirst = pData->m_nParam1Start; //use 参数1效值起始位
3 z _4 d3 v4 f" a9 _$ rfloatfParam = *pData->m_pfParam2; //use 参数2
6 x) g6 D/ J, fintnPeriod = (int)fParam;
3 ~3 c, E" S0 j! f1 K: ~! B3 N传回结果
$ I7 t, B" f- [5 T2 d/ g* |& IfTotal+= pValue[i-j];" u0 P9 P! q- A- N+ \
pData->m_pResultBuf0 o7 {0 Y) P! c/ _ D, K* \& R/ t, _
//////////////////////////////////////////comment |