这是一个基于体积加权移动平均线(VWMA)和指数移动平均线(EMA)的趋势跟踪策略,结合了价格角度分析和动态追踪止损机制。该策略主要通过监测VWMA与快速移动平均线的交叉,同时结合价格运动的角度条件来确定入场时机,并使用百分比追踪止损来管理风险。
策略的核心逻辑基于以下几个关键组件: 1. 使用25周期的VWMA作为主要趋势指标 2. 通过8周期VWMA作为快速信号线 3. 采用50周期EMA确定更长期趋势 4. 计算50周期EMA的角度(设定为45度阈值) 5. 可选的200周期EMA作为市场偏差过滤器 入场信号在快速移动平均线与主VWMA发生交叉,且价格角度满足条件时触发。策略通过1%的动态追踪止损来保护利润。
这是一个结构完善的趋势跟踪策略,通过角度分析和多重移动平均线的配合,能够在主要趋势中获得较好的表现。虽然存在一定的滞后性和参数敏感性问题,但通过建议的优化方向,策略仍有提升空间。特别适合在较长时间周期的趋势交易中应用。
/*backtest
start: 2024-02-18 00:00:00
end: 2024-10-16 00:00:00
period: 2h
basePeriod: 2h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=6
strategy("PVSRA Trailing Strategy with Angle Condition (40-50 degrees)", overlay=true)
// === INPUTS ===
priceData = input.source(close, title="Price Data")
maLength = input.int(25, title="Moving Average Length", minval=2)
useBias = input.bool(false, title="Long/Short just above/below 200 EMA")
useTrailing = input.bool(true, title="Use Trailing Stop")
trailPerc = input.float(1.0, title="Trailing Stop Percentage", minval=0.1)
anglePeriod = input.int(14, title="Period for Angle Calculation", minval=1)
// === CÁLCULOS ===
maValue = ta.vwma(priceData, maLength)
maLong = ta.ema(high, 50)
maShort = ta.ema(low, 50)
maFast = ta.vwma(close, 8)
bias = ta.ema(close, 200)
longBias = useBias ? close > bias : true
shortBias = useBias ? close < bias : true
// === CÁLCULO DO ÂNGULO DA MÉDIA MÓVEL DE 50 ===
ma50 = ta.ema(close, 50)
angle = math.atan((ma50 - ma50[anglePeriod]) / anglePeriod) * (180 / math.pi) // Converte radianos para graus
// === CONDIÇÃO DE ÂNGULO ===
validAngleL = angle >= 45
validAngleS = angle <= 45
// === PLOTS ===
plot(maValue, color=color.orange, title="Moving Average")
plot(maFast, color=color.green, title="Fast MA")
plot(ma50, color=color.blue, title="50 EMA")
plotshape(series=(strategy.position_size > 0) ? maValue : na,
color=color.red, style=shape.circle, location=location.absolute,
title="Long Stop")
plotshape(series=(strategy.position_size < 0) ? maValue : na,
color=color.red, style=shape.cross, location=location.absolute,
title="Short Stop")
// === CONDIÇÕES DE ENTRADA ===
enterLong = close > maValue and ta.crossover(maFast, maValue) and close > maLong and longBias and validAngleL
enterShort = close < maValue and ta.crossunder(maFast, maValue) and close < maShort and shortBias and validAngleS
// === CONDIÇÕES DE SAÍDA ===
exitLong = ta.crossunder(maFast, maValue) and strategy.position_size > 0
exitShort = ta.crossover(maFast, maValue) and strategy.position_size < 0
// === EXECUÇÃO DA ESTRATÉGIA ===
if (enterLong)
strategy.entry("EL", strategy.long)
if (enterShort)
strategy.entry("ES", strategy.short)
if (exitLong or exitShort)
strategy.close_all()
// === TRAILING STOP ===
if (useTrailing and strategy.position_size > 0)
trailPrice = close * (1 - trailPerc / 100)
strategy.exit("Trailing Long", from_entry="EL", stop=trailPrice)
if (useTrailing and strategy.position_size < 0)
trailPrice = close * (1 + trailPerc / 100)
strategy.exit("Trailing Short", from_entry="ES", stop=trailPrice)