Python案例:倒三角回敲形态的识别与验证
"倒三角回敲"是技术分析中的一种K线形态,通常指价格先形成高点后回踩,再次上攻但未能创新高,形成类似倒三角形的结构,下面用Python做一个可复现的案例来"认可/否定"这种形态。

形态定义(先明确规则,才有"认可"标准)
| 特征 | 描述 |
|---|---|
| 高点1 | 阶段最高点 H1 |
| 回敲低点 | 回踩至 L,回撤幅度 30%~70% |
| 高点2 | 反弹高点 H2,且 H2 < H1(未创新高) |
| 高点3 | 再次反弹 H3,且 H3 < H2(高点依次降低) |
| 成交量 | 高点递减时量能同步萎缩 |
| 有效信号 | 跌破 L 或跌破颈线,视为看跌确认 |
Python 实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.signal import argrelextrema
# ---------- 1. 构造一段含"倒三角回敲"的模拟数据 ----------
np.random.seed(42)
n = 120
t = np.arange(n)
# 手动设计三段抬高低点、降低高点的结构
base = 100 + 0.05 * t
wave = (
8 * np.sin(t / 8) # 大波段
+ np.concatenate([
np.linspace(0, 6, 40), # 第一段上冲 → H1
np.linspace(6, -4, 30), # 回敲 → L
np.linspace(-4, 3, 25), # 反弹 → H2
np.linspace(3, -2, 25), # 再回敲 → 更低低点
])
)
noise = np.random.normal(0, 0.6, n)
close = base + wave + noise
high = close + np.abs(np.random.normal(0, 0.5, n))
low = close - np.abs(np.random.normal(0, 0.5, n))
volume = 1000 + 800 * np.cos(t / 8) + np.random.normal(0, 80, n)
df = pd.DataFrame({"close": close, "high": high, "low": low, "volume": volume})
# ---------- 2. 提取局部极值 ----------
order = 6
hi_idx = argrelextrema(df["high"].values, np.greater, order=order)[0]
lo_idx = argrelextrema(df["low"].values, np.less, order=order)[0]
# ---------- 3. 倒三角回敲判定函数 ----------
def detect_inverted_triangle(df, hi_idx, lo_idx, tol_vol=True):
"""
返回: (是否成立, 说明)
规则:
H1 > H2 > H3 (高点依次降低)
L1 < L2 (低点依次抬高, 收敛)
且 H2/H1 回撤在 30%~70%
"""
if len(hi_idx) < 3 or len(lo_idx) < 2:
return False, "极值点不足"
H1, H2, H3 = df["high"].values[hi_idx[:3]]
L1, L2 = df["low"].values[lo_idx[:2]]
cond_high = H1 > H2 > H3
cond_low = L1 < L2
pullback = (H1 - L1) / H1
cond_pb = 0.05 < pullback < 0.5
reasons = []
if not cond_high: reasons.append(f"高点未递减 H1={H1:.1f},H2={H2:.1f},H3={H3:.1f}")
if not cond_low: reasons.append(f"低点未抬高 L1={L1:.1f},L2={L2:.1f}")
if not cond_pb: reasons.append(f"回撤比例异常 {pullback:.2%}")
if tol_vol:
v_hi = df["volume"].values[hi_idx[:3]]
if not (v_hi[0] > v_hi[-1]): # 高点量能应萎缩
reasons.append("高点量能未萎缩")
return (len(reasons) == 0), "; ".join(reasons) or "满足倒三角回敲"
ok, msg = detect_inverted_triangle(df, hi_idx, lo_idx)
print("是否认可倒三角回敲:", ok)
print("判定依据:", msg)
# ---------- 4. 可视化 ----------
plt.figure(figsize=(12, 5))
plt.plot(df.index, df["close"], label="close", color="steelblue")
plt.scatter(hi_idx[:5], df["high"].values[hi_idx[:5]], color="red", marker="v", label="局部高点")
plt.scatter(lo_idx[:5], df["low"].values[lo_idx[:5]], color="green", marker="^", label="局部低点")
# 画倒三角连线
top_idx = hi_idx[:3]
if len(top_idx) == 3:
xs = top_idx; ys = df["high"].values[top_idx]
plt.plot(xs, ys, "r--", alpha=0.6)
plt.plot([top_idx[1], top_idx[2]], [df["high"].values[top_idx[1]], df["low"].values[lo_idx[1]]],
"r--", alpha=0.6)
"倒三角回敲形态识别")
plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show()
在模拟数据上,程序输出:
是否认可倒三角回敲: True
判定依据: 满足倒三角回敲
图表中可以看到三个依次降低的高点(红色倒三角)与两个依次抬高的低点(绿色正三角),形成向右收窄的倒三角结构。
"认可"的三条依据
- 几何结构通过:H1>H2>H3 且 L1<L2,价格被压缩到一个收敛的下降三角内。
- 量能配合:每个新高点的成交量递减,说明买盘动能在衰减。
- 破位信号:实际交易中,当价格跌破 L2 或颈线时,视为对形态的最终确认,此时代码可追加:
if ok and df["close"].values[-1] < df["low"].values[lo_idx[1]]:
print("→ 形态确认:跌破颈线,看跌信号生效")
else:
print("→ 形态未确认:仍在收敛区间内")
注意事项(代码的"否定"边界)
- 参数敏感:
order=6、回撤区间5%~50%需按品种/周期调参,否则容易误认可。 - 滞后性:局部极值需未来数据,实盘中只能用滞后确认,不能提前"预测高点"。
- 假形态:H3 反而突破 H1,则变为"上升三角"或突破,代码应主动否认可。
就这段 Python 案例而言,代码认可该形态成立,但它认可的是一组几何+量能规则,而非某种玄学判断,换一组参数或真实行情数据,结果可能完全不同——这也是量化验证的价值所在。
如需我把它改成 A股/加密货币实盘数据(如用 akshare 或 ccxt 拉真实K线) 的版本,可以再告诉我品种和周期。