许多年以前,我曾经在
2 K" W/ f& b3 L; ^* }3 H" W, [理想公式区发布了
4 ?8 ?2 @( E/ o8 B4 B"5 R. A1 ?, ]* P: v8 m
如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言): g( _, Q, g- i6 B
"$ E" R) E8 p4 V9 m+ P1 c! }, }2 m) D% @
7 f; M! ?# d) w现在更新foxtrader(飞狐交易师) & e* G H1 O. }* g: N4 _
连结 DLL的方法- y* H9 o7 H! a+ e. w0 z. W2 B$ {
2 j- w% S2 H8 Yfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
B7 Z, F6 A" x& y, a$ Dgauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
. s2 \8 @9 P# `2 a5 x" Bgauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
" L1 P) @# L. H: W9 o7 mfoxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效. L4 R; q6 ]0 J7 K7 a
/ S( n; d3 C7 C4 g7 z也就是这五个结构都能用
8 {1 U/ j( h" D# Y, w" e H' Ltypedefstruct tagSTKDATA
( ?' d# H8 C/ }9 w6 N* }* d0 u, `8 V; Otypedefunion tagSTKDATAEx2 u9 {- z; L" {1 X, Q. E' r
typedefstruct tagSPLITDATA
5 T# `" G& @! o- Atypedefstruct tagCALCPARAM- k4 P3 m1 g' b5 [. r* ~7 h
typedefstruct tagCALCINFO: k6 H$ W& i5 C/ d' d, P1 k
8 G4 l9 P: j( |- w5 V$ w自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
* ?4 j6 q$ q0 f7 \, m: V! s也就是这五个结构中 g& R7 A. K+ ^; e7 n3 H
typedefstruct tagSTKDATA 2 u3 Q/ @) }$ ?6 f' o- f& v
typedefunion tagSTKDATAEx
' \- j( R( d2 w% A: q+ H% ytypedefstruct tagSPLITDATA Z+ L/ u8 b0 M5 C
typedefstruct tagCALCPARAM" o) W) h! X9 A2 [5 |, ~/ g
typedefstruct tagCALCINFO) P' t& |- ?4 h
只有这两个可以用! G4 T' Q' G# a" L1 {9 ]* w
typedefstruct tagCALCPARAM
+ ^8 ]; X8 m- L! \typedefstruct tagCALCINFO
y: e' R t6 r0 ~7 v7 M值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
5 f6 b5 A7 L9 C; f( ytypedefstruct tagCALCPARAM
. N. K1 \7 r: T, R4 r例如:在 foxtrader中
- Q6 A' p3 G/ v( V; C5 u5 E: }MA1:=MA(CLOSE,3);) i2 b6 S; w1 @5 r9 B# v+ a$ p$ M6 ~
MA2:=MA(CLOSE,6);9 s3 j) r+ h8 H. j, B1 X2 \6 M
MA3:=MA(CLOSE,12);1 V3 j1 ^# J5 g, D* b P) Y/ {6 k
MA4:=MA(CLOSE,24);6 @4 \( C2 H+ b$ G
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
$ d( _" {* H" l其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个; }/ i% ~, R8 a
下面这两式计算结果相同
5 ?) U; n: H+ ?! d& uxx:(MA(CLOSE,3)+MA(CLOSE,6)+MA(CLOSE,12),MA(CLOSE,24),MA(CLOSE,12),),MA(CLOSE,24)/6*0.95,color0000ff,linethick2;{foxtrader 自行计算}. P- n ~5 D7 m& e2 N5 e- H. z
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
/ R5 q1 {( P) R! Z3 W5 P其他例子( k6 `9 l, b4 V- |6 w
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
2 t$ m0 S1 ~5 a5 doooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;
5 S( T9 `0 ~6 W0 t" p其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
; J0 Q6 J7 P0 H' V; j4 Z# rfTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误3 e) l9 o: P" x0 R% P
* w+ M5 j' Y- M$ Q# x
; R, r9 ^1 L6 [. ~, O- s5 ]7 u! h+ T////////////////////////////////////////////////////////foxfunc.h2 e2 v4 U( A c
#ifndef__FOXFUNC_H_INCLUDE
2 U! Z. k5 s' N& G#define__FOXFUNC_H_INCLUDE- o1 O+ I% l9 ~9 q6 X- @
/*
: X, \5 @& K* q$ m+ n$ _0 H8 w飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
( P) G" p6 l% S1 n1 C U( T1.本规范适用于飞狐交易师V3.x公式系统.8 O9 M- k+ o2 x3 s% a! W
2.扩展函数用于实现系统函数不能实现的特殊算法.8 b' H2 Z& x; N# B
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.
% f' N; l; M$ B( U5 x4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
2 a, R/ i7 W9 |- @5.动态连接库名称和函数名称可以自己定义.% o) m' A5 p8 K
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.$ e8 t- F# w* ]# ^8 A. R
*/
" Z) x6 @3 p. Y* t" l#ifdef__cplusplus; l. [* j& G9 [9 j( f4 |
extern"C"
1 v- J' t9 C) }2 X& b- I6 m8 z{: |0 d C4 F9 F N" B
#endif//__cplusplus
4 V9 ]4 R* E) y! c- j/ Z3 M* A///////////////////////////////////////////////////////////////////////////
9 A, E) I2 Z8 M//分析周期
9 e1 U5 F- @- N* i- DenumDATA_TYPE
& c5 m- w& }% N F1 {- {' N6 {3 {{
4 Y2 ^+ t( u( t' c8 E4 yTICK_DATA=2,//分笔成交( w. R2 b/ a2 M
MIN1_DATA,//1分钟线 Q6 f% k+ }" P, W! q7 v' N
MIN5_DATA,//5分钟线 % ~/ f. | E- U& @
MIN15_DATA,//15分钟线
' e% C( B C4 p: A! s/ [" mMIN30_DATA,//30分钟线
, A3 T8 w& l$ D- B9 u# mMIN60_DATA,//60分钟线
, Y. d7 v. G' y6 ADAY_DATA,//日线
8 q. E0 z& a0 e2 y" @$ x+ aWEEK_DATA,//周线4 E F7 k9 c: t: F6 g! F
MONTH_DATA,//月线$ s8 u/ q; h$ w6 b5 u2 I8 t0 _
YEAR_DATA,//年线9 Z- S K! ]( f$ l1 g8 |
MULTIDAY_DATA,//多日线1 {3 B& j. K' n. S& j0 N# T% L Q
MULTIMIN_DATA//多分钟线
" M- T) p, X; c; A: C' y. _}; s; g+ E% M( J
///////////////////////////////////////////////////////////////////////////2 Y- \% K0 F) I8 F4 J
//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用/ c7 x/ u' S8 x& i( J: w2 i, }
typedefstruct tagSTKDATA - w+ w @2 S; N' ]$ X2 V
{
9 Y6 p3 s6 d6 h3 V5 `; t _tm_ ; //时间,UCT
* a/ ^" o( ^7 X6 b& Tfloatm_fOpen; //开盘 open3 E0 g$ q$ q% t _5 @9 j! k& Q
floatm_fHigh; //最高 high
0 L0 F _- K, X- Q* o/ W2 E4 i! efloatm_fLow; //最低 low, [3 c* R" r+ v- @6 |( N
floatm_fClose; //收盘 close
+ M7 P. x7 c: R# K& ]% b* ifloatm_fVolume; //成交量 Volume- W Z8 ^* Y5 O% {' g# v" q
floatm_fAmount; //成交额 amount g/ N3 w% X' S: B
WORDm_wAdvance; //上涨家数 仅大盘有效$ |2 B" V" @$ R4 w
WORDm_wDecline; //下跌家数 仅大盘有效. ?9 J; ]1 u7 c3 J2 `1 V* I9 f5 W
}STKDATA;
& \4 n( `9 {. @' u9 E定义STKDATA为 tagSTKDATA的简单别名,STKDATA
2 V9 y: O" |5 Q4 N7 K0 c为真正方便使用名称,tagSTKDATA 为定目的的过水名称 m/ d, E3 [7 m, ~6 V
////////////////////////////////////////////////////////////////////////////
! B9 {/ \& f x$ X& m5 ]3 v//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构( i# D4 [8 e% K
typedefunion tagSTKDATAEx% V0 Z3 m) b! U( r
{' j& [5 b$ N5 i. r& N3 s. k2 ?% }
struct/ ^' W+ [4 }4 G) r* A& W* F. f
{3 X* L9 @2 p+ W g- q! F$ s
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open! Z. [7 g+ H+ H4 _
floatm_fHigh; //最高 high
, k2 O, l( {7 k" A+ Afloatm_fLow; //最低 low
4 e) J2 ?% M0 \, c- qfloatm_fClose; //收盘 close* N: t7 n2 c; x3 y0 l% d4 f
floatm_fVolume; //成交量 Volume2 |+ v) P) E3 L* ~+ D- j h
floatm_fAmount; //成交额 amount
) ~4 u. ^- `5 w! R& K9 b" Sfloatm_fBuyVol[3]; //买1--买3量
$ c% X6 Y( S$ X- h: K3 Ufloatm_fSellPrice[3]; //卖1--卖3价
$ J" `. `7 Q# v' ?floatm_fSellVol[3]; //卖1--卖3量
* A4 Y; G1 ]4 A# N* r};
9 h$ g" E5 j# |, L9 D9 Ofloatm_fDataEx[12];
/ V/ }( H& f( f2 {7 v: r}STKDATAEx;
" y7 Q; q$ d; t% T* w4 L////////////////////////////////////////////////////////////////////////////
" B8 s( Z" @8 \$ N: C3 R//定义取用除权数据的结构, o% w% L2 H5 W& b9 }0 }
typedefstruct tagSPLITDATA
8 l% v# t( j* o1 g( t* {{
i4 d( ^- N P) stime_tm_time; //时间,UCT
8 a, `4 [9 k7 ?& efloatm_fHg; //红股
3 Q) S; x8 p$ v3 |floatm_fPg; //配股
+ J0 z; r* v( k2 y) n# Y7 i. Ifloatm_fPgj; //配股价
3 v, ^% `1 S" rfloatm_fHl; //红利
- [3 U2 S$ D! p# s6 h}SPLITDATA;3 U) f6 `; Y; A, ] y) a
/////////////////////////////////////////////////////////////////////////////) ^0 Z$ v1 X0 {5 X, t9 e2 x/ Z
/*财务数据顺序(m_pfFinData内容)+ [' q! L7 j3 p: z
序号内容! U+ p, j' v1 w1 A
0总股本(万股),
/ x& A( {6 a% c8 O0 V2 {1国家股,
9 b9 j3 _' G& v! y+ _+ ~# S5 z1 ?' d2发起人法人股,
8 e, H! f0 c: s/ g3法人股,
) \0 v+ ^+ n" M# Z# S4 p4B股,$ R% |. O# m" x3 B- h0 o
5H股,
7 a0 S7 s' Y) e, X, W5 q( z0 `6流通A股,$ \6 n/ f7 H( c2 {9 k! [
7职工股,7 C; B1 ^8 ^; _6 x
8A2转配股,; [4 f) Y; y h1 x) r0 \. M4 ~' w6 b/ L
9总资产(千元),
' c& n2 E: h, j& w0 ^) y10流动资产,
- P/ j! a# f7 I1 l# D7 p' f5 {11固定资产,
f4 y: a! C* I- Q12无形资产,
! x5 m% D' r E& W13长期投资,
5 T# [; A6 K- p$ l. X( M0 E14流动负债,
4 L7 P7 Z7 t8 Z" ^0 p) y+ J: Z15长期负债,) Z' m+ d- V) ^# a6 u
16资本公积金,' }. ?& q# E1 M% P4 u
17每股公积金,
8 b' `* W3 M L( B8 j5 H5 f' d# P% ?18股东权益,3 R( \$ q* T$ T7 R6 V j9 V
19主营收入,7 `" z8 \7 M% Z. y4 |7 u
20主营利润,. }; ^5 {+ s2 |2 N2 V+ v6 o# v$ a
21其他利润,2 l! K( P |3 B( W' Y" V& x
22营业利润,
! m* J( Q" }% A7 {* ?" a' m23投资收益,) s4 c& p/ ~4 p8 w$ [
24补贴收入,8 E, ], a& o7 `
25营业外收支,
. P/ y. m) \( V; v26上年损益调整,7 W4 H' q1 m: _/ i2 C
27利润总额,% A1 v O4 n, L h& V
28税后利润,# ~. V; i; V4 f
29净利润,+ c) ?/ s" V% c9 m
30未分配利润,' v/ g! H4 P8 s* A- P: e8 j/ T6 M6 G
31每股未分配,9 \. E" I8 U* W
32每股收益,+ S1 l8 k) R6 L y% d
33每股净资产,
3 }+ Q" J% B5 Y# q34调整每股净资,1 j: N u* f( O7 A" u& a
35股东权益比,
" }. I4 ^" l6 F; @/ k36净资收益率) i* U& d! V' Q& E
*/0 `5 S& r- \! G. h. I1 l
/////////////////////////////////////////////////////////////
% m7 f: E' {( n& I. k2 {3 ]5 z9 ~. u//定义取用caller函数传递参数项 的结构- b1 x: t' \+ m- n$ d" e6 c z
typedefstruct tagCALCPARAM
- e1 C% i! s2 G) g7 @! j7 m& F y" G{, ^: B# _5 P6 D
union1 W+ \; A% r% X$ J0 q
{
& M9 {2 P: w4 Q& L$ fconstfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
/ u" u0 ~5 C, r) C$ [constfloat m_fParam; //数值参数 valueof parameter- u, M6 O+ E' p" ] ]% U
};% y) t& ~* f& V+ ~ i: P2 G
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
. I! j W, w# N$ U: l: m+ S}CALCPARAM;
, N+ C. `& f: C' D) D: ~* N- M/ \/////////////////////////////////////////////////////////////////////////////
: F4 _- r1 N: g S# \* I//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )
. T' l0 m0 |/ \6 mtypedefstruct tagCALCINFO
~+ z; _) u7 I- P{
. E$ a7 [6 @( XconstDWORD m_dwSize; //结构大小
& z: E3 l# y9 Z6 @/ u8 [constDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
# M- {4 [. p0 `8 F! UconstDWORD m_dwSerial; //调用软件序列号
# F2 v) l! [3 v8 n% i6 v( \; rconstchar* m_strStkLabel; //股票代码4 D5 D' ]2 S2 k" M, c
constBOOL m_bIndex; //大盘
8 ]+ R+ T- @/ `& l( \7 v$ bconstint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度( M, }$ P9 D7 Z" [: ]4 T
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
7 W* a" |! N; X# X3 p6 t0 R: A% x) nconstSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
* M6 X) _) e% ]5 V$ \ V# yconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
) k7 [; [1 B. g% w& Y* k. oconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
$ P1 Y* k( t( @* Tconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 21 s% ~# `! t9 [3 s$ K! A
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
# U r* C0 Q: _9 Bconstfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4& j' a# L. m3 |0 E
float*m_pResultBuf; //结果缓冲区& Z9 v2 d L) Y% Y" |4 v. _* K
constDWORD m_dataType; //数据类型+ @: n7 N) C) R. j
constfloat* m_pfFinData; //财务数据
1 b! C! c4 {; L- x& \1 S$ E5 p5 U//以上与分析家兼容,所以沿用其结构和名称+ @+ m' `$ r/ R: Q1 ~6 N
//以下为飞狐交易师扩展(fortagSTKDATAEx)9 S2 n8 ]& l* I
constDWORD m_dwReserved; // 保留
8 W& j" p) K" ~7 ?: K$ i$ _( S0 ?) t! Yconstint m_nNumParam; // 调用参数数量" i J. }+ k0 c# J9 y! H) F5 B
constCALCPARAM* m_pCalcParam; // 调用参数数组
0 F( J" D. g9 ?- k; iconstDWORD m_dwReservedEx[4]; // 保留9 W' r: J- ~2 Z: F: t
char*m_strStkName; //股票名称
% u; E3 b1 I0 E1 uSPLITDATA*m_pSplitData; //除权数据; ]. U; r. m" x8 d
intm_nNumSplitData; //除权次数+ X. m: O; W$ W+ u2 ]
}CALCINFO;
; \( U0 S; m' I1 P/*
5 m5 |. |7 l& F: y% z1 `注1:(与分析家兼容)
/ i, b: j7 u1 W$ r) L4 F5 p1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.1 ~& T* e( K3 o8 D5 w6 w
2.当一个参数无效时,则其后的所有参数均无效.6 _4 H2 d& U2 D) \+ ]) k! M
如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.
1 f- E) p5 D; b* A3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
# g* L5 c) F& A9 x# e- O. Q4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
: R N$ F% l8 y8 k5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
' S; e; \1 V: y% |# [8 z8 [3 _2 H数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
1 ~3 c0 ?$ }- A- b在时间上m_pData[x]与 m_pfParam1[x]是一致的
. C: S; E3 C P- F# _/ r注2:(飞狐交易师扩展)
7 _; v- y* C3 ~- m$ T# D p1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。
( L6 p: i& P& t: F2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
: S7 A4 ] Y# W7 Y! y3 Y4 L, c7 G3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。
n) Z# p, B1 R/ y( B4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.
1 q: m' A3 i: P% `8 E5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。
m4 q2 ~5 p7 c9 _" s1 P! V6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。6 {. K. O m/ @' b$ V! u! c& w0 Y" p
7.经此扩展,对分析家的DLL依然可以调用、兼容。
" P% H: c3 x8 b2 @3 |2 l' l*/, T! ^9 J+ t' j$ P' {7 {
///////////////////////////////////////////////////////////////////////////////////
" h6 y7 A: x& i$ }) I% i/*函数输出
& x4 h H6 T" p* \8 X__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);% Y+ _5 t6 x! N
1.函数名称需全部大写." `! S7 V6 a; F
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;
+ `) H; J4 D2 S. c, W对于C++程序还需包括在extern"C" { } 括号中.
* B8 _/ @+ g4 p- C" p# J9 l3.函数计算结果用pData->m_pResultBuf带回.7 W& O H) E7 q( Y- l- \6 [
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:6 S; ^" G+ T% h: R" {" ?
m_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.
, b# S' ]( T$ d: F0 f5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER) g5 x* B+ A. s" [, X; b
*/) _7 U8 Q4 v6 @, Z- t' `" Y [
//示例函数,使用时用实际名称替换* A0 e! q/ T9 o
__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);3 B! ^" z$ }! s5 _9 W: F) R! r
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);
% s: N- j% n' }9 P//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
& t9 Y, a/ F& t__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
% K: \5 c) e5 F( t7 j( Y2 z( }# R//WINAPI = _stdcall
! G0 |* ~; m# O+ g8 ~#ifdef__cplusplus" ]& {$ K+ u- H" _+ E* A9 o
}9 W- i0 T2 R! M9 [
#endif//__cplusplus! I( a6 p" Y6 \* E! b$ ]# S
#endif//__FOXFUNC_H_INCLUDE7 l3 f, [! O* I$ I& `
2 V4 L( v" F4 @ `( N
//////////////////////////////////////////comment 注解
4 C8 ?! R' Y+ c, i__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
. [3 P8 m* M. R& o: b1 _3 opData是指向 址标总结构 CALCINFO的 总址标
$ P8 T! N" I. Y取用第二个参数数值floatfParam = *pData→m_pfParam2
/ a+ Q* B) c: r取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;( U# g) L( x: H% O# j- S
取用股票数据长度intndata = pData→m_nNumData;
7 I7 p- W% e3 U) H7 y! m) z1 |第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0$ s- L, H$ ~- h# u7 p$ h
第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0, x+ r* @' y9 ]; S! G
第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
4 u& T8 Q. G+ M4 l9 @1 ~0 Iconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
1 `1 W; V% K! V+ a D1 m- q取用股票数据结构
0 [5 Q3 N/ s8 [pData→m_nNumData= 变数数据长度
* Y- [, w- l6 r( R7 J- _5 z$ KpData→m_pData= pointer to struc STKDATA 的址标6 N9 o" H7 a0 W( K
pData→m_pData[x]数据结构的第x个数据
& x* ?+ W+ I P9 C3 k8 I u; J8 N% ]pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
. l5 I6 p0 @3 f' g取用结果缓冲序列
z! W" O! ~8 A0 p1 D- |pData->m_pResultBuf
" \" S5 J, `; D$ o, S! ~" X取得第一个序列参数的起始序位,如 2,...5 , . 7...( N3 R! N$ R3 f. P. y4 o
intnFirst = pData->m_nParam1Start; + I" q0 U1 q; X/ ^
for( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
( m9 C8 c) u* H7 G/ {取得第二个数值参数的数值
/ M- y; P. m [3 ?/ BfloatfParam = *pData->m_pfParam2; # I. i# v! y# @& W3 ]6 ~) f) Y' v
intnPeriod = (int)fParam; K) s; T% ]3 i8 K1 n) G4 W7 W- Q! L* z
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;8 p( P) X+ l) e9 y6 B
取用序列参数的单个直pValue& E1 ?2 I) o+ N6 I
取用缓冲序列的单个值pData->m_pResultBuf# E* G$ s D6 e( ?0 d& ]4 ?9 T$ C
constCALCPARAM* m_pCalcParam; // 调用参数数组5 i$ }( A H) j5 g
m_pCalcParam为序列址标,指向各序列参数的指标
; W, @1 y7 E! S第一个序列参数pData→m_pCalcParam[0]* j3 D3 o- ]1 h, m6 J
constfloat* m_pfParam; //指向序列参数的址标4 i" B t# P) I* i
第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart" L/ U0 J" e2 h9 a, Q
第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
9 T" c8 s* C" {取用第一个序列参数的单个直pValue1
( [# s# X0 E3 ]8 |* ~第二个序列参数pData→m_pCalcParam[1]
' v0 h' m- A5 g第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart
, H2 u' R( {( e) C7 \2 m* i第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;1 N. [9 q% ?) j; F
取用第二个序列参数的单个直pValue2! e5 ~( V% }$ K. e6 G( ~% E H
第三个序列参数pData→m_pCalcParam[2]1 l$ h( G3 w: s5 E) [; C; @. V
第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart
+ L/ b% j/ \+ l8 \+ d# u第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;, F2 b: W' i3 @
取用第三个序列参数的单个直pValue3: \& g, \# J) q; S
第四个序列参数pData→m_pCalcParam[3]
/ k5 |& N, U- R) h9 M# t4 B( j% m第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart" y) p( O( t. i8 @" g
第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;: Y" }2 f' g M' Z( q) O
取用第四个序列参数的单个直pValue4
7 j2 G( @* n) ]7 I& w9 q1 |- q如果有四个序列参数,则取用序位最高的那一个序位
7 r3 a( Q0 h( k; u# `; Eif( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
3 f% u3 Y6 _% ]5 \ YpData->m_pCalcParam[1].m_nParamStart>= 0 &&
$ t' p( z; ~1 NpData->m_pCalcParam[2].m_nParamStart>= 0 &&; {, _6 B! |; v* R3 r7 ~- i; n
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值
/ P: W5 K) a- O4 V5 [& f{8 V7 G8 Y+ [% R: i4 d
//计算返回的序列的第一个有效值位置: U, q$ N" Q3 _" v+ N
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
9 ?2 Z1 T% Y, C//若不知,则
0 K/ y; n: C8 _& G$ ?# Z/** |3 `( p4 c1 C8 f) U: b, |
intnFirst = pData->m_pCalcParam[0].m_nParamStart;
% h& J0 ~! R9 Z* F. n( S; X5 x& Lif( nFirst < pData->m_pCalcParam[1].m_nParamStart ) , u# W, @8 a* U0 d- J
nFirst= pData->m_pCalcParam[1].m_nParamStart;+ Z# [4 d/ r8 e2 J' p* o8 C3 F
if( nFirst < pData->m_pCalcParam[2].m_nParamStart )
T7 u; ]2 J, n% H+ o1 |) snFirst= pData->m_pCalcParam[2].m_nParamStart;2 T, k2 ?# y4 u5 ^$ f% r
if( nFirst < pData->m_pCalcParam[3].m_nParamStart ) ; o$ s: A- h3 n' g* S0 b
nFirst= pData→m_pCalcParam[3].m_nParamStart;1 o) k2 E8 s' p$ ~
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;
. s! i8 y* F( J- fconstfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
5 ~$ J/ [/ F, b+ ?" j3 S" _4 dconstfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;
! h; w) \, v/ V, i$ @$ |% [constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;: R* t' n7 q% _" A7 [9 n5 R" e
//-------------------
9 r2 |, h' t; z! ` Q% Hfloatm_fOpen; //开盘 open1 D/ S0 X2 H3 B' W; O! A
floatm_fHigh; //最高 high; b# Z/ x8 \* v7 B* R; ~& u
floatm_fLow; //最低 low
. n/ d: k& S) r8 \7 P+ V: h. vfloatm_fClose; //收盘 close
$ H% _- | K7 f# _. j- q7 }floatm_fVolume; //成交量 Volume. K! {) M# V2 v: W
floatm_fAmount; //成交额 amount
D6 k4 [5 k6 F( X5 g- i4 { U调用收盘据, t3 F1 ?6 s* m( J- X" j2 p. J3 Y
pData→m_nNumData= 变数数据长度
( h, [ n. _$ mpData→m_pData= pointer to struc STKDATA! D) _2 s$ R2 P' `& M
pData→m_pData[x]第x个数据$ s* N. b) q. w
pData→m_pData[x].m_fHigh第x个数据中的 High
/ L& }! U l8 }@@@@@@@@@@@important !!!!!!!
5 k7 s# L+ s0 e- X% ^+ dsinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
3 D# d: ]1 ]+ d B/ yso,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
* c1 _" x! B `pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
% m! W& ^5 F# x* S2 SpData→m_pData[i-j].m_fHighto use high8 ]* g4 f9 L2 ~( g
pData->m_pData[i-j].m_fLow
& H4 C4 J( L9 epData->m_pData[i-j].m_fClose$ O8 |2 [3 F% _7 j: b
m_pData= pointer to struc STKDATA
- a) d0 z0 r' P6 W- Dincalling C++ dll function: C% H, C6 B' i# h( F/ Q( u9 ?( c
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)0 J- E# i( S0 A/ \
touse a single value in variable ‘High’
) \: T" S9 [7 @8 ?pData→m_pData[i-j].m_fHighto use high
2 |2 m% D' a( q+ R/ sconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
) d0 ?8 o& x0 C0 W' C' W/ C# s" {9 i+ tconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
4 d L; \7 |; c# g( d+ m0 e/ D- Econstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
5 E, s/ x& E2 k: dconstfloat* m_pfParam4; 7 Q' `! O. M& ~2 O* G/ p
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
/ M1 d4 t* N0 C; ?9 vpData→m_pfParam1= pointer to 第一个(序列)参数; v1 |2 ?! U8 `# i* H8 c
pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值5 P9 {1 M& E$ S5 a. c1 B" |
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数6 T t4 B$ \- M/ ]! j
cpParam[x] = 取用第一个(序列)参数的第x 个值
$ x1 Y8 u- ~# p; p7 y' _m_pResultBuf= 结果缓冲列
; L. v$ R) }0 @6 y# \0 q; jpData→m_pResultBuf= pointer to 结果缓冲列
& d, V, l& d+ i1 zpData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
/ m* ~/ L( W+ D, S- |//////////////////////////////////////////comment
7 ^0 c. Q0 J% m% l8 t$ w//////////////////////////////////////////comment 注解
# K& R- I) ~3 O" ~constint m_nParam1Start; //统杅1衄虴宎弇离; ?3 d6 }0 a) k7 Y, F; G# S
constfloat* m_pfParam1; //覃蚚统杅1
7 W" `6 y" M* \4 t: Q( Bconstfloat* m_pfParam2; //覃蚚统杅20 O( G8 J5 `6 K! g$ R+ x' I
constfloat* m_pfParam3; //覃蚚统杅3' N( _) u: O( r- y$ d$ U1 F5 l# T
constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4: w7 U4 a) n& P7 n- x/ J
//const float* m_pfParam5; // parameters must be <= 4
+ w3 X, O4 m- ~ @$ G//const float* m_pfParam6; ; `( p9 L- i/ ^; @) S; C
//const float* m_pfParam7; ) X# K. W1 J. H: t1 r
//const float* m_pfParam8;
; G5 E1 a7 n' z/ r7 x8 [( c& l//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
9 c8 l7 t) |( N$ o3 ^$ @pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
& W, \' H4 u& I&&pData->m_pCalcParam[2].m_nParamStart>=0) 4 S: H/ p3 C$ p
{+ O+ X: o z. g9 e+ U$ @# v
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0
o* \0 `7 \$ G8 NintnPeriod = (int)fParam; //统杅1; Q$ I5 z) F3 `9 Z$ q' g" r
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
5 T: L O5 U& m4 Vconstfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
% T# T% a" h) g1 r) A" {constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
) p1 d3 J/ F& U' x8 ~constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4( U: m7 z% D9 X* S" X7 a
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
- K2 x! F2 c6 L0 O* L5 ` x6 {3 D//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值; V& x! U0 |6 A1 I& v5 u f
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
5 w0 S( w. g2 H6 ntouse pData→m_pData[x].m_fClose+ } Y: I% A3 h* c }$ Z
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; $ @! |, ?- r- I( ]8 X5 S
|1,2,3 , … , m_nNumParam | float m_fOime_t
; S9 O* B8 `/ g) y|1,2,3 , … , m_nNumParam | float m_fHigh;# \' c: e% Y3 z$ P( Y3 C5 w
.. .
0 ]5 r* D, q$ H+ V' c, i|1,2,3 , … , m_nNumParam | WORD m_wDecline;
3 { k3 ?! j7 q& x* M3 F7 `9 b' Qm_nNumParam= 数据high,close,open,low的长度
4 T" k" C" m: n/ K8 }9 l. i. atouse high:
3 \5 m# ~* o5 `pData→m_pData[x].m_fHigh
0 B. K- w. P( g/ ~contentof struct STKDATA
0 n X! q# X0 t2 ?5 b$ ptime_tm_time; //时间,UCT
) g: x7 ]5 j- p2 z- {6 @9 Ifloatm_fOpen; //开盘 open
( E$ l! \1 J, P0 qfloatm_fHigh; //最高 high
' m# D9 d \: q" }4 P( Efloatm_fLow; //最低 low9 @' f( H [; e7 z3 U& S: w' r
floatm_fClose; //收盘 close; H+ ^8 Y5 d! x g# ~3 K% x; Y1 d
floatm_fVolume; //成交量 Volume
2 ~& o" f- z% D) _ Qfloatm_fAmount; //成交额 amount
8 [2 [+ U5 o7 E" e' WWORDm_wAdvance; //上涨家数 仅大盘有效, b5 A6 t4 n- Z- ?: _/ V6 i
WORDm_wDecline; //下跌家数 仅大盘有效
% {) Y$ }3 t4 K( t2 U0 R调用传递参数及传回结果" S( i! I* x, @, \3 h- o. m
调用传递参数
) A0 @1 P0 y; y9 Y2 o: p' I) U. V! Q(pData->m_pfParam1 && //参数1有效Param1exists% ~! p9 @" y/ ?! g5 C/ d9 q% d/ L
pData->m_nParam1Start<0&& //参数1为常数' o7 t6 a# s9 A2 R
pData->m_pfParam2==NULL) //
4 k! V r/ q( d9 U5 e* s l- rlocalprocedure 定义使用变数
- x' {% N1 c) b9 I' @; b$ donstfloat* pValue = pData→m_pfParam1; //use constant参数1
. Q; I1 L2 U8 PintnFirst = pData->m_nParam1Start; //use 参数1效值起始位7 x; K9 `2 \) O8 p/ v, ^
floatfParam = *pData->m_pfParam2; //use 参数2, c( @9 ?3 I6 S( ~# |
intnPeriod = (int)fParam; ( [, v3 O% u2 {8 \, t( G) S
传回结果
: ?* K% u4 \! d0 I+ GfTotal+= pValue[i-j];- K" E0 E. }1 I5 G4 |
pData->m_pResultBuf4 `' a2 C- x) p" q9 N
//////////////////////////////////////////comment |