找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1980

积分

0

好友

274

主题
发表于 2025-12-24 19:49:46 | 查看: 34| 回复: 0

大多数交易者在市场波动时往往只能被动应对,经常错失先机。是否有可能提前识别出潜在的趋势反转区域,为决策提供前瞻性参考?本文将深入解析一种结合了统计学与机器学习的可视化方法,通过量化手段在价格图表上勾勒出具有统计意义的“反转概率区域”。这套方法融合了Python数据处理、隐马尔可夫模型与核密度估计等关键技术,为量化投研和策略开发提供了一个实用的分析框架。

核心原理:三步构建统计“警戒线”

该方法通过三个核心步骤将价格行为转化为可视化的概率区域:

  1. 枢轴点检测:识别图表中的局部高点与低点(即枢轴点),这些点代表了价格运行中的关键转折,是后续分析的起点。算法通过滑动窗口比较价格,确定窗口内的极值点。
  2. 波动率状态标记:市场并非总处于同一种波动环境。我们使用隐马尔可夫模型(HMM)对价格对数收益率序列进行建模,自动将市场划分为不同的波动率状态(例如低、中、高波动)。这使得生成的反转区域能够动态适应不同的市场“性格”。
  3. 概率映射:针对每个波动率状态,收集历史摆动数据(振幅与持续时间)。利用核密度估计(KDE)对这些二维数据点进行拟合,生成一个连续的概率密度曲面。通过计算概率积分,我们可以提取出特定置信度(如50%、75%)的等高线,这些线即为图表上展示的“反转弧线”。

完整代码实现

1. 参数设置与数据准备

首先,导入必要的库并配置基础参数。

import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import matplotlib.patches as mpatches
from hmmlearn.hmm import GaussianHMM
from scipy.stats import gaussian_kde

# 参数配置
TICKER = 'TSLA'           # 股票代码
START = '2022-01-01'      # 开始日期
END = '2024-12-31'        # 结束日期
INTERVAL = '1d'           # 时间间隔
PIVOT_K = 5               # 枢轴点窗口大小
N_STATE = 3               # HMM 状态数量
BAND_P = [0.50]           # 概率带阈值
GRID_NX = 60              # KDE X 轴网格(振幅)
GRID_NY = 60              # KDE Y 轴网格(持续时间)

2. 核心功能函数

定义数据下载、枢轴点检测、状态标记等关键函数。

def download_ohlc(ticker, start, end, interval):
    """下载并清洗OHLCV数据"""
    df = yf.download(ticker, start=start, end=end,
                     interval=interval, auto_adjust=True, progress=False)
    if isinstance(df.columns, pd.MultiIndex):
        df.columns = df.columns.get_level_values(0)
    df.columns = df.columns.map(str.title)
    df.dropna(subset=['Open', 'High', 'Low', 'Close'], inplace=True)
    return df

def detect_pivots(df, k):
    """使用滑动窗口检测局部高点和低点"""
    pivots, last = [], 0
    H, L = df['High'].values, df['Low'].values
    for i in range(k, len(df) - k):
        win_h = H[i - k:i + k + 1]
        win_l = L[i - k:i + k + 1]
        if L[i] == win_l.min() and last != -1:
            pivots.append((i, L[i], -1))
            last = -1
        elif H[i] == win_h.max() and last != 1:
            pivots.append((i, H[i], 1))
            last = 1
    return pivots

def label_regimes(df, n_state):
    """使用HMM为每个价格柱分配波动率状态标签"""
    lr = np.log(df['Close']).diff().dropna().values.reshape(-1, 1)
    model = GaussianHMM(n_components=n_state,
                        covariance_type='diag',
                        n_iter=200, random_state=0)
    model.fit(lr)
    states = model.predict(lr)
    states = np.insert(states, 0, states[0])
    return pd.Series(states, index=df.index)

def swing_stats(pivots):
    """计算每个摆动的振幅和持续时间"""
    amp, dur = [], []
    for (i1, p1, t1), (i2, p2, t2) in zip(pivots, pivots[1:]):
        if t1 == -1 and t2 == 1:  # 从低点到高点
            amp.append((p2 - p1) / p1)
            dur.append(i2 - i1)
        elif t1 == 1 and t2 == -1:  # 从高点到低点
            amp.append((p1 - p2) / p1)
            dur.append(i2 - i1)
    return np.array(amp), np.array(dur)

def kde_grid(samples, levels, nx, ny):
    """使用KDE构建概率网格并计算阈值"""
    amp, dur = samples
    if len(amp) < 15:
        return None
    x_max = np.percentile(amp, 99) * 1.2
    y_max = np.percentile(dur, 99) * 1.2
    xs = np.linspace(0, x_max, nx)
    ys = np.linspace(1, y_max, ny)
    X, Y = np.meshgrid(xs, ys)
    kde = gaussian_kde(np.vstack([amp, dur]))
    Z = kde(np.vstack([X.ravel(), Y.ravel()])).reshape(X.shape)
    dx, dy = xs[1] - xs[0], ys[1] - ys[0]
    grid = np.sort(Z.ravel())[::-1]
    cdf = np.cumsum(grid * dx * dy)
    thresh = []
    for p in levels:
        idx = np.searchsorted(cdf, p)
        idx = min(idx, len(grid) - 1)
        thresh.append(grid[idx])
    return xs, ys, Z, thresh

def build_kde_by_regime(df, pivots, regimes):
    """为每个波动率状态构建KDE概率映射字典"""
    out = {}
    for st in regimes.unique():
        idxs = set(regimes[regimes == st].index)
        pv = [p for p in pivots if df.index[p[0]] in idxs]
        out[st] = kde_grid(swing_stats(pv), BAND_P, GRID_NX, GRID_NY)
    return out

3. 执行流程与可视化

整合以上模块,生成最终的可视化图表。

# 执行完整流程
df = download_ohlc(TICKER, START, END, INTERVAL)
pivots = detect_pivots(df, PIVOT_K)
regimes = label_regimes(df, N_STATE)
kde_dict = build_kde_by_regime(df, pivots, regimes)

# 可视化
plt.style.use('dark_background')
fig, (ax1, ax2) = plt.subplots(
    2, 1, sharex=True,
    gridspec_kw={'height_ratios': [5, 1]},
    figsize=(14, 8))
green, red = '#089981', '#F23645'
width = 0.6

# 绘制K线图和反转弧线
for dt, row in df.iterrows():
    x = mdates.date2num(dt)
    o, h, l, c = row[['Open', 'High', 'Low', 'Close']]
    col = green if c >= o else red
    ax1.vlines(x, l, h, color=col)
    y0 = min(o, c)
    r = mpatches.Rectangle((x - width / 2, y0),
                           width, abs(c - o),
                           facecolor=col, edgecolor=col)
    ax1.add_patch(r)

for i, price, typ in pivots:
    dt = df.index[i]
    reg = regimes.loc[dt]
    grid = kde_dict.get(reg)
    if grid is None:
        continue
    xs, ys, Z, th = grid
    A, T = np.meshgrid(xs, ys)
    sign = 1 if typ == -1 else -1
    base = mdates.date2num(dt)
    Xab = base + T
    Yab = price + sign * A * price
    col = green if sign == 1 else red
    for lvl, p in zip(th, BAND_P):
        cs = ax1.contour(Xab, Yab, Z, levels=[lvl], colors=col, alpha=0.4)
        ax1.clabel(cs, fmt={lvl: f'{int(p * 100)}%'}, inline=True, fontsize=8)

ax1.set_title(f'{TICKER} 反转概率区域')
ax1.set_ylabel('价格')

# 绘制波动率状态散点图
ax2.scatter(df.index, regimes, c=regimes, cmap='tab10', s=4)
states = sorted(regimes.unique())
ax2.set_yticks(states)
ax2.set_yticklabels([str(int(s)) for s in states])
ax2.set_ylabel('状态')
ax2.xaxis_date()
plt.subplots_adjust(bottom=0.15)
fig.autofmt_xdate()
plt.tight_layout()
plt.show()

结果解读与应用

运行代码后,你将得到一张叠加了反转概率弧线的K线图。每条弧线代表一个统计意义上的包络线:

  • 弧线之内:若后续价格走势保持在50%概率弧线内,表明此次波动属于当前市场状态下的“典型”行为。
  • 突破弧线:如果价格强势突破弧线边界,则意味着出现了统计学上的“异常值”,可能预示着强劲的趋势启动或市场情绪发生剧烈变化。

以分析结果为例,可能会得到如下洞察:

“最近一次价格摆动的振幅达到49.59%,显著超过了历史75%分位数(24.77%)。结合当前模型识别为‘状态2’(高波动率环境),这提示我们预期中的反转区域宽度较大,市场可能正经历剧烈波动。”

方法的局限性与扩展方向

需要注意的是,本方法的效果建立在几个前提之上:准确的枢轴点识别、HMM状态划分的合理性以及历史摆动分布的相对稳定性。在市场结构突变、流动性骤降或由突发新闻驱动的极端行情中,模型信号可能滞后或失效。

你可以在此基础上进行多种有意义的扩展,例如:

  • 精细化:添加多档概率带(如25%, 75%, 90%)以进行更细致的风险校准。
  • 多周期:将方法应用于分钟级、小时级或周线数据,观察不同时间尺度下的模式。
  • 模型优化:尝试用GARCH模型、滚动波动率或聚类算法替代HMM进行市场状态划分。
  • 多因子过滤:引入成交量、持仓量变化或另类情绪数据作为额外的过滤条件,以提高信号的稳健性。
  • 策略结合:将概率区域作为动态支撑阻力位,与订单流分析或其他交易信号结合,寻找高盈亏比的入场边际。

总结

本文详细介绍了一套基于Python的数据驱动分析方法,用于可视化和评估价格潜在的反转概率区域。该方法从识别关键枢轴点出发,通过隐马尔可夫模型动态适应市场波动状态,最终利用核密度估计技术将历史统计规律映射为直观的图表弧线。其核心价值在于为交易者提供了一个量化不确定性、可视化风险边界的分析框架,是机器学习技术在量化交易领域一个颇具启发的实战案例。




上一篇:重要提示:原文内容缺失,无法进行SEO优化
下一篇:嵌入式性能分析实战指南:从GPIO翻转到指令级Trace的7种方法
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-1-12 04:40 , Processed in 0.196943 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表