双周期波动率调整突破交易系统是一种基于著名的海龟交易法则设计的量化策略,该策略利用两种不同的时间周期(20日和55日)来捕捉市场突破,同时结合波动率指标进行动态仓位管理。该系统融合了趋势跟踪、突破交易、波动率调整仓位和金字塔加仓等多种量化交易技术,旨在有效捕捉中长期市场趋势。策略核心逻辑是在价格突破前期高点或低点时入场,通过波动率(ATR)计算合理仓位大小,并在趋势持续发展时进行金字塔式加仓,最终通过短周期反向突破进行止损或获利了结。该策略特别适用于黄金等具有明显趋势特性的资产类别。
分析代码可以看出,该策略的核心原理包括以下几个方面:
双周期突破入场:策略采用两套入场系统 - 系统1使用20日高点/低点突破作为主要入场信号;系统2在前次交易亏损后启用,采用55日高点/低点突破作为入场信号。这种设计能够根据市场状态自动调整入场敏感度。
波动率测量与仓位管理:策略使用20日平均真实波幅(ATR)作为市场波动率的度量,通过公式:单位仓位 = 风险金额 / (N * 点值) 计算合理仓位。其中风险金额等于账户权益乘以设定的风险百分比(默认1%)。这种方法确保在不同波动率环境下维持一致的风险暴露。
金字塔加仓机制:当已有盈利头寸的价格继续朝有利方向移动(至少0.5N的距离)时,策略允许添加相同大小的新单位。这种金字塔式加仓方法能够在强趋势市场中扩大盈利潜力。
短周期反向突破平仓:策略使用10日低点/高点作为多/空头寸的退出信号。当价格跌破10日最低点时,平掉所有多头头寸;当价格突破10日最高点时,平掉所有空头头寸。
系统切换机制:策略会根据交易结果自动调整入场系统。如果某个方向的交易亏损,下次同方向交易将使用系统2(55日周期);盈利交易后则恢复使用系统1(20日周期)。
通过这些原理的组合应用,策略在趋势市场中能够早期入场,顺势加仓,并在趋势反转初期退出,有效地捕捉中长期市场趋势。
深入剖析代码,我们可以总结出该策略具有以下几个主要优势:
机械化交易决策:策略完全基于量化规则执行交易,消除了人为情绪干扰,保证了交易纪律的严格执行。代码中明确定义了入场、加仓和出场条件,无需主观判断。
动态风险管理:通过将每笔交易的风险限制为账户权益的固定百分比(默认1%),并结合ATR调整仓位大小,策略能够在不同波动率环境下维持一致的风险暴露。这种方法在高波动市场中自动减小仓位,在低波动市场中适当增加仓位。
自适应市场条件:双周期设计使策略能够根据市场状态自动调整。在连续盈利的趋势市场中使用较短周期(20日)保持灵敏度;在遭遇亏损后切换到更长周期(55日)减少假信号。
复利增长机制:策略基于当前账户权益计算仓位大小,随着账户增长自动增加仓位,实现复利效应;同时通过金字塔加仓机制在强趋势中扩大盈利潜力。
多市场适应性:策略设计适用于多种资产类别,尤其在黄金等具有明显趋势特性的市场中表现更为出色。通过调整参数,可以针对不同市场特性进行优化。
明确的风险控制:使用10日反向突破作为出场信号,为每笔交易提供明确的止损点,有效控制单笔交易风险;同时通过设置最大风险百分比控制系统性风险。
尽管该策略有诸多优势,但仍存在以下潜在风险:
假突破风险:在震荡市场中,价格可能频繁突破高点/低点但随后迅速回落,导致连续亏损。代码中缺乏过滤假突破的机制,可能在非趋势市场中产生较多无效信号。
加仓风险放大:金字塔加仓机制在趋势延续时非常有效,但如果趋势突然反转,多单位头寸可能导致较大亏损。虽然策略设置了退出条件,但在剧烈反转中可能仍会遭受较大损失。
参数敏感性:策略性能高度依赖于各项参数设置(入场周期、出场周期、ATR周期、加仓间距等)。不同市场环境可能需要不同参数组合,固定参数可能导致表现不稳定。
流动性风险:在流动性较差的市场中,大量加仓可能导致滑点增加或难以按预期价格成交,影响实际执行效果。代码中没有针对流动性问题的处理机制。
系统性风险暴露:作为纯趋势跟踪策略,在市场普遍下跌或剧烈波动期间,可能与其他趋势策略产生高度相关性,难以提供多样化保护。
计算精度问题:代码中使用math.floor函数向下取整计算仓位,在小额账户中可能导致仓位过小或无法交易。同时,点值设置不当也可能导致仓位计算错误。
针对这些风险,可以考虑添加趋势过滤器、设置最大头寸限制、优化加仓规则以及增加波动率调整机制等方法进行风险控制。
基于代码分析,该策略有以下几个可优化方向:
增加趋势过滤器:当前策略纯粹基于价格突破交易,容易受到假突破影响。可以添加趋势指标(如移动平均线、ADX等)作为过滤条件,仅在趋势方向一致时执行交易,减少震荡市场中的亏损交易。
优化加仓规则:现有加仓机制相对简单,可以考虑引入递减加仓比例(后续加仓单位逐渐减小)或设置最大加仓次数限制,平衡扩大收益与控制风险的需求。
动态参数调整:可以基于市场波动率或趋势强度动态调整入场/出场周期和加仓间距。例如,在高波动市场中延长入场周期,在低波动市场中缩短出场周期,使策略更具适应性。
增加时间过滤:添加交易时间过滤条件,避开重大经济数据公布或流动性较差的时段,减少异常波动带来的风险。
多时间框架确认:结合更长时间周期的趋势方向作为交易过滤条件,例如只在日线趋势与4小时趋势方向一致时执行交易,提高信号质量。
优化资金管理:可以引入更复杂的资金管理模型,如凯利公式或最优f值方法,根据预期胜率和盈亏比动态调整风险比例,进一步优化资金增长曲线。
增加止盈机制:当前策略仅有基于反向突破的出场机制,可以考虑添加部分利润锁定机制,如达到特定盈利目标时平掉部分头寸,兼顾趋势捕捉和利润保护。
这些优化方向能够有效提升策略的稳定性和盈利能力,特别是在不同市场环境下的适应性。
双周期波动率调整突破交易系统是一种基于海龟交易法则的完整量化交易策略,融合了突破入场、波动率仓位管理、金字塔加仓和自适应周期等多种量化交易技术。策略通过捕捉价格突破进入趋势,利用波动率控制风险敞口,并通过金字塔加仓最大化趋势收益。
该策略的核心价值在于其全面的系统设计,包括入场、出场、仓位管理和风险控制等各个方面,形成了一个自洽的交易系统。特别是其波动率调整仓位机制和双周期自适应设计,使策略能够在不同市场环境中保持相对稳定的表现。
然而,作为一种趋势跟踪策略,其在震荡市场中表现可能不佳,需要通过增加趋势过滤器、优化加仓规则和动态参数调整等方法进行完善。同时,该策略适合作为投资组合中的一部分,与其他类型的策略(如均值回归策略)结合使用,以实现更平滑的收益曲线。
总体而言,这是一个设计合理、逻辑清晰的量化交易策略,具有良好的理论基础和实用价值。通过适当的参数优化和补充机制,该策略有潜力在多种市场环境中产生稳定收益。
/*backtest
start: 2024-06-16 00:00:00
end: 2025-06-15 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"DOGE_USDT"}]
*/
//@version=5
strategy("Turtle Trading System (Full Version)", overlay=true, pyramiding=1, default_qty_type=strategy.cash, default_qty_value=1)
// === User Inputs ===
riskPercent = input.float(1.0, title="Risk % of Equity per Trade", minval=0.1, maxval=5.0, step=0.1)
pointValue = input.float(1.0, title="Point Value ($/point)")
entryPeriod1 = input.int(20, title="System 1 Entry Period")
entryPeriod2 = input.int(55, title="System 2 Entry Period (after loss)")
exitPeriod = input.int(10, title="Exit Period")
nPeriod = input.int(20, title="N Period (ATR)")
pyramidSpacing = input.float(0.5, title="Add Units Every N x ...", step=0.1)
// === Volatility Measure (N) ===
N = ta.atr(nPeriod)
// === Donchian Channels ===
entryHigh1 = ta.highest(high, entryPeriod1)
entryLow1 = ta.lowest(low, entryPeriod1)
entryHigh2 = ta.highest(high, entryPeriod2)
entryLow2 = ta.lowest(low, entryPeriod2)
exitLong = ta.lowest(low, exitPeriod)
exitShort = ta.highest(high, exitPeriod)
// === Account & Sizing ===
equity = strategy.equity
riskDollars = equity * (riskPercent / 100)
unitSize = riskDollars / (N * pointValue)
positionSize = math.floor(unitSize)
// === Trade Management Flags ===
var bool lastLongLoss = false
var bool lastShortLoss = false
// === Entry Conditions ===
useSystem1Long = close > entryHigh1[1]
useSystem2Long = lastLongLoss and close > entryHigh2[1]
useSystem1Short = close < entryLow1[1]
useSystem2Short = lastShortLoss and close < entryLow2[1]
// === Exit Conditions ===
longExit = close < exitLong
shortExit = close > exitShort
// === Pyramiding Entries ===
var float lastLongEntryPrice = na
var float lastShortEntryPrice = na
canAddLong = strategy.opentrades > 0 and strategy.position_size > 0 and close >= lastLongEntryPrice + (pyramidSpacing * N)
canAddShort = strategy.opentrades > 0 and strategy.position_size < 0 and close <= lastShortEntryPrice - (pyramidSpacing * N)
// === Execute Entries ===
if (useSystem1Long or useSystem2Long)
strategy.entry("Long", strategy.long, qty=positionSize)
lastLongEntryPrice := close
lastLongLoss := false
if (useSystem1Short or useSystem2Short)
strategy.entry("Short", strategy.short, qty=positionSize)
lastShortEntryPrice := close
lastShortLoss := false
if (canAddLong)
strategy.entry("Long Add", strategy.long, qty=positionSize)
lastLongEntryPrice := close
if (canAddShort)
strategy.entry("Short Add", strategy.short, qty=positionSize)
lastShortEntryPrice := close
// === Exits ===
if (longExit)
strategy.close("Long")
strategy.close("Long Add")
lastLongLoss := close < lastLongEntryPrice
if (shortExit)
strategy.close("Short")
strategy.close("Short Add")
lastShortLoss := close > lastShortEntryPrice
// === Plotting ===
plot(entryHigh1, title="20-Day High", color=color.green)
plot(entryLow1, title="20-Day Low", color=color.red)
plot(entryHigh2, title="55-Day High", color=color.lime, linewidth=1)
plot(entryLow2, title="55-Day Low", color=color.maroon, linewidth=1)
plot(exitLong, title="10-Day Low (Exit Long)", color=color.orange)
plot(exitShort, title="10-Day High (Exit Short)", color=color.blue)