基于平滑Z评分交叉的动量优化价格统计交易策略

Z-SCORE SMA stdev PNL Momentum Filter
创建日期: 2025-06-03 10:44:56 最后修改: 2025-06-03 10:44:56
复制: 0 点击次数: 65
avatar of ianzeng123 ianzeng123
2
关注
62
关注者

基于平滑Z评分交叉的动量优化价格统计交易策略 基于平滑Z评分交叉的动量优化价格统计交易策略

概述

这个策略基于Z评分(Z-Score)这一统计学概念,用于识别价格相对于其局部平均值的统计偏差。该策略计算收盘价的Z评分,然后应用短期和长期移动平均线来平滑Z评分值。当短期平滑Z评分上穿长期平滑Z评分时生成多头入场信号,当短期平滑Z评分下穿长期平滑Z评分时生成平仓信号。该策略还包含信号间隔控制和基于动量的蜡烛过滤器,以减少噪音交易。

策略原理

该策略的核心是Z评分的计算和应用。Z评分是一个统计量,用于衡量一个数据点与样本均值的偏离程度,以标准差为单位。在此策略中,Z评分计算公式为: Z = (收盘价 - SMA(收盘价, N)) / STDEV(收盘价, N) 其中N是用户定义的基础周期。

策略的执行流程如下: 1. 计算收盘价的原始Z评分 2. 对原始Z评分应用短期平滑(SMA) 3. 对原始Z评分应用长期平滑(SMA) 4. 当短期平滑Z评分上穿长期平滑Z评分时,如果满足额外条件,则开仓做多 5. 当短期平滑Z评分下穿长期平滑Z评分时,如果满足额外条件,则平仓

额外条件包括: - 信号间隔:两个相同类型的信号(入场或出场)之间必须间隔最小数量的K线 - 动量过滤:当连续出现三根或更多的上涨K线时,禁止入场;当连续出现三根或更多的下跌K线时,禁止出场

策略优势

  1. 统计学基础:Z评分是一个成熟的统计工具,能够有效识别价格偏离其均值的程度,适合捕捉价格回归均值的机会。
  2. 平滑处理:通过对原始Z评分应用短期和长期平滑,减少了噪音,提高了信号质量。
  3. 信号间隔控制:通过设置最小信号间隔,有效减少了过度交易和重复信号。
  4. 动量过滤:通过禁止在强烈趋势中逆势交易,避免了在强势行情中的不必要损失。
  5. 简洁性:策略仅使用收盘价数据,不依赖复杂的指标组合,易于理解和实施。
  6. 实时盈亏监控:包含实时显示未实现盈亏的表格,便于交易者监控持仓状态。
  7. 参数灵活性:用户可以根据不同市场和时间框架调整Z评分基础周期和平滑参数,提高适应性。

策略风险

  1. 统计假设风险:Z评分假设价格分布近似正态分布,在非正态分布的市场环境中可能表现不佳。
  2. 参数敏感性:Z评分基础周期和平滑参数的选择对策略性能有显著影响,参数选择不当可能导致过拟合或信号迟滞。
  3. 单一因子限制:策略仅基于Z评分交叉生成信号,缺乏其他确认指标,可能导致假信号。
  4. 市场环境依赖:在强趋势市场中,基于均值回归的策略可能持续产生错误信号。
  5. 信号滞后:由于使用了移动平均平滑,信号可能出现滞后,错过最佳入场或出场点。

解决方法: - 对不同市场环境进行回测,找到最优参数组合 - 结合趋势过滤器,在强趋势市场中减少或禁用交易 - 添加额外的确认指标,如成交量分析或其他技术指标 - 考虑使用自适应参数,根据市场波动性自动调整Z评分参数

优化方向

  1. 趋势识别集成:添加趋势识别组件,在明确趋势方向的市场中调整策略行为。这可以通过长期移动平均线或ADX指标实现,避免在强趋势中产生错误的均值回归信号。
  2. 波动性调整:实现Z评分参数的自适应调整,根据市场波动性自动优化基础周期和平滑参数。这将提高策略在不同市场环境中的鲁棒性。
  3. 多重时间框架分析:整合更高时间框架的Z评分信号作为确认,仅在多个时间框架信号一致时交易,减少假信号。
  4. 止损机制:实现基于Z评分波动范围的动态止损,提高风险管理能力。例如,可以将止损设置为入场Z评分的特定偏离倍数。
  5. 部分利润获取:实施分段获利策略,在Z评分达到特定阈值时部分平仓,优化资金管理。
  6. 成交量确认:添加成交量分析作为交易确认,仅在Z评分信号得到成交量支持时执行交易,提高信号质量。
  7. 指标组合:将Z评分与其他统计或技术指标结合,如RSI或布林带,创建多因子决策模型,增强策略可靠性。

总结

基于平滑Z评分交叉的动量优化价格统计交易策略是一个基于统计学原理的简洁交易系统,专注于捕捉价格相对于其局部均值的偏离和回归。通过平滑处理、信号间隔控制和动量过滤,该策略有效减少了噪音交易,提高了信号质量。该策略特别适合震荡市场和均值回归行为明显的金融产品。

然而,策略也存在一些局限性,如依赖统计假设、参数敏感性和单一因子决策等。通过添加趋势识别、波动性调整、多时间框架分析、止损机制、成交量确认和多因子组合等优化措施,可以显著提升策略的鲁棒性和表现。

总的来说,这是一个理论基础扎实、实现简洁、易于理解和扩展的策略框架,适合作为交易系统的基础组件或教育工具,帮助交易者理解统计学在交易中的应用。

策略源码
/*backtest
start: 2024-06-03 00:00:00
end: 2025-06-02 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/

//@version=6
strategy("Price Statistical Strategy-Z Score V 1.01", overlay=true)

// === Enable / Disable Z-Score Strategy Block ===
enableZScore = input.bool(true, title="Enable Smoothed Z-Score Strategy", tooltip="When enabled, this block calculates a smoothed Z-Score of the closing price and generates entry/exit signals based on crossover behavior between short-term and long-term smoothed Z-Scores.\n\nRecommended for quick and classic detection of price deviation from mean.\nSensitive to outliers. Best suited for relatively normal-distributed market conditions.")

// === Z-Score Parameters ===
zBaseLength = input.int(3, minval=1, title="Z-Score Base Period")
shortSmooth = input.int(3, title="Short-Term Smoothing")
longSmooth = input.int(5, title="Long-Term Smoothing")

// === Z-Score Calculation Function ===
f_zscore(src, length) =>
    mean = ta.sma(src, length)
    std_dev = ta.stdev(src, length)
    z = (src - mean) / std_dev
    z

// === Z-Score Logic ===
zRaw = f_zscore(close, zBaseLength)
zShort = ta.sma(zRaw, shortSmooth)
zLong = ta.sma(zRaw, longSmooth)


// === Minimum gap between identical signals ===
gapBars = input.int(5, minval=1, title="Bars gap between identical signals", tooltip="Minimum number of bars required between two identical signals (entry or exit). Helps reduce signal noise.")


// === Candle-based momentum filters ===
bullish_3bars = close > close[1] and close[1] > close[2] and close[2] > close[3] and close[3] > close[4]
bearish_3bars = close < close[1] and close[1] < close[2] and close[2] < close[3] and close[3] < close[4]

// === Entry and Exit Logic with minimum signal gap and candle momentum filter ===
var int lastEntryBar = na
var int lastExitBar  = na

if enableZScore
    longCondition = (zShort > zLong)
    exitCondition = (zShort < zLong)

    if longCondition and (na(lastEntryBar) or bar_index - lastEntryBar > gapBars) and not bullish_3bars
        strategy.entry("Z Score", strategy.long)
        lastEntryBar := bar_index

    if exitCondition and (na(lastExitBar) or bar_index - lastExitBar > gapBars) and not bearish_3bars
        strategy.close("Z Score", comment="Z Score")
        lastExitBar := bar_index

// === Real-time PnL Table for Last Open Position ===
var table positionTable = table.new(position.bottom_right, 2, 2, border_width=1)

// Header Labels
table.cell(positionTable, 0, 0, "Entry Price", text_color=color.white, bgcolor=color.gray)
table.cell(positionTable, 1, 0, "Unrealized PnL (%)", text_color=color.white, bgcolor=color.gray)

// Values (only when position is open)
isLong        = strategy.position_size > 0
entryPrice    = strategy.position_avg_price
unrealizedPnL = isLong ? (close - entryPrice) / entryPrice * 100 : na

// Define dynamic text color for PnL
pnlColor = unrealizedPnL > 0 ? color.green : unrealizedPnL < 0 ? color.red : color.gray

// Update Table Content
if isLong
    table.cell(positionTable, 0, 1, str.tostring(entryPrice, "#.####"), text_color=color.gray, bgcolor=color.new(color.gray, 90))
    table.cell(positionTable, 1, 1, str.tostring(unrealizedPnL, "#.##") + " %", text_color=pnlColor, bgcolor=color.new(pnlColor, 90))
else
    table.cell(positionTable, 0, 1, "—", text_color=color.gray, bgcolor=color.new(color.gray, 90))
    table.cell(positionTable, 1, 1, "—", text_color=color.gray, bgcolor=color.new(color.gray, 90))
相关推荐