许多年以前,我曾经在! J& r: C, d, A: m! ?
理想公式区发布了
" o$ q8 g1 G' ?"
" `$ K, b9 ` t如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言) J0 C* e K9 Z2 p" D0 Z4 Z
"( [$ {4 B7 R6 m5 n; G- X( {% W
5 r+ `" ~/ e- x H V8 [4 F现在更新foxtrader(飞狐交易师)
9 Q! x: D# K1 U9 H' Z+ Y连结 DLL的方法/ }# x6 H( |; G
/ o; H$ a2 L* g: Ffoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )8 @6 t) U6 x) L7 x" C! z+ t1 B
gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )
+ j3 i n- G" K. l9 z9 F& P' Ogauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
! ]/ j) D+ x6 {* U! V5 U1 S' }foxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效; c4 l* \, r4 K6 I# y; @
8 j S7 s4 j1 i1 `! s2 Y" q' A也就是这五个结构都能用( w% f$ A; f8 b% l0 K" i5 T+ [
typedefstruct tagSTKDATA / r+ N+ ?/ t. f. K( }. w5 e5 u
typedefunion tagSTKDATAEx
, w1 K. s* K* {& p: ctypedefstruct tagSPLITDATA
; G# r3 f& D1 }+ wtypedefstruct tagCALCPARAM6 u( u1 e7 @4 M. ~% x
typedefstruct tagCALCINFO! x; K% \5 k# ^' d4 x$ Z
5 p0 b. x5 ^2 O, l自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
0 m4 q& |7 B/ J' [8 n: A也就是这五个结构中1 D/ ]; c" u) g' B$ w# x
typedefstruct tagSTKDATA
; u0 U$ @$ M, J7 H% k: q: c7 ftypedefunion tagSTKDATAEx) D6 u |8 m. N' u
typedefstruct tagSPLITDATA
- S- V- @# L6 K+ I* d& Z2 ?- stypedefstruct tagCALCPARAM1 ^5 ]9 q6 s& Z( A2 Z: h! G8 @
typedefstruct tagCALCINFO6 M/ m. b3 E6 C+ E; M! j
只有这两个可以用
/ V% E: j& J( N$ E/ U' `4 ftypedefstruct tagCALCPARAM7 P9 a' O" m7 L! @! _% u1 ]0 O4 s
typedefstruct tagCALCINFO t( S, a" d4 w' w$ c& {/ i
值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
' c$ v( Y& {, k! V4 W" Mtypedefstruct tagCALCPARAM
' P! O' _/ \! i0 r2 |例如:在 foxtrader中
8 u8 v0 v6 R) {) e( u( W" \MA1:=MA(CLOSE,3);: @; k" w2 r5 a7 p7 E- w
MA2:=MA(CLOSE,6);$ x" u" _: G0 ?' d# [5 h
MA3:=MA(CLOSE,12);
6 K" F# _! x- z, NMA4:=MA(CLOSE,24);
" v; O, U, X( @% Y3 G- C& A( SMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}. F) C: h3 ^6 t6 K4 \# \0 g
其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个6 Q& l6 w+ g: k. u$ |% ]
下面这两式计算结果相同& M ]0 c: ~1 d: d9 S* p# j, P
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 自行计算}
/ }7 {4 P* F* I* q0 k! dMYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}
0 X" n Z1 j& T. U. f" q其他例子
: e/ n+ x2 G9 a' X8 Koooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)
3 Q2 N+ g* \9 w& a4 k* @oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;& V# w, w. X9 {1 S. W0 G
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的
1 u9 }& M p5 O- _3 {2 qfTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
. J: W( Z0 E. M# z) S1 P. M
! b% i5 o1 o! J( V5 M8 i
) ^; t; l; \; _ R4 T) `0 p////////////////////////////////////////////////////////foxfunc.h$ x. D. Z4 M5 O" u) }
#ifndef__FOXFUNC_H_INCLUDE
- m" ]9 t, a/ h, c: R% ]% c#define__FOXFUNC_H_INCLUDE e+ d9 w/ G& q& K
/*
: O# S2 m6 S/ }1 s/ u R飞狐交易师“C语言接口”扩展程序调用接口规范V3.0
; ~( o( U8 q8 j# d; f+ ]1.本规范适用于飞狐交易师V3.x公式系统.( C2 }/ f6 {: }% k3 J5 j
2.扩展函数用于实现系统函数不能实现的特殊算法.- S9 ?, r6 X- J8 q
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程." ]1 k- M! e `+ R# }1 T* I
4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
: ?1 J6 @( s9 E: u' i+ ?5.动态连接库名称和函数名称可以自己定义.2 Y7 E. t* R9 z0 Y
6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
' b3 Y, D( Q3 }1 u, S*/ ^$ D( A V9 c0 e; ~0 j9 Y
#ifdef__cplusplus
6 o6 g- L( Q! V* Jextern"C"
/ D$ O* N/ a, r- k0 V{
@/ {- ?% o9 \. l* O4 a#endif//__cplusplus
' }. ~7 V/ \& }3 a8 E///////////////////////////////////////////////////////////////////////////
' c2 V! o7 r. ] r3 ^1 V//分析周期
. B$ @5 }/ X: UenumDATA_TYPE
3 d$ e" a: g3 \6 z- M- T{/ `, L( T$ p/ k! r6 ?2 E
TICK_DATA=2,//分笔成交
3 X3 q7 j; \$ A2 m- ]; wMIN1_DATA,//1分钟线, E1 \& c2 m) y& b
MIN5_DATA,//5分钟线
" C4 n& E3 y$ ^% d. y5 hMIN15_DATA,//15分钟线% [2 F0 D |8 S" S0 Y U* j; X) w
MIN30_DATA,//30分钟线9 b' [3 Y& T( Q% [% @
MIN60_DATA,//60分钟线
# K$ d6 ^# k1 ]& yDAY_DATA,//日线/ K4 x; j: l& C( a8 f, ^1 Y
WEEK_DATA,//周线& ?! `0 Q4 A/ x% g! }, n) i' r" g
MONTH_DATA,//月线+ l2 B( M B- R( P/ A1 V& K( I a% ~
YEAR_DATA,//年线8 L" W$ K+ A, r3 J
MULTIDAY_DATA,//多日线
$ Q9 D$ U& t1 IMULTIMIN_DATA//多分钟线$ e+ c1 z! Z# }
};, l& G5 j# E6 `! U( F
///////////////////////////////////////////////////////////////////////////! n1 ]5 F! s( K4 c; y
//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用
2 \ v: E$ `# Atypedefstruct tagSTKDATA 6 R* q3 g0 Q' u0 |+ N
{
8 ?9 B) P: D2 g& n3 Z) x; D! W _tm_ ; //时间,UCT
# T, i' @$ M0 K7 Z+ H5 \! `4 \+ Mfloatm_fOpen; //开盘 open7 y8 p; q* L/ W; ^
floatm_fHigh; //最高 high
. ?# q' J- m* o1 | {floatm_fLow; //最低 low5 E8 y( C5 E4 T G9 X* @
floatm_fClose; //收盘 close
9 x+ ~1 J% n+ P+ ~/ S" \2 R& xfloatm_fVolume; //成交量 Volume/ y% E1 q, ?$ \
floatm_fAmount; //成交额 amount
0 m( ?( Y% e2 t$ X* g- s& DWORDm_wAdvance; //上涨家数 仅大盘有效$ r, f1 s+ Q2 f* H; N P: i8 v
WORDm_wDecline; //下跌家数 仅大盘有效
6 B, s5 s {% l0 m9 {}STKDATA;# c W* {5 ~5 @8 g9 A( |/ R
定义STKDATA为 tagSTKDATA的简单别名,STKDATA
, ]5 z3 ?2 b. I为真正方便使用名称,tagSTKDATA 为定目的的过水名称
& W) @# G% T" W2 W. b; j////////////////////////////////////////////////////////////////////////////
# Q$ L9 T5 \' i c0 h, q//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
1 M1 F9 O& z4 s2 `' L/ r* stypedefunion tagSTKDATAEx' M3 e# [$ M+ `: _) H; s
{
& }- Y w Z- Z/ rstruct/ s: B" k4 ?# ?/ T
{
% L6 c7 p. ?/ |4 o. [( hfloatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open& e0 z; |7 E+ q9 R
floatm_fHigh; //最高 high5 i, c3 W; {9 t( u
floatm_fLow; //最低 low
# Q% }9 y( ^! |# I# |: \floatm_fClose; //收盘 close: `9 T2 _3 B- V6 g# W! f: p
floatm_fVolume; //成交量 Volume
% J6 e8 e3 C3 ?; Dfloatm_fAmount; //成交额 amount) i N7 W s- W/ I' P
floatm_fBuyVol[3]; //买1--买3量
8 L" g" h, F) d: ~floatm_fSellPrice[3]; //卖1--卖3价5 ^9 A+ B6 j# w+ D }: v
floatm_fSellVol[3]; //卖1--卖3量
9 Z# Y" \1 k) {};
6 ]- s5 r: H- h8 a) o8 Bfloatm_fDataEx[12];
8 ] b% U! G7 G+ ^$ M}STKDATAEx;, L+ }. Y1 R0 K0 h! s
////////////////////////////////////////////////////////////////////////////
7 w" g; `& j( G) j//定义取用除权数据的结构) y7 c1 l6 C G7 ~2 s
typedefstruct tagSPLITDATA + F1 K" E0 y3 T, ?- q! ~1 f. L
{
* ^: Y# J# p$ R, m* Ttime_tm_time; //时间,UCT
, d2 [# r! [# w. \0 Y$ hfloatm_fHg; //红股
" W; |6 @: J6 H5 j& j) U) d- R$ e+ R, v7 sfloatm_fPg; //配股5 c, m3 I+ j( y4 s+ \& r
floatm_fPgj; //配股价
, v1 @+ [- K4 Q" wfloatm_fHl; //红利
+ L" I& m* w6 P7 q* s" O0 H& f; e}SPLITDATA;( [3 k" n$ t0 L& D
/////////////////////////////////////////////////////////////////////////////3 I& p4 l6 V0 E" g. D$ R; G
/*财务数据顺序(m_pfFinData内容)
* o0 D# T2 y. B1 e0 ^序号内容
! K. Z7 d0 ~% X1 Y1 J0总股本(万股),
- l8 R) L3 z$ {# a! q) z1国家股,
' X! K& }0 s; f! M3 k8 j# i2发起人法人股,% j; j% z/ x" P8 j+ e, h
3法人股,
( `8 R: X$ x( J7 b* ^4B股,% T! Q# D" e* M2 | |4 ]
5H股,
6 i8 y9 c) F4 C: V6 a+ I$ a6流通A股,
& Q9 `' r3 h- b7职工股,
" C. _: Y1 p; r9 x$ @8 v7 `! b& F; l8A2转配股,
+ N+ I/ ^4 Q, x9总资产(千元),! S. c& J% c- s' o) }% ^9 u k
10流动资产,
) [. J) N) x1 \4 f0 V1 p11固定资产,
5 t3 U, l. C4 A2 r+ R3 j* [6 [12无形资产,& M! J" s0 @/ F. O1 F. [
13长期投资,
& C: ]% W7 z3 z3 n! x; M* v14流动负债,
\ _: j* ]" ?- J& e# w2 z; Y15长期负债,: {9 |& @" v8 T$ I! ?& g
16资本公积金, m, J, {! l+ r$ ~' h. I
17每股公积金,
& l3 r) L6 G# q& }: d18股东权益,2 t4 u2 T" Q8 M* K
19主营收入,7 m4 @) C. f# M* m
20主营利润," \: B2 D5 x* Z! ^5 O
21其他利润,
9 C- p& U* M( i {) v22营业利润,
. c7 g2 ~# G/ s u" v: @9 b23投资收益,
8 S* G& U+ D/ d2 H& Z$ G24补贴收入,
9 v$ q3 X) s e0 H8 P$ e$ j25营业外收支,
4 G( k# @2 d( A" r) o- V26上年损益调整,
% k/ Q, k$ J1 T5 {3 f; a1 n2 i+ _27利润总额,
# w- D2 `; P2 [% x C5 T/ H28税后利润,! `9 G* H* k! p* j! r- P, t7 H
29净利润,
9 M; w: U/ Z$ B1 y30未分配利润,- V2 M) t- T p
31每股未分配,
3 R$ p" f% L( Q( Q# n32每股收益,
/ f: ?1 O" c4 |, q6 S33每股净资产,
% ]; R3 ]+ Q& U [% K34调整每股净资,6 B, k& R7 E/ N! }3 M' o5 y
35股东权益比,3 T( \/ A# \2 }& l% _
36净资收益率
) A* `1 j, f2 [: E8 @. O*/% i3 E7 k. \ i/ R) j2 n0 b
/////////////////////////////////////////////////////////////
' Q& k5 \- p7 V//定义取用caller函数传递参数项 的结构
+ c: q' h! N: D7 h+ Rtypedefstruct tagCALCPARAM
7 R5 |/ H6 Y7 \: k1 P{
2 x; g. A' @+ N! a; O7 ?union* A% m) q* V- V4 V3 V& l
{
- v$ B6 y, a, Yconstfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/2
. N+ \4 R; l/ Z2 Z4 rconstfloat m_fParam; //数值参数 valueof parameter
7 q) G+ L* |% _, `8 S};. s% a5 A$ F9 I5 ^. U6 z
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....5 b2 A! l C+ b- p" A/ j# c
}CALCPARAM;" L! F7 y+ R+ R. s8 @: x! t% s
/////////////////////////////////////////////////////////////////////////////3 S3 }0 j' L" D3 Q4 E, z, N
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 )
) E# F, Q5 Z' ^' Gtypedefstruct tagCALCINFO. h2 B3 I, ^1 l- ~ ]
{% R- S5 D% {4 g* w! d7 D/ B9 o
constDWORD m_dwSize; //结构大小
7 r% [8 d' L- x! Q5 {' z9 vconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210)
/ [% p; B& d3 ?2 `1 q: e9 O3 N/ P9 rconstDWORD m_dwSerial; //调用软件序列号
8 u1 Z3 z% N3 o4 m% n; ~constchar* m_strStkLabel; //股票代码
% L5 R% b l; F7 AconstBOOL m_bIndex; //大盘: ^! s; j7 Z; }- L- U! j
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度) e- V6 s. }9 H3 D3 {' z* v$ j
constSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL: T2 b2 I& [" p' ~/ X' A' S
constSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
) }( M0 q6 d1 t( Vconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter v. c9 ?' N7 p/ R( z
constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
% ?/ X8 E$ {3 E/ W1 wconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
/ X+ r' a4 O! O* D8 D$ z! gconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
0 w6 e9 {5 |- i- d0 o3 P& B* hconstfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4- r5 O" |. K6 M: U
float*m_pResultBuf; //结果缓冲区
" W h3 K! V: J& L& F1 q4 kconstDWORD m_dataType; //数据类型
; x4 M; K' k: n7 e2 V, qconstfloat* m_pfFinData; //财务数据+ _& T8 r6 ]! W: N8 m
//以上与分析家兼容,所以沿用其结构和名称# ?0 o1 x' b, F0 B
//以下为飞狐交易师扩展(fortagSTKDATAEx)
9 u5 p# ]) `" e2 [! h! `. H7 kconstDWORD m_dwReserved; // 保留# ^" D+ t6 c5 b: @: b" Z
constint m_nNumParam; // 调用参数数量
$ \5 P6 v6 F1 G+ d1 @constCALCPARAM* m_pCalcParam; // 调用参数数组
+ o( {9 {) t( O, v: P8 A l6 I) r' @% v& YconstDWORD m_dwReservedEx[4]; // 保留
( o/ i% u f" s! F2 p& u- |char*m_strStkName; //股票名称6 \4 |8 ~- V7 M4 W- p4 G1 j
SPLITDATA*m_pSplitData; //除权数据
+ j0 J' E+ R! e. _$ C3 }intm_nNumSplitData; //除权次数
! ]% n) J0 o; g( M' \. R7 z}CALCINFO;1 T9 u5 [" b' ^9 ]4 O- N# B0 w
/*
" m- a- f. j2 p# a. r注1:(与分析家兼容)
/ ?; _4 f1 ?+ c- p( l5 O1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.- n5 u2 C8 G D* @2 b
2.当一个参数无效时,则其后的所有参数均无效.- |- C! V- _# r
如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL., _, {; v5 ~8 m1 n7 d3 a+ X' q% H
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.
8 ^& [0 E* t6 t0 O9 K0 x4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;
9 @* [ b# M- q* T, p5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
' i# m L+ @1 d7 ^2 ~4 A数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.8 V: Z- H6 M1 M, g: i
在时间上m_pData[x]与 m_pfParam1[x]是一致的& O1 W8 ?3 B3 j) N2 a
注2:(飞狐交易师扩展)' c8 g" ]1 {- k `6 m9 [
1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。6 P' J5 e* N9 C$ u5 v( J3 o
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.+ x: J9 R/ _1 C9 L. U
3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。8 B- `# z! n8 \7 F: x
4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.
- g' h+ U( c5 ?5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。
: g1 X9 Q7 g7 C; V/ h" {6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
. J0 e. w- v" W3 p7 B# `2 m7.经此扩展,对分析家的DLL依然可以调用、兼容。
7 F7 {& h* H7 B9 S*/
+ } d- |; \/ ]% m) N! _///////////////////////////////////////////////////////////////////////////////////
+ Q! h L1 Z4 H3 P/*函数输出, d, e3 h. s6 T
__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);
/ Z# \6 |8 G1 ?* j" k0 X1.函数名称需全部大写. \! h! _5 }1 y' C' G
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;& C0 s' H4 p7 @ W1 r
对于C++程序还需包括在extern"C" { } 括号中.$ M$ W# @( V9 ~+ q/ f$ U
3.函数计算结果用pData->m_pResultBuf带回.& v6 G% V2 g O( W, F
4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:
* C5 M/ Q: G- Im_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.+ Y& ]8 v+ W8 N4 U3 S* Z
5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER
. Q% \5 D1 i1 G*/
7 F$ E- L0 X `# Y; v2 Q+ i//示例函数,使用时用实际名称替换9 b% w+ J7 `3 A9 H' C Z- P
__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);
3 J. X4 y5 y/ i( s__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);% t) `' i2 C8 e! w4 }
//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
* Z. z D9 d0 f' @) n; ~__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
" T2 c! u" w6 A2 M3 }! n' T: c. Y+ L//WINAPI = _stdcall
* {* [: i+ X& K# j; ]#ifdef__cplusplus
. _! g. c6 O7 T* H0 S& e `! `}
/ Y! q; x' y5 d( E. I) S# ]6 m#endif//__cplusplus
- W! X' d; A C9 }#endif//__FOXFUNC_H_INCLUDE
, k# e1 Q3 W' n
! k* e3 ~% L$ s' k! r4 n* U//////////////////////////////////////////comment 注解
: l8 O: d0 d2 P0 Z b9 v__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
4 R8 ?7 j% r" `# Z9 ~, `( F, rpData是指向 址标总结构 CALCINFO的 总址标
$ y5 b0 D1 Y6 U. c取用第二个参数数值floatfParam = *pData→m_pfParam2 + K& V1 N5 p$ S; ]$ o" ^ j
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;
9 A5 ^, u+ a1 T( J/ [$ a取用股票数据长度intndata = pData→m_nNumData;
L0 A B5 A0 ]# B3 F第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0
. f- @) I+ q& x% \. b' P, `. d: `第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0" u: o! f3 |$ t
第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL
8 `% Y3 |, b$ yconstfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标2 Y- T- @* c% X% ^# }/ [, C
取用股票数据结构* u5 R6 Z3 ^( j; S I
pData→m_nNumData= 变数数据长度
8 y- U& c$ t/ q, K6 c2 I* m( M fpData→m_pData= pointer to struc STKDATA 的址标
+ O7 P+ {1 q2 t* c* n% FpData→m_pData[x]数据结构的第x个数据# f5 Z& w$ M# |7 w* J2 m' P) M
pData→m_pData[x].m_fHigh数据结构的第x个数据中的 High' Q: P2 j7 v1 k5 Y( o. D
取用结果缓冲序列/ }1 v' c" j2 ~3 s
pData->m_pResultBuf
7 v$ u& Z, F) I% y2 i取得第一个序列参数的起始序位,如 2,...5 , . 7...' ~' G0 |' U. w6 o
intnFirst = pData->m_nParam1Start;
& k6 ~$ W' Y) t0 J! ?( Qfor( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ )
& J8 d3 J7 C3 e5 W2 n& |取得第二个数值参数的数值
6 K4 a, c# h6 X2 R) ~floatfParam = *pData->m_pfParam2; " S: H/ v8 B6 d3 w) g. u
intnPeriod = (int)fParam;
% R" S" Z! p( R. ?取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;
5 j+ C, Q' U* l4 q取用序列参数的单个直pValue- o9 z. G9 I+ u& Y1 I( e
取用缓冲序列的单个值pData->m_pResultBuf! }+ H, C8 S4 v& u. P& Z5 q
constCALCPARAM* m_pCalcParam; // 调用参数数组, b7 K% L- l* m1 {. ~: l3 A
m_pCalcParam为序列址标,指向各序列参数的指标2 D. \/ w9 M2 [
第一个序列参数pData→m_pCalcParam[0]
+ [9 ]& e. H0 o+ L+ a# e* X) kconstfloat* m_pfParam; //指向序列参数的址标
& }8 ?: b6 |8 d; O) P第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart
! u4 K- l" f* a5 ?4 D* n第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
8 g z' x2 Q7 o {# K& I, W; X取用第一个序列参数的单个直pValue1/ @. ]) z6 Q+ q$ [
第二个序列参数pData→m_pCalcParam[1]
# \; v$ ]2 Z8 Z6 k, U( L5 e第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart; |1 l+ S1 y9 h/ Y+ P. ]1 |
第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;- s4 F6 `7 E- ?1 i4 B' D4 x4 V& U1 X$ C
取用第二个序列参数的单个直pValue2
: R' i$ u9 p( C; A% E/ s第三个序列参数pData→m_pCalcParam[2]. z7 n! `! k. H. v5 E) o. _
第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart5 r6 F) u) L6 P! J4 }" ]. U$ X
第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;$ R# m3 w! n9 r" K
取用第三个序列参数的单个直pValue3
; [6 Q! |5 W/ N# H. ?第四个序列参数pData→m_pCalcParam[3]4 _- l; Q# T3 H( l7 H" y+ p$ x
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart
( `. H) V) s" D- J9 c3 Z第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;6 a3 F: X& _7 F! f! @
取用第四个序列参数的单个直pValue4* @0 W9 O; m1 Z: b' l! ~; Q
如果有四个序列参数,则取用序位最高的那一个序位
2 V* s1 e' s8 e# l: m( H$ Iif( pData->m_pCalcParam[0].m_nParamStart >= 0 &&4 {9 r6 L& ^( J: s. i b. z
pData->m_pCalcParam[1].m_nParamStart>= 0 &&0 l; u7 [- T, {# a! [5 D6 X- q
pData->m_pCalcParam[2].m_nParamStart>= 0 &&
2 w/ S- c! y/ ]: ~: m) F4 HpData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值
' i5 q, l. l1 o/ f1 r{
& _6 T; B: E- S8 y0 A//计算返回的序列的第一个有效值位置 o" q* R, O5 s; Y
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
2 }, m; `& F/ ? J6 F' R& g: G6 V//若不知,则, _8 A" w* A/ _+ M
/*
$ l: N |$ {- g6 g! ]$ o) Y3 iintnFirst = pData->m_pCalcParam[0].m_nParamStart;
$ u. }7 ^% @% U2 ^. S( Qif( nFirst < pData->m_pCalcParam[1].m_nParamStart ) % B# p9 Q: y1 c2 ?5 h% q
nFirst= pData->m_pCalcParam[1].m_nParamStart;
2 T3 X( M8 L- R0 iif( nFirst < pData->m_pCalcParam[2].m_nParamStart )
" K* `; t6 Y1 }3 ^. F6 k3 V. anFirst= pData->m_pCalcParam[2].m_nParamStart;
; l: u1 G) Y' H4 ~if( nFirst < pData->m_pCalcParam[3].m_nParamStart )
- |! t/ p1 l) y! B. RnFirst= pData→m_pCalcParam[3].m_nParamStart;
5 l/ ]- d( b9 }( m" Cconstfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;, d9 j& _ `3 \
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;. b2 [) a% [8 Q" D# {/ t4 V f8 g, z
constfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;3 {0 ]# l# ~3 j0 r
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;* {% e9 S4 [' h: m/ V( A! D
//-------------------9 ?, H* [+ t6 a) v" t* }6 P
floatm_fOpen; //开盘 open; g' ?" f' h9 K3 S. b# \$ g
floatm_fHigh; //最高 high
6 ]: c: p: I6 I& l: G. k! xfloatm_fLow; //最低 low: ]( ] j9 @: k$ R+ J# U# k
floatm_fClose; //收盘 close
3 P1 P Z& v: T# G3 A( |; cfloatm_fVolume; //成交量 Volume' y1 ]. D% o4 m8 c0 W
floatm_fAmount; //成交额 amount0 J% V; I# W" H* ^; l, F
调用收盘据- L* O+ G; j7 _( u: ^
pData→m_nNumData= 变数数据长度
! K" @) l! @. R- N; \: }0 X* fpData→m_pData= pointer to struc STKDATA
( W5 Q. d9 a7 g$ o' rpData→m_pData[x]第x个数据4 s' z8 ~ \: i& X7 b
pData→m_pData[x].m_fHigh第x个数据中的 High
2 J/ [1 v3 L3 ?; x+ W V9 a3 a@@@@@@@@@@@important !!!!!!!
& j6 y6 g5 I: K {sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror
' D! p1 o( r) r) u- c& P$ cso,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct- }& r( c7 g: _1 Q+ K6 S& ^! }
pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader0 O( L0 b. A% W2 ?; b d2 j( o
pData→m_pData[i-j].m_fHighto use high$ W1 k6 B$ q8 ~ a1 n
pData->m_pData[i-j].m_fLow
" S: _- n7 N% l% wpData->m_pData[i-j].m_fClose
: H) A' ]) V( W2 s$ y' @% Mm_pData= pointer to struc STKDATA
3 C. V; k' b# D7 H1 O3 fincalling C++ dll function Q1 p2 M5 b# J! B4 I# d
m_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)
( ~7 j$ Q, r% {1 B( h, O5 ttouse a single value in variable ‘High’
% e5 J5 \0 f9 l( {" Q5 T, ?3 ~- Q4 wpData→m_pData[i-j].m_fHighto use high
; {4 T2 T: C. `. x% j" {( |6 Q1 L: O( p8 _constfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1
* ^, o/ {- C3 [- p. K% _0 oconstfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
! c: _. ^- L* M( _; vconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
! m% F U* m! h% d. {3 `7 h- xconstfloat* m_pfParam4;
: d. R7 R: ~; M3 J; `& |m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数5 Q2 ]0 R3 d8 n+ X+ k/ {- b3 A
pData→m_pfParam1= pointer to 第一个(序列)参数
4 I0 j5 ^: x- c% B2 L4 KpData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值7 U- K* H2 l4 i- f, @
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数
9 U1 ^4 H* S2 f* ?9 _5 r( _cpParam[x] = 取用第一个(序列)参数的第x 个值% ~7 @3 a# P# m) U
m_pResultBuf= 结果缓冲列9 B" g1 i1 j. r% X" h
pData→m_pResultBuf= pointer to 结果缓冲列
V% J L N1 W( q( q: LpData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
0 i6 c* G. T# T6 j5 \//////////////////////////////////////////comment
0 l9 p E/ i' c//////////////////////////////////////////comment 注解, P. R8 ?6 }# X M! n) v( K* G! s y
constint m_nParam1Start; //统杅1衄虴宎弇离
0 a) w5 G( I4 g# D6 s( j$ l2 w R! Econstfloat* m_pfParam1; //覃蚚统杅1
* D( J' H$ C7 T5 A& L* x! Cconstfloat* m_pfParam2; //覃蚚统杅2
) Y' D9 y1 j% ^' |, D. _constfloat* m_pfParam3; //覃蚚统杅3
- |) C$ y/ T9 `constfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4
0 _/ o; ?2 m5 s* {6 g1 z//const float* m_pfParam5; // parameters must be <= 43 [6 k; J8 y: U5 Y3 S {
//const float* m_pfParam6; - q, S. C \1 M6 H+ t' \8 c2 z
//const float* m_pfParam7;
' R) t+ g4 N& }$ u# P/ k//const float* m_pfParam8;% b4 |% x& N9 G2 R; `7 _% U
//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
p* h2 y5 L) S/ epData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0, e8 x1 |" n. b
&&pData->m_pCalcParam[2].m_nParamStart>=0) 8 G( h9 [: x P/ S# R) l _! h9 g, d- T8 m
{# A# d6 O& N5 @4 R
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0& N# Y0 \3 ?7 }! j. B
intnPeriod = (int)fParam; //统杅1! o. U; z6 p8 v8 A
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值0 T+ V$ [, e2 l/ a8 ]5 P
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
/ m I2 q% |( ]constfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
8 V; h) e. I" O3 U4 O4 K8 {constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4
i# A8 L$ F& z9 I8 ?; n4 [//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
" q. h6 V8 r5 {! C$ u//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
4 d+ K" Z/ Y: n) _- @//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
' e5 C, j% }1 l( \touse pData→m_pData[x].m_fClose& W/ R/ j' H1 p1 C
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; " _# }# f7 T8 V; g3 A- }
|1,2,3 , … , m_nNumParam | float m_fOime_t 6 k" u$ H9 k. N: J( c
|1,2,3 , … , m_nNumParam | float m_fHigh;
9 B, l( q, h4 |- Q8 a.. .
: i( G, a& E! f0 ]6 F|1,2,3 , … , m_nNumParam | WORD m_wDecline;3 n# j' _. W) C
m_nNumParam= 数据high,close,open,low的长度& H& W; G' E; y X
touse high:
- d2 a. _9 P+ e' JpData→m_pData[x].m_fHigh
6 P9 }$ s$ H! Econtentof struct STKDATA. R I$ O% V! Y
time_tm_time; //时间,UCT8 ^+ @( s, P8 K) }. U& J1 C
floatm_fOpen; //开盘 open d+ u! m' \+ v1 b: i
floatm_fHigh; //最高 high7 e( h; a6 J5 ^# d8 I
floatm_fLow; //最低 low
# S0 C, t* p! k: L% ~8 Nfloatm_fClose; //收盘 close
7 K9 h6 w5 f4 m3 Gfloatm_fVolume; //成交量 Volume; G- Q/ }( a" ~2 {) V* j. k
floatm_fAmount; //成交额 amount
( F- W) d3 b# h/ K* bWORDm_wAdvance; //上涨家数 仅大盘有效
$ V& T4 G9 C1 D: B4 u% x1 @WORDm_wDecline; //下跌家数 仅大盘有效8 r: S$ S* {" R: G9 T U# j
调用传递参数及传回结果
* o, B2 P; a7 I% ?, J) d a调用传递参数
% H/ G! ^' U9 _(pData->m_pfParam1 && //参数1有效Param1exists% ?9 f: n$ W' U; O" T% e: @
pData->m_nParam1Start<0&& //参数1为常数
" Q ^7 c& L- E0 w7 @. wpData->m_pfParam2==NULL) //. t' E# I9 @. \/ [
localprocedure 定义使用变数
4 ` E6 A( n( gonstfloat* pValue = pData→m_pfParam1; //use constant参数1
2 D3 d& K2 i, e$ jintnFirst = pData->m_nParam1Start; //use 参数1效值起始位
* o8 i9 s* l2 E1 ?& sfloatfParam = *pData->m_pfParam2; //use 参数2+ ?# y) ^ h4 O6 c, C8 Q1 } s) g" [
intnPeriod = (int)fParam;
# d: ?) x: u0 a" K* Z( K传回结果
* k+ o3 Y' Y( XfTotal+= pValue[i-j];8 O" X( X0 \) I! e
pData->m_pResultBuf
" }2 i; d- d: n+ s5 F//////////////////////////////////////////comment |