网上看到一个思路很好的报警指标, 但是有一个问题,报不了警, 请高手帮忙看一看, 非常感谢!
以下内容为转载:
KDJ提醒器 0.5
我自己写的KDJ提醒器。
它可以设置两个时间框架(Timeframe)及KDJ指标(实际上使用的不是KDJ指标而是MT4自带的Stochastic指标)的相关参数,当KDJ在两个时间框架上同时出现低位金叉或高位死叉时,将会向你发现提示信息。在选择入场点时,KDJ出现低位金叉或高位死叉是一个非常不错的判断方法。
相关参数说明:
p_RefTimeframe1:参考时间框架1,默认值:PERIOD_M5 (即5分钟图)
p_RefTimeframe2:参数时间框架2,默认值:PERIOD_M15(即15分钟图)
p_CareCrossType:所关心的交叉点类型(1-关注金叉,-1-关注死叉,0-不关注任何交叉,相当于暂停处理),默认值:1
p_TopLimit:死叉时,KD的值必须高于这个值(即需要高位死叉)
p_BottomLimit:金叉时,KD的值必须底于这个值(即需要低位金叉)
p_Kperiod:KDJ指标的%K周期,默认值:8
p_Dperiod:KDJ指标的%D周期,默认值:5
p_Slowing:慢线周期,默认值:3
p_MessageboxAlarm:出现条件时,是否弹出消息提示对象框,默认值:true
p_SendMailAlarm:是否发邮件提示消息,默认值:false
我在中国移动可以申请一个手机邮箱,并开通了邮件到达通知功能,这样我把p_SendMailAlarm参数设置成true,于是这个“邮件提示”就变成了“短信提示”,非常好用。
源代码如下:
//+------------------------------------------------------------------+
//| KDJ交叉信号告警.mq4 |
//| Jesse Loo |
//| |
//+------------------------------------------------------------------+
//** KDJ交叉信号告警 **
//当KDJ出现指定的金叉或死叉时发出告警
//Version: 0.50
//Date: 2007.01.25
//修改记录:
#property copyright \"Jesse Loo\"
#property link \"\"
string EA_FLAG = \"EA_KDJ_0.50\"; //自动交易程序的标志
// **** 外部参数 ****
extern int p_RefTimeframe1 = PERIOD_M5; //参考时间框架1
extern int p_RefTimeframe2 = PERIOD_M15; //参考时间框架2
extern int p_CareCrossType = 1; //所关心的交叉点类型(1-关注金叉,-1-关注死叉,
//0-不关注任何交叉,相当于暂停处理)
extern int p_TopLimit = 20; //死叉时,KDJ的值必须高于这个值
extern int p_BottomLimit = 80; //金叉时,KDJ的值必须底于这个值
extern int p_Kperiod = 8; //%K周期
extern int p_Dperiod = 5; //%D周期
extern int p_Slowing = 3; //慢线周期
extern bool p_MessageboxAlarm = true; //弹出消息提示
extern bool p_SendMailAlarm = false; //发送邮件提示信息
// **** 全局变量 ****
datetime g_dtLastCrossTime = 0; //前一次告警的最后一个交叉点的出现时间
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
if (GlobalVariableCheck(\"KDJCross_ForceSendMailAlarm\") &&
MathAbs(GlobalVariableGet(\"KDJCross_ForceSendMailAlarm\")) > 0.9999)
{
Print(\"KDJCross_ForceSendMailAlarm = true\");
}
else
{
Print(\"KDJCross_ForceSendMailAlarm = false\");
}
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
int nRef1CrossType = 0;
datetime dtRef1CrossTime = 0;
int nRef2CrossType = 0;
datetime dtRef2CrossTime = 0;
datetime dtLastCrossTime = 0;
if (p_RefTimeframe1 > 0)
{
//在参考时间框架1寻找第一个交叉点
nRef1CrossType = FindKDJCross(dtRef1CrossTime, p_RefTimeframe1, p_Kperiod, p_Dperiod, p_Slowing);
if (nRef1CrossType != -999 && dtRef1CrossTime >dtLastCrossTime)
{
dtLastCrossTime = dtRef1CrossTime;
}
}
if (p_RefTimeframe2 > 0)
{
//在参考时间框架2寻找第一个交叉点
nRef2CrossType = FindKDJCross(dtRef2CrossTime, p_RefTimeframe2, p_Kperiod, p_Dperiod, p_Slowing);
if (nRef1CrossType != -999 && dtRef2CrossTime >dtLastCrossTime)
{
dtLastCrossTime = dtRef2CrossTime;
}
}
if ((nRef1CrossType == p_CareCrossType && nRef2CrossType == 0) ||
(nRef1CrossType == p_CareCrossType && nRef2CrossType == p_CareCrossType))
{
if (dtLastCrossTime > g_dtLastCrossTime)
{
//告警条件达到,发出告警
string strAlarmMsg = Symbol() + \",KDJ cross \" + nRef1CrossType + \" be detected!\";
Print(\"KDJ Cross Alarm: \", strAlarmMsg);
bool bGlobalSendMailAlarm = false;
if (GlobalVariableCheck(\"KDJCross_ForceSendMailAlarm\") &&
MathAbs(GlobalVariableGet(\"KDJCross_ForceSendMailAlarm\")) > 0.9999)
{
bGlobalSendMailAlarm = true;
}
if (p_SendMailAlarm || bGlobalSendMailAlarm)
{
SendMail(\"Alarm: \" + strAlarmMsg, \"Alarm happened: \" + strAlarmMsg);
}
if (p_MessageboxAlarm)
{
MessageBox(strAlarmMsg, \"Alarm\");
}
g_dtLastCrossTime = dtLastCrossTime;
}
}
return(0);
}
//功能:寻找KDJ指示最近的一个交叉点类型
//参数:
// dtCross - [out]返回交叉点的时间
//返回:
// 若是金叉则返回1,若是死叉则返回-1,没有找到时(如数据不足)则返回-999
int FindKDJCross(datetime &dtCross, int nTimeframe, int nKperiod, int nDperiod, int nSlowing)
{
int nResult = -999;
int nCrossValue = -1;
int i;
int nBarsCount = iBars(NULL, nTimeframe) - 30;
for (i = 0; i < nBarsCount; i++)
{
int nMain1 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_MAIN, i);
int nMain2 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_MAIN, i + 1);
int nSignal1 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_SIGNAL, i);
int nSignal2 = iStochastic(NULL, nTimeframe, nKperiod, nDperiod, nSlowing, MODE_SMA, 0, MODE_SIGNAL, i + 1);
if (nMain2 = nSignal1)
{
//金叉
nResult = 1;
nCrossValue = nMain1;
break;
}
else if (nMain2 >= nSignal2 && nMain1 p_BottomLimit)
{
//金叉位置太高,需要忽略之
nResult = -999;
}
if (nResult == -1 && nCrossValue < p_TopLimit)
{
//死叉位置太低,需要忽略之
nResult = -999;
}
if (nResult != -999)
{
dtCross = iTime(NULL, nTimeframe, i);
//Print(\"In timeframe \", nTimeframe, \" Cross \", nResult, \" happened at \", TimeToStr(dtCross, TIME_DATE|TIME_MINUTES|TIME_SECONDS));
}
//没有找到交叉点
return (nResult);
}
//+------------------------------------------------------------------+ |