风天君 2007-11-15 16:44
本人做的kd指标的改进的KDCD指标
发一个本人做的kd指标的改进的KDCD指标,原理有点象MACD指标,比原来的KD指标看着清楚一点。
代码:
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 White
#property indicator_color2 Yellow
#property indicator_color3 Green
#property indicator_color4 Red
extern int KPeriod=8;
extern int DPeriod=3;
extern int Slowing=5;
double MainBuffer[];
double SignalBuffer[];
double KDCDBuffer[];
double KDCDBuffer1[];
double HighesBuffer[];
double LowesBuffer[];
double zjBuffer[];
int draw_begin1=0;
int draw_begin2=0;
int draw_begin3=0;
int init()
{
string short_name;
IndicatorBuffers(7);
SetIndexBuffer(4, HighesBuffer);
SetIndexBuffer(5, LowesBuffer);
SetIndexBuffer(6, zjBuffer);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, MainBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, SignalBuffer);
SetIndexStyle(2,DRAW_HISTOGRAM);
SetIndexBuffer(2, KDCDBuffer);
SetIndexStyle(3,DRAW_HISTOGRAM);
SetIndexBuffer(3, KDCDBuffer1);
short_name="KDCD("+KPeriod+","+DPeriod+","+Slowing+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Main");
SetIndexLabel(1,"Signal");
SetIndexLabel(2,"KDCD");
draw_begin1=KPeriod+Slowing;
draw_begin2=draw_begin1+DPeriod;
draw_begin3=draw_begin1+DPeriod;
SetIndexDrawBegin(0,draw_begin1);
SetIndexDrawBegin(1,draw_begin2);
SetIndexDrawBegin(2,draw_begin2);
SetIndexDrawBegin(3,draw_begin2);
return(0);
}
int start()
{
int i,j,k;
int counted_bars=IndicatorCounted();
double price;
i=Bars-KPeriod;
if(counted_bars>KPeriod) i=Bars-counted_bars-1;
while(i>=0)
{
double min=1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=Low[k];
if(min>price) min=price;
k--;
}
LowesBuffer[ i]=min;
i--;
}
//---- maximums counting
i=Bars-KPeriod;
if(counted_bars>KPeriod) i=Bars-counted_bars-1;
while(i>=0)
{
double max=-1000000;
k=i+KPeriod-1;
while(k>=i)
{
price=High[k];
if(max<price) max=price;
k--;
}
HighesBuffer [ i]=max;
i--;
}
//---- %K line
i=Bars-draw_begin1;
if(counted_bars>draw_begin1) i=Bars-counted_bars-1;
while(i>=0)
{
double sumlow=0.0;
double sumhigh=0.0;
for(k=(i+Slowing-1);k>=i;k--)
{
sumlow+=Close[k]-LowesBuffer[k];
sumhigh+=HighesBuffer[k]-LowesBuffer[k];
}
zjBuffer[ i]=sumlow/sumhigh*100;
MainBuffer[ i]=2*zjBuffer[ i]-100;
i--;
}
//---- last counted bar will be recounted
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
//---- signal line is simple movimg average
for(i=0; i<limit; i++)
SignalBuffer[ i]=2*iMAOnArray(zjBuffer,Bars,DPeriod,0,MODE_SMA,i)-100;
//----
for(j=0; j<limit; j++)
{
KDCDBuffer[ j]=2*(MainBuffer[ j]-SignalBuffer[ j]);
if(KDCDBuffer[ j]>0) KDCDBuffer1[ j]=KDCDBuffer[j];
}
return(0);
}
[i]效果图见附件[/i]
[[i] 本帖最后由 xfxyldj 于 2007-11-16 11:41 编辑 [/i]]
dongke 2007-11-15 20:50
楼主 干脆发mq4 文件好了。
代码我贴进去编译出错。。
xfxyldj 2007-11-15 20:57
写得不错。欢迎自创指标。
以后把mq4文件压缩作为附件发表。
这样发表因为主页模式的关系对[color=red]“[ i]”[/color]编译成了斜体字了。
有些坛友拷贝了直接编译就很难通过。
或者使用代码插件模式发表。
例如:
[code]SignalBuffer[i]=iMAOnArray(MainBuffer,Bars,DPeriod,0,MODE_SMA,i);[/code]
这样就不会变斜体了。
[[i] 本帖最后由 xfxyldj 于 2007-11-15 20:59 编辑 [/i]]
rsdy18418081 2007-11-16 11:33
呵呵。如果能解决KD的钝化问题就好了哦!!
也许把波动区间去掉,不要限制在0-100就可以???:yct63 :yct63
xfxyldj 2007-11-16 11:43
回复 2楼 的帖子
代码部分修改完毕。没有问题了,可以拷贝粘贴了。
风天君 2007-11-17 14:48
KDCD指标的改进版
KDCD指标的改进版
下边的代码是本人直接用iStochastic函数做的KDCD指标,计算方法与前边的代码相同,但直接用了系统提供的iStochastic函数,这样代码就简洁多了。
代码如下:
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_color1 White
#property indicator_color2 Yellow
#property indicator_color3 Green
#property indicator_color4 Red
extern int KPeriod=8;
extern int DPeriod=3;
extern int Slowing=5;
double MainBuffer[];
double SignalBuffer[];
double KDCDBuffer[];
double KDCDBuffer1[];
int draw_begin1=0;
int draw_begin2=0;
int draw_begin3=0;
int init()
{
string short_name;
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0, MainBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1, SignalBuffer);
SetIndexStyle(2,DRAW_HISTOGRAM);
SetIndexBuffer(2, KDCDBuffer);
SetIndexStyle(3,DRAW_HISTOGRAM);
SetIndexBuffer(3, KDCDBuffer1);
short_name="KDCD("+KPeriod+","+DPeriod+","+Slowing+")";
IndicatorShortName(short_name);
SetIndexLabel(0,"Main");
SetIndexLabel(1,"Signal");
SetIndexLabel(2,"KDCD");
SetIndexLabel(3,"KDCD");
SetIndexDrawBegin(0,KPeriod+Slowing);
SetIndexDrawBegin(1,KPeriod+Slowing+DPeriod);
SetIndexDrawBegin(2,KPeriod+Slowing+DPeriod);
SetIndexDrawBegin(3,KPeriod+Slowing+DPeriod);
return(0);
}
int start()
{
int i,limit,counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars<0) counted_bars--;
limit=Bars-counted_bars;
for(i=0;i<limit;i++)
{
KDCDBuffer1[i]=EMPTY_VALUE;
MainBuffer[i]=2*iStochastic(NULL,0,KPeriod,DPeriod,Slowing,MODE_EMA,0,MODE_MAIN,i)-100;
SignalBuffer[i]=2*iStochastic(NULL,0,KPeriod,DPeriod,Slowing,MODE_EMA,0,MODE_SIGNAL,i)-100;
KDCDBuffer[i]=2*(MainBuffer[i]-SignalBuffer[i]);
if(KDCDBuffer[i]>0) KDCDBuffer1[i]=KDCDBuffer[i];
}
return(0);
}
效果图:
[localimg=1000,613]1[/localimg]
[attach]14076[/attach]
风天君 2007-11-17 15:34
MQ4文件
MQ4文件见前6楼的附件KDCD.rar文件。可下载使用。
风天君 2007-11-17 23:14
回复 4楼 的帖子
KD指标的算法决定了它没有办法解决钝化的问题。钝化也是所有的振荡指标共有的问题。威廉指标,RSI指标都是这一类的指标,都无法解决钝化的问题。
KD指标要先算一个未成熟随机值rsv:
rsv=(Cn-LN)/(Hn-Ln);
然后取rsv的加权移动平均,就是K值。然后再取K值的加权移动平均,就是D值。
这就很明白了,rsv不可能小于0,也不可能大于100。同时rsv的加权移动平均值K也就不可能小于0,也不可能大于100。同理,D值也不可能小于0,也不可能大于100。
既然限定了波动区间,那钝化的问题就不可能解决了。即便是把波动区间乘以10,变为0到1000,也解决不了。因为从视觉上看,比例是一样的。
我所改进的KD指标,把波动区间扩大到了-100到100,也解决不了钝化的问题。至于如何改到了-100到100的?很简单,就把K值乘以2再减去100就可以了。D值自然跟进K值。
想要知道钝化的问题是怎么产生的,推荐4楼主看看这本书——《大师的命门》。
lnlwwgm 2007-11-29 23:18
看起来很不错我下来试一下
看看起来很不错我下来试一下
yuzhiyi987 2008-3-18 17:52
谢谢了 先收下了
cherry1982 2008-3-21 01:43
不错.谢谢
风天君 2008-8-5 00:31
有要指标的吗。编了无数无用的指标。呵呵。给我发短消息。