许多年以前,我曾经在9 _& Q/ K7 j* S; s) B) b w$ J
理想公式区发布了2 \6 ^9 i% e9 X
"
1 m6 N" {9 E7 V1 Q2 g K8 b+ k$ R如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)2 k0 j; c$ g# T" k
"
& b7 E e; g, J8 g% v1 |1 A+ N+ I( Q) y3 ?+ G' l9 L
现在更新foxtrader(飞狐交易师) & `1 k6 \, Y/ ^, w! g* T
连结 DLL的方法
+ o; t1 Q8 C% S& a+ }
8 `, D6 M7 `6 a5 ]; Afoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )
s; P% J8 e% y0 c& S4 Hgauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )1 E7 j, ]. R3 V6 V* X* T5 H
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响* d/ s+ t: Q+ l' y) x
foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效; l' K! z: h3 G, `" N8 v& Y6 L
) ]3 ~7 h8 m: y5 W, W也就是这五个结构都能用# s0 [7 ?' [# U8 g& G/ Q
typedefstruct tagSTKDATA 6 m6 |* o d7 _. B* D* j
typedefunion tagSTKDATAEx) K' h6 y9 S9 N" a& A+ F
typedefstruct tagSPLITDATA ' k& h8 E! N' R; E
typedefstruct tagCALCPARAM% {9 H( @* A8 F% A: W$ u3 `7 D; D
typedefstruct tagCALCINFO
0 D+ G5 D# C& O7 X: V) h) x
+ h; R8 D2 d) i7 \0 S自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C0 G N7 r2 _& p u# L
也就是这五个结构中5 G0 D* g9 O2 {9 l
typedefstruct tagSTKDATA
% L# w2 w* ~- T2 ttypedefunion tagSTKDATAEx
7 U! r" q, k- \8 A! J2 d* B: f* stypedefstruct tagSPLITDATA 2 s* p( t) V! _
typedefstruct tagCALCPARAM
4 P1 z: O9 l7 U7 mtypedefstruct tagCALCINFO. @6 M* z8 W" N. ^% e
只有这两个可以用; K- }# v5 i; G9 P! a6 J
typedefstruct tagCALCPARAM& q) H8 \ y# E+ p- W- R( l& I) R
typedefstruct tagCALCINFO
2 N) z' L6 L6 n3 R值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
% {+ I& }, D6 Y& }* Ptypedefstruct tagCALCPARAM
5 x1 A9 m% `; E2 W, X+ s例如:在 foxtrader中& i) H" X' ?& J; L: s; C5 k
MA1:=MA(CLOSE,3);$ b) j2 w @9 P% r# z
MA2:=MA(CLOSE,6);) n% ~+ y& U/ x$ C- C
MA3:=MA(CLOSE,12);
! s# I( @+ ~9 }: j& @MA4:=MA(CLOSE,24);
2 C: |& T4 f( {+ s, C- qMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
1 D* o9 Q* G4 V1 b6 J; O其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个
# P% b6 D% D: P" L( C下面这两式计算结果相同, q/ B# N1 W0 a f7 h; L7 F& Z( i0 |
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 自行计算}
" e2 F- x3 Z" [3 a! |1 S' T8 RMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}4 {5 x8 \) Q' N8 F! E; n
其他例子) K8 G' o& }5 w3 i! d7 Z( r
oooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
, V" n7 n' W$ ~4 L1 v; [) J- [oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;) C5 ~3 f7 q' p9 T& a* n
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
8 {) I$ p) H/ p W9 s( }fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
) o+ r- Y5 l1 Y8 N
; R% Y2 C& k2 i% o1 a4 A* b' v _* e+ T( y F# d
////////////////////////////////////////////////////////foxfunc.h- c, v: _+ @. f! D$ C/ t
#ifndef__FOXFUNC_H_INCLUDE
& M2 {1 i- j9 n T) p# H# o1 {9 r#define__FOXFUNC_H_INCLUDE- L! d l; N0 x: a* c3 E* ]) [3 `
/*0 R+ F l+ l" I" |
飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
3 D+ B! M; N# W8 v# ~. k/ W4 K1.本规范适用于飞狐交易师V3.x公式系统.) Q3 R. O# A$ R
2.扩展函数用于实现系统函数不能实现的特殊算法. F; R0 b6 x0 Y$ N
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.' L+ U7 m7 @# i& D- Q4 h
4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)2 a M* J$ e/ w/ J; Z
5.动态连接库名称和函数名称可以自己定义.
+ z* [& C \ p- o6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
l, M! c' M3 B! @" @6 M2 I& n1 ]*/- i( G) [( N/ s# S/ I( p! O+ w
#ifdef__cplusplus. k) Q) ^- _! H+ ?$ J( U w
extern"C"
& b: R1 I4 U1 j* z* I{8 `6 e/ Q' Q* n( H5 Q
#endif//__cplusplus
9 b4 w% h% K/ R9 K0 c" I9 Z" T///////////////////////////////////////////////////////////////////////////' F5 b: j& h# \( j ^3 f
//分析周期' W5 Q* A2 m+ C/ k6 O4 F0 _. e
enumDATA_TYPE
[- t7 J) C6 d{
0 b4 o' ~: s0 R/ r8 I2 eTICK_DATA=2,//分笔成交, I* e3 g6 e3 L3 _
MIN1_DATA,//1分钟线0 m' G7 q* _ i- N' n3 s
MIN5_DATA,//5分钟线
2 G; W% G! h. l" ?MIN15_DATA,//15分钟线/ O! e1 \' G1 G% d) S# Z; |
MIN30_DATA,//30分钟线! m6 v/ X: {; h$ T5 \
MIN60_DATA,//60分钟线; F* v8 e- F* V, P: }' j
DAY_DATA,//日线 J6 @, L A2 {$ x
WEEK_DATA,//周线
: O/ ?- [! N0 h- }1 ?MONTH_DATA,//月线 _$ N$ \ U! h9 c8 A
YEAR_DATA,//年线
" T0 V/ R- h% mMULTIDAY_DATA,//多日线7 c! W8 l7 R! L5 o
MULTIMIN_DATA//多分钟线$ q1 q: T- @: D: l
};
& o% C) n# ~3 q' l, D! S///////////////////////////////////////////////////////////////////////////
' U* {7 ~, i. A4 R//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用
0 @( Q* F; k. n* t; l, Z$ Qtypedefstruct tagSTKDATA 2 V/ Z- R9 X- L5 j0 q! K, l9 }
{
/ x% n4 C$ u7 v4 e4 b) z _tm_ ; //时间,UCT8 B1 z# w+ m) V& z9 r4 Z
floatm_fOpen; //开盘 open
( B% S+ X6 K/ Tfloatm_fHigh; //最高 high
; k& E6 Y+ u# @( ~1 efloatm_fLow; //最低 low* p# N X8 v& E* d0 d
floatm_fClose; //收盘 close% |" e3 w5 b3 W4 J
floatm_fVolume; //成交量 Volume
$ T3 n, z$ L r& S+ }$ ~$ qfloatm_fAmount; //成交额 amount) r. ~/ Q; _, s) q
WORDm_wAdvance; //上涨家数 仅大盘有效( p# G, z+ Q8 y/ `7 M4 t' [) K
WORDm_wDecline; //下跌家数 仅大盘有效4 f% _, C1 t/ Q7 N, ~
}STKDATA;
5 e/ n/ v9 j/ A2 P. R; ^! Z3 U定义STKDATA为 tagSTKDATA的简单别名,STKDATA ( U' R3 D, [7 p% l5 m
为真正方便使用名称,tagSTKDATA 为定目的的过水名称
+ B$ S8 r9 @: [////////////////////////////////////////////////////////////////////////////' A8 k% m. F6 \& [
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
! j- q1 n/ Q8 f' q5 ntypedefunion tagSTKDATAEx
5 ]* K9 G/ e" n4 d0 j1 r{
, \! e) `3 I7 C6 O& }struct
; H- k( M! b5 a. n, \; @{# \$ M: w" j/ C9 p+ s6 F
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open( [/ ]" |- c' `- R
floatm_fHigh; //最高 high
n0 M j8 w! ~$ u- L. W% w( xfloatm_fLow; //最低 low9 i8 i; M, B4 B( Q4 v
floatm_fClose; //收盘 close
. U5 @# F. H% w( g8 Y' d4 u6 { Rfloatm_fVolume; //成交量 Volume1 u4 T/ A# M1 C- G1 F3 C& Z, L
floatm_fAmount; //成交额 amount
$ D0 d5 [+ C! z9 H. Rfloatm_fBuyVol[3]; //买1--买3量" N$ K+ J# ~6 F# n t5 t. R$ [
floatm_fSellPrice[3]; //卖1--卖3价2 S9 H' p# V1 n0 l" G
floatm_fSellVol[3]; //卖1--卖3量
2 m* w' Y! e) m, f# o};$ Y, d& r. ^% Y: ]
floatm_fDataEx[12];. h6 S! N, l) ~- P/ n
}STKDATAEx;
# g9 y; m5 U3 x$ M% x* s" r1 z////////////////////////////////////////////////////////////////////////////
9 _* X7 B6 O4 y7 y- B% s//定义取用除权数据的结构8 d: p5 z/ q% ]
typedefstruct tagSPLITDATA
6 \/ v4 H( F: U) _. X{
- o, O0 Z+ C' x- o! Rtime_tm_time; //时间,UCT" }0 X0 V F; [& [4 X3 w
floatm_fHg; //红股; m8 Q* K. y( u$ \3 j
floatm_fPg; //配股
f$ }; ?2 C& Efloatm_fPgj; //配股价3 X7 V, l5 o ~5 c6 C. X$ |1 h
floatm_fHl; //红利
, X: V& q2 Z+ \0 [8 j}SPLITDATA;
$ g7 d$ D- Y( T# U/////////////////////////////////////////////////////////////////////////////
; c) L, u, U! I* q2 ?9 A/ q! R/*财务数据顺序(m_pfFinData内容)
W; W1 k# U M& v9 A序号内容
1 C9 b8 B; p5 ~. ^, V0总股本(万股),
( V5 G4 @: q6 H6 s' [1国家股,
8 C( w4 A) m" d2发起人法人股,
8 v6 }& R( X+ S1 A: [3 C& I3法人股,
! v7 ^; l6 [" _6 v8 X3 X4B股,
2 p; D" g, }5 N4 d: J5H股,! l5 | \2 S+ D% [3 p
6流通A股,
4 r& d/ |- @3 n& j6 N1 h7职工股," {" X/ n. d7 r1 L! b
8A2转配股,5 h1 h2 w5 C: _" ^1 t1 { L$ L# @
9总资产(千元),
1 C( l ^( R. o3 F8 x10流动资产,9 M2 s* w' w) M, V
11固定资产,
" Q" H1 q; Y( S% L$ {3 O% c12无形资产,$ O: o8 A) l' u& Y
13长期投资,! W7 F; a/ R2 @. J1 {
14流动负债,0 c7 w" b$ {5 e i
15长期负债,& | n% t7 `. C$ d' V& _1 h
16资本公积金,
- s) B$ s3 \4 C. A! _+ c17每股公积金,
& J2 X7 F3 Q( ~7 U- N18股东权益,, S% [" v! o4 @% r
19主营收入,: \7 P/ f: U( V
20主营利润,
* Q/ Q( ^: i @. J) d; n/ f21其他利润,- d# }% f5 m* V5 a5 k* \
22营业利润,
# j/ [ G2 g0 `' W' h& P23投资收益,8 {, R2 `0 E7 w0 U* f5 V
24补贴收入,
: V" ^+ T$ `, s3 {0 ]# `25营业外收支,
6 d6 x2 M5 i3 n+ H! H$ Q2 K7 k26上年损益调整,7 d+ c) N4 c; f
27利润总额,
$ j6 T- x0 A/ p, g0 N( E; [. I' G3 E& z28税后利润,$ U9 D* E/ w- ?' l" f7 S3 T# U
29净利润,
1 L1 i' d2 |& l3 k0 r7 N* J30未分配利润,# q5 X# X' T3 N I$ F5 D% t1 `4 ?
31每股未分配,) a; O1 l9 p: R
32每股收益,
; Z" k1 o2 y# X6 {9 I: g2 b33每股净资产,
2 r& i* @4 ]8 n' V7 W* u34调整每股净资,
( s6 s. `/ S, u35股东权益比,
* h3 a8 c7 x5 k2 c: `; F36净资收益率8 ?$ {7 t7 Y8 c$ l1 Y ?& _
*// s* B5 @- H: P# g8 _$ x
/////////////////////////////////////////////////////////////
5 \! f4 u) {: g7 h//定义取用caller函数传递参数项 的结构
8 G8 [) J) Y! F) ]0 ftypedefstruct tagCALCPARAM. Y* ~, D3 q5 M& A& J9 f
{
# G' z! I! F) _$ g( m7 ]union2 F6 G, z s; h
{
) @- Z1 X5 ], r+ ? c: {constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/29 P: J; Y/ X5 G" k3 i
constfloat m_fParam; //数值参数 valueof parameter B0 O6 \ A' `/ {7 Z. q
};
, c/ E( p9 O1 C1 K) `9 R, Oconstint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....
7 J- N8 |" ?$ X9 @7 A}CALCPARAM;1 }/ e( C' h% n8 o
/////////////////////////////////////////////////////////////////////////////1 U9 J1 R/ F8 d5 X( U* T- c
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )
" ^# d4 k. E1 Q, b, b, ctypedefstruct tagCALCINFO5 c' \ D0 H, L7 r8 T+ C: \
{
+ u/ T( y1 L9 _( ^' QconstDWORD m_dwSize; //结构大小
. }; G% w- T' i# EconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
( }1 e0 I* O& V; {constDWORD m_dwSerial; //调用软件序列号
& P: A* k! ^* Econstchar* m_strStkLabel; //股票代码
2 h) S9 H: s6 Y5 EconstBOOL m_bIndex; //大盘! X. M3 G) y( O+ a' H6 m: X
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度: X4 Q5 X, f+ W+ r j" a8 v
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL' a$ h8 O5 l/ ]
constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
: h3 b* t6 j; @$ J2 sconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
$ U/ d5 q& ~8 O8 tconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 1 W' E: u0 f3 N
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
4 r$ D6 t% I4 z* M" dconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3/ O, m- @' _; I# e2 o* K
constfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4$ p! j0 |; L7 @ F3 b
float*m_pResultBuf; //结果缓冲区
3 U5 V8 D; B% dconstDWORD m_dataType; //数据类型& v9 H4 ]" ]6 s, `
constfloat* m_pfFinData; //财务数据9 Z4 O# L" x$ o
//以上与分析家兼容,所以沿用其结构和名称
# Y+ D2 @, |) W) D! l: r; E+ L F//以下为飞狐交易师扩展(fortagSTKDATAEx)
% P' t& c+ O( e, a; I# L' JconstDWORD m_dwReserved; // 保留% e5 T+ C) p# F4 \# P" D
constint m_nNumParam; // 调用参数数量) b7 I0 r i. Q1 ^( O: o
constCALCPARAM* m_pCalcParam; // 调用参数数组' v- l5 q4 F3 [) k0 k9 X, K
constDWORD m_dwReservedEx[4]; // 保留
9 |& E+ }2 W4 t9 R% T9 ]2 |$ qchar*m_strStkName; //股票名称) v! F. y; ~5 o; a6 w$ j* {
SPLITDATA*m_pSplitData; //除权数据2 B9 S1 R; B; |3 q6 u* \& C
intm_nNumSplitData; //除权次数
3 _# q6 w$ m# c3 z}CALCINFO;# i( [2 ?" F1 I8 ]# }
/*& K' G$ Q( y1 q ~; w
注1:(与分析家兼容). A, a8 t' J* B' B
1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.# W5 m+ l" w8 _7 M; M
2.当一个参数无效时,则其后的所有参数均无效.
! [) x) z; H8 S9 |# c如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.
5 d" f- p! E, l7 A3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
6 C( j: B3 @( R3 I) _4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;/ z9 {2 W% y# a
5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
0 L) S$ E& L( S% ~5 S. k数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.* V8 S1 E2 N* A; ]3 E5 |
在时间上m_pData[x]与 m_pfParam1[x]是一致的
9 t8 x( e1 e# K( u s注2:(飞狐交易师扩展)
2 l& Q) t ]/ p1 h$ J1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。+ g$ L2 L5 n [5 [. ^3 u2 f O
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
. X2 f6 A/ e4 t3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。- `! O7 r w8 u8 d# C/ S$ y
4.若i位置的参数为数值,取用m_pCalcParam.m_fParam., v. L4 E- Q0 }+ X3 }2 T0 Y
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。8 F, R3 w* G6 q& K% o
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。7 i- r/ v4 u3 ]9 @
7.经此扩展,对分析家的DLL依然可以调用、兼容。( {7 R" C+ V+ o0 _; j7 C0 N
*/4 x) `8 S. J0 @0 t4 G% G
///////////////////////////////////////////////////////////////////////////////////
. Y, a. `7 o7 X/ S- J4 B- j/*函数输出
9 U& g/ @) ^1 p& j% o__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);: \+ M, `4 r2 Y8 l
1.函数名称需全部大写.
* ?2 }: _- @- y$ [) F# U2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;" d5 ^7 r! i( d7 d1 g- F
对于C++程序还需包括在extern"C" { } 括号中.0 v; l; g/ g8 L, ^
3.函数计算结果用pData->m_pResultBuf带回.
" ^- A4 E% N& r& G8 p4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
. N j/ t4 T) ~# q5 ], e4 Vm_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.5 u4 V% ~) l; P2 l
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
$ J+ z: \7 Q5 @+ ^8 Q2 \* }8 J6 w*/
! y* q. t% L* X! y//示例函数,使用时用实际名称替换
4 r6 q b% h0 r5 |# ]7 Y__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);9 u: x; t- z& J' z# r# R% n, E
__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);# e6 A" \# Y! ^. T
//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
" [& ]! i; ~! p! A__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
9 N" H& j/ Y5 T$ M4 L6 i//WINAPI = _stdcall
+ q2 Y: A# X9 t#ifdef__cplusplus+ z+ b2 |$ G B1 F. d$ I' e0 r& Q
}
# O2 v6 t! _5 m/ O3 N#endif//__cplusplus4 L/ u: g. ]8 Y
#endif//__FOXFUNC_H_INCLUDE! V. H8 J# o# z0 I+ f% J8 \2 ^1 S
: V. n# e, {7 J: L6 n$ ?//////////////////////////////////////////comment 注解$ d2 K: G. ^4 Q: D& Y0 a
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)( y! Y2 j& Q* p, A
pData是指向 址标总结构 CALCINFO的 总址标0 o* o5 B! d) g& ?
取用第二个参数数值floatfParam = *pData→m_pfParam2 - {* }: |$ B9 i" j' o6 m
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;
: d. h* P1 a4 [, v) y2 p取用股票数据长度intndata = pData→m_nNumData;
3 J3 B9 [; y: T第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<04 y( P2 \" Y% A& i" M( P
第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
. Y/ b7 m8 _4 F( ?+ ~ q3 w第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
2 ~1 q5 \* k. u/ c8 d a3 F1 K9 S/ Iconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标9 I9 L3 s5 h% M) B. u# ?0 g1 y2 m" n! m
取用股票数据结构
# P! Z# Y7 j, y9 ~pData→m_nNumData= 变数数据长度
; t0 z% Y! z/ S/ q& L- W) Z4 VpData→m_pData= pointer to struc STKDATA 的址标1 ^8 q: A7 w& [* t. y; h2 Z
pData→m_pData[x]数据结构的第x个数据% h4 G9 x3 f1 O: Y4 q- E
pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High
! H; W8 E0 B* p; |! l- |* R& W1 y! R9 ^1 o取用结果缓冲序列
4 o1 I6 Y! @. _7 O1 }4 t; ApData->m_pResultBuf3 Q+ S* V' J* Y% L. I
取得第一个序列参数的起始序位,如 2,...5 , . 7...+ T. x1 n$ I" ]7 y
intnFirst = pData->m_nParam1Start;
. M* Q( I7 J: [6 R9 F7 P$ g, R: Afor( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )! J8 E. g1 J% C
取得第二个数值参数的数值
1 @& b7 P3 N1 D' e) D- zfloatfParam = *pData->m_pfParam2;
8 w2 }# I/ ~* P% ~2 |intnPeriod = (int)fParam;
: K9 q) C: J# T! u- u# \" z C取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;
% T+ H3 h/ L* V7 r" B' x取用序列参数的单个直pValue7 e6 j( D! s* D7 H
取用缓冲序列的单个值pData->m_pResultBuf
5 a& b+ P) T% }' P1 u( L/ DconstCALCPARAM* m_pCalcParam; // 调用参数数组: B" V5 e! ]6 v8 `
m_pCalcParam为序列址标,指向各序列参数的指标9 x" c, t; P* O& e+ s1 @% s
第一个序列参数pData→m_pCalcParam[0]) O7 T7 E7 c& b8 D- s% N3 G: s
constfloat* m_pfParam; //指向序列参数的址标0 n3 ~' l" z w/ ^' O$ H
第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
2 S7 a6 Q/ I/ A8 |第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;( l d6 M; M5 N6 Y0 o6 u
取用第一个序列参数的单个直pValue1
( t# D3 t' O9 Q0 o, s' q% A6 z' ~第二个序列参数pData→m_pCalcParam[1]
( T0 F- N7 k! N" _9 _! u8 @第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart: H! R$ k) T. m: j4 _: K* S" L. Z
第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;( S2 q: f+ I" Y' Q3 v# H
取用第二个序列参数的单个直pValue25 K# V) v2 |$ o/ \5 B0 m2 @, `
第三个序列参数pData→m_pCalcParam[2]
/ Q) S9 }2 \( y3 F9 T" g& }第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart8 h! C: \; u8 k# } Y, x
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;3 ?0 S) w* S: W+ K2 x5 ], D: @
取用第三个序列参数的单个直pValue3
1 B/ b0 q) E, d8 H. _6 ~第四个序列参数pData→m_pCalcParam[3]0 @$ `8 h6 h2 @ F& B
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart6 U' z( U v2 I2 [" y @+ C. f
第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;9 Z0 v9 A0 j( L% J
取用第四个序列参数的单个直pValue4. B0 u3 K' e2 U6 C) b6 Q7 g6 u# M
如果有四个序列参数,则取用序位最高的那一个序位+ K7 z1 w" ]) ?8 i* k
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&" k4 B" l0 X/ J& W f
pData->m_pCalcParam[1].m_nParamStart>= 0 &&+ r7 U: @" C. ]
pData->m_pCalcParam[2].m_nParamStart>= 0 &&) Z2 g( g. _0 ?
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值
" r" L- u3 r/ B$ E7 D{
5 a- p9 |: z1 H5 P//计算返回的序列的第一个有效值位置, w8 K# H. a! H+ S. {
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致' o) V% G; e6 _! y
//若不知,则2 c6 D- V! _7 |) R( L& ~
/*/ ~! ]+ F; e& B/ `( `
intnFirst = pData->m_pCalcParam[0].m_nParamStart;
, _- a/ [; X. I5 F1 a' b% iif( nFirst < pData->m_pCalcParam[1].m_nParamStart ) ) E7 y3 S& \4 d$ P
nFirst= pData->m_pCalcParam[1].m_nParamStart;
) u" V L3 _' s# }+ _" T& jif( nFirst < pData->m_pCalcParam[2].m_nParamStart )
$ y6 U) Q: E- v+ k' y" GnFirst= pData->m_pCalcParam[2].m_nParamStart;
. x1 Z7 s" |; i( h- zif( nFirst < pData->m_pCalcParam[3].m_nParamStart ) ) Q) m; E f1 v3 _/ u1 I. I
nFirst= pData→m_pCalcParam[3].m_nParamStart;3 ^! E" g5 g1 m4 A
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;
3 E: n* Z0 |4 M! S1 U7 kconstfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;4 U3 @6 U) @- q3 R0 J
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;+ d/ L1 X2 C5 k% ?0 J
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;- T" H& m+ E% W" O0 x
//-------------------
& q. t# X$ o& ]2 mfloatm_fOpen; //开盘 open4 I# Q/ A. B! F, L' ~1 [+ f* ]
floatm_fHigh; //最高 high
! u! i" I1 s0 C& `1 D' yfloatm_fLow; //最低 low! ^. t1 g$ u1 T/ ~7 }$ P; h
floatm_fClose; //收盘 close3 T \9 [& c/ o- x
floatm_fVolume; //成交量 Volume! o: v6 d( u; p. c3 C
floatm_fAmount; //成交额 amount# A9 D7 s4 v! R/ C4 }
调用收盘据# e) z+ ~8 j0 _7 A, _0 @% a
pData→m_nNumData= 变数数据长度/ G' z/ [$ ~/ Q3 E
pData→m_pData= pointer to struc STKDATA
# i3 c1 \" c) gpData→m_pData[x]第x个数据
: Z& l3 H5 H% b5 hpData→m_pData[x].m_fHigh第x个数据中的 High
7 [6 o# i% S0 O- @" K$ S, _. a/ N) l@@@@@@@@@@@important !!!!!!!
( q' C1 l e: FsinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
6 J6 j1 B' D1 D) \4 ?so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
/ E) H1 Y' u3 K+ r( v5 IpData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader
( Q+ M" A5 H) ~" s+ ?( |, YpData→m_pData[i-j].m_fHighto use high
, O3 r# c" |5 t: g: R6 WpData->m_pData[i-j].m_fLow1 m0 N) B" v. W& X" o% U1 e) i6 A0 {
pData->m_pData[i-j].m_fClose
4 _* `8 k0 c/ X4 p" J% W" e2 fm_pData= pointer to struc STKDATA; |0 F0 Q( ~6 e! ?1 a2 Y2 L
incalling C++ dll function
2 c3 g! m/ W C1 {" ~: xm_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)
8 d. e. I; t/ T- m8 u& @* L& ltouse a single value in variable ‘High’; r2 C2 N- v! y6 L [* a: F
pData→m_pData[i-j].m_fHighto use high+ ? x) e) e0 W. I1 @
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 8 r$ T1 o. i( h+ I
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2' ~3 v0 o. @0 J: l
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
+ q% O8 o- Q7 G O/ yconstfloat* m_pfParam4; $ D, `/ t; k p% \
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数
! X& `: Y9 k: S+ O, vpData→m_pfParam1= pointer to 第一个(序列)参数
# S9 ?9 Q- Y4 a5 opData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值' p; ^% T$ r Z. P3 i9 r$ F, B2 e
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
" a5 }# M) G9 ?( dcpParam[x] = 取用第一个(序列)参数的第x 个值
; U9 O3 ~+ k9 R# V# Km_pResultBuf= 结果缓冲列5 v/ O" J$ D d7 R& C
pData→m_pResultBuf= pointer to 结果缓冲列6 @1 q4 m3 C, t/ Q: {4 r* j+ |. I. F4 o" w- b
pData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值7 D; @0 h" C/ `4 K0 {$ } y
//////////////////////////////////////////comment
2 [/ I" h% f& s# j2 H+ A//////////////////////////////////////////comment 注解# r! O" L3 ?; z
constint m_nParam1Start; //统杅1衄虴宎弇离
* a, v. S5 j( ]1 n* Y& gconstfloat* m_pfParam1; //覃蚚统杅1
; ]$ P& G' P* a: Uconstfloat* m_pfParam2; //覃蚚统杅20 n. g2 l! L, P$ {
constfloat* m_pfParam3; //覃蚚统杅3
) f$ _' s2 t1 o) M- f* l" gconstfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 48 z2 y. y7 L4 {6 b6 D4 d& V
//const float* m_pfParam5; // parameters must be <= 4" o' d3 m. d. b9 g! L3 @% L
//const float* m_pfParam6;
9 U2 h8 S1 N( s) L; X1 ]9 n//const float* m_pfParam7;
6 {% m, q- X# }; K//const float* m_pfParam8;
% d/ m( V- d& o3 d4 q) ~4 ]" r4 S//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&# s% d1 E: U/ n. h4 \. S
pData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0$ f1 A& l1 `5 F$ v9 q1 p
&&pData->m_pCalcParam[2].m_nParamStart>=0) % o2 t0 c( z! d: X
{6 O" y2 Y5 i" t* J5 V
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0$ v7 g1 k/ C1 I3 W' f
intnPeriod = (int)fParam; //统杅1
/ S- I6 y1 e6 r//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值3 F; r2 V, _ W6 m
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
4 @; N9 |& W' J l, Gconstfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值" t- s. v! q9 h
constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4, M! o- P5 o: {' _
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值' B, I+ e# V4 V9 ^
//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
: w: K# Z* \* V& O! w; A9 O" _//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
K$ U, {) g9 q: n5 R4 g1 u; }. Ztouse pData→m_pData[x].m_fClose7 y0 u6 j0 F6 ^% C
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; 7 W( m: x9 U, w" M/ P8 R
|1,2,3 , … , m_nNumParam | float m_fOime_t ; H2 P1 J8 O |$ _6 \
|1,2,3 , … , m_nNumParam | float m_fHigh;
" _+ ]5 l: c- r* ~.. .
2 Q! b) S# ?8 x|1,2,3 , … , m_nNumParam | WORD m_wDecline;
$ i7 f+ v7 l2 O+ O; om_nNumParam= 数据high,close,open,low的长度
5 U2 j# d/ U& H: T: ]4 j3 Rtouse high:
. u* P# A2 s. L) g( X+ CpData→m_pData[x].m_fHigh- l( C- S. | E& h
contentof struct STKDATA. o1 f4 P- N: x0 q
time_tm_time; //时间,UCT
4 H' Z6 N0 t* }: ~* `floatm_fOpen; //开盘 open) d9 c8 K2 d0 D: h% p9 H
floatm_fHigh; //最高 high8 {2 G6 C0 W) K- I5 P
floatm_fLow; //最低 low
3 c* e/ M- a( S' X9 r5 Pfloatm_fClose; //收盘 close9 W, ]! w; u$ O2 m
floatm_fVolume; //成交量 Volume7 s$ [# \: S/ C
floatm_fAmount; //成交额 amount2 `3 G( ]5 B: E! I
WORDm_wAdvance; //上涨家数 仅大盘有效
2 L0 w) |7 ?2 U* y5 a4 tWORDm_wDecline; //下跌家数 仅大盘有效
; O0 | @* U: A* Y调用传递参数及传回结果0 A4 f+ q$ Y2 w& r1 I$ c5 H3 Q" z
调用传递参数
" A; k* w4 O: \) g( f2 b(pData->m_pfParam1 && //参数1有效Param1exists
) @3 ]$ g% \0 A+ npData->m_nParam1Start<0&& //参数1为常数
, _8 i$ m. {% i6 J# ppData->m_pfParam2==NULL) //
% w* Z$ I4 ~. G2 S4 Hlocalprocedure 定义使用变数
# g* e3 ~ x" x0 S) ]/ k9 Sonstfloat* pValue = pData→m_pfParam1; //use constant参数1! u$ [' |9 ]: b9 Z
intnFirst = pData->m_nParam1Start; //use 参数1效值起始位
, A$ g4 f8 g/ u1 t" }1 E8 h' N1 B+ X \floatfParam = *pData->m_pfParam2; //use 参数2
: Z) p/ F5 J, c: i- [$ U% P5 s4 pintnPeriod = (int)fParam; ( ^3 g; }3 {; E+ F
传回结果
) d% m6 L: n5 _& ?1 j3 y/ NfTotal+= pValue[i-j];( F( `- f$ j j* z
pData->m_pResultBuf. Q5 ~* V6 J% I$ a3 F" S
//////////////////////////////////////////comment |