许多年以前,我曾经在
~/ \3 j0 k7 ]( u* w' s, [$ Q' n理想公式区发布了 A) P% G6 g+ Y/ w$ E
"
$ B& @! c1 ^. ^* i如何用 Foxtrader(飞狐)连结 C++动态程式库 DLL及 80x86Macro Assembly (组合语言)
9 B' T+ Y7 g/ C' _/ e# G"( R7 p- v5 y" l. `+ K0 u( `5 Q
0 g# q$ t/ ~: {; A; a6 d现在更新foxtrader(飞狐交易师)
1 L, P% a, S" `8 G* g连结 DLL的方法
& R( n6 K; p7 i( e. o
( k0 `2 |+ V0 ]4 N4 dfoxtrader- - > DLL (C++ and assembly) = ( foxfunc.h + foxfunc.cpp +pow10.asm )- l/ h9 I! m; p/ ^" B' q
gauss- - > DLL (C++ and assembly) = ( foxfunc.cpp + meigj.asm )7 j5 \+ ?- G, z# G7 S' `
gauss只用到函数参数传递,所以使用新的 c++compiler, 不受影响
9 A) X4 y5 u( x- Ffoxtrader的 foxfunc.h宣告的结构型态 (struct)在 2004vc++ 6.0 全部有效
+ ~$ B0 }$ r) g
9 {2 v- D! \, H也就是这五个结构都能用- I$ | w0 B' E, z! e
typedefstruct tagSTKDATA
8 D) p7 E+ ^( b. S9 q. Ctypedefunion tagSTKDATAEx
$ b* |# x3 r8 Dtypedefstruct tagSPLITDATA
& F- q% p, S [% P" v+ ^; B6 P& M/ utypedefstruct tagCALCPARAM. A" S% k; t. i$ m+ ?( `( {' w
typedefstruct tagCALCINFO
$ E$ ]3 \% Z8 J8 q! Z: ?4 D% q- q
! {# ^5 x, w' d, W3 k( a! Z7 G* e自2008年起,vc++ 2008, vc++ 2010, vc++2017 对struct的编译,已经完全 c++化,不再相容于 C
" D+ p( j, T/ W9 ^1 b" h也就是这五个结构中! F6 _7 H. N7 q/ n. S0 `0 \
typedefstruct tagSTKDATA 7 e% I1 R ~* f4 ]" N8 F
typedefunion tagSTKDATAEx" n7 F* B) E: o* {
typedefstruct tagSPLITDATA
; @6 K# K; {% ?5 \. B9 ztypedefstruct tagCALCPARAM! C! @* x2 _( k' N9 T% C! h
typedefstruct tagCALCINFO
+ V4 J$ A. H6 S3 M# n9 K% ?3 Z& V只有这两个可以用
$ B* m7 c* n- J# \# @typedefstruct tagCALCPARAM& E) _% j; G% j6 ]$ H( L6 y
typedefstruct tagCALCINFO0 M" x$ a$ i" R( D2 J# s
值得庆幸的是,下面这个结构的函数参数传递个数可以有无数个
( B4 z+ y4 z! B J& Xtypedefstruct tagCALCPARAM
' F" j' G5 f$ d2 F/ h4 f8 q4 a例如:在 foxtrader中! ?( V7 R, M* E- w; X4 S
MA1:=MA(CLOSE,3);7 f7 o; y; S/ ~3 o7 q# g5 a
MA2:=MA(CLOSE,6);
. T6 Q/ }+ C7 h1 I& k1 ~9 r* [MA3:=MA(CLOSE,12);4 j+ D7 P0 m& R3 w$ r5 D
MA4:=MA(CLOSE,24);0 V; n" p2 q ]! w
MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,5)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0}
% O% g0 h) f& `其中MYFUNC2017=MYFUNC2017.dll, MYBBI = MYFUNC2017.dll 中的MYBBI函数,这里 MYBBI函数传递的参数共有 7个/ B; _- r$ K; o0 u) t! l) _
下面这两式计算结果相同' X0 E' Z- J8 k8 z
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 自行计算}
8 U; S4 e9 T# c: [MYBBI1:"MYFUNC2017@MYBBI"(MA1, MA2,MA3,MA4,MA3,MA4,6)*0.95,colorff00ff,linethick3; {2017 vc++ 15.0 , dll计算}* s" R% M9 d5 {3 } _2 g
其他例子
$ G- e/ g+ x$ a/ y# w7 poooq:="MYFUNC2008good@MYMACLOSE"(c,,c,c,6),colorffffff,linethick5;(---> pow10.asm)# w$ J* K* d1 i2 h9 E
oooq1:"MYFUNC2010@MYMAVAR"(ma(c,5),5),colorgreen,linethick5;0 f2 q: s2 q# a6 P" G1 ^
其中pow10.asm里面有很多不同定义或宣告被注解不用,那是因为后来在逐步侦测法修改语码中才发现在foxfunc.cpp主程式中,下面这行错误,也就是新的 compiler不再相容于 C,因此在pow10.asm里面被注解不用的定义或宣告中,有些应该是可以用的. `+ i7 l( I) b+ ]8 \
fTotal= pData->m_pData.m_fClose; // @@@@@@@ vc++ 2010 cl.exe 使pData->m_pData[i-j].m_fClose错误
6 w7 M0 s" |6 J$ ?
D! u+ y: ^, r4 C* {& o% U! z& f
////////////////////////////////////////////////////////foxfunc.h# F! e0 F: K0 z6 c9 @+ ]! @
#ifndef__FOXFUNC_H_INCLUDE
+ y6 t7 y- O/ h' N! a! e#define__FOXFUNC_H_INCLUDE; }. Q5 [* x% E6 l) n
/*
t, o7 R$ \: x% u j# W飞狐交易师“C语言接口”扩展程序调用接口规范V3.07 K: t& M! g3 ]6 k6 S
1.本规范适用于飞狐交易师V3.x公式系统.2 f1 F5 J' f' l' Y" M; r
2.扩展函数用于实现系统函数不能实现的特殊算法.0 _) g8 ^6 [2 Z1 H
3.扩展函数用windows32位动态连接库实现,建议使用MicrosoftVisual C++编程.' J8 R/ G1 ~" Q l& N
4.调用时在公式编辑器中写"动态库名称@函数名称"(参数表)即可,例如下面函数可以写为"FOXFUNC@MYMACLOSE"(5)
( U+ ~8 L* w1 e. H- M4 z5.动态连接库名称和函数名称可以自己定义.
4 i3 P& W6 m8 I0 P* E/ y8 b. U& `6.使用时必须将动态库拷贝到飞狐交易师安装目录下的FmlDLL子目录下使用.
# E0 n& o0 k8 t( b, U1 p*/; j& t: [# E% \1 \
#ifdef__cplusplus: s( g9 e7 b$ o1 N- `8 W: E
extern"C"
; c" ^" B8 e5 K7 S: q. d9 c{
3 F1 r* s T, U; c9 F& k3 c#endif//__cplusplus# T i9 T1 | R! T
///////////////////////////////////////////////////////////////////////////
# ]1 j( Q* Z7 ]% ^/ l//分析周期
/ T" q$ X' t' C3 W! J4 v# ]( DenumDATA_TYPE& W) L+ l: \! M: l* n; R( W; f
{
, Q# F( T; f- }3 p0 ~- N0 ]TICK_DATA=2,//分笔成交- m# F# N+ I# m$ I4 P* N9 A. X
MIN1_DATA,//1分钟线
W! r5 Z, v8 L) L0 BMIN5_DATA,//5分钟线
( O2 ]2 l5 q# ]& R. ~MIN15_DATA,//15分钟线9 E0 K2 f! Y4 {& {( u
MIN30_DATA,//30分钟线
2 c5 w! E. j1 r* |- AMIN60_DATA,//60分钟线
) [2 Z. I4 w' u) r: @& tDAY_DATA,//日线
0 m" X1 n1 _/ z5 O5 g% p2 wWEEK_DATA,//周线
7 B. T! I/ M; c* A- P% q7 S) E4 Z$ c) ^MONTH_DATA,//月线3 ?& h# }" ^6 j X! r V. h# E6 W& d
YEAR_DATA,//年线: p0 Q; Z" z$ q' V d
MULTIDAY_DATA,//多日线
- N$ U, Y; p2 y$ MMULTIMIN_DATA//多分钟线$ u8 o5 j# w6 R
};
! g0 y9 U! X$ K' Z///////////////////////////////////////////////////////////////////////////0 ~& t5 Y0 _7 R& ?
//定义取用股票基本数据的结构 只有 VC++ 6.0 能compile成功使用+ X; M' A* y# g1 E5 m
typedefstruct tagSTKDATA
c; M9 F) W* t; w7 R{
: @% h2 x7 g6 Q$ c2 h) ? T _tm_ ; //时间,UCT
% y, B( ]4 G9 A7 t+ zfloatm_fOpen; //开盘 open
3 _' U- M* y- [, W& K4 Tfloatm_fHigh; //最高 high
4 l6 R5 Z: v, G5 x5 {floatm_fLow; //最低 low7 a y5 d/ J) q* i2 u. T
floatm_fClose; //收盘 close L5 w. h- F& S, z& x* m
floatm_fVolume; //成交量 Volume4 X- \8 y$ b3 {/ N. G
floatm_fAmount; //成交额 amount
: Z! M, G' ~/ K; |! L- ]: {+ lWORDm_wAdvance; //上涨家数 仅大盘有效
6 p3 r; r) z5 H5 X# G: B( PWORDm_wDecline; //下跌家数 仅大盘有效$ B( k, y8 d! s' d7 T
}STKDATA;
! D! W( N/ _5 g! ~" [定义STKDATA为 tagSTKDATA的简单别名,STKDATA
/ _( ^( \5 h4 e$ g4 Q% I; D9 q为真正方便使用名称,tagSTKDATA 为定目的的过水名称8 k/ ]' ?0 l4 f, \7 f3 y0 U5 J
////////////////////////////////////////////////////////////////////////////% [. W3 i4 K0 p% o8 w3 U
//扩展数据,用于定义取用分笔成交数据的买卖盘 的结构
% |: \+ h1 u4 l8 Atypedefunion tagSTKDATAEx
+ x- M" j3 l }{
6 N8 w+ [- k: t, d8 Ustruct
) G" V9 h: w3 s+ v7 ?. o{) ~# t1 h( o) E: `5 M
floatm_fBuyPrice[3]; //买1--买3价floatm_fOpen; //开盘 open9 @7 r. ?5 ]2 B
floatm_fHigh; //最高 high( X, i+ N: t( A: K9 O d* ~
floatm_fLow; //最低 low* n5 [7 M$ Q" R
floatm_fClose; //收盘 close
2 S- V- F" Q% @# |6 q: a4 i( e! y' Bfloatm_fVolume; //成交量 Volume
9 G& |4 o2 z. ^; b1 Pfloatm_fAmount; //成交额 amount
c) x' }8 d8 y7 S6 C: m% p, m4 |floatm_fBuyVol[3]; //买1--买3量
- m! ^" \, y6 ]4 ~5 B0 Q" g o3 zfloatm_fSellPrice[3]; //卖1--卖3价5 T& f& \& R* h. [
floatm_fSellVol[3]; //卖1--卖3量4 l. L8 Z+ a: `2 D
};
6 ~8 T" W4 M# b3 p- I" y; Yfloatm_fDataEx[12];
" z4 ^: n' C% h# }}STKDATAEx;
8 P6 E6 q! f/ }8 J4 G& C////////////////////////////////////////////////////////////////////////////2 K: S* N, f. u9 N
//定义取用除权数据的结构
9 V# u7 S* \& ^ `9 Ftypedefstruct tagSPLITDATA 1 `+ a7 t& w0 w! N5 `) Z9 U
{
& H: p" _% _4 K3 K- W5 J7 L2 [time_tm_time; //时间,UCT
) q0 n7 g# u3 _" ?( Tfloatm_fHg; //红股9 O; E9 F6 `: y6 `; S/ J
floatm_fPg; //配股& ` u! w K& U" j3 `
floatm_fPgj; //配股价
f4 F: P" ^: ]# ?0 y J, T* ?floatm_fHl; //红利
h# Q% t2 p/ P2 j4 ^4 k! B p" H}SPLITDATA;
9 A0 O0 r" i$ [) s. p/////////////////////////////////////////////////////////////////////////////
" ~: B6 S! l& m' E9 c; w% z# _/*财务数据顺序(m_pfFinData内容)" W+ g( I1 E! l" L
序号内容
1 ?) U/ ~ U6 L) m+ h/ {3 n0总股本(万股),; m, x" n5 z& E" Q: {* D
1国家股,
& L) [/ ?. L) T4 E2发起人法人股,2 A$ k4 O* p. z
3法人股,
" R+ U9 Q; s& Q4B股,8 c) \& g; ]+ g. \
5H股,
& j0 a* a- W6 c- f4 x: ~6流通A股,& |( y% N: E7 t) _1 F
7职工股,
2 \$ z. L4 S9 d& T1 t ?8A2转配股,& z3 r. B# V4 E" {
9总资产(千元),
: W/ }7 Y& G6 |1 a! c10流动资产,6 t: a# M& N8 {* e
11固定资产,- k ?/ m2 s/ x O
12无形资产,
n3 |8 I; x0 j) l' R13长期投资,
5 f9 W: c1 N3 I4 N' ^( @; I( E" i14流动负债,9 T' ~& a3 u' W" j# P7 p7 v. R V
15长期负债,' h1 y( c* Z7 B
16资本公积金,% p6 F( r8 R O7 L* |8 v
17每股公积金," Y, D0 N2 J; u
18股东权益,( C& a' {8 ^7 w V2 q# ^8 a
19主营收入,
% D. s2 m! _; }0 m( d4 [) b20主营利润,
# t# A$ M/ i \9 W0 r21其他利润,9 }" A# l$ k4 C, e
22营业利润," M+ P' X# v4 f) ^, U
23投资收益,! `' ]6 q, \' ^4 x! D
24补贴收入,6 p" c, a- q8 c* t; j
25营业外收支,
0 v0 H3 h: v. k1 v26上年损益调整,7 F( J# n1 r/ h( `! {
27利润总额,
3 _7 n4 q0 Q5 O. S5 i6 u" W; b28税后利润,, p" ~# S& I' K
29净利润,
4 |; @% p5 L% U4 p9 l+ z) S* O30未分配利润,; c. z1 C9 A% }# C! J
31每股未分配,1 |5 X* D, j& P0 T* ^6 r
32每股收益,
. O) J J7 b- Z7 ^9 G& b33每股净资产,' C/ Y( ]* a) Q! x Z
34调整每股净资,5 e4 ] f. h" n* N! y
35股东权益比,
- E4 I2 q7 K3 d8 y36净资收益率
% g6 A) V' X7 T" g7 k, l0 \' d$ s*/
# t: ~' D. [; Z1 S! N: r8 G: i/////////////////////////////////////////////////////////////
. Y: {9 f' _+ | A f4 v' u//定义取用caller函数传递参数项 的结构
6 |2 ^/ d( ] W( ]: ^5 O. @$ ~2 ztypedefstruct tagCALCPARAM- @8 Y0 j5 _6 p
{
0 U+ r9 O/ _6 Junion
% b3 E) }* n6 s8 J4 w! h{
+ }" s3 d- A0 K* \constfloat* m_pfParam; //指向序列参数的址标,指向一个浮点型数组pointertofloat variable parameter / ex. c,h,l,o, co2...co2=(c+o)/27 t, @$ M& g+ C+ o* t' p) |) {
constfloat m_fParam; //数值参数 valueof parameter
: C% {. t& q/ K5 T w; p7 J};) g. ^ Q- V' r, L, y1 K
constint m_nParamStart; //序列参数有效起始位置thestart address of variable parameter / ex. c,h,l,o,co2.....2 R5 @. z$ _0 Q6 Q# T1 R7 ~, J. u
}CALCPARAM;% ~# Q! @9 o" _
/////////////////////////////////////////////////////////////////////////////: l! Q' q, h& O" i9 n" @
//定义全部取用址标 的总结构 (各指标指向前述各结构以便取的各结构的数据,接口信息数据的结构 ); U9 s1 l5 u8 r3 R t6 r
typedefstruct tagCALCINFO1 @1 I' A$ z9 b2 Z# \: l v
{# {; s ~" L4 E! V6 b+ T
constDWORD m_dwSize; //结构大小
+ ~/ C3 k j; z- u) M# O; W9 YconstDWORD m_dwVersion; //调用软件版本(V2.10: 0x210); o; ]& r' [, E% m9 }0 O6 m
constDWORD m_dwSerial; //调用软件序列号4 j9 u/ G( T4 L, M2 t
constchar* m_strStkLabel; //股票代码4 }# G' x# k1 _. T) Y
constBOOL m_bIndex; //大盘2 s& L8 @# L9 y
constint m_nNumData; //数据数量(pData,pDataEx,pResultBuf数据数量)数据长度
t$ S, W7 V: y. A# t. SconstSTKDATA* m_pData; //常规数据,注意:当m_nNumData==0时可能为NULL
$ M- l$ G* Z/ d; }6 t' hconstSTKDATAEx* m_pDataEx; //扩展数据,分笔成交买卖盘,注意:可能为NULL
& @& `) t4 @4 y3 [* m) t( aconstint m_nParam1Start; //参数1有效起始位置<0/ constant parameter >0 /variable parameter
; {' r/ c6 O; w; |+ V* k8 Yconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 0 {" e: }' g* t7 h" Y2 I
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2
# a6 `, y8 H( ]9 _ ]- v' ?2 jconstfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3
z( `4 k4 s8 k& gconstfloat* m_pfParam4; //调用参数4/pointer to variable parameter 4
1 j# V2 Q7 u; S7 j2 f( z/ @% Ifloat*m_pResultBuf; //结果缓冲区
0 k* A5 {% N% w3 T& L. V) z$ QconstDWORD m_dataType; //数据类型2 ^+ ~4 r+ H9 n4 [; `3 j
constfloat* m_pfFinData; //财务数据
0 r4 D9 |1 z( v) n8 w9 H//以上与分析家兼容,所以沿用其结构和名称
: \8 Q: U6 n2 S* z7 t//以下为飞狐交易师扩展(fortagSTKDATAEx)- m8 N- ^' `; n1 H6 L) Y+ N' \9 L
constDWORD m_dwReserved; // 保留% E; D% U5 O: X
constint m_nNumParam; // 调用参数数量, m- T# F; K" n4 R( P: {4 `, }% a
constCALCPARAM* m_pCalcParam; // 调用参数数组2 B1 ?8 p/ m8 v2 `7 S, L
constDWORD m_dwReservedEx[4]; // 保留+ X# _- F6 s) \8 ]. X0 I5 e
char*m_strStkName; //股票名称0 r6 U, Q; h. x+ h3 q( j! R$ O
SPLITDATA*m_pSplitData; //除权数据/ N3 C- } T( t, ?# H; `" F7 D3 b
intm_nNumSplitData; //除权次数
0 s" Q/ ^* }, E. r* H1 b( i}CALCINFO;% U/ `& {) P5 b
/*
8 P5 F/ [0 }9 ~注1:(与分析家兼容)
1 s2 |1 Y4 {7 _) {4 S! d1.函数调用参数由m_pfParam1--m_pfParam4带入,若为NULL则表示该参数无效.* K$ k& `4 w- @4 w; U; d% m( M) b
2.当一个参数无效时,则其后的所有参数均无效.
, e) I7 P4 @- U如:m_pfParam2为NULL,则m_pfParam3,m_pfParam4一定为NULL.$ N* W# `9 u( c6 X, o
3.参数1可以是常数参数或序列数参数,其馀参数只能为常数参数.# b3 e8 @# x" y7 k
4.若m_nParam1Start<0,则参数1为常数参数,参数等于*m_pfParam1;! t# f( F6 |" D! O5 C
5.若m_nParam1Start>=0,则参数1为序列数参数,m_pfParam1指向一个浮点型数组,
: y8 d7 i# Y$ \% G* ^数组大小为m_nNumData,数据有效范围为m_nParam1Start至 m_nNumData-1.
1 _& n& O5 H, }: v$ {1 M* G在时间上m_pData[x]与 m_pfParam1[x]是一致的
: V4 h, a8 Q7 O, n6 D+ Y) Y$ h/ q0 U注2:(飞狐交易师扩展)9 `/ N, p% c( Q4 A; @8 X
1.该扩展结构使调用参数在技术上可以是无限数目的,且每个参数都可为数值或序列,由公式中实际的调用参数决定。5 y7 J/ d8 w7 r5 L
2.CALCPARAM结构用于带入参数信息和实际数据,m_pCalcParam数组大小为m_nNumParam,数据有效范围为0 至m_nNumParam-1.
5 `6 s# z. y- k9 D3.按参数的顺序,m_pCalcParam[0]为第一个参数的数据,m_pCalcParam[1]为第二个参数的数据...,为了保持兼容,原m_nParam1Start、m_pfParam1等5个属性依然有赋值。: }* D$ V' `% n7 _
4.若i位置的参数为数值,取用m_pCalcParam.m_fParam.. F- I% w) O2 g; X
5.若i位置的参数为序列,取用m_pCalcParam.m_pfParam,数组大小为m_nNumData,数据有效范围为m_pCalcParam.m_nParamStart至 m_nNumData-1.若m_pCalcParam.m_nParamStart<0,则此数组中无有效数据。* ?$ Q' g2 S9 P6 n
6.由于可以调用多个序列,许多序列的计算可以先在公式中进行,然后作为调用的参数即可。
) q8 F( a8 g7 i V) o; n' M, d6 v7.经此扩展,对分析家的DLL依然可以调用、兼容。
& M( D% d# r0 Z0 g*/
. g9 G. n0 X6 n///////////////////////////////////////////////////////////////////////////////////% I; c0 O6 {# n' M
/*函数输出/ f& P8 f, o3 O4 p9 Q8 _% g
__declspec(dllexport)int xxxxxxxx(CALCINFO* pData);* Y0 y, m: R: ~$ S
1.函数名称需全部大写. B4 d0 s Q! W; U
2.函数必须以上述形式声明,请用实际函数名称替代xxxxxxxx;; V5 w4 Z3 K6 L1 P2 ?) y
对于C++程序还需包括在extern"C" { } 括号中.
" K. o/ ^; {, r S- D# G3.函数计算结果用pData->m_pResultBuf带回.
6 ^( ?8 e/ b* X4.函数返回-1表示错误或全部数据无效,否则返回第一个有效值位置,即:+ d! l/ |% N2 c
m_pResultBuf[返回值]-- m_pResultBuf[m_nNumData-1]间为有效值.
" H1 p% O1 X3 k3 ]5.函数名称长度不能超过15字节,动态连接库文件名不能超过9字节(不包括扩展名),动态库名称不能叫SYSTEM,EXPLORER) i8 U" z2 ?7 a0 L; X% m
*/
" _1 ~& J. Q) Y2 x2 ?0 W//示例函数,使用时用实际名称替换
# g$ P" q) C+ e2 Q__declspec(dllexport)int WINAPI MYMACLOSE(CALCINFO* pData);
& t4 n3 ^* v N/ s# V__declspec(dllexport)int WINAPI SMOOTH(CALCINFO* pData);- ?- e" T, i- \! u2 q: b
//__declspec(dllexport) int WINAPI MYMAVAR(CALCINFO* pData);
" N5 y( Q6 g# ~% K/ `__declspec(dllexport)int WINAPI MYBBI(CALCINFO* pData);
8 M9 ]$ L9 Y8 U& K" j7 \//WINAPI = _stdcall* W5 L& S, u$ s$ _% o* Q& ^# K
#ifdef__cplusplus
* g- I, \' T& b% y4 A! v4 N6 u}7 P" T! A, ~* ^' s8 c( c
#endif//__cplusplus
6 n1 B1 G4 r' V+ M# F* u4 b! V#endif//__FOXFUNC_H_INCLUDE! g6 h# f% ?9 A }4 k+ P. z
' J5 n6 ~ w* h- H8 x) e8 H! t% Q
//////////////////////////////////////////comment 注解& K% ?4 W, X' v U' i+ X
__declspec(dllexport)int WINAPI MYMAVAR(CALCINFO* pData)
. K% A" @* B& |, U0 d f+ d: r1 _pData是指向 址标总结构 CALCINFO的 总址标" D" L. H+ @7 i0 j
取用第二个参数数值floatfParam = *pData→m_pfParam2 : Y3 x. q& [5 i) S5 s/ p* W
取用第一个序列参数的址标constfloat* pValue = pData->m_pfParam1;( z' W, S. Q: A* Z: Y% D
取用股票数据长度intndata = pData→m_nNumData;# `$ a# p5 F: C, W. x
第一个参数存在且为数值pData->m_pfParam1&& pData→m_nParam1Start<0% i. |/ r. F5 l2 G7 B
第一个参数存在且为序列pData->m_pfParam1&& pData→m_nParam1Start>=0
/ Z b2 e' e8 U; K0 u" n# s) ]( a" }第一个及第二个参数存在且为序列,第三个参数不存在pData->m_pfParam1&& pData->m_pfParam2 && pData->m_nParam1Start>=0&& pData->m_pfParam3==NULL7 z4 `6 u2 r) L) G B) s
constfloat* cpParam = pData->m_pfParam1; 定义cpParam为第一个序列参数的址标
5 U% t2 a$ B3 ?* @$ o4 C取用股票数据结构
* x! `2 z8 F+ H' VpData→m_nNumData= 变数数据长度
- C: W& {) X9 ]6 W% r) {$ Z* j- {pData→m_pData= pointer to struc STKDATA 的址标
2 {8 A' ^9 a$ U3 o( v1 tpData→m_pData[x]数据结构的第x个数据
, k9 S# f1 P- i) B1 l0 V: vpData→m_pData[x].m_fHigh数据结构的第x个数据中的 High7 @- Z5 ~1 N. h& g" b3 Y8 R
取用结果缓冲序列
8 j, [7 n" S- i- T; j/ C4 \pData->m_pResultBuf6 w7 W0 m+ A. u( z
取得第一个序列参数的起始序位,如 2,...5 , . 7...
% V3 ^. l2 W$ kintnFirst = pData->m_nParam1Start;
! W) w! M I2 Ifor( i = nFirst+nPeriod-1; i < pData->m_nNumData; i++ ) v; G- r4 [) a3 N7 w' U
取得第二个数值参数的数值- c9 _4 Q* H+ H
floatfParam = *pData->m_pfParam2; 1 _: d) O: F: R( b$ z4 z/ V
intnPeriod = (int)fParam;/ K" X- C& v1 `8 F; E- d4 y8 X
取用第一个序列参数的址标constfloat* pValue = pData→m_pfParam1;7 S) \! L! r' \9 Y' E+ M# K
取用序列参数的单个直pValue
! M! d0 D/ J9 e8 Z+ p取用缓冲序列的单个值pData->m_pResultBuf
' e2 L- [( I) k; @constCALCPARAM* m_pCalcParam; // 调用参数数组, W+ l: p( {4 S3 P# L
m_pCalcParam为序列址标,指向各序列参数的指标" j) t3 f9 c7 n" P$ X. K! S
第一个序列参数pData→m_pCalcParam[0]
' f$ v- V0 n c3 H8 f3 U& vconstfloat* m_pfParam; //指向序列参数的址标* `3 B0 @# z. `4 \8 D! T2 E2 J+ m0 z8 C
第一个序列参数的起始序位pData->m_pCalcParam[0].m_nParamStart1 [3 c4 m$ x9 m7 N' h
第一个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[0].m_pfParam;
/ D- t3 E) ] e取用第一个序列参数的单个直pValue1# L: _5 R0 \9 O- H
第二个序列参数pData→m_pCalcParam[1]
) [3 I i z3 f+ H! l- s第二个序列参数的起始序位pData->m_pCalcParam[1].m_nParamStart; a- ?( E# R9 u( r# M& G) d7 C
第二个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[1].m_pfParam;" O4 n- a6 m1 g) `8 c
取用第二个序列参数的单个直pValue29 g/ N, B( v: n" X9 g
第三个序列参数pData→m_pCalcParam[2]% `9 b/ c/ q* z. ]. G
第三个序列参数的起始序位pData->m_pCalcParam[2].m_nParamStart
$ Z+ O! k8 N6 }4 {4 l$ K; D第三个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[2].m_pfParam;
, b/ r' w) _9 M8 A. Q9 S( L; a8 W取用第三个序列参数的单个直pValue3/ R6 X T1 T% A3 r' k e
第四个序列参数pData→m_pCalcParam[3]: u2 f- @* P3 A+ t: N; ^& T% J
第四个序列参数的起始序位pData->m_pCalcParam[3].m_nParamStart& |- ]: L( [2 b1 Z0 o
第四个序列参数的址标constfloat* pValue1 = pData→m_pCalcParam[3].m_pfParam;
, U( g& k. T7 R, H取用第四个序列参数的单个直pValue4
+ w4 H# Q# {+ t' }6 S如果有四个序列参数,则取用序位最高的那一个序位/ T' n( A4 @9 ?
if( pData->m_pCalcParam[0].m_nParamStart >= 0 &&
/ E- F" k3 e! epData->m_pCalcParam[1].m_nParamStart>= 0 &&: t. l5 @& y, I0 W( F: z. q
pData->m_pCalcParam[2].m_nParamStart>= 0 &&5 X* l. \2 {9 N9 |$ i
pData->m_pCalcParam[3].m_nParamStart>= 0 ) //4个序列都含有效数值
: e) a6 |8 w' _- x$ g1 ~{6 a- b, F" _9 L, x
//计算返回的序列的第一个有效值位置( ?! {% v# }; }. v
intnFirst = pData->m_pCalcParam[3].m_nParamStart;//已知返回的序列的第一个有效值位置与第4个序列一致
0 \9 _2 K% U' c5 I//若不知,则" n% U6 _1 C O R6 C% o. B, d% y
/*
& S; o+ S3 o0 v- |+ RintnFirst = pData->m_pCalcParam[0].m_nParamStart;
4 V. ^% c, |3 ^- f* w& c" rif( nFirst < pData->m_pCalcParam[1].m_nParamStart )
6 T' _7 J" s: h XnFirst= pData->m_pCalcParam[1].m_nParamStart;% u1 A& @* Q% T
if( nFirst < pData->m_pCalcParam[2].m_nParamStart ) 8 X' a* r8 |; o* p1 n$ e
nFirst= pData->m_pCalcParam[2].m_nParamStart;# O |6 m1 L% Y, S
if( nFirst < pData->m_pCalcParam[3].m_nParamStart )
4 U. z# M: {$ u6 nnFirst= pData→m_pCalcParam[3].m_nParamStart;* Y$ [8 I/ N/ j ]$ z# z8 Y$ y
constfloat* pValue1 = pData->m_pCalcParam[0].m_pfParam;; ]4 o: `; M6 A$ E* d0 L
constfloat* pValue2 = pData->m_pCalcParam[1].m_pfParam;
/ T0 e( H$ }/ H. J& i+ t. D# Hconstfloat* pValue3 = pData->m_pCalcParam[2].m_pfParam;- f1 {# L* E7 F) |* A% Z
constfloat* pValue4 = pData->m_pCalcParam[3].m_pfParam;$ T; L7 p3 |- `
//-------------------& e) G4 l n( f( R/ ?
floatm_fOpen; //开盘 open7 L/ i) G6 k& D6 c4 d/ ?
floatm_fHigh; //最高 high
+ @3 l* y0 B6 s/ Y0 Q. t: \floatm_fLow; //最低 low
) G0 e. d" I7 h' [floatm_fClose; //收盘 close
5 a2 Q5 ^3 q" u# c/ A. Gfloatm_fVolume; //成交量 Volume
! H. e( u, m+ V v0 H1 V1 `floatm_fAmount; //成交额 amount8 r% s4 N1 f# u
调用收盘据- x3 P5 W! w, g% k y' u; W5 t
pData→m_nNumData= 变数数据长度! H/ R3 k* W9 b( }0 o* l
pData→m_pData= pointer to struc STKDATA
" ?' o* Q) |2 {8 f: }pData→m_pData[x]第x个数据9 v( u6 z8 Z l" ?$ Z
pData→m_pData[x].m_fHigh第x个数据中的 High
/ Z/ T/ `. F, K4 T/ h@@@@@@@@@@@important !!!!!!!
3 h/ k! o( g" x* A0 Q" a4 @/ S$ @sinceVC++ 2008, cl.exe will make ‘pData→m_pData[i-j].m_fClose’ anerror6 H& j1 l+ T2 _3 ?* f
so,pass the high,low,open and close just from the function parameter ,that is use ‘ CALCPARAM’ struct
O/ c7 k4 N# {pData->m_pData[i-j].m_fOpen// to use open , there is no way in using a varable for calculationoutside foxtrader" h9 z% q K0 `, d- z, B( |& g" O* b
pData→m_pData[i-j].m_fHighto use high
0 M/ J4 j# T2 ?& Q* B1 cpData->m_pData[i-j].m_fLow% p4 |% ?! Z1 Q6 {2 n0 E& G7 y
pData->m_pData[i-j].m_fClose
" [2 P* o$ G* s0 \9 H; `5 s! P% n3 am_pData= pointer to struc STKDATA: E% o9 H) D1 {# r" L6 D
incalling C++ dll function
$ {: Q& @& c4 A0 }, Wm_pDatais passed to pData (CALCINFO* pData . A CALCINFO* type pointer)* D9 N" [! i( U/ h- _) L- Q* L$ [
touse a single value in variable ‘High’& B q& z" p$ F" A) p+ F5 k9 K
pData→m_pData[i-j].m_fHighto use high
3 ~+ \8 ^ o' q& K) ?$ Uconstfloat* m_pfParam1; //调用参数1/pointer to variable parameter 1 # V | L7 G4 g7 C d7 `1 r
constfloat* m_pfParam2; //调用参数2/pointer to variable parameter 2( a/ e, g5 X* q. n/ o5 p5 E* s
constfloat* m_pfParam3; //调用参数3/pointer to variable parameter 3: R _& S0 i& d2 D
constfloat* m_pfParam4; 2 u: I: o0 B3 e+ `* b! T
m_pfParam1,m_pfParam2, m_pfParam3, m_pfParam4 = pointer to caller function 的参数# I& N; G- {8 p: z0 y! R# y' f
pData→m_pfParam1= pointer to 第一个(序列)参数
0 y& B$ l' l3 Y, O7 ~pData→m_pfParam1[x]= 取用第一个(序列)参数的第x 个值; r* \9 C$ C( I, ~& R; l0 @+ V& f
constfloat* cpParam = pData→m_pfParam1; =定义 cpParam为 pointerto 第一个(序列)参数( u6 o5 B" j' l# h4 {
cpParam[x] = 取用第一个(序列)参数的第x 个值 B( x5 t# e8 {8 ~. N
m_pResultBuf= 结果缓冲列+ A! ~" D) a" E" Z7 d& G; o/ B
pData→m_pResultBuf= pointer to 结果缓冲列
k5 U6 v3 M- L: [' ipData→m_pResultBuf[x] = 取用结果缓冲列的第 x个值
9 x/ | ^8 H, A" ?1 M//////////////////////////////////////////comment
0 C' F; ` f% e//////////////////////////////////////////comment 注解
( g" H9 Q& D4 X: G1 i5 r$ hconstint m_nParam1Start; //统杅1衄虴宎弇离
* i3 L4 y6 \" j3 \! jconstfloat* m_pfParam1; //覃蚚统杅1
% o5 t1 E; f8 c4 {# [! q4 |constfloat* m_pfParam2; //覃蚚统杅2 ]% n; s& y4 i
constfloat* m_pfParam3; //覃蚚统杅3
5 x/ H7 b! W6 U% h+ Wconstfloat* m_pfParam4; //覃蚚统杅4,parameters must be <= 4
6 O3 f5 M( n4 Q1 ]8 W//const float* m_pfParam5; // parameters must be <= 4
3 O) S# ~+ ]% X9 P//const float* m_pfParam6;
3 `+ b" W2 ^0 n9 d//const float* m_pfParam7;
9 {( N. o @- Z4 N. w' K//const float* m_pfParam8;
* M0 a+ P$ M6 j" p+ G//pData->m_pfParam1 && pData->m_pfParam2 &&pData->m_pfParam3 && pData->m_nParam1Start>=0 &&
# W" I( X: O8 X5 h- E" e6 m+ JpData->m_pCalcParam[0].m_nParamStart>=0&& pData->m_pCalcParam[1].m_nParamStart>=0
! C$ K: f, H5 v8 r&&pData->m_pCalcParam[2].m_nParamStart>=0) 7 L( `8 H! E( d- |& ?
{. h+ ]9 k# x0 C4 x8 I
floatfParam = *pData->m_pfParam4; //pointer ,pData->m_pCalcParam[3].m_nParamStart >= 0 M0 m/ a9 P1 k/ l8 b5 }7 [
intnPeriod = (int)fParam; //统杅1. K# G0 y$ f) G. D% h, U
//const float* cpParam = pData->m_pfParam2; // cpParam = pointer to第一个序列参数,cpParam = 取用第一个序列参数的第i 个值/ Q# e" o) ]$ M6 |6 E
constfloat* cpParam1 =pData->m_pCalcParam[0].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
0 n6 G* y- ~7 |4 U$ k& l" g$ Dconstfloat* cpParam2 =pData->m_pCalcParam[1].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
; w% q6 ?9 i5 a: d1 }constfloat* cpParam3 =pData->m_pCalcParam[2].m_pfParam; // cpParam =pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值//parameters must be <= 4( P4 I! U6 g/ Q( ~1 k6 C0 S X- c' r
//const float* cpParam4 =pData->m_pCalcParam[3].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值
( d5 m6 F( @# H1 i8 c: a0 Y- N0 ]4 \//const float* cpParam5 =pData->m_pCalcParam[4].m_pfParam; //cpParam = pointer to 第一个序列参数,cpParam = 取用第一个序列参数的第i 个值$ _7 n5 p0 C/ |, O- `( i
//m_pData = const struct pointer to struct STKDATA , pointer to structSTKDATA ,
_2 Y% \+ V5 t& }touse pData→m_pData[x].m_fClose! z+ K! a i6 Q' W$ p5 ^3 v
pData→m_pData[x]= | 1,2,3 , … , m_nNumParam | time_t m_time; . k( P* n' Y6 M0 M" ~
|1,2,3 , … , m_nNumParam | float m_fOime_t 5 W, u* V, e0 }/ d! F
|1,2,3 , … , m_nNumParam | float m_fHigh;
) F2 A( N0 Q, }3 z- N) G4 ?.. .0 w a, T( N) t- a
|1,2,3 , … , m_nNumParam | WORD m_wDecline;- }+ z) q3 V5 _: h
m_nNumParam= 数据high,close,open,low的长度
2 p% i* N1 i& v" L3 d6 mtouse high:
% f( G, ]$ G7 t3 L: Q- r& h- ]pData→m_pData[x].m_fHigh4 k% q( e$ x s: m! a! P- j
contentof struct STKDATA
; i; W, d# T- h' ^time_tm_time; //时间,UCT* j0 m" n% f* W$ J
floatm_fOpen; //开盘 open
9 H' c e# B# d5 e) P" cfloatm_fHigh; //最高 high* q# M8 x0 [% i) e8 X( E
floatm_fLow; //最低 low
3 }6 |) i# }2 k' ~& r0 ufloatm_fClose; //收盘 close/ y7 L! a2 n- P9 U% R/ h# J% I
floatm_fVolume; //成交量 Volume3 ^! k3 z0 ^! l/ T
floatm_fAmount; //成交额 amount' h9 e3 `' s' S d% I1 E2 |
WORDm_wAdvance; //上涨家数 仅大盘有效
* `, k, \5 B7 CWORDm_wDecline; //下跌家数 仅大盘有效
) g" @; S; E) r H调用传递参数及传回结果
% c6 @5 D( v* o1 a) j调用传递参数
( c; w$ R4 J8 ]; s! B4 }(pData->m_pfParam1 && //参数1有效Param1exists* h J; d0 ~: R( O" o* A- a
pData->m_nParam1Start<0&& //参数1为常数
. Q: j S5 T4 p: }$ ^3 e$ `4 ^2 PpData->m_pfParam2==NULL) //, P, }1 G/ @% g' x4 X% M
localprocedure 定义使用变数5 N/ Z3 V9 k$ m6 t- ~( z; b a
onstfloat* pValue = pData→m_pfParam1; //use constant参数1
8 e7 v) K% m& BintnFirst = pData->m_nParam1Start; //use 参数1效值起始位! I3 @6 C6 A8 p2 k
floatfParam = *pData->m_pfParam2; //use 参数2
+ u2 ~! m8 T" G3 ?: |intnPeriod = (int)fParam; b) d+ k8 A3 w- X7 x
传回结果
) T, z2 I4 k2 A. A" u+ RfTotal+= pValue[i-j];
/ p1 |8 L. {# [0 t$ DpData->m_pResultBuf
7 D0 o' ?* ^* }% g; A" V! V0 p1 z//////////////////////////////////////////comment |