缠论笔的基础就不再为大家阐述了
下面工具展示两种缠论K线 1、用普通K线展示 2、用处理了包含关系的缠论K线展示(强烈推荐)
!!!补充一句,特别感谢我们的缠论张老师 '杀手张一' 为我们提供迭代思路
!!! 硬货来了,2017-06-22 补充了线段,更方便大家查看
================需要修改的参数==============
股票代码, 生成k线的结束日期, 看几天/分钟前的k线,轴展示的时间距离,所看级别,是否是缠论K线
使用方法:1、克隆研究 2、复制my_chan.py 到研究下(创建文件my_chan.py 把代码拷入) 3、修改以上参数 并运行即可
!!!这里最后一段未完成的笔,迭代次级别,如果次级别形成线段,那么此级别就是一笔(对应此级别:日-30分钟-5分钟-1分钟)
这样能够更准确的找到最后一笔下或上,从而找买卖点
!!!这里 K线周期可以看 1d,30m,5m, 1m, 因为最后一笔只迭代了这几个时间段的笔,如果大家需要看其他时间的笔
请注释 代码 line 251:biIdx = con2Cxianduan(stock_code, k_data, chanK, frsBiType, biIdx, end_date, cur_ji) 即可
# 缠论K线图展示完整版
import my_chan as chan
import matplotlib as mat
import numpy as np
import datetime as dt
import matplotlib.pyplot as plt
# bokeh.plotting
import time
from bokeh.models import ColumnDataSource, Rect, HoverTool, Range1d, LinearAxis, WheelZoomTool, PanTool, ResetTool, ResizeTool, PreviewSaveTool
# ================需要修改的参数==============
stock_code = '002560.XSHE' # 股票代码
end_date = '2017-06-22 15:00:00' # 最后生成k线日期
stock_days = 6 # 看几天/分钟前的k线
x_jizhun = 20 #x轴展示的时间距离 5:日,40:30分钟, 48: 5分钟
# stock_frequency = '5m' # 1d日线, 30m 30分钟, 5m 5分钟,1m 1分钟
stock_frequency = '1m' # 1d日线, 30m 30分钟, 5m 5分钟,1m 1分钟
chanK_flag = True# True 看缠论K线, False 看k线
# ============结束==================
initial_trend = "down"
cur_ji = 1 if stock_frequency=='1d' else \
2 if stock_frequency=='30m' else \
3 if stock_frequency=='5m' else 4
print '======笔形成最后一段未完成段判断是否是次级别的走势形成笔======='
def con2Cxianduan(stock, k_data, chanK, frsBiType, biIdx, end_date, cur_ji = 1):
max_k_num = 4
if cur_ji>=4 or len(biIdx)==0: return biIdx
idx = biIdx[len(biIdx)-1]
k_data_dts = list(k_data.index)
st_data = chanK['enddate'][idx]
if st_data not in k_data_dts: return biIdx
# 重构次级别线段的点到本级别的chanK中
def refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji):
new_biIdx = []
biIdxB = biIdx[len(biIdx)-1] if len(biIdx)>0 else 0
for xdIdxcn in xdIdxc:
for chanKidx in range(len(chanK.index))[biIdxB:]:
if judge_day_bao(chanK, chanKidx, chanKc, xdIdxcn, cur_ji):
new_biIdx.append(chanKidx)
break
return new_biIdx
# 判断次级别日期是否被包含
def judge_day_bao(chanK, chanKidx, chanKc, xdIdxcn, cur_ji):
_end_date = chanK['enddate'][chanKidx]+datetime.timedelta(hours=15) if cur_ji==1 else chanK['enddate'][chanKidx]
_start_date = chanK.index[chanKidx] if chanKidx==0\
else chanK['enddate'][chanKidx-1]+datetime.timedelta(minutes=1)
# print '连接包含日期', chanK.index[chanKidx], chanKc.index[xdIdxcn], chanK['enddate'][chanKidx]
return _start_date<=chanKc.index[xdIdxcn]<=_end_date
# cur_ji = 1 #当前级别
#符合k线根数大于4根 1日级别, 2 30分钟, 3 5分钟, 4 一分钟
if len(k_data_dts) - k_data_dts.index(st_data)>4:
frequency = '30m' if cur_ji+1==2 else '5m' if cur_ji+1==3 else '1m'
# print "次级别为:%s"%frequency
# print chanK
k_data_c = get_price(stock, st_data, end_date, frequency=frequency)
chanKc = chan.parse2ChanK(k_data_c, k_data_c.values)
fenTypesc, fenIdxc = chan.parse2ChanFen(chanKc)
if len(fenTypesc)==0: return biIdx
biIdxc, frsBiTypec = chan.parse2ChanBi(fenTypesc, fenIdxc, chanKc)
if len(biIdxc)==0: return biIdx
xdIdxc, xdTypec = chan.parse2Xianduan(biIdxc, chanKc)
biIdxc = chan.con2Cxianduan(stock, k_data_c, chanKc, frsBiTypec, biIdxc, end_date, cur_ji+1)
if len(xdIdxc)==0: return biIdx
# print cur_ji, '次级别线段', xdIdxc, xdTypec
#连接线段位为上级别的bi
lastBiType = frsBiType if len(biIdx)%2==0 else -frsBiType
if len(biIdx)==0:
return refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji)
lastbi = biIdx.pop()
firstbic = xdIdxc.pop(0)
# print '最后一笔下和连段上',lastBiType, xdTypec
# 同向连接
if lastBiType == xdTypec:
print '同向连接'
biIdx = biIdx + refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji)
# 逆向连接
else:
# print '开始逆向连接'
# print chanKc.index[firstbic],len(chanK.index), biIdx[len(biIdx)-1]
# print lastBiType, chanK['low'][lastbi], chanKc['low'][firstbic], chanK['high'][lastbi],chanKc['high'][firstbic]
_mid = [lastbi] if (lastBiType == -1 and chanK['low'][lastbi]<=chanKc['low'][firstbic])\
or (lastBiType == 1 and chanK['high'][lastbi]>=chanKc['high'][firstbic]) else\
[chanKidx for chanKidx in range(len(chanK.index))[biIdx[len(biIdx)-1]:]\
if judge_day_bao(chanK, chanKidx, chanKc, firstbic, cur_ji)]
# print '中间点', _mid
# print '日期比较', '次级别', frequency
# for chanKidx in range(len(chanK.index))[biIdx[len(biIdx)-1]:]:
# print chanK.index[chanKidx], chanKc.index[firstbic],\
# chanK['enddate'][chanKidx], chanK.index[chanKidx]<=chanKc.index[firstbic]<=(chanK['enddate'][chanKidx]\
# if cur_ji>1 else chanK['enddate'][chanKidx]+datetime.timedelta(hours=15))
biIdx = biIdx + [_mid[0]] + refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji)
# print '最后'
return biIdx
'''
以下代码拷贝自https://www.joinquant.com/post/1756
感谢alpha-smart-dog
'''
# dt.datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")-dt.timedelta(days=5)
quotes = get_price(stock_code, datetime.datetime.strptime(end_date, "%Y-%m-%d %H:%M:%S")-datetime.timedelta(days=stock_days) , end_date,\
frequency=stock_frequency,skip_paused=False,fq='pre')
# print quotes
# 缠论k线
quotes = chan.parse2ChanK(quotes, quotes.values) if chanK_flag else quotes
# print quotes
quotes[quotes['volume']==0]=np.nan
quotes= quotes.dropna()
Close=quotes['close']
Open=quotes['open']
High=quotes['high']
Low=quotes['low']
T0 = quotes.index.values
length=len(Close)
# ht = HoverTool(tooltips=[
# ("date", "@date"),
# ("open", "@open"),
# ("close", "@close"),
# ("high", "@high"),
# ("low", "@low"),
# ("volume", "@volume"),
# ("money", "@money"),])
# TOOLS = [ht, WheelZoomTool(dimensions=['width']),\
# ResizeTool(), ResetTool(),\
# PanTool(dimensions=['width']), PreviewSaveTool()]
fig = plt.figure(figsize=(16, 8))
ax1 = plt.subplot2grid((10,4),(0,0),rowspan=10,colspan=4)
#fig = plt.figure()
#ax1 = plt.axes([0,0,3,2])
X=np.array(range(0, length))
pad_nan=X+nan
#计算上 下影线
max_clop=Close.copy()
max_clop[Close<Open]=Open[Close<Open]
min_clop=Close.copy()
min_clop[Close>Open]=Open[Close>Open]
#上影线
line_up=np.array([High,max_clop,pad_nan])
line_up=np.ravel(line_up,'F')
#下影线
line_down=np.array([Low,min_clop,pad_nan])
line_down=np.ravel(line_down,'F')
#计算上下影线对应的X坐标
pad_nan=nan+X
pad_X=np.array([X,X,X])
pad_X=np.ravel(pad_X,'F')
#画出实体部分,先画收盘价在上的部分
up_cl=Close.copy()
up_cl[Close<=Open]=nan
up_op=Open.copy()
up_op[Close<=Open]=nan
down_cl=Close.copy()
down_cl[Open<=Close]=nan
down_op=Open.copy()
down_op[Open<=Close]=nan
even=Close.copy()
even[Close!=Open]=nan
#画出收红的实体部分
pad_box_up=np.array([up_op,up_op,up_cl,up_cl,pad_nan])
pad_box_up=np.ravel(pad_box_up,'F')
pad_box_down=np.array([down_cl,down_cl,down_op,down_op,pad_nan])
pad_box_down=np.ravel(pad_box_down,'F')
pad_box_even=np.array([even,even,even,even,pad_nan])
pad_box_even=np.ravel(pad_box_even,'F')
#X的nan可以不用与y一一对应
X_left=X-0.25
X_right=X+0.25
box_X=np.array([X_left,X_right,X_right,X_left,pad_nan])
# print box_X
box_X=np.ravel(box_X,'F')
# print box_X
#Close_handle=plt.plot(pad_X,line_up,color='k')
vertices_up=array([box_X,pad_box_up]).T
vertices_down=array([box_X,pad_box_down]).T
vertices_even=array([box_X,pad_box_even]).T
handle_box_up=mat.patches.Polygon(vertices_up,color='r',zorder=1)
handle_box_down=mat.patches.Polygon(vertices_down,color='g',zorder=1)
handle_box_even=mat.patches.Polygon(vertices_even,color='k',zorder=1)
ax1.add_patch(handle_box_up)
ax1.add_patch(handle_box_down)
ax1.add_patch(handle_box_even)
handle_line_up=mat.lines.Line2D(pad_X,line_up,color='k',linestyle='solid',zorder=0)
handle_line_down=mat.lines.Line2D(pad_X,line_down,color='k',linestyle='solid',zorder=0)
ax1.add_line(handle_line_up)
ax1.add_line(handle_line_down)
v=[0,length,Open.min()-0.5,Open.max()+0.5]
plt.axis(v)
T1 = T0[-len(T0):].astype(dt.date)/1000000000
# print T1
Ti=[]
for i in range(len(T0)/x_jizhun):
a=i*x_jizhun
d = dt.date.fromtimestamp(T1[a])
# print d
T2=d.strftime('$%Y-%m-%d$')
Ti.append(T2)
#print tab
d1= dt.date.fromtimestamp(T1[len(T0)-1])
d2=(d1+datetime.timedelta(days=1)).strftime('$%Y-%m-%d$')
Ti.append(d2)
ax1.set_xticks(np.linspace(-2,len(Close)+2,len(Ti)))
ll=Low.min()*0.97
hh=High.max()*1.03
ax1.set_ylim(ll,hh)
ax1.set_xticklabels(Ti)
plt.grid(True)
plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
'''
以上代码拷贝自https://www.joinquant.com/post/1756
感谢alpha-smart-dog
K线图绘制完毕
'''
x_date_list = quotes.index.values.tolist()
# for x_date in x_date_list:
# d = datetime.datetime.fromtimestamp(x_date/1000000000)
# print d.strftime("%Y-%m-%d %H:%M:%S.%f")
# print x_date_list
k_data = quotes
k_values = k_data.values
# 缠论k线
chanK = quotes if chanK_flag else chan.parse2ChanK(k_data, k_values)
fenTypes, fenIdx = chan.parse2ChanFen(chanK)
# print "分型", fenTypes, fenIdx
biIdx, frsBiType = chan.parse2ChanBi(fenTypes, fenIdx, chanK)
# biIdx = con2Cxianduan(stock_code, k_data, chanK, frsBiType, biIdx, end_date, cur_ji)
# print chanK
print "笔", biIdx, frsBiType
print '股票代码', get_security_info(stock_code).display_name
# 3.得到分笔结果,计算坐标显示
x_fenbi_seq = []
y_fenbi_seq = []
for i in range(len(biIdx)):
if biIdx[i]:
fenType = -frsBiType if i%2==0 else frsBiType
# dt = chanK['enddate'][biIdx[i]]
# 缠论k线
dt = chanK.index[biIdx[i]] if chanK_flag else chanK['enddate'][biIdx[i]]
# print k_data['high'][dt], k_data['low'][dt]
time_long = long(time.mktime((dt+datetime.timedelta(hours=8)).timetuple())*1000000000)
# print x_date_list.index(time_long) if time_long in x_date_list else 0
if fenType == 1:
plt.text(x_date_list.index(time_long), k_data['high'][dt], \
str(k_data['high'][dt]), ha='left', fontsize=12)
x_fenbi_seq.append(x_date_list.index(time_long))
y_fenbi_seq.append(k_data['high'][dt])
if fenType == -1:
plt.text(x_date_list.index(time_long), k_data['low'][dt], \
str(k_data['low'][dt]), va='bottom', fontsize=12)
x_fenbi_seq.append(x_date_list.index(time_long))
y_fenbi_seq.append(k_data['low'][dt])
# bottom_time = None
# for k_line_dto in m_line_dto.member_list[::-1]:
# if k_line_dto.low == m_line_dto.low:
# # get_price返回的日期,默认时间是08:00:00
# bottom_time = k_line_dto.begin_time.strftime('%Y-%m-%d') +' 08:00:00'
# break
# x_fenbi_seq.append(x_date_list.index(long(time.mktime(datetime.strptime(bottom_time, "%Y-%m-%d %H:%M:%S").timetuple())*1000000000)))
# y_fenbi_seq.append(m_line_dto.low)
# 在原图基础上添加分笔蓝线
plt.plot(x_fenbi_seq,y_fenbi_seq)
#线段画到笔上
xdIdxs,xfenTypes = chan.parse2ChanXD(frsBiType,biIdx,chanK)
print '线段', xdIdxs,xfenTypes
x_xd_seq = []
y_xd_seq = []
for i in range(len(xdIdxs)):
if xdIdxs[i]:
fenType = xfenTypes[i]
# dt = chanK['enddate'][biIdx[i]]
# 缠论k线
dt = chanK.index[xdIdxs[i]] if chanK_flag else chanK['enddate'][xdIdxs[i]]
# print k_data['high'][dt], k_data['low'][dt]
time_long = long(time.mktime((dt+datetime.timedelta(hours=8)).timetuple())*1000000000)
# print x_date_list.index(time_long) if time_long in x_date_list else 0
if fenType == 1:
x_xd_seq.append(x_date_list.index(time_long))
y_xd_seq.append(k_data['high'][dt])
if fenType == -1:
x_xd_seq.append(x_date_list.index(time_long))
y_xd_seq.append(k_data['low'][dt])
# bottom_time = None
# for k_line_dto in m_line_dto.member_list[::-1]:
# if k_line_dto.low == m_line_dto.low:
# # get_price返回的日期,默认时间是08:00:00
# bottom_time = k_line_dto.begin_time.strftime('%Y-%m-%d') +' 08:00:00'
# break
# x_fenbi_seq.append(x_date_list.index(long(time.mktime(datetime.strptime(bottom_time, "%Y-%m-%d %H:%M:%S").timetuple())*1000000000)))
# y_fenbi_seq.append(m_line_dto.low)
# 在原图基础上添加分笔蓝线
plt.plot(x_xd_seq,y_xd_seq)
plt.show()
# 在原图基础上添加分笔蓝线
# plt.plot(x_fenbi_seq,y_fenbi_seq)
# plt.show()
======笔形成最后一段未完成段判断是否是次级别的走势形成笔======= 笔 [2, 10, 17, 48, 53, 64, 68, 72, 76, 88, 94, 103, 109, 127, 158, 178, 183, 194, 221, 229, 235, 239, 249, 254, 261, 265, 270, 281, 290] 1 股票代码 通达股份 线段 [2, 127, 221, 254, 290] [-1, 1, -1, 1, -1]
# coding=utf-8
# 研究中创建my_chan.py 拷贝此代码即可
import pandas as pd
import numpy as np
import datetime
# 处理k线成缠论k线,临时函数
def parse2ChanKTMP(k_data, k_values, in_chan = False):
baohan_columns = ['enddate'] + list(k_data.keys()) if not in_chan else list(k_data.keys())
# print baohan_columns
dfbao = pd.DataFrame(np.zeros(len(k_data.index)*len(baohan_columns)).reshape(len(k_data.index),len(baohan_columns)), index = k_data.index,columns=baohan_columns)\
if not in_chan else k_data
# print dfbao
# stdt = k_data.index[0]
# dfbao.set_value(stdt, baohan_columns, [stdt] + list(k_data.values[0]))
# 比较上一个包含的时间点
dt_bf = 0
def set_baohan_value(dt, value):
dfbao.set_value(dt, baohan_columns, value)
return dt
for i, dt in enumerate(k_data.index):
if i==0:
dt_bf = set_baohan_value(dt, [dt] + list(k_values[i])) if not in_chan else dt
continue
if in_chan and (k_data['enddate'][dt]==0 or i==0): continue
# 非包含情况
if (k_data['high'][dt]>dfbao['high'][dt_bf] and k_data['low'][dt]>dfbao['low'][dt_bf])\
or (k_data['high'][dt]<dfbao['high'][dt_bf] and k_data['low'][dt]<dfbao['low'][dt_bf]):
if in_chan:
dt_bf = dt
continue
dt_bf = set_baohan_value(dt, [dt] + list(k_values[i]))
continue
# 包含情况
enddate = dt if not in_chan else dfbao['enddate'][dt]
dt_bf = set_baohan_value(dt_bf, \
[enddate, dfbao['open'][dt_bf], k_data['close'][dt], \
max(k_data['high'][dt], dfbao['high'][dt_bf]), \
min(k_data['low'][dt], dfbao['low'][dt_bf]), \
k_data['volume'][dt]+dfbao['volume'][dt_bf], \
k_data['money'][dt]+dfbao['money'][dt_bf]])
if in_chan:
dfbao.set_value(dt, ['enddate'], 0)
dfbao = dfbao[dfbao['enddate']!=0]
return dfbao
# 处理k线成缠论k线
def parse2ChanK(k_data, k_values):
chanK = parse2ChanKTMP(k_data, k_values)
while True:
chanK1 = parse2ChanKTMP(chanK, chanK.values, True)
if(len(chanK.index)==len(chanK1.index)):
break
chanK = chanK1
return chanK
# chanK = parse2ChanK(k_data, k_values)
# print chanK
# 找顶底分型的idx
# 如果 连续顶顶,或底底: 顶:high最大的顶, 低:low最小的低
# 顶:1 低:-1
def parse2ChanFen(chanK):
fenTypes = [] # 分型类型数组 1,-1构成
fenIdx = [] # 分型对应缠论k的下标
# 添加分型数据
# 过滤连续同分型
def appendFen(ft, fidx):
if len(fenIdx)==0:
fenTypes.append(ft)
fenIdx.append(fidx)
return
fenType_bf = fenTypes[len(fenTypes)-1]
if fenType_bf == ft:
fenType_bf, fenIdx_bf = fenTypes.pop(), fenIdx.pop()
fidx = fenIdx_bf if (ft==1 and chanK['high'][fenIdx_bf]>chanK['high'][fidx])\
or (ft==-1 and chanK['low'][fenIdx_bf]<chanK['low'][fidx]) else fidx
fenTypes.append(ft)
fenIdx.append(fidx)
for i, dt in enumerate(chanK.index):
if i==0 or i==len(chanK.index)-1:continue
# 顶分型
if chanK['high'][i+1]<chanK['high'][i]>chanK['high'][i-1]:
appendFen(1, i)
# 底分型
if chanK['low'][i+1]>chanK['low'][i]<chanK['low'][i-1]:
appendFen(-1, i)
return fenTypes, fenIdx
# fenTypes, fenIdx = parse2ChanFen(chanK)
# print fenTypes, fenIdx
# 分型构成笔
# 构成笔条件,1、顶低分型间隔了n个chanK线, 2、中间不会出现比第一个分型结构更高(顶)或更低(底)的分型,否则线段破坏,连接上一笔
def parse2ChanBi(fenTypes, fenIdx, chanK):
biIdx = [] # 笔对应的缠论k线 idx
frsBiType = 0 # 起始笔的走势,biIdx 奇数下标就是相反走势 1、向上,-1向下
least_khl_num = 3 # 分笔间隔的最小 chanK 数量 中间排除顶低的chanK
toConBfIdx = 0 # 连接到上一笔末尾的 分型idx
# 判断笔破坏
def judgeBiBreak(idxb, idxa):
fenType = fenTypes[idxb]
fenType1 = -fenType
# print '分型破坏前', fenType, fenIdx[idxb], fenIdx[idxa]
_break = False
_breaki_k = 0
_breakj_k = 0
for k in range(idxb, idxa)[2::2]:
# 当前i分型破坏
if judgeBreak(fenType, fenIdx[idxb], fenIdx[k]):
# print '首分型破坏里', fenType, fenIdx[idxb], fenIdx[k], k
_break, _breaki_k = True, k
break
for k in range(idxb, idxa)[1::2]:
# 末尾j分型破坏
if judgeBreak(fenType1, fenIdx[idxa], fenIdx[k]):
# print '末尾分型破坏里', fenType1, fenIdx[k], fenIdx[idxa],
_break, _breakj_k = True, k
break
# print '破坏结果', _break, fenIdx[_breaki_k], fenIdx[_breakj_k]
return _break, _breaki_k, _breakj_k
# 分型破坏
def judgeBreak(fenType, bf, af):
return (fenType==-1 and chanK['low'][af]<chanK['low'][bf])\
or (fenType==1 and chanK['high'][af]>chanK['high'][bf])
def reAssignBi(biIdx, breakBi, breakBj, i, j):
toConBfIdx = i+1 if len(biIdx)==0 else breakBi
if breakBi>0 and len(biIdx)>0:
fb_ = biIdx.pop()
# print '首分型破坏, 旧分型:%d, 新的分型:%d'%(fb_,fenIdx[breakBi])
biIdx.append(fenIdx[breakBi])
if 0<breakBj<breakBi and judgeBreak(fenTypes[i-1], biIdx[len(biIdx)-2], fenIdx[breakBj]):
fa_=biIdx.pop()
fb_=biIdx.pop()
# print '尾分型破坏并连接上一点, 移除分型:%d,旧分型:%d, 新的分型:%d'%(fa_, fb_,fenIdx[breakBj])
biIdx.append(fenIdx[breakBj])
toConBfIdx = breakBj
return toConBfIdx, -1 # -1:break 1:continue 0:不执行
if breakBj>0:
# breakBj = breakBj1 if breakBj==-1 or judgeBreak(fenTypes[i-1], fenIdx[breakBj], fenIdx[breakBj1]) else breakBj
if j+2>=len(fenIdx) and len(biIdx)>1 and\
judgeBreak(fenTypes[i-1], biIdx[len(biIdx)-2], fenIdx[breakBj]):
fa_=biIdx.pop()
fb_=biIdx.pop()
# print '尾分型破坏并连接上一点, 移除分型:%d,旧分型:%d, 新的分型:%d'%(fa_, fb_,fenIdx[breakBj])
biIdx.append(fenIdx[breakBj])
toConBfIdx = breakBj
return toConBfIdx, -1 # -1:break 1:continue 0:不执行
return toConBfIdx, 1 # -1:break 1:continue 0:不执行
return toConBfIdx, 0 # -1:break 1:continue 0:不执行
for i, kidx in enumerate(fenIdx):
# print '生成的笔', biIdx
# print toConBfIdx, 'the i is ', i
if i<toConBfIdx or i==len(fenIdx)-1 : continue
# 后面没有符合条件的笔
if len(biIdx)>1 and toConBfIdx==0:break
toConBfIdx = 0
for j in range(len(fenIdx))[i+1::2]:
# print '差是', fenIdx[j]-kidx
if (fenIdx[j]-kidx)>least_khl_num:
# print 'append', i, j, fenIdx[i], fenIdx[j]
# breakType True 同分型, False 末尾分型
flag, breakBi, breakBj = judgeBiBreak(i, j)
# print flag, breakBi
if flag:
toConBfIdx, _bcn = reAssignBi(biIdx, breakBi, breakBj, i, j)
if _bcn==-1:break
if _bcn==1:continue
if len(biIdx)==0:
biIdx.append(kidx)
frsBiType = -fenTypes[i]
biIdx.append(fenIdx[j])
toConBfIdx, _bcn = reAssignBi(biIdx, breakBi, breakBj, i, j)
if _bcn==-1 or _bcn==1:
biIdx = []
toConBfIdx = i+1
break
toConBfIdx = j
break
biIdx.append(fenIdx[j])
# print biIdx
toConBfIdx = j
# print toConBfIdx
break
return biIdx, frsBiType
#最终线段生成
#1、遍历相对高低点,判断线段破坏,
# 破坏以后,如果总长度是0,i可以后移,否则重构之前的线段
# 重构规则,找破坏点相对高点/低点,如果存在线段高点/低点>/<破坏高点/低点, 则连接此线段
#2、形成线段中间至少有两点j-i>2
def parse2ChanXD(frsBiType,biIdx,chanK):
lenBiIdx = len(biIdx)
xdIdx = []
xfenTypes = []
if lenBiIdx==0 : return xdIdx,xfenTypes
afIdx = 0
#重构线段
def refactorXd(txIdx, nxIdx, chanK):
xdIdxn = xdIdx
xfenTypesn = xfenTypes
if len(xdIdxn)==0 or txIdx==-1 or nxIdx==-1: return 0,xdIdxn,xfenTypesn
for m in range(-len(xdIdxn)+1, 1)[1::2]:
k = -m
#满足逆向不破坏
# print '开始逆向破坏:逆向分型,逆向点,线段点', xfenTypesn[k], nxIdx, xdIdxn[k]
if (xfenTypesn[k]==-1 and chanK['low'][xdIdxn[k]]<chanK['low'][nxIdx])\
or (xfenTypesn[k]==1 and chanK['high'][xdIdxn[k]]>chanK['high'][nxIdx]):
for n in range(-len(xdIdxn)+1, m):
xfenTypesn.pop()
xdIdxn.pop()
xdIdxn.append(txIdx)
xfenTypesn.append(-xfenTypesn[len(xfenTypes)-1])
return biIdx.index(txIdx), xdIdxn, xfenTypesn
xdIdxn = []
xfenTypesn = []
# print '逆向破坏', nxIdx, xdIdxn, xfenTypesn
return biIdx.index(nxIdx), xdIdxn, xfenTypesn
# 判断线段破坏
def judgeBreak(fenType, afPrice, idx, chanK):
return (fenType==-1 and afPrice<chanK['low'][idx]) \
or (fenType==1 and afPrice>chanK['high'][idx])
for i, idx in enumerate(biIdx):
if afIdx < 0 :break # 线段破坏以后没有合适线段
fenType = 1 if (frsBiType==1 and i%2==1) or (frsBiType==-1 and i%2==0) \
else -1
# print '开始判断%d,分型类型%d'%(idx, fenType)
#符合要求的连段
if i<afIdx:continue
#找同向相对高低点
afPrice = 0 if fenType==-1 else 10000
tongxiang_price_ = 10000 - afPrice
nixiang_idx, tongxiang_idx = -1, -1
i_continued = False
for j in range(i+1, lenBiIdx)[0::2]:
#同向相对高低点
if (fenType==-1 and tongxiang_price_>chanK['low'][biIdx[j-1]]) \
or (fenType==1 and tongxiang_price_<chanK['high'][biIdx[j-1]]):
tongxiang_price_ = chanK['high'][biIdx[j-1]] if fenType==1 else chanK['low'][biIdx[j-1]]
tongxiang_idx = biIdx[j-1]
#线段破坏
# print '线段破坏前', idx, tongxiang_idx
#同向破坏
if judgeBreak(fenType, tongxiang_price_, idx, chanK) and idx!=tongxiang_idx:
# print '同向已经破坏'
afIdx, xdIdx, xfenTypes = refactorXd(tongxiang_idx, nixiang_idx, chanK)
i_continued = True
break
# print '符合要求前', biIdx[i], biIdx[j], afPrice, chanK['high'][biIdx[j]], chanK['low'][biIdx[j]],fenType
if (fenType==-1 and chanK['high'][biIdx[j]]>afPrice) or (fenType==1 and chanK['low'][biIdx[j]]<afPrice):
afPrice = chanK['high'][biIdx[j]] if fenType==-1 else chanK['low'][biIdx[j]]
nixiang_idx = biIdx[j]
#线段不符合要求
# print '符合要求的i,j', biIdx[i], biIdx[j]
if j-i<=2:continue
#逆向破坏
# if judgeBreak(-fenType, nixiang_idx, idx, chanK) and idx!=nixiang_idx:
# # print '逆向已经破坏'
# afIdx, xdIdx, xfenTypes = refactorXd(tongxiang_idx, nixiang_idx, chanK)
# break
if len(xdIdx)==0:
# print '线段长度为0破坏', fenType, idx, judgeBreak(fenType, tongxiang_price_, idx, chanK)
if judgeBreak(fenType, tongxiang_price_, idx, chanK):
i_continued = True
break
xfenTypes.append(fenType)
xdIdx.append(idx)
xdIdx.append(biIdx[j])
xfenTypes.append(-fenType)
else:
#不用同向线段连接
# fenTypeb = xfenTypes[len(xfenTypes)-1]
# xdIdxb = xdIdx.pop()
# if fenTypeb == -fenType:
# xdIdx.append(biIdx[j])
# else:
# xdIdx.append(xdIdxb)
# xfenTypes.append(-fenTypeb)
# xdIdx.append(biIdx[j])
xfenTypes.append(-xfenTypes[len(xfenTypes)-1])
xdIdx.append(biIdx[j])
afIdx = j
i_continued = True
break
else:continue
if not i_continued and len(xdIdx)>0 :
#都不符合要求时,最后重构最小线段
last_idx = xdIdx.pop()
last_type = xfenTypes[len(xfenTypes)-1]
for j in range(biIdx.index(last_idx), len(biIdx))[2::2]:
if judgeBreak(last_type, chanK['low'][biIdx[j]] if last_type==-1 else chanK['high'][biIdx[j]], last_idx, chanK):
last_idx = biIdx[j]
xdIdx.append(last_idx)
break
return xdIdx,xfenTypes
# biIdx, frsBiType = parse2ChanBi(fenTypes, fenIdx, chanK)
# print biIdx,frsBiType
#简单线段形成,主要用于判断是否是大级别的笔
#区间找高低点,判断是否符合 高低点中包含>2个笔点就阔以
def parse2Xianduan(biIdx, chanK):
xdIdx = []
if len(biIdx)==0: return xdIdx, 0
def appendXd(lowIdx, highIdx, xdType):
if len(xdIdx)==0:
if xdType == 1:
xdIdx.append(lowIdx)
else:
xdIdx.append(highIdx)
if (xdType == 1 and len(xdIdx)%2==1) or (xdType == -1 and len(xdIdx)%2==0):
xdIdx.append(highIdx)
else:
xdIdx.append(lowIdx)
def genXianduan(biIdx, chanK, xdType=0):
highMax, lowMin = 0, 10000
highIdx, lowIdx = -1,-1
lenXd = len(xdIdx)
for idx in biIdx:
if chanK['high'][idx]>highMax:
highMax = chanK['high'][idx]
highIdx = idx
if chanK['low'][idx]<lowMin:
lowMin = chanK['low'][idx]
lowIdx = idx
# 构成简易线段
# print biIdx, xdIdx, lowIdx, highIdx
xdDiff = biIdx.index(lowIdx)-biIdx.index(highIdx)
if abs(xdDiff)>2:
if lenXd==0:
xdType = 1 if xdDiff<0 else -1
appendXd(lowIdx, highIdx, xdType)
# print lowIdx, highIdx, xdIdx
genXianduan(biIdx[biIdx.index(xdIdx[len(xdIdx)-1]):], chanK, xdType)
return xdType
xdType = genXianduan(biIdx, chanK)
return xdIdx,xdType
# 笔形成最后一段未完成段判断是否是次级别的走势形成笔
def con2Cxianduan(stock, k_data, chanK, frsBiType, biIdx, end_date, cur_ji = 1):
max_k_num = 4
if cur_ji>=4 or len(biIdx)==0: return biIdx
idx = biIdx[len(biIdx)-1]
k_data_dts = list(k_data.index)
st_data = chanK['enddate'][idx]
if st_data not in k_data_dts: return biIdx
# 重构次级别线段的点到本级别的chanK中
def refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji):
new_biIdx = []
biIdxB = biIdx[len(biIdx)-1] if len(biIdx)>0 else 0
for xdIdxcn in xdIdxc:
for chanKidx in range(len(chanK.index))[biIdxB:]:
if judge_day_bao(chanK, chanKidx, chanKc, xdIdxcn, cur_ji):
new_biIdx.append(chanKidx)
break
return new_biIdx
# 判断次级别日期是否被包含
def judge_day_bao(chanK, chanKidx, chanKc, xdIdxcn, cur_ji):
_end_date = chanK['enddate'][chanKidx]+datetime.timedelta(hours=15) if cur_ji==1 else chanK['enddate'][chanKidx]
_start_date = chanK.index[chanKidx] if chanKidx==0\
else chanK['enddate'][chanKidx-1]+datetime.timedelta(minutes=1)
return _start_date<=chanKc.index[xdIdxcn]<=_end_date
# cur_ji = 1 #当前级别
#符合k线根数大于4根 1日级别, 2 30分钟, 3 5分钟, 4 一分钟
if len(k_data_dts) - k_data_dts.index(st_data)>4:
frequency = '30m' if cur_ji+1==2 else '5m' if cur_ji+1==3 else '1m'
k_data_c = get_price(stock, st_data, end_date, frequency=frequency)
chanKc = parse2ChanK(k_data_c, k_data_c.values)
fenTypesc, fenIdxc = parse2ChanFen(chanKc)
if len(fenTypesc)==0: return biIdx
biIdxc, frsBiTypec = parse2ChanBi(fenTypesc, fenIdxc, chanKc)
if len(biIdxc)==0: return biIdx
xdIdxc, xdTypec = parse2Xianduan(biIdxc, chanKc)
biIdxc = con2Cxianduan(stock, k_data_c, chanKc, frsBiTypec, biIdxc, end_date, cur_ji+1)
if len(xdIdxc)==0: return biIdx
# 连接线段位为上级别的bi
lastBiType = frsBiType if len(biIdx)%2==0 else -frsBiType
if len(biIdx)==0:
return refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji)
lastbi = biIdx.pop()
firstbic = xdIdxc.pop(0)
# 同向连接
if lastBiType == xdTypec:
biIdx = biIdx + refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji)
# 逆向连接
else:
# print '开始逆向连接'
_mid = [lastbi] if (lastBiType == -1 and chanK['low'][lastbi]<=chanKc['low'][firstbic])\
or (lastBiType == 1 and chanK['high'][lastbi]>=chanKc['high'][firstbic]) else\
[chanKidx for chanKidx in range(len(chanK.index))[biIdx[len(biIdx)-1]:]\
if judge_day_bao(chanK, chanKidx, chanKc, firstbic, cur_ji)]
biIdx = biIdx + [_mid[0]] + refactorXd(biIdx, xdIdxc, chanK, chanKc, cur_ji)
return biIdx
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程