量化中N字型技术形态的实现
最近一个客户提出了使用N字型技术形态量化交易的思路,本人比较擅长技术或数据统计的编写,这种自定义的略费了一些时间,大约一天完工,简单说一下思路。
通过波段可以简单的看到,在k线波段的走势中和sdkj的波段有些类似,也就是skdj的金叉-死叉之间往往是大概率的波段高点,死叉-金叉则是波段的低点,当然因为有些时候行情的波动高点低可能会在其他的地方,认真观察会发现,当金叉死叉间的k线数量大于10根以上的话,基本上90%的概率就是波段的高低点。有了这个思路就比较好写了。
编写sdkj指标的数据,获取金叉死叉k线,获取金叉死叉之间的高低点即可,为了减小出错的概率,以大于10根的k线的波段为基准,依次从高点低到下一个金死叉求高低点,然后高点低存储然后进行判断即可。
分享部分代码供朋友们参考。
#存储走出的波段的最高最低点位lowest = []highest = []#记录所有的金叉死叉的list,包括id及方向_md = []#计算sdkj数据,并把数据放置到天勤web guid的附图中nn, mm = 15, 3lowv = k1['low'].rolling(nn).min()highv = k1['high'].rolling(nn).max()rsv = tl.EMA((k1['close'] - lowv) / (highv - lowv) * 100, mm)k1['k'] = tl.EMA(rsv, mm) k1['d'] = tl.MA(k1['k'], mm) k1['zero'] = 50 k1['crossup'] = tafunc.crossup(k1['d'], k1['zero'])k1['crossdown'] = tafunc.crossdown(k1['d'], k1['zero'])#非天勤可以去除下面的代码,此几行代码为在附图画sdkj指标k1['k.board'] = 'SKDJ' k1['d.board']='SKDJ'k1['d.color'] = 0xFF9933CC k1['d.width'] = 4 k1['zero.board']='SKDJ'k1['crossup.board'] = 'SKDJ'k1['crossdown.board'] = 'SKDJ'#遍历所有数据,存储_mdfor i in range(500):if k1['crossup'].iloc[i] == 1:_md.append([i, 1])if k1['crossdown'].iloc[i] == 1:_md.append([i, -1])#倒序查找4个波段之前的符合10根k线的id,N字其实只需要高低点各2个数据即可for i in range(-4, -len(_md), -1):ss = 0if _md[i][0] - _md[i - 1][0] >= 10:ss = iss1 = _md[i][1]print('获取到符合条件的点位', i, _md[i][0], _md[i][1])breakif ss != 0:#如果此点是死叉,则先找低点if ss1 == -1:index1 = k1['high'].iloc[_md[ss - 1][0]:_md[ss][0]].idxmax()num1 = k1['high'].iloc[index1]highest.append(num1) ss2 = sswhile ss2 < 0:if index1 < _md[ss2 + 1][0] <= 499:index1 = k1['low'].iloc[(index1):_md[ss2 + 1][0]].idxmin()num2 = k1['low'].iloc[index1]lowest.append(num2)if index1 < _md[ss2 + 2][0] <= 499:index1 = k1['high'].iloc[index1:_md[ss2 + 2][0]].idxmax()num3 = k1['high'].iloc[index1]highest.append(num3)ss2 = ss2 + 2#如果此点是金叉,则先找高点elif ss1 == 1:index1 = k1['low'].iloc[_md[ss - 1][0]:_md[ss][0]].idxmin()num1 = k1['low'].iloc[index1]lowest.append(num1)ss2 = ss while ss2 < 0:if index1 < _md[ss2 + 1][0] <= 499:index1 = k1['high'].iloc[(index1):_md[ss2 + 1][0]].idxmax()num2 = k1['high'].iloc[index1]highest.append(num2) if index1 < _md[ss2 + 2][0] <= 499:index1 = k1['low'].iloc[index1:_md[ss2 + 2][0]].idxmin()num3 = k1['low'].iloc[index1]lowest.append(num3) ss2 = ss2 + 2#数据筛选并正序高低点数据打印highest=highest[-2:]lowest=lowest[-2:]print(f'高点\n{highest}')print(f'低点\n{lowest}')
到了这里,下一步就是判断了,有了2个高点 2个低点,n字自然就出来了
上升的用2个低点,一个高点
下降的用2个高点,一个低点。
以上代码在天勤,mindgo,python版同花顺,okex,huobi,binance等平台都可正常使用,用的指标为ema,我直接调用了talib的,也可以自定义,代码可以参考:
def ema(series, n):"""指数加权移动平均线: 求series序列n周期的指数加权移动平均计算公式:ema(x, n) = 2 * x / (n + 1) + (n - 1) * ema(x, n).shift(1) / (n + 1)注意:1. n 需大于等于12. 对距离当前较近的k线赋予了较大的权重Args:series (pandas.Series): 数据序列n (int): 周期Returns:pandas.Series: 指数加权移动平均线序列"""ema_data = series.ewm(span=n, adjust=False).mean()return ema_data