缠论是一个伟大的理论,让我们看K线图不再是天书,而是变得有规律可循。
首先第一步就是要确定一个最新级别的分析图作为A0,并画出笔和线段来。
画笔的规则很简单,但是有些时候临近K线间价格相差无几的情况下,是否成笔的判断,需要我们放大图形,去读取每根K线的高低价位数字,去仔细分析才能确定,这样颇费心神。所以一款自动画笔的利器尤为重要,可为我们节约大量的时间和精力。
幸好的是缠论笔的规则定义不复杂,可以编程实现。
在实现过程中也是几次修正错误,方得今日较高的正确率。
笔成立的三个条件:
1. 顶分型高于底分型
2. K线合并后,顶底分型不能共用标准K线
3.合并前,顶底之间(不含顶和底)不得小于3根标准化前的K线
另外还有新笔和旧笔的区分,我个人更喜欢新笔。
那么在MT4中,如何实现呢?看似规则简单,真实现起来做到较高的准确率,也是历经几次反复才得以解决。
下面总结下几个问题:
笔的2端是顶底分型,所以第一步首先扫描整个K线范围找出所有的顶底分型
这一步只需要按照分型成立的条件去处理就可以了,无需顾及其他,在后面的步骤中我们逐步挑选符合条件的分型,扔掉不需要的分型;
int i= total;
for(; i > 0; i--) {
g_fractalinfo[i].index = i;
if(isUpFractal(high, low, i)) {
//顶分型
g_fractalinfo[i].setType(UP);
g_fractalinfo[i].enable();
}
else if(isDownFractal(high, low, i) ) {
//底分型
g_fractalinfo[i].setType(DOWN);
g_fractalinfo[i].enable();
}
else {
g_fractalinfo[i].empty(); //既不是顶分型也不是底分型
}
}
所有分型存放到一个g_fractalinfo集合对象中。
第二步 在分型的基础上依次提取笔
笔的起点是分型,所以从g_fractalinfo集合对象中的第二个分型开始,寻找符合条件的一笔
找到分型后分几种情况进行处理:
1、按文章前面提到的笔的规则判断是否成笔,如果成笔,那么开启此分型,并且记录最后一笔笔尾索引:
g_fractalinfo[i].enable();
last_fractal_index= i;
2、如果分型类型与last_fractal_index所指分型类型相同,都是顶分型或都是底分型,并且价格更高或更低,那么前一个分型无效:
对顶分型:
if(high[i] < high[last_fractal_index]) {
g_fractalinfo[i].empty();
continue;
}
对底分型:
if(low[i] > low[last_fractal_index]) {
g_fractalinfo[i].empty();
continue;
}
3、最复杂的情况是分型类型不同,但是last_fractal_index所指分型(假设叫Fa)和当前分型(假设叫Fb)不构成笔。
这种情况下又要分2种情况来处理了:
a) 继续寻找下一个分型Fc,和Fa分型构成笔,那么此笔Fa~Fc有效,Fb作废;
b) 继续寻找分型Fc,Fa~Fc不能成笔,但是能够和Fb构成笔,那么显然Fb和之前的分型F构成了笔,Fb和Fc也构成了一笔。并且F和Fb之间的分型作废,所以关键是寻找F
示意图如下:图中黑色的直线都是一笔
其实F也好寻找,如上图示意,F就是第一个高于Fa的顶分型。
上述算法在Find_a_Bi函数里。有了上述算法,画笔就不会有大问题了。
代码如下:
for(; i > 0; i--) {
if(!g_fractalinfo[i].IsFractal()) {
continue;
}
if(g_fractalinfo[i].IsUpFractal()) {
if(g_fractalinfo[last_fractal_index].IsUpFractal()) {
//前一个也是顶分型,所以置空
if(high[i] < high[last_fractal_index]) {
g_fractalinfo[i].empty();
continue;
}
g_fractalinfo[last_fractal_index].setType(NONFR);
g_fractalinfo[last_fractal_index].disable();
last_fractal_index= i;
}
else if(g_fractalinfo[last_fractal_index].IsDownFractal()) {
//前一个是底分型
int ii= Find_a_Bi(i,last_fractal_index);
if(ii > 0) {
g_fractalinfo[ii].enable();
last_fractal_index= ii;
i = ii;
}
else {
//关闭此分型
g_fractalinfo[i].empty();
continue;
}
}
else {
//设置分型
g_fractalinfo[i].enable();
last_fractal_index= i;
}
}
else if(g_fractalinfo[i].IsDownFractal() ) {
//底分型
if(g_fractalinfo[last_fractal_index].IsDownFractal()) {
//前一个也是底分型,所以置空
if(low[i] > low[last_fractal_index]) {
g_fractalinfo[i].empty();
continue;
}
g_fractalinfo[last_fractal_index].setType(NONFR);
g_fractalinfo[last_fractal_index].disable();
last_fractal_index= i;
}
else if(g_fractalinfo[last_fractal_index].IsUpFractal()) {
//前一个是顶分型
int ii= Find_a_Bi(i,last_fractal_index);
if(ii > 0) {
g_fractalinfo[ii].enable();
last_fractal_index= ii;
i = ii;
}
else {
//关闭此分型
g_fractalinfo[i].empty();
continue;
}
}
else {
g_fractalinfo[i].enable();
last_fractal_index= i;
}
}
else {
g_fractalinfo[i].empty(); //既不是顶分型也不是底分型
}
}