旗帜决定方向!不用CNN,快速检测三角形整理

这个底部点位,他又一次精准命中了(3143那个点,不是3066,周五上证实际下探到3152点)。不过,我更好奇的是他的研究方法,也就图的下半部分。知道大致的底之后,再结合缺口、前低等一些信息,确实有可能比较精准地预测底部点位。

我当时就回了一句,最近忙着上课,等有时间了,把这个三角形检测写出来。

这个检测并不难,写一个教学示例,一个小时的时间足够了。但写生产代码要花不少时间,所以,这里先给大家分享下教学代码,算是把思路贡献出来。

在分享我的算法之前,先推荐一个外网的方案。同样是教学代码,显然不如我随手写的优雅,先小小自得一下。不过,这样的好处就是,他的代码可能更容易读懂。

所谓旗形整理(或者说三角形检测),就是下面这张图:

在这张图,每次上涨的局部高点连接起来,构成压力线;而下跌的局部低点连起来,构成支撑线。

如果我们再在开始的位置画一条竖线,就构成了一个小旗帜,这就是旗形的来由。

旗形整理的特别之处是,整理何时结束似乎是可以预测的,因为这两条线之间的交易空间会越来越窄。

当它小于一个ATR时,就是整理必须结束,即将选择方向的时候。

下图显示了随时间推移,震荡幅度越来越小的情况。

最终,股价会选择方向。一旦选择方向,就往往会有一波较大的行情(或者下跌):

所以,能够自动化检测旗形整理,有以下作用:

  1. 如果当前处理在旗形整理中,可以设定合理的波段期望。
  2. 检测临近整理结束,可以减仓等待方向。
  3. 一旦方向确定,立即加仓。

现在,我们就来看如何实现。首先,我们有这样一个标的:

这是已经上涨后的。我们再来看它上涨前的:

肉眼来看,一个旗形整理似有若无。我们需要用算法来给它照上居里夫人的x光:

我们的算法分这样几步:

  1. 找到每阶段的峰和谷的坐标
  2. 通过这些坐标及它们的收盘价,进行趋势线拟合
  3. 通过np.poly1d生成趋势线
  4. 将趋势线和k线图画在一张图上
def find_peak_pivots(df, win):
    local_high = (df.close.rolling(win)
                    .apply(lambda x: x.argmax()== win-1))
    local_high[:win] = 0
    
    # find_runs函数是量化24课内容
    v,s,l = find_runs(local_high)

    peaks = []
    i = 0
    while i < len(v):
        if l[i] >= win // 2:
            if s[i] > 0:
                peaks.append(s[i] - 1)
        for j in range(i+1, len(v)):
            if l[j] >= win // 2:
                peaks.append(s[j] - 1)
                i = j
        if j == len(v)-1:
            break

    return peaks

这是一个简易地峰谷检测算法:

def find_valley_pivots(df, win):
local_min = (df.close.rolling(win)
.apply(lambda x: x.argmin()== win-1))
local_min[:win] = 0

v,s,l = find_runs(local_min)

valleys = []
i = 0
while i < len(v):
if l[i] >= win // 2:
if s[i] > 0:
valleys.append(s[i] - 1)
for j in range(i+1, len(v)):
if l[j] >= win // 2:
valleys.append(s[j] - 1)
i = j
if j == len(v)-1:
break

return valleys

接下来进行趋势线拟合和绘图:

def trendline(df):
peaks = find_peak_pivots(df, 20)
valleys = find_valley_pivots(df, 20)

y = df.close[peaks].values
p = np.polyfit(x=peaks, y = y, deg=1)
upper_trendline = np.poly1d(p)(np.arange(0, len(df)))

y = df.close[valleys].values
v = np.polyfit(x=valleys, y = y, deg=1)
lower_trendline = np.poly1d(v)(np.arange(0, len(df)))

candle = go.Candlestick(x=df.index,
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
line=dict({"width": 1}),
name="K 线",
increasing = {
"fillcolor":"rgba(255,255,255,0.9)",
"line": dict({"color": RED})
},
decreasing = {
"fillcolor": GREEN,
"line": dict(color = GREEN)
})
upper_trace = go.Scatter(x=df.index,
y=upper_trendline,
mode='lines',
name='压力线')

lower_trace = go.Scatter(x=df.index,
y=lower_trendline,
mode='lines',
name='支撑线')

fig = go.Figure(data=[candle,lower_trace, upper_trace])

fig.show()

最后,我们对该标的在上涨之前的形态进行检测,得到以下结果:

以西蒙斯的名义起誓!这个结果真的很美!

我精心挑选了这个例子作为首例。因为这个结果还能说明现实的复杂性:旗形整理结束时,主力示表态前,受大盘影响,方向仍有一定不确定性。

此时,要看关键点位。这里没有跌破前低,这是此后能凝聚共识、返身上涨的关键。

我们再来看一个最近一个月翻了7倍的标的:

这是检测出来的旗形整理

完美捕捉!

当然,这里只是示例代码,在实际运用中,由于我们使用了小样本线性回归,回归结果具有不稳定性,在实际应用中,还需要辅以其它方法让其预测更稳定。无论如何,我们已经迈出了关键一步。

所有评论(1)

  1. admin说道:

    This message is used to verify that this feed (feedId:72969092581465088) belongs to me (userId:72962173791003648). Join me in enjoying the next generation information browser https://follow.is.

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注