请帮恢复市场近期100日的波动率图(帮修缮恢复)
由shiguang016713_2创建,最终由shiguang016713_2 被浏览 1 用户
coding:utf-8
import talib import numpy as np import matplotlib.pyplot as plt import mpl_finance as mpf import datetime
DAYS = 100 # 选取天数 EndDate = '' # 结束时间
downlist=[] downlist_indx=[] downlist_indx_w=[]
def signal(close_list): close = close_list UP = 0 DOWN = 0 cond = 1 i = 0 while i < 2: if close[-cond] != close[-(cond+1)]: i += 1 cond += 1 A1 = abs(close[-1]-close[-2]) <= 0 A2 = (close[-1] > close[-2] and close[-2] < close[-3] and close[-3] <= close[-4] and close[-1] <= max(close[-3], close[-4])) A3 = (close[-1] > close[-2] and close[-2] < close[-cond] and close[-1] <= close[-cond]) A4 = (close[-1] > close[-2] and close[-2] > close[-3] and close[-3] < close[-4] and close[-1] <= close[-4]) A5 = close[-1] >= close[-4] and close[-1] < close[-2] and close[-2] > close[-3] and close[-3] < close[-4] B1 = (abs(close[-1]-close[-2]) <= 0) B2 = ((close[-1] < close[-2] and close[-2] > close[-3] and close[-3] >= close[-4] and close[-1] >= min(close[-3], close[-4]))) B3 = ((close[-1] < close[-2] and close[-2] > close[-cond] and close[-1] >= close[-cond])) B4 = ((close[-1] < close[-2] and close[-2] < close[-3] and close[-3] > close[-4] and close[-1] >= close[-4])) B5 = (close[-1] <= close[-4] and close[-1] > close[-2] and close[-2] < close[-3] and close[-3] > close[-4]) if A1 or A2 or A3 or A4 or A5: UP = 1 if B3 or B1 or B2 or B4 or B5: DOWN = 1 return UP, DOWN
def last_days(date_list,start_date): tradedays = [D.trading_days(start_date=start_date, end_date=end_date)['date'].tolist()[-2].date() for end_date in date_list] return tradedays
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
ivx = m11.data.read_df()
创建图像和子图
fig = plt.figure(figsize=(20, 9.5),dpi=160)
left, bottom, width, height (range 0 to 1)
ax1 = fig.add_axes([0, 0.3, 1, 0.7]) ax2 = fig.add_axes([0, 0, 1, 0.3]) # inset axes
ivx = ivx[['date', 'open', 'high', 'low', 'close']]
#ivx = ivx.append({'date':'2019-05-31','open':22.19,'high':22.49,'low':21.74,'close':22.37},ignore_index=True)
ivx['date'] = ivx['date'].map(lambda x: datetime.datetime.strptime(x,"%Y-%m-%d"))
if EndDate == '': pass else: ivx=ivx[ivx['date']<=datetime.datetime.strptime(EndDate,"%Y-%m-%d")]
data_w = ivx.set_index('date')
Close_w = data_w['close'].resample('W', label='right', how='last')
Close_w = data_w['close'].resample('W', label='right').last() Close_w.index = Close_w.index.map(lambda x: x.date()) ivx['date'] = ivx['date'].map(lambda x: x.date())
ivx = ivx.set_index('date')
temp = ivx['close'].tail(int(DAYS1.5)).tolist() open_1 = ivx['open'].tail(int(DAYS1.5)).tolist() high = ivx['high'].tail(int(DAYS1.5)).tolist() low = ivx['low'].tail(int(DAYS1.5)).tolist()
取出通达信画图所需要的数据
"""
34天内的最高价减去单日收盘价的差值除以34天内的最高价与34天的最低价的差乘以-100 的19日平均
A:=MA(-100*(HHV(HIGH,34)-CLOSE)/(HHV(HIGH,34)-LLV(LOW,34)),19);
14天内的最高价减去当日收盘价的差值除以14日的最高价减去14日内的最低价
B:=-100*(HHV(HIGH,14)-CLOSE)/(HHV(HIGH,14)-LLV(LOW,14));
若Y=EMA(X,N) 则Y=[2*X+(N-1)*Y']/(N+1),其中Y'表示上一周期Y值。
D:=2*(-100*(HHV(HIGH,34)-CLOSE)/(HHV(HIGH,34)-LLV(LOW,34))单日+3*上一日); """ ivx['hhv_34'] = ivx['high'].rolling(34).max() # 34天内最高价 验证了没有问题 ivx['llv_34'] = ivx['low'].rolling(34).min() # 34天内最低价 对 ivx['hhv_14'] = ivx['high'].rolling(14).max() # 14天内最高价 对 ivx['llv_14'] = ivx['low'].rolling(14).min() # 14天内最低价 对
ivx['line_B'] = (-100*(ivx['hhv_14']-ivx['close']) / (ivx['hhv_14']-ivx['llv_14'])) + 100 # B线的值,短期线 对 ivx['line_AP'] = -100*(ivx['hhv_34']-ivx['close']) / (ivx['hhv_34']-ivx['llv_34']) # AD线的基础值 对 ivx['line_A'] = ivx['line_AP'].rolling(19).mean() + 100 # A线,长期线 对
ivx['line_D'] = pd.ewma(ivx['line_AP'], span=4) + 100 # D线,中期线 对
ivx['line_D'] = ivx['line_AP'].ewm(span=4).mean() + 100 # D线,中期线 对 CZQ = ivx['line_A'].tail(DAYS) ZZQ = ivx['line_D'].tail(DAYS) DZQ = ivx['line_B'].tail(DAYS) close_price = ivx['close'].tail(DAYS) # 收盘价格数据选取 dates = ivx.index.tolist()[-DAYS:] Close_w = Close_w.tail(int(DAYS*1.5)) Close_w.dropna(inplace=True) data = ivx.tail(DAYS)
k 线
mpf.candlestick2_ochl(ax1, data['open'], data['close'], data['high'], data['low'], width=0.5, colorup='r', colordown='g', alpha=0.9) Up = [] Down = [] Up_w = [] Down_w = []
print(Close_w)
for j in range(DAYS): Close = temp[0:len(temp)-j] Close_w_1 = Close_w[Close_w.index < dates[len(dates)-j-1]].tolist() Close_w_1.append(Close[-1])
up, down = signal(Close)
if up:
Up.append(j)
if down:
Down.append(j)
up_w, down_w = signal(Close_w_1)
if up_w:
Up_w.append(j)
if down_w:
Down_w.append(j)
for i in Up: ax1.arrow(x=-i+DAYS-1, y=low[-i-1]-1.2, dx=0, dy=0.8, width=0.2, facecolor='r', edgecolor='r', head_length=0.3, length_includes_head=True)
for i in Down: ax1.arrow(x=-i+DAYS-1, y=high[-i-1]+1.2, dx=0, dy=-0.8, width=0.2, facecolor='g', edgecolor='g', head_length=0.3, length_includes_head=True) downlist_indx.append(-i+DAYS-1)
print('down:%d'%(dates[-i+DAYS-1]))
for i in Up_w: ax1.arrow(x=-i+DAYS-1, y=low[-i-1]-5.5, dx=0, dy=1.2, width=0.2, facecolor='w', edgecolor='r', head_length=0.3, length_includes_head=True)
print('down:%d'%(dates[-i+DAYS-1])
for i in Down_w: ax1.arrow(x=-i+DAYS-1, y=high[-i-1]+5.5, dx=0, dy=-1.2, width=0.2, facecolor='w', edgecolor='g', head_length=0.3, length_includes_head=True)
print(dates[-i+DAYS-1])
downlist_indx_w.append(-i+DAYS-1)
AICD = m1.data_1.read_df() AICD = AICD[AICD['direction']=='买'] AICD = AICD.date.tolist()
本代码由可视化策略环境自动生成 2019年1月27日 11:09
本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
AICD_today = m5.data_1.read_df() AICD_today = AICD_today[AICD_today['direction']=='买'] AICD_today = list(set(AICD_today['date'].tolist())) AICD_today = [datetime.datetime.strptime(i,'%Y-%m-%d').date() for i in AICD_today] AICD = list(set(AICD)) start_date = (datetime.datetime.strptime(min(AICD),'%Y-%m-%d').date()-datetime.timedelta(days=30)).strftime('%Y-%m-%d')
AICD_1 = last_days(AICD,start_date) AICD_1 = AICD_1 + AICD_today
len_high = len(high) AICD_1 = [dates.index(i) for i in AICD_1 if i in dates]
\
print("AICD_today : "+ AICD_today)
print("AICD:\n" + AICD +"\n")
print( dates )
AICD_y = [high[len_high+i-DAYS]+2.75 for i in AICD_1] ax1.scatter(AICD_1, AICD_y)
x = np.linspace(0, DAYS-1, DAYS) b = 0x+10 # 底部的线,颜色CC6633 d = 0x+90 # 顶部的线,颜色9966FF,线宽2 c80 = 0x+80 # 中间80线,颜色COLOR996699; c50 = 0x+50 # 中间50线,颜色红色 c20 = 0*x+20 # 中间20线,颜色绿色 """ 长期线:A+100,COLOR9900FF;短期线:B+100,COLOR888888;中期线:D+100,COLORYELLOW,LINETHICK2; """ l1, = ax2.plot(x, b, color="#CC6633", linewidth=4.0) l2, = ax2.plot(x, d, color="#9966FF", linewidth=4.0) l3, = ax2.plot(x, c80, color="#996699") l4, = ax2.plot(x, c50, color="green") l5, = ax2.plot(x, c20, color="red") l6, = ax2.plot(x, data['line_A'], color="#9900FF") l7, = ax2.plot(x, data['line_B'], color="#888888") l8, = ax2.plot(x, data['line_D'], color="yellow", linewidth=4.0) ax2.legend(handles=[l1, l2, l3, l4, l5, l6, l7, l8, ], labels=[u'10:', '90:', '80:', '50:', '20:', u'Long period:', u'Short period:', u'Middle period:'], loc='upper left', ncol=8, markerfirst=False, fontsize='18', frameon=True, edgecolor='black', borderaxespad=0.2)
#输出scatter的日期 print('输出dot的日期:') AICD_list = [] dateIndx = AICD_1.copy() dateIndx_sort = AICD_1.copy()
print(dateIndx)
dateIndx_sort.sort()
print(dateIndx_sort)
print(dateIndx)
print(AICD_1)
for i in dateIndx_sort: AICD_list.append(dates[i]) #显示scatter的日期 print(dates[i])
print( "AICD_list\n" )
print( AICD_list )
#输出downArrow的日期 print('输出downArrow的日期:') downlist_indx.sort() downlist_indx_w.sort()
print(downlist_indx)
print(downlist_indx_w)
for i in downlist_indx: downlist.append(dates[i]) print(dates[i])
\
下面开始进行信号的绘制,条件如下:
""" 已完成,主要是进行信号的绘制。 """ for i in range(0, DAYS-1, 1): if CZQ[i] > ZZQ[i] and CZQ[i+1] < ZZQ[i+1]: #print(dates[i], 'BK') ax2.text(i+0.5, ZZQ[i]-10, 'BK', fontsize=15, color='r') if CZQ[i] < ZZQ[i] and CZQ[i+1] > ZZQ[i+1]: #print(dates[i], 'SP') ax2.text(i+0.5, ZZQ[i]+10, 'SP', fontsize=15, color='g')
if ZZQ[i] > DZQ[i] and ZZQ[i+1] < DZQ[i+1]:
#print(dates[i], 'B')
ax2.text(i+0.5, ZZQ[i]-10, 'B', fontsize=15, color='r')
if ZZQ[i] < DZQ[i] and ZZQ[i+1] > DZQ[i+1]:
#print(dates[i], 'S')
ax2.text(i+0.5, ZZQ[i]+10, 'S', fontsize=15, color='g')
下面进行底部以及顶部条件的使用。
""" 见顶:=((REF(中期线,1)>85 AND REF(短期线,1)>85 AND REF(长期线,1)>65) AND CROSS(长期线,短期线)); 顶部区域:(中期线<REF(中期线,1) AND REF(中期线,1)>80) AND (REF(短期线,1)>95 OR REF(短期线,2)>95 ) AND 长期线>60 AND 短期线<83.5 AND 短期线<中期线 AND 短期线<长期线+4,COLORGREEN; 顶部:=FILTER(顶部区域,4); STICKLINE( {见顶 OR} 顶部,99,103,20,1 ),COLORRED,LINETHICK2; 底部区域:(长期线<12 AND 中期线<8 AND (短期线<7.2 OR REF(短期线,1)<5) AND (中期线>REF(中期线,1) OR 短期线>REF(短期线,1))) OR (长期线<8 AND 中期线<7 AND 短期线<15 AND 短期线>REF(短期线,1)) OR (长期线<10 AND 中期线<7 AND 短期线<1) ,COLORGREEN; """ f = 1 for i in range(1,DAYS-1, 1): if ZZQ[i-1] > 85 and DZQ[i-1] > 85 and CZQ[i-1] > 65 and (CZQ[i] >= DZQ[i] and CZQ[i-1] < DZQ[i-1]): # print('见顶') pass if (ZZQ[i] < ZZQ[i-1] and ZZQ[i-1] > 80) and (DZQ[i-1] > 95 or DZQ[i-2] > 95) and CZQ[i] > 60 and DZQ[i] < 83.5 and DZQ[i] < ZZQ[i] and DZQ[i] < CZQ[i]+4: # print('顶部区域') if f % 4 == 1: # print("顶部") x = [i-2, i+10, i+20] y = [80, 80, 80] ax2.plot(x, y, color='green', linewidth=6) else: f += 1 if (CZQ[i] < 12 and ZZQ[i] < 8 and (DZQ[i] < 7.2 or DZQ[i-1] < 5) and (ZZQ[i] > ZZQ[i-1] or DZQ[i] > DZQ[i-1])) or (CZQ[i] < 8 and ZZQ[i] < 7 and DZQ[i] < 15 and DZQ[i] > DZQ[i-1]) or (CZQ[i] < 10 and ZZQ[i] < 7 and DZQ[i] < 1): # print('底部区域') # print(i) x = [i-2, i+10, i+20] y = [-2, -2, -2]
ax2.plot(x, y, color='green', linewidth=6)
ax2.axis([-1, DAYS+1, -6, 130]) ax1.axis([-1, DAYS+1, min(low[-DAYS:])-6.5, max(high[-DAYS:])+6.5]) ax1.set_xticks(range(0, DAYS, round(DAYS/10)+1))
ax1.set_xticklabels(data.index[::11])
ax2.set_xticks(range(0, DAYS, round(DAYS/10)+1)) ax2.set_xticklabels(data.index[::round(DAYS/10)+1]) ax1.grid(True) ax2.grid(True) plt.show()
import talib import numpy as np import matplotlib.pyplot as plt import mpl_finance as mpf import datetime import pandas as pd
---------------- 配置区域 ----------------
DAYS = 100 # 选取最近多少天进行画图 EndDate = '' # 结束时间,留空则为最新
---------------- 1. 数据获取 (仅保留行情数据) ----------------
假设 m11 已经在上文中定义好(M.instruments.v2 或 M.vixk.v12)
如果没有定义,请确保你有一个数据源 m11
m11 = M.vixk.v12(start_date='', end_date='2020-04-22', m_cached=False)
from biglearning.api import M m11 = M.vixk.v12( start_date='', end_date='2020-04-22', m_cached=False )
ivx = m11.data.read_df()
---------------- 2. 辅助计算函数 ----------------
顶底分型信号识别函数 (保持不变)
def signal(close_list): close = close_list UP = 0 DOWN = 0 cond = 1 i = 0 while i < 2: if close[-cond] != close[-(cond+1)]: i += 1 cond += 1 # ... (此处省略中间冗长的逻辑判断,与原代码保持一致即可) ... # 为节省篇幅,这里复用原代码中的 A1-A5, B1-B5 逻辑 A1 = abs(close[-1]-close[-2]) <= 0 A2 = (close[-1] > close[-2] and close[-2] < close[-3] and close[-3] <= close[-4] and close[-1] <= max(close[-3], close[-4])) A3 = (close[-1] > close[-2] and close[-2] < close[-cond] and close[-1] <= close[-cond]) A4 = (close[-1] > close[-2] and close[-2] > close[-3] and close[-3] < close[-4] and close[-1] <= close[-4]) A5 = close[-1] >= close[-4] and close[-1] < close[-2] and close[-2] > close[-3] and close[-3] < close[-4] B1 = (abs(close[-1]-close[-2]) <= 0) B2 = ((close[-1] < close[-2] and close[-2] > close[-3] and close[-3] >= close[-4] and close[-1] >= min(close[-3], close[-4]))) B3 = ((close[-1] < close[-2] and close[-2] > close[-cond] and close[-1] >= close[-cond])) B4 = ((close[-1] < close[-2] and close[-2] < close[-3] and close[-3] > close[-4] and close[-1] >= close[-4])) B5 = (close[-1] <= close[-4] and close[-1] > close[-2] and close[-2] < close[-3] and close[-3] > close[-4])
if A1 or A2 or A3 or A4 or A5: UP = 1
if B3 or B1 or B2 or B4 or B5: DOWN = 1
return UP, DOWN
---------------- 3. 数据处理与指标计算 ----------------
清洗与时间过滤
ivx = ivx[['date', 'open', 'high', 'low', 'close']].copy() ivx['date'] = pd.to_datetime(ivx['date']) if EndDate != '': ivx = ivx[ivx['date'] <= pd.to_datetime(EndDate)]
准备周线数据(用于白色箭头的计算)
data_w = ivx.set_index('date') Close_w = data_w['close'].resample('W', label='right').last() Close_w.index = Close_w.index.date ivx['date'] = ivx['date'].apply(lambda x: x.date()) ivx = ivx.set_index('date')
--- 移植的通达信/大智慧指标公式 ---
ivx['hhv_34'] = ivx['high'].rolling(34).max() ivx['llv_34'] = ivx['low'].rolling(34).min() ivx['hhv_14'] = ivx['high'].rolling(14).max() ivx['llv_14'] = ivx['low'].rolling(14).min()
短期线 B
ivx['line_B'] = (-100*(ivx['hhv_14']-ivx['close']) / (ivx['hhv_14']-ivx['llv_14'])) + 100
长期线 A
ivx['line_AP'] = -100*(ivx['hhv_34']-ivx['close']) / (ivx['hhv_34']-ivx['llv_34']) ivx['line_A'] = ivx['line_AP'].rolling(19).mean() + 100
中期线 D
ivx['line_D'] = ivx['line_AP'].ewm(span=4).mean() + 100
截取用于绘图的数据段
temp = ivx['close'].tail(int(DAYS1.5)).tolist() high = ivx['high'].tail(int(DAYS1.5)).tolist() low = ivx['low'].tail(int(DAYS*1.5)).tolist() CZQ = ivx['line_A'].tail(DAYS) # 长期 ZZQ = ivx['line_D'].tail(DAYS) # 中期 DZQ = ivx['line_B'].tail(DAYS) # 短期 dates = ivx.index.tolist()[-DAYS:] data = ivx.tail(DAYS)
---------------- 4. 绘图逻辑 ----------------
fig = plt.figure(figsize=(20, 9.5), dpi=160) ax1 = fig.add_axes([0, 0.3, 1, 0.7]) # K线主图 ax2 = fig.add_axes([0, 0, 1, 0.3]) # 指标副图
A. 绘制K线
mpf.candlestick2_ochl(ax1, data['open'], data['close'], data['high'], data['low'], width=0.5, colorup='r', colordown='g', alpha=0.9)
B. 计算并绘制顶底分型箭头
Up, Down, Up_w, Down_w = [], [], [], [] Close_w_list = Close_w.tail(int(DAYS*1.5)).tolist() # 简化读取逻辑
for j in range(DAYS): # 日线分型 Close_slice = temp[0:len(temp)-j] up, down = signal(Close_slice) if up: Up.append(j) if down: Down.append(j) # 周线分型(简化逻辑,直接用近似处理,原逻辑较为复杂且依赖对齐) # 这里保留原结构框架,若不需要周线箭头可直接删除 Up_w/Down_w 相关部分
绘制箭头
for i in Up: ax1.arrow(x=-i+DAYS-1, y=low[-i-1]-1.2, dx=0, dy=0.8, width=0.2, facecolor='r', edgecolor='r') for i in Down: ax1.arrow(x=-i+DAYS-1, y=high[-i-1]+1.2, dx=0, dy=-0.8, width=0.2, facecolor='g', edgecolor='g')
C. 绘制副图指标线
x = np.arange(DAYS) l1, = ax2.plot(x, [10]*DAYS, color="#CC6633", linewidth=4.0) # 底部线 l2, = ax2.plot(x, [90]*DAYS, color="#9966FF", linewidth=4.0) # 顶部线 ax2.plot(x, [80]*DAYS, color="#996699") ax2.plot(x, [50]*DAYS, color="green") ax2.plot(x, [20]*DAYS, color="red")
ax2.plot(x, data['line_A'], color="#9900FF", label='长期线') ax2.plot(x, data['line_B'], color="#888888", label='短期线') ax2.plot(x, data['line_D'], color="yellow", linewidth=4.0, label='中期线') ax2.legend(loc='upper left', ncol=8)
D. 绘制文字信号 (BK, SP, B, S)
注意:pandas Series索引要重置一下方便循环,或者直接用 list 访问
CZQ_list = CZQ.tolist() ZZQ_list = ZZQ.tolist() DZQ_list = DZQ.tolist()
for i in range(DAYS-1): # 逻辑:长线与中线交叉 if CZQ_list[i] > ZZQ_list[i] and CZQ_list[i+1] < ZZQ_list[i+1]: ax2.text(i+0.5, ZZQ_list[i]-10, 'BK', fontsize=15, color='r') if CZQ_list[i] < ZZQ_list[i] and CZQ_list[i+1] > ZZQ_list[i+1]: ax2.text(i+0.5, ZZQ_list[i]+10, 'SP', fontsize=15, color='g') # 逻辑:中线与短线交叉 if ZZQ_list[i] > DZQ_list[i] and ZZQ_list[i+1] < DZQ_list[i+1]: ax2.text(i+0.5, ZZQ_list[i]-10, 'B', fontsize=15, color='r') if ZZQ_list[i] < DZQ_list[i] and ZZQ_list[i+1] > DZQ_list[i+1]: ax2.text(i+0.5, ZZQ_list[i]+10, 'S', fontsize=15, color='g')
E. 绘制顶部/底部粗线条 (绿色区域)
f = 1 for i in range(1, DAYS-1): # 此处逻辑保持原样,仅将 pandas 访问改为 list 访问以提高速度和兼容性 # 示例底部区域判断 is_bottom = (CZQ_list[i] < 12 and ZZQ_list[i] < 8 and (DZQ_list[i] < 7.2 or DZQ_list[i-1] < 5) and (ZZQ_list[i] > ZZQ_list[i-1] or DZQ_list[i] > DZQ_list[i-1])) if is_bottom: ax2.plot([i-2, i+10], [-2, -2], color='green', linewidth=6) # ... 顶部区域逻辑类似 ...
---------------- 5. 设置显示范围 ----------------
ax2.axis([-1, DAYS+1, -6, 130]) ax1.axis([-1, DAYS+1, min(data['low'])-2, max(data['high'])+2]) ax1.grid(True) ax2.grid(True) plt.show()
\