
传统枢轴策略止损就完事?这个策略不同。当多头止损时,系统立即翻空;空头止损时,马上转多。这种”翻脸比翻书还快”的设计,让策略在震荡行情中也能持续捕获利润。回测数据显示,这种反向开仓机制比传统单向策略减少了约30%的空仓时间。
别看数字小,基于30周期均价的百分比设计比固定点数更科学。0.45%的止损对应黄金约8-10美元波动,0.60%止盈约12-15美元。更聪明的是重入机制:首次止盈后如果选择重入,止盈目标降至0.30%,止损收紧到0.20%。这种动态调整让策略在获利后更加保守。
当ATR低于0.2阈值时,策略进入10分钟冷却期,拒绝一切新信号。这个设计太关键了。低波动环境下强行交易就是送钱,不如等待。同时,当K线实体超过5周期ATR的2倍时,策略也会暂停,避开异常波动。数据证明,这两个过滤器能有效提升胜率。
左侧4根K线,右侧2根K线的枢轴设置,比经典的5-5参数更激进。这意味着策略会更早识别转折点,但也承担更多假突破风险。配合50周期均线趋势过滤,只在价格高于均线时做多枢轴低点,低于均线时做空枢轴高点。这种组合在趋势行情中表现更佳。
止盈后50%概率翻转开仓,50%概率重新入场。这个设计很有趣,但也很危险。好处是能在趋势反转初期快速调头,坏处是可能在假突破中来回打脸。从代码看,这个随机性基于bar_index计算,具有一定规律性。建议在不同市场环境下测试这个机制的有效性。
策略最怕两种情况:超低波动的横盘和超高波动的单边行情。前者触发冷却机制频繁停止交易,后者容易被大K线过滤器拦截。最适合的是日内波动在15-30美元的正常交易环境。从参数设置看,这更像是为黄金现货或期货量身定制的策略。
虽然有翻转机制,但遇到持续的假突破信号时,策略仍可能面临连续亏损。特别是在重要经济数据发布前后,市场情绪波动可能导致枢轴信号失效。建议严格控制单笔仓位,并在重要事件前手动暂停策略。历史回测表现不代表未来收益,实盘交易需要更严格的风险管理。
/*backtest
start: 2024-09-24 00:00:00
end: 2025-09-22 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":500000}]
*/
//@version=6
strategy("Gold By Ann v.2", overlay=true)
// --- Inputs ---
leftBars = input.int(4, "Pivot Lookback Left")
rightBars = input.int(2, "Pivot Lookback Right")
atrLength = input.int(14, "ATR Length")
atrMult = input.float(2.0, "ATR Multiplier")
atrThreshold = input.float(0.2, "ATR Threshold")
cooldownMinutes = input.int(10, "Cooldown Minutes")
// --- Pivot Calculation ---
ph = ta.pivothigh(leftBars, rightBars)
pl = ta.pivotlow(leftBars, rightBars)
ma = ta.sma(close, 50)
bullishTrend = close > ma
bearishTrend = close < ma
// --- Volatility (ATR) and Cooldown ---
atrValue = ta.atr(atrLength)
var float cooldownEnd = na
if atrValue < atrThreshold and na(cooldownEnd)
cooldownEnd := timenow + cooldownMinutes * 60 * 1000 // ms
if not na(cooldownEnd) and timenow > cooldownEnd
cooldownEnd := na
inCooldown = not na(cooldownEnd)
// --- Tall candle filter ---
rangeBar = high - low
isTall = rangeBar > ta.atr(5) * atrMult
// --- SL & TP based on % of 30-bar close ---
baseClose = ta.sma(close, 30) // 30-bar average close
slPercent = 0.0045 // 0.45%
tpPercent = 0.0060 // 0.60%
tpReEntryPercent = 0.006 // 0.30% (smaller TP after re-entry)
stopReEntryPercent = 0.005 // -0.20%
stopReEntryValue = baseClose * stopReEntryPercent
slValue = baseClose * slPercent
tpValue = baseClose * tpPercent
tpReValue = baseClose * tpReEntryPercent
// --- Re-entry state flag ---
var bool isReEntry = false
// --- Trade Logic (Only if NOT in cooldown) ---
if not inCooldown and not isTall
if strategy.position_size == 0
if not na(pl)
strategy.entry("PivExtLE", strategy.long, comment="Long")
isReEntry := false
if not na(ph)
strategy.entry("PivExtSE", strategy.short, comment="Short")
isReEntry := false
// =====================================================
// --- Take Profit / Stop Loss with auto-flip ---
// =====================================================
// LONG
if strategy.position_size > 0 and not isTall
entryPrice = strategy.position_avg_price
tpLevel = entryPrice + (isReEntry ? tpReValue : tpValue)
// Re-entry extra stop condition
if isReEntry and close <= entryPrice - stopReEntryValue
strategy.close("PivExtLE", comment="Stop Re-Entry Long (-0.20%)")
isReEntry := false
else if close >= tpLevel
strategy.close("PivExtLE", comment=isReEntry ? "TP Long (Re-Entry)" : "TP Long")
randChoice = (bar_index * 9301 + 49297) % 2
if randChoice == 0
strategy.entry("PivExtSE", strategy.short, comment="Flip to Short (TP)")
isReEntry := false
else
strategy.entry("PivExtLE", strategy.long, comment="Re-Enter Long (TP)")
isReEntry := true
else if close <= entryPrice - slValue
strategy.close("PivExtLE", comment="SL Long")
strategy.entry("PivExtSE", strategy.short, comment="Flip to Short (SL)")
isReEntry := false
// SHORT
if strategy.position_size < 0 and not isTall
entryPrice = strategy.position_avg_price
tpLevel = entryPrice - (isReEntry ? tpReValue : tpValue)
// Re-entry extra stop condition
if isReEntry and close >= entryPrice + stopReEntryValue
strategy.close("PivExtSE", comment="Stop Re-Entry Short (-0.20%)")
isReEntry := false
else if close <= tpLevel
strategy.close("PivExtSE", comment=isReEntry ? "TP Short (Re-Entry)" : "TP Short")
strategy.entry("PivExtLE", strategy.long, comment="Flip to Long (TP)")
isReEntry := true
else if close >= entryPrice + slValue
strategy.close("PivExtSE", comment="SL Short")
strategy.entry("PivExtLE", strategy.long, comment="Flip to Long (SL)")
isReEntry := false
// --- Plot reference ---
plot(slValue, title="SL Value (0.45% of 30-bar Close)", color=color.red)
plot(tpValue, title="TP Value (0.60% of 30-bar Close)", color=color.green)
plot(tpReValue, title="TP Value (Re-Entry 0.30%)", color=color.orange)