繁簡切換您正在訪問的是FX168財經網,本網站所提供的內容及信息均遵守中華人民共和國香港特別行政區當地法律法規。

FX168财经网>人物频道>帖子

【量化缠论】之分型、笔、线段识别

作者/谎言梦 2019-05-09 17:35 0 来源: FX168财经网人物频道

因为缠论文章都是博客形式,并无很规范的写作格式与篇章结构,自己理解起来着实不易,每次读都感悟不同,程序也是改了又改。
下文对于缠论的理解以及程序的处理都是个人粗浅的理解,还望对缠论有很深造诣的前辈指出不足之处。

详情见研究模块!

(代码中发现些许问题,因为分享之后的研究无法替换,所以将修改后的代码我放在评论区了。)

       因为缠论文章都是博客形式,并无很规范的写作格式与篇章结构,自己理解起来着实不易,每次读都感悟不同,程序也是改了又改。
       下文对于缠论的理解以及程序的处理都是个人粗浅的理解,还望对缠论有很深造诣的前辈指出不足之处。

一、序言¶

       研究模块中实现了“缠论”的分型,笔,线段。
       开始本想实现维克多交易法则中的维克多交易法则,维克多123法则和2B法则是判断趋势变动的最基本法则。思考如何实现对于趋势"图"的识别,想到了缠论中关于分型,笔以及线段的描述。
       其中对简单的1-2-3准则的进行简单总结:

  1. 趋势线被突破。价格穿越绘制的趋势线

  2. 上升趋势不再创新高,或下降趋势不再创新低。

  3. 在下降趋势中,价格向上穿越先前的短期反弹高点;或在上升趋势中,价格向下穿越先前的短期回档低点。
           示意图如下所示:

       维克多交易规则具体的学习还是要到《专业投机原理》一书中深刻领会,在这里仅仅是一个概括。
       我们可以将维克多的趋势看为缠论的一个线段,维克多的趋势破坏即可认为是缠论中的线段被破坏,如下图中9所示,触发交易信号。下面介绍一下缠论之分型、笔、线段。

二、缠论之分型、笔、线段¶

       下面的定义与图,都适合任何周期的 K 线图。先看图中的第 1、2,图中的小线段代表的是 K 线,这里不分阳线阴线,只看 K 线高低点。
缠论

       像图1这种,第二K线高点是相邻三K线高点中最高的,而低点也是相邻三K线低点中最高的,定义其顶分型;图2这种第二K线低点是相邻三K线低点中最低的,而高点也是相邻三K线高点中最低的,定义为底分型。看不明白定义的,看图就明白了。

       顶分型的最高点叫该分型的顶,底分型的最低点叫该分型的底,由于顶分型的底和底分型的顶是没有意义的,所以顶分型的顶和底分型的底就可以简称为顶和低。也就是说,当我们以后说顶和底时,就分别是说顶分型的顶和底分型的底。

       两个相邻的顶和底之间构成一笔,所谓笔,就是顶和底之间的其他波动,都可以忽略不算,但注意,一定是相邻的顶和底,隔了几个就不是了。而所谓的线段,就是至少由三笔组成。但这里有一个细微的地方要分清楚,因为结合律是必须遵守的,像图3这种,顶和底之间必须共用一个K线,这就违反结合律了,所以这不算一笔,而图4,就光是顶和底了,中间没有其他K线,一般来说,也最好不算一笔,而图5,是一笔的最基本的图形,顶和底之间还有一根K线。在实际分析中,都必须要求顶和底之间都至少有一K线当成一笔的最基本要求。

       当然,实际图形里,有些复杂的关系会出现,就是相邻两K线可以出现如图6这种包含关系,也就是一K线的高低点全在另一K线的范围里,这种情况下,可以这样处理,在向上时,把两K线的最高点当高点,而两K线低点中的较高者当成低点,这样就把两K线合并成一新的K线;反之,当向下时,把两K线的最低点当低点,而两K线高点中的较低者当成高点,这样就把两K线合并成一新的K线。经过这样的处理,所有K线图都可以处理成没有包含关系的图形。在我的处理中,将下方这些形式都进行了包含关系的处理。
包含处理

       而图7,就给出了经过以上处理,没有包含关系的图形中,三相邻K线之间可能组合的一个完全分类,其中的二、四,就是分别是顶分型和底分型,一可以叫上升K线,三可以叫下降K线。所以,上升的一笔,由结合律,就一定是底分型+上升K线+顶分型;下降的一笔,就是顶分型+下降K线+底分型。注意,这里的上升、下降K线,不一定都是3根,可以无数根,只要一直保持这定义就可以。当然,简单的,也可以是1、2根,这只要不违反结合律和定义就可以。

       至于图8,就是线段的最基本形态,而图9,就是线段破坏,也就是两线段组合的其中一种形态。
       有人可能要说,这怎么有点像波浪理论,缠论作者认为这不奇怪,作者认为缠论的理论可以严格地推论出波浪理论的所有结论,而且还可以指出他理论的所有不足,波浪理论和缠论的理论一点可比性都没有。不仅是波浪理论,所有关于股市的理论,只要是关系到“图形”的,缠论的理论都可以严格推论,因为缠论的理论是关于走势图形最基础的理论,谁都逃不掉。

       缠论中根据可操作性定义了不同显微级别的,对于中枢和走势类型,也就有了关于不同级别的图形的研究。进而,就有了不同级别显微镜的比喻。而实际上,一般能得到的图,最多也就是 1 分钟级别的,因此,可以从这个图入手。当然,也可以从 5 分钟,甚至更高入手,但这就等于把显微镜倍数弄小了,看到的东西自然没有 1 分钟的多且清楚。再次强调,什么级别的图和什么级别的中枢没有任何必然关系,走势类型以及中枢就如同显微镜下的观察物,是客观存在的,其存在性由上面所说最原始的递归定义保证,而级别的图,就如同显微镜,不同倍数的看这客观的图就看到不同的精细程度,如此而已。所以,不能把显微镜和显微镜观察的东西混在一起了。

       如果我们首先确立了显微镜的倍数,也就是说,例如我们把 1 分钟图作为最基本的图,那么就可以开始定义上一课程说的分型、笔、线段等等。有了线段,就可以定义 1 分钟的中枢,然后就是 1 分钟的走势类型,然后按照递归的方法,可以逐步定义 5 分钟、30 分钟、日、周、月、季度、年的中枢和走势类型。而有的人总是不明白,例如总是在问,5 分钟图怎么看,30 分钟怎么看,其实,如果你选择 5 分钟或 30 分钟为最基本的图,那么和 1 分钟的看法一样,只不过你的显微镜倍数比较小,看起来比较粗糙而已。而如果你已经选择 1 分钟作为最基本的图,也就是选定了 1 分钟这个倍数的显微镜,那么看 1 分钟图就可以。

       所以程序中也定义了换算不同分钟级别的函数get_Fnk,根据需求可获得不同级别的分钟数据。

       另外,鄙人对于分型的寻找,如果一个底分型之后遇到一个顶分型,其中底分型的底高于顶分型的顶,如下图中一所示,则上一个底分型不被确立,跳过该顶分型,接着寻找一个下一个更低的底分型或者顶高于该底分型的顶分型。(话着实有些绕,抱歉抱歉!看图您就明白了。)
图

       缠论具体细则可参考《教你炒股票-缠中说禅》,其中关于“分型,笔,线段”的内容可参考第62-65课的内容。

用缠论分型处理之后的图形如下,符合维克多上升趋势:
维克多

三、不足之处¶

  1. 因为思绪混乱,程序更改多次,看着也许会有些混乱;

  2. 判断包含关系、找寻顶底的程序没有写成函数;

  3. 因为要实现维克多交易规则,程序还要判断准则还需更改,所以暂时并未没有实现,下一步计划实现维克多1-2-3与维克多2B交易规则。

def get_Fnk(security, start, end, n=5):'''    获得k分钟k线函数    '''import pandas as pdk_data = get_price(security, start_date=start, end_date=end, frequency='minute', fields=['open','close','high', 'low'])# 去除9:00与13:00的数据for i in range(len(k_data)/242):team = list(k_data.index)x = [s.strftime("%Y-%m-%d %H:%M:%S") for s in team]y = filter(lambda t : "09:31:00" in t, x)k_data= k_data.drop(k_data.index[x.index(y[0])])del x[x.index(y[0])]y = filter(lambda t : "13:01:00" in t, x)k_data= k_data.drop(k_data.index[x.index(y[0])])del x[x.index(y[0])]# 计算n分钟K线Fnk = pd.DataFrame()for i in xrange(n,len(k_data)+1,n):temp = k_data[i-n : i]temp_open = temp.open[0]temp_high = max(temp.high)temp_low = min(temp.low)temp_k = temp[-1:]temp_k.open = temp_opentemp_k.high = temp_hightemp_k.low = temp_lowFnk = pd.concat([Fnk,temp_k],axis = 0)return Fnkdef middle_num(k_data):# 鸡肋函数,完全的强迫症所为,只为下面画图时candle图中折线时好看而已 - -!# k_data 为DataFrame格式plot_data=[]for i in xrange(len(k_data)):temp_y = (k_data.high[i]+k_data.low[i])/2.0plot_data.append(temp_y)return plot_data
import numpy as npimport pandas as pdimport matplotlib as mplimport matplotlib.pyplot as pltimport matplotlib.finance as mpfk_data = get_Fnk(n=5,security = '000001.XSHE',start = '2015-12-02',end = '2015-12-05')## 判断包含关系after_fenxing = pd.DataFrame()temp_data = k_data[:1]zoushi = [3] # 3-持平 4-向下 5-向上for i in xrange(len(k_data)):case1_1 = temp_data.high[-1] > k_data.high[i] and temp_data.low[-1] < k_data.low[i]# 第1根包含第2根case1_2 = temp_data.high[-1] > k_data.high[i] and temp_data.low[-1] == k_data.low[i]# 第1根包含第2根case1_3 = temp_data.high[-1] == k_data.high[i] and temp_data.low[-1] < k_data.low[i]# 第1根包含第2根case2_1 = temp_data.high[-1] < k_data.high[i] and temp_data.low[-1] > k_data.low[i] # 第2根包含第1根case2_2 = temp_data.high[-1] < k_data.high[i] and temp_data.low[-1] == k_data.low[i] # 第2根包含第1根case2_3 = temp_data.high[-1] == k_data.high[i] and temp_data.low[-1] > k_data.low[i] # 第2根包含第1根case3 = temp_data.high[-1] == k_data.high[i] and temp_data.low[-1] == k_data.low[i] # 第1根等于第2根case4 = temp_data.high[-1] > k_data.high[i] and temp_data.low[-1] > k_data.low[i] # 向下趋势case5 = temp_data.high[-1] < k_data.high[i] and temp_data.low[-1] < k_data.low[i] # 向上趋势if case1_1 or case1_2 or case1_3:if zoushi[-1] == 4:temp_data.high[-1] = k_data.high[i]else:temp_data.low[-1] = k_data.low[i]elif case2_1 or case2_2 or case2_3:temp_temp = temp_data[-1:]temp_data = k_data[i:i+1]if zoushi[-1] == 4:temp_data.high[-1] = temp_temp.high[0]else:temp_data.low[-1] = temp_temp.low[0]elif case3:zoushi.append(3)passelif case4:zoushi.append(4)after_fenxing = pd.concat([after_fenxing,temp_data],axis = 0)temp_data = k_data[i:i+1]elif case5:zoushi.append(5)after_fenxing = pd.concat([after_fenxing,temp_data],axis = 0)temp_data = k_data[i:i+1]# after_fenxing.head()
/opt/conda/envs/python2/lib/python2.7/site-packages/pandas/core/generic.py:2177: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the c*eats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  self[name] = value
/opt/conda/envs/python2/lib/python2.7/site-packages/IPython/core/interactiveshell.py:3066: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the the c*eats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  exec(code_obj, self.user_global_ns, self.user_ns)
## 因为使用candlestick2函数,要求输入open、close、high、low。为了美观,处理k线的最大最小值、开盘收盘价,之后k线不显示影线。for i in xrange(len(after_fenxing)):if after_fenxing.open[i] > after_fenxing.close[i]:after_fenxing.open[i] = after_fenxing.high[i]after_fenxing.close[i] = after_fenxing.low[i]else:after_fenxing.open[i] = after_fenxing.low[i]after_fenxing.close[i] = after_fenxing.high[i]## 画出k线图stock_middle_num = middle_num(after_fenxing)fig, ax = plt.subplots(figsize = (50,20))fig.subplots_adjust(bottom=0.2)mpf.candlestick2(ax, list(after_fenxing.open),list(after_fenxing.close),list(after_fenxing.high),list(after_fenxing.low), width=0.6, colorup='r', colordown='b',alpha=0.75 )plt.grid(True)dates = after_fenxing.indexax.set_xticklabels(dates) # Label x-axis with dates# ax.autoscale_view()plt.plot(stock_middle_num,'k', lw=1)plt.plot(stock_middle_num,'ko')plt.setp(plt.gca().get_xticklabels(), rotation=30)
/opt/conda/envs/python2/lib/python2.7/site-packages/matplotlib/finance.py:1306: MatplotlibDeprecationWarning: This function has been deprecated in 1.4 in f*or of `candlestick2_ochl`, which maintains the original argument order, or `candlestick2_ohlc`, which uses the open-high-low-close order. This function will be removed in 1.5
  mplDeprecation)
[None, None, None, None, None, None, None, None, None, None]
/opt/conda/envs/python2/lib/python2.7/site-packages/matplotlib/collections.py:590: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  if self._edgecolors == str('face'):
## 找出顶和底temp_num = 0 #上一个顶或底的位置temp_high = 0 #上一个顶的high值temp_low = 0 #上一个底的low值temp_type = 0 # 上一个记录位置的类型i = 1fenxing_type = [] # 记录分型点的类型,1为顶分型,-1为底分型fenxing_time = [] # 记录分型点的时间fenxing_plot = [] # 记录点的数值,为顶分型去high值,为底分型去low值fenxing_data = pd.DataFrame() # 分型点的DataFrame值while (i < len(after_fenxing)-1):case1 = after_fenxing.high[i-1]<after_fenxing.high[i] and after_fenxing.high[i]>after_fenxing.high[i+1] #顶分型case2 = after_fenxing.low[i-1]>after_fenxing.low[i] and after_fenxing.low[i]<after_fenxing.low[i+1] #底分型if case1:if temp_type == 1: # 如果上一个分型为顶分型,则进行比较,选取高点更高的分型 if after_fenxing.high[i] <= temp_high:i += 1#                 continueelse:temp_high = after_fenxing.high[i]temp_num = itemp_type = 1i += 4elif temp_type == 2: # 如果上一个分型为底分型,则记录上一个分型,用当前分型与后面的分型比较,选取同向更极端的分型if temp_low >= after_fenxing.high[i]: # 如果上一个底分型的底比当前顶分型的顶高,则跳过当前顶分型。i += 1else:fenxing_type.append(-1)fenxing_time.append(after_fenxing.index[temp_num].strftime("%Y-%m-%d %H:%M:%S"))fenxing_data = pd.concat([fenxing_data,after_fenxing[temp_num:temp_num+1]],axis = 0)fenxing_plot.append(after_fenxing.high[i])temp_high = after_fenxing.high[i]temp_num = itemp_type = 1i += 4else:temp_high = after_fenxing.high[i]temp_num = itemp_type = 1i += 4elif case2:if temp_type == 2: # 如果上一个分型为底分型,则进行比较,选取低点更低的分型 if after_fenxing.low[i] >= temp_low:i += 1#                 continueelse:temp_low = after_fenxing.low[i]temp_num = itemp_type = 2i += 4elif temp_type == 1: # 如果上一个分型为顶分型,则记录上一个分型,用当前分型与后面的分型比较,选取同向更极端的分型if temp_high <= after_fenxing.low[i]: # 如果上一个顶分型的底比当前底分型的底低,则跳过当前底分型。i += 1else:fenxing_type.append(1)fenxing_time.append(after_fenxing.index[temp_num].strftime("%Y-%m-%d %H:%M:%S"))fenxing_data = pd.concat([fenxing_data,after_fenxing[temp_num:temp_num+1]],axis = 0)fenxing_plot.append(after_fenxing.low[i])temp_low = after_fenxing.low[i]temp_num = itemp_type = 2i += 4else:temp_low = after_fenxing.low[i]temp_num = itemp_type = 2i += 4else:i += 1
print fenxing_typeprint fenxing_timeprint fenxing_plotfenxing_data
[-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1]
['2015-12-02 09:55:00', '2015-12-02 10:35:00', '2015-12-02 11:20:00', '2015-12-02 13:35:00', '2015-12-02 14:05:00', '2015-12-02 14:30:00', '2015-12-03 09:50:00', '2015-12-03 11:05:00', '2015-12-03 13:30:00', '2015-12-03 14:30:00', '2015-12-04 11:20:00', '2015-12-04 13:25:00']
[12.35, 11.949999999999999, 12.119999999999999, 12.109999999999999, 12.59, 12.25, 12.75, 12.43, 12.699999999999999, 12.26, 12.300000000000001, 12.09]

openclosehighlow
2015-12-02 09:55:0011.7011.7411.7411.70
2015-12-02 10:35:0012.2312.3512.3512.23
2015-12-02 11:20:0011.9512.0012.0011.95
2015-12-02 13:35:0012.1212.0912.1212.09
2015-12-02 14:05:0012.1112.1512.1512.11
2015-12-02 14:30:0012.5912.4712.5912.47
2015-12-03 09:50:0012.3312.2512.3312.25
2015-12-03 11:05:0012.6612.7512.7512.66
2015-12-03 13:30:0012.4312.5012.5012.43
2015-12-03 14:30:0012.5812.7012.7012.58
2015-12-04 11:20:0012.1512.1912.1912.15
2015-12-04 13:25:0012.2412.3012.3012.24

下面画出识别分型之后的走势图!

fig, ax = plt.subplots(figsize = (20,5))dates = fenxing_data.indexax.set_xticklabels(dates) # Label x-axis with datesax.autoscale_view()plt.plot(fenxing_plot,'k', lw=1)plt.plot(fenxing_plot,'o')plt.grid(True)plt.setp(plt.gca().get_xticklabels(), rotation=30)
[None, None, None, None, None, None, None, None]

识别完分型的candle图如下:

分形图

其中黑框为底分型,黄框为顶分型,椭圆为记录的位置,用以跟之后的k线进行比对。

用缠论处理之后,上图符合维克多交易法则上升趋势:维克多

 
分享到:
举报财经168客户端下载

全部回复

0/140

投稿 您想发表你的观点和看法?

更多人气分析师

  • 张亦巧

    人气2152文章4145粉丝45

    暂无个人简介信息

  • 梁孟梵

    人气2152文章3177粉丝39

    qq:2294906466 了解群指导添加微信mfmacd

  • 指导老师

    人气1856文章4423粉丝52

    暂无个人简介信息

  • 李冉晴

    人气2296文章3821粉丝34

    李冉晴,专业现贷实盘分析师。

  • 刘钥钥1

    人气2016文章3119粉丝34

    专业从事现货黄金、现货白银模似实盘操作分析指导

  • 张迎妤

    人气1896文章3305粉丝34

    个人专注于行情技术分析,消息面解读剖析,给予您第一时间方向...

  • 金泰铬J

    人气2320文章3925粉丝51

    投资问答解咨询金泰铬V/信tgtg67即可获取每日的实时资讯、行情...

  • 金算盘

    人气2696文章7761粉丝125

    高级分析师,混过名校,厮杀于股市和期货、证券市场多年,专注...

  • 金帝财神

    人气4736文章8329粉丝118

    本文由资深分析师金帝财神微信:934295330,指导黄金,白银,...