以下内容为转载:
. t' ^0 J9 x: W8 ]' y, D8 e& D K1 _" X
, q& N7 c( s" d! h: x
KDJ提醒器 0.5我自己写的KDJ提醒器。
6 s/ E4 \2 B% t t
它可以设置两个时间框架(Timeframe)及KDJ指标(实际上使用的不是KDJ指标而是MT4自带的Stochastic指标)的相关参数,当KDJ在两个时间框架上同时出现低位金叉或高位死叉时,将会向你发现提示信息。在选择入场点时,KDJ出现低位金叉或高位死叉是一个非常不错的判断方法。
' B0 |8 {0 D% @% ~0 \
5 N- W$ V8 a% v3 P& Y
相关参数说明:
8 ~6 b7 N: ?4 Q' b$ F" R$ Fp_RefTimeframe1:参考时间框架1,默认值:PERIOD_M5 (即5分钟图)
8 E ?. B+ j6 z& p1 v$ qp_RefTimeframe2:参数时间框架2,默认值:PERIOD_M15(即15分钟图)
' n4 x h. c# h$ R- |
p_CareCrossType:所关心的交叉点类型(1-关注金叉,-1-关注死叉,0-不关注任何交叉,相当于暂停处理),默认值:1
; Y0 ^0 h4 A8 Q5 ?* @9 c! L% o! d+ S+ O1 z( o: B. d
p_TopLimit:死叉时,KD的值必须高于这个值(即需要高位死叉)
8 a9 L. q0 `# k6 _! b; E0 w( L
p_BottomLimit:金叉时,KD的值必须底于这个值(即需要低位金叉)
! S! H8 p- E. ^! ]$ T
9 a. D2 `8 ]) ^+ q
p_Kperiod:KDJ指标的%K周期,默认值:8
! A( l6 n" o }$ B# C; C8 @- x7 u
p_Dperiod:KDJ指标的%D周期,默认值:5
" z$ Y+ i8 ^% A! K1 X% Q- Kp_Slowing:慢线周期,默认值:3
" e: {% G6 |4 [2 ^, j. t( C
$ g1 M; P: e- V/ |! t6 }! Zp_MessageboxAlarm:出现条件时,是否弹出消息提示对象框,默认值:true
; Y; b& g. M* T7 v1 H5 \/ Pp_SendMailAlarm:是否发邮件提示消息,默认值:false
1 }6 |- N# _3 ?+ S) d% B8 s# H' J
* o! r; B5 L. U8 |+ x% k. {) H( S
9 N: w8 ]/ L1 X7 E$ U- W我在中国移动可以申请一个手机邮箱,并开通了邮件到达通知功能,这样我把p_SendMailAlarm参数设置成true,于是这个“邮件提示”就变成了“短信提示”,非常好用。
~ y/ W# C( l6 m* |0 \9 ^
- n* a- J% P1 e' |0 E$ J
! U0 R0 S/ d: C4 t源代码如下:
5 j2 S: X$ N# O7 s4 X2 R& m//+------------------------------------------------------------------+
$ e2 B. F0 J R- U
//| KDJ交叉信号告警.mq4 |
" ^# i( P- }% k5 X2 Y+ H! n+ E//| Jesse Loo |
( ^5 R/ a' o& z( e4 U9 ?" O//| |
8 Z; U0 a5 u( S: ^. t% o3 B
//+------------------------------------------------------------------+
6 E3 H `. U* D( |2 @7 ?
//** KDJ交叉信号告警 **
3 Y9 K1 G) C, m9 Z
//当KDJ出现指定的金叉或死叉时发出告警
6 {3 Z& H; P# `+ Y3 O; ^, m
//Version: 0.50
' b7 K& @" y1 p8 h//Date: 2007.01.25
) Y+ o$ p% K6 S9 |& c//修改记录:
: k# j: } I0 F# B- M' ?#property copyright "Jesse Loo"
% x0 t$ f! k! ^" K0 S8 O#property link ""
5 e- |1 D% B3 X0 _. l8 Y4 zstring EA_FLAG = "EA_KDJ_0.50"; //自动交易程序的标志
% k, u* ?8 O o2 b+ ~) e7 V7 z c6 d: a
8 d$ h& J- F9 F
8 k* Z M9 ?" |0 \. |; t' C# f
. y$ y F: p0 ~) `0 O/ @
// **** 外部参数 ****
* O+ d) M2 D; dextern int p_RefTimeframe1 = PERIOD_M5; //参考时间框架1
) {0 }7 m1 ?; Y0 y: A& M* nextern int p_RefTimeframe2 = PERIOD_M15; //参考时间框架2
# Y6 F' j' c; M- d* X2 J$ K E
9 i% ~4 V1 N. p, @- |9 Q7 w. b! i* N$ cextern int p_CareCrossType = 1; //所关心的交叉点类型(1-关注金叉,-1-关注死叉,
% ], B# v l+ |3 [. d3 m8 i5 M //0-不关注任何交叉,相当于暂停处理)
- t9 w: y+ I, ~- O5 V7 d: E3 A7 R% ]* t, [0 p7 a
extern int p_TopLimit = 20; //死叉时,KDJ的值必须高于这个值
/ ]# ^5 `; G* `5 M$ Aextern int p_BottomLimit = 80; //金叉时,KDJ的值必须底于这个值
( v) A& v: A' f% l8 S
2 m8 f6 p! i7 k$ _8 A. N6 t
extern int p_Kperiod = 8; //%K周期
' ?- h: T0 C5 Bextern int p_Dperiod = 5; //%D周期
* r2 W, x. ^8 k3 Xextern int p_Slowing = 3; //慢线周期
0 \. M: x0 q' D! ^/ e% m6 p1 `7 v* @6 Y3 |$ N
extern bool p_MessageboxAlarm = true; //弹出消息提示
0 Z) i" I: N4 B n7 {( S, z; jextern bool p_SendMailAlarm = false; //发送邮件提示信息
: g1 J& J% H. p+ Y* Q
0 v+ N8 w, d# T! e- J) M" N2 P: r+ `4 b; D
( [6 S, {& t5 J7 f// **** 全局变量 ****
) r; C4 e* o' k6 G/ Pdate g_dtLastCrossTime = 0; //前一次告警的最后一个交叉点的出现时间
# E# u2 N& Q( }+ [: {
z' I$ b# M- K* p7 t5 L% R, T# r2 V0 E/ Q" c
6 B$ J% a# P5 h5 k" B7 B; X- Y7 }( e( |1 |% a+ v7 k! O
//+------------------------------------------------------------------+
' m0 S8 A, Z" L/ N//| expert initialization function |
+ N5 q( N# V O/ k6 f" ?//+------------------------------------------------------------------+
- T* ]. ^% i) T- ^! q- i( u: i
int init()
6 O8 P. e q- N% W- W/ k{
0 B ?; y) z- W+ Y
if (GlobalVariableCheck("KDJCross_ForceSendMailAlarm") &&
/ F2 Y' N- T; ]7 g% a+ d
MathAbs(GlobalVariableGet("KDJCross_ForceSendMailAlarm")) > 0.9999)
; y9 o1 d: V9 i {
/ m0 H6 G5 C- ]" L n1 Y4 T6 J
Print("KDJCross_ForceSendMailAlarm = true");
. o5 {" z0 l6 [% d }
9 ~0 Q3 x% K1 L, @0 m2 V else
6 @! {1 Z" M; Z; g {
( V2 l6 Y7 c! {: z6 @ Print("KDJCross_ForceSendMailAlarm = false");
% {0 }) A: \% w' q; D4 t
}
( n) J/ E7 P/ F! c+ e+ p7 C6 ~1 e
) x1 p6 o1 n1 d" S6 q# R, F return(0);
0 U+ l3 j$ L# A4 h1 y
}
+ X; o2 E1 E4 C: Y" M0 h6 O
y: u' B* F! z( f( M, d7 x; o% G; _4 y, q3 }
9 q8 s. f: A I7 s6 S- A//+------------------------------------------------------------------+
; o# h. V/ T( B& w3 w//| expert deinitialization function |
' [; {7 I, N7 x+ v- j3 M//+------------------------------------------------------------------+
6 @8 V1 v$ \6 B7 bint deinit()
" l, o& O( G% ^1 N" R) x
{
- @' P; j1 G) z. k. @) {3 R) S7 M; L% K% p6 U
return(0);
$ N) q$ v. y2 F* Y8 i
}
! A: A2 V" l4 h( ]9 I$ [
/ B- i: d" W$ o* p$ j0 a8 V. ~' n
: S+ Z( _/ K; O+ N0 V& v$ s//+------------------------------------------------------------------+
& z+ w. B$ g- _# h: f7 L//| expert start function |
" C) E- l/ ~, g//+------------------------------------------------------------------+
- W4 `7 i4 s) Nint start()
/ t+ w7 C5 ^- K8 K3 o$ _2 ]
{
4 s j' {. F- c) u4 n. e int nRef1CrossType = 0;
5 S) _ z4 E, c, ^4 r date dtRef1CrossTime = 0;
9 s/ K) u9 `$ {# _, D) c! R( m l1 ^$ m4 f6 z4 Z; @
int nRef2CrossType = 0;
: Y4 w; w2 V) }1 c; T6 V' t
date dtRef2CrossTime = 0;
$ e5 b% Y" v* L6 u2 y6 t
5 c8 y! K2 a, a3 j" G9 a9 b datetime dtLastCrossTime = 0;
7 z" m1 @" D- O , @0 _/ \9 p$ Z/ J4 @
if (p_RefTimeframe1 > 0)
/ J3 \8 n; \* {9 v5 z {
2 v# V& |+ f4 K h: k3 X; x6 V6 ^ //在参考时间框架1寻找第一个交叉点
' x. w- w% K" X+ I9 v/ p8 b
nRef1CrossType = FindKDJCross(dtRef1CrossTime, p_RefTimeframe1, p_Kperiod, p_Dperiod, p_Slowing);
% g, N; g% y3 G( W+ _: b4 c7 s
% O2 y" S9 I% h% R/ L. g) S if (nRef1CrossType != -999 && dtRef1CrossTime >dtLastCrossTime)
) m: w* O5 w/ x' e: | {
# z. A1 \8 X) }' {. m( P
dtLastCrossTime = dtRef1CrossTime;
+ M, H/ k5 n2 C1 S" |/ k! g( b }
1 N' D8 p4 j! p }
! \2 a. Z: ]7 _
4 @7 F3 q2 P X* K. V2 q if (p_RefTimeframe2 > 0)
3 H3 L# A" U, [, J- D0 k
{
% ?6 U6 D# G0 n5 q6 Z' K
//在参考时间框架2寻找第一个交叉点
& x& h: _0 v2 j7 H" ~+ k' A) U( j
nRef2CrossType = FindKDJCross(dtRef2CrossTime, p_RefTimeframe2, p_Kperiod, p_Dperiod, p_Slowing);
- c+ r4 U2 w) c0 C5 W
?; C! D6 r5 [- S5 y1 l8 q. f
( L( _# a* ^& J( H' S& A if (nRef1CrossType != -999 && dtRef2CrossTime >dtLastCrossTime)
$ ~, A# i, d+ C: H* h9 S# { {
2 A3 ^5 d+ I3 F7 \1 U9 T% N5 }; c
dtLastCrossTime = dtRef2CrossTime;
5 E1 p6 s$ h4 v/ f8 t- a8 Y }
' w% ^4 |1 n' R. G7 I& r/ V }
, c; G$ j1 T* ] ; Z, R$ y' y7 Y! P- u
if ((nRef1CrossType == p_CareCrossType && nRef2CrossType == 0) ||
: ]2 Y3 L' T8 R! T (nRef1CrossType == p_CareCrossType && nRef2CrossType == p_CareCrossType))
) v9 H7 [8 U+ k8 W {
. G! N8 d% @. V) C6 n9 t7 K
if (dtLastCrossTime > g_dtLastCrossTime)
/ P+ N/ H5 v" {# _& w* f {
4 o8 D! ~5 m% ]. i3 e$ {; }
//告警条件达到,发出告警
e- F+ L* k7 ~ string strAlarmMsg = Symbol() + ",KDJ cross " + nRef1CrossType + " be detected!";
( w) f" T) Y/ f0 s8 e5 d
% ]7 @: \1 V9 B9 v4 U
Print("KDJ Cross Alarm: ", strAlarmMsg);
, U' T4 z6 h/ [! A; f! B 6 X# i0 a3 c" K5 j
bool bGlobalSendMailAlarm = false;
- h7 M7 W) U( {. g$ q% I' G$ \3 t
if (GlobalVariableCheck("KDJCross_ForceSendMailAlarm") &&
5 x% y0 t0 Y& |6 [ MathAbs(GlobalVariableGet("KDJCross_ForceSendMailAlarm")) > 0.9999)
0 z6 u' o8 a5 d( O) ?: B {
$ e0 _; Y" k! |: _2 W bGlobalSendMailAlarm = true;
% w8 e7 I6 T' _% O: c }
4 l1 H% N* @, D" ~ . t) F' o6 O# z+ N" `4 t
if (p_SendMailAlarm || bGlobalSendMailAlarm)
2 V+ q5 {/ [0 T5 g8 c# l9 c) K2 }
{
$ ~3 a; v% w1 U; C4 b9 b: X
SendMail("Alarm: " + strAlarmMsg, "Alarm happened: " + strAlarmMsg);
" W4 Q- v/ B) T9 t+ r6 a! V
}
) k* d, n/ T! e7 n6 [ % D0 z7 o. b9 N5 c
if (p_MessageboxAlarm)
+ [: ?, s2 A8 h( Q
{
; [; K+ t! U3 H' Z: N" \
MessageBox(strAlarmMsg, "Alarm");
y) n s. \! T& ~7 W+ l }
3 F, P: q L- z' L( Y+ X# M
8 l# ^1 q1 o4 {' {- ^# _# f
1 R" ?, v. G5 _) L3 ~ g_dtLastCrossTime = dtLastCrossTime;
8 J- B. c3 i, q% N, Z7 R }
0 B) v6 v4 K1 E9 s }
9 r0 o& @! n; _4 ~4 P/ @+ ?" E& J, i- R
& S# g# S: A9 K8 \1 `. A return(0);
" F; h. ~* J7 l' H4 i K}
# k7 \. L" U; L. C% v: l; {
7 d1 `: l! `) g* H+ e4 x//功能:寻找KDJ指示最近的一个交叉点类型
- y9 _5 U' d- c) q# m
//参数:
1 a! e, \! i( T
// dtCross - [out]返回交叉点的时间
2 O, b d) t! D( d//返回:
' g6 G' |, Z0 z8 |$ h' k. K6 N// 若是金叉则返回1,若是死叉则返回-1,没有找到时(如数据不足)则返回-999
( j4 G, _" X+ o+ P
int FindKDJCross(datetime &dtCross, int nTimeframe, int nKperiod, int nDperiod, int nSlowing)
v4 k- v; u2 ~/ z. E- {- {- Z, N{
! e" S3 M% T1 F2 y& d
int nResult = -999;
/ X4 z4 M7 Y2 T9 q9 h+ _( X
int nCrossValue = -1;
% V& p- U0 W4 h; }! K
$ \( F; n6 l! e' }8 G2 a5 ] int i;
$ x8 [9 E2 q1 D% D int nBarsCount = iBars(NULL, nTimeframe) - 30;
& r% D2 z, B) M | Y/ L5 Q
8 J3 O3 x+ o" V1 a6 F8 x for (i = 0; i < nBarsCount; i++)
3 s# C* o6 ^( ?8 B. F% x' w. n8 N4 D {
2 d, u: v$ x$ y J int nMain1 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_MAIN, i);
& G1 {0 u/ i1 `6 w" ~
int nMain2 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_MAIN, i + 1);
( ^" x1 ~* U! o$ z
3 H- @4 |$ `8 f6 p
int nSignal1 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_SIGNAL, i);
7 W: C: g! a1 e) b3 _ int nSignal2 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_SIGNAL, i + 1);
" p& {+ X9 S0 V
; |) c D) U, b- v! N4 o& n
if (nMain2 <= nSignal2 && nMain1 >= nSignal1)
. q D7 h. u9 n1 t& _, t {
8 i9 b0 z9 t; Y3 s$ g
//金叉
) B& W; k$ G: E& w5 C nResult = 1;
# z) m/ e2 J) r' M
nCrossValue = nMain1;
; K5 }/ y! ~! d2 M8 W! A break;
2 o# ~* _% {6 z1 l }
& ]& C* ^5 g7 G+ [4 O! }# b
else if (nMain2 >= nSignal2 && nMain1 <= nSignal1)
, g! S x2 ^- t0 i: r1 f
{
; } _9 o$ V+ B/ {' J* V O
//死叉
+ K* w. Z6 V6 m6 n3 E% w nResult = -1;
! y! Z4 ^; s; b7 b+ B7 |
nCrossValue = nMain1;
: e9 V- _& x- D2 @
break;
5 p# K, E8 N: l5 A/ v5 u
}
! m }6 P" j3 P" O) M
}
6 w+ p( W5 o1 L5 m
7 n. g4 n. G6 O3 j6 S6 _ //Print(nTimeframe, " , ", nResult, ",nCrossValue=", nCrossValue, ",p_TopLimit=",p_TopLimit,",p_BottomLimit=",p_BottomLimit);
' e+ g+ W# |9 i0 X& m9 t
5 J4 V' T: n3 a- m6 R if (nResult == 1 && nCrossValue > p_BottomLimit)
) K* Q H' _8 b# s1 O: j {
% c# f- I; D. a# U. V
//金叉位置太高,需要忽略之
* f9 I0 ~8 c6 P' V7 f! Q
nResult = -999;
: N4 L1 b4 g$ d, k7 u7 V' k
}
$ _ V+ N0 \9 E" V* S3 v9 x if (nResult == -1 && nCrossValue < p_TopLimit)
( h$ e. p1 R1 B; u' r" v
{
& N% q& v* \3 b7 i. t2 i( k$ G //死叉位置太低,需要忽略之
7 D2 f( _1 p/ o: M( E6 w) F+ o; P nResult = -999;
( O- C& @& q, {2 q$ |* a3 g' f" M }
5 _2 y( b6 ]0 N$ v' j5 Q& T
+ Q4 T- P: Y* k, k D. }+ F1 s if (nResult != -999)
j# a2 y5 t, j7 x
{
c) ~7 v; ]2 v dtCross = iTime(NULL, nTimeframe, i);
" y9 [5 }( o) h5 A# ]7 n* ^
{$ }+ n- s: ]/ C* A //Print("In timeframe ", nTimeframe, " Cross ", nResult, " happened at ", TimeToStr(dtCross, TIME_DATE|TIME_MINUTES|TIME_SECONDS));
$ l6 l8 s" N7 |, L, z }
; ~! q' g1 a; U
7 M; u4 a8 v( g4 A0 ^5 b, } //没有找到交叉点
: H* u% I7 Y m+ ^* D. H$ f
return (nResult);
0 c, q+ C& P0 W0 i/ J
}
) K; [# u6 U$ p I* `$ T/ i* [% A# D# }- n2 k, ] |( @) f0 `7 [; Q
//+------------------------------------------------------------------+