缠论是一个伟大的理论,让我们看K线图不再是天书,而是变得有规律可循。

应用缠论而言,首先就是要确定一个最小级别的分析图作为A0,并画出笔和线段来。

画笔的规则很简单,但是有些时候临近K线间价格相差无几的情况下,是否成笔的判断,需要我们放大图形,去读取每根K线的高低价位数字,去仔细分析才能确定,这样颇费心神。所以一款自动画笔的利器尤为重要,可为我们节约大量的时间和精力。

幸好的是缠论笔的规则定义不复杂,可以编程实现。

本人在实现过程中也是几次修正错误,方得今日较高的正确率。

相邻的顶底分型构成笔,但是还需要满足三个条件:

1. 顶分型一定要高于底分型,底分型一定要低于顶分型,也就是说两者不能形成包含形态;

2. K线合并成标准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所指分型类型相同,都是顶分型或都是底分型,并且价格更高或更低,那么当前分型有效,笔延伸到当前分型,并关闭last_fractal_index所指分型:

g_fractalinfo[last_fractal_index].setType(NONFR);
                g_fractalinfo[last_fractal_index].disable();               //当前分型有效
                g_fractalinfo[i].enable();
                last_fractal_index= i;

3、如果分型类型与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;
}

 

4、最复杂的情况是分型类型不同,但是last_fractal_index所指分型(假设叫Fa)和当前分型(假设叫Fb)不构成笔。

 

这种情况下又要分2种情况来处理了:

a) 继续寻找下一个分型Fc,和Fa分型构成笔,那么此笔Fa~Fc有效,Fb作废;

b) 继续寻找分型Fc,Fa~Fc不能成笔,但是能够和Fb构成笔,那么显然Fb和之前的分型F构成了笔,Fb和Fc也构成了一笔。并且F和Fb之间的分型作废,所以关键是寻找F

 

示意图如下:图中黑色的直线都是一笔

python缠论api 缠论 编程_python缠论api

 

其实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();
g_fractalinfo[i].enable();
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();
g_fractalinfo[i].enable();
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(); //既不是顶分型也不是底分型
}
}