这是一个基于多重技术指标的趋势跟踪策略,通过动态调整持仓实现波段交易。该策略主要利用指数移动平均线(EMA)、相对强弱指标(RSI)和趋势方向指数(ADX)进行市场趋势分析和交易信号生成,同时使用真实波动幅度(ATR)来设定动态止损和获利目标。
该策略是一个结合了多重技术指标的趋势跟踪交易系统。它主要通过EMA确定价格趋势方向,RSI判断市场超买超卖状态,ADX验证趋势强度,最后利用ATR动态调整仓位大小和风险管理参数。策略支持多种仓位计算方法,包括基于账户百分比、固定资金量和固定合约数量等。
这是一个综合运用多个技术指标的趋势跟踪策略,通过多维度的趋势确认和完善的风险管理机制,实现相对稳健的交易。策略的优势在于系统的趋势确认机制和灵活的仓位管理,但也需要注意指标滞后性和市场环境适应性等问题。通过持续优化和风险控制的改进,该策略有望在各类市场环境中保持稳定表现。
/*backtest
start: 2025-02-10 00:00:00
end: 2025-02-17 00:00:00
period: 45m
basePeriod: 45m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("EMA Momentum Scalper", shorttitle="EMS", overlay=true, pyramiding=0)
// === ПАРАМЕТРЫ ===
posSizeMethod = input.string("Capital %", title="Метод расчета позиции", options=["% Based", "Capital %", "Fixed Capital Based", "Fixed Contract Size"])
riskPerTrade = input.float(3, title="Риск на сделку (%)", minval=0.1, maxval=100, step=0.5) / 100
capitalPctPerTrade = input.float(10, title="Доля капитала на сделку (%)", minval=0.1, maxval=100, step=0.5) / 100
fixedCapitalAmount = input.float(100, title="Фиксированная сумма капитала", minval=0)
fixedContractSize = input.int(10, title="Фиксированный размер контракта")
atrLength = input.int(14, title="Длина ATR")
atrMultiplierSL = input.float(2.5, title="ATR множитель для SL")
atrMultiplierTP = input.float(1.5, title="ATR множитель для TP")
timeoutBars = input.int(20, title="Выход через X баров, если нет TP/SL")
emaLength = input.int(50, title="Длина EMA")
rsiLength = input.int(14, title="Длина RSI")
rsiOverbought = input.int(70, title="RSI перекупленность")
rsiOversold = input.int(30, title="RSI перепроданность")
adxLength = input.int(14, title="Длина ADX")
adxThreshold = input.float(20, title="Порог ADX для тренда")
leverage = input.int(15, title="Плечо", minval=1, maxval=100)
// === ИНДИКАТОРЫ ===
atr = ta.atr(atrLength)
ema = ta.ema(close, emaLength)
rsi = ta.rsi(close, rsiLength)
// === ADX ===
diPlus = ta.rma(math.max(high - high[1], 0), adxLength)
diMinus = ta.rma(math.max(low[1] - low, 0), adxLength)
dx = 100 * math.abs(diPlus - diMinus) / (diPlus + diMinus)
adx = ta.rma(dx, adxLength)
// === УСЛОВИЯ ВХОДА ===
longEntry = ta.crossover(close, ema) and rsi > 50 and adx > adxThreshold
shortEntry = ta.crossunder(close, ema) and rsi < 50 and adx > adxThreshold
// === РАСЧЕТ РАЗМЕРА ПОЗИЦИИ ===
var float qty = na
riskAmount = strategy.equity * riskPerTrade
stopLossDistance = atr * atrMultiplierSL
positionSize = riskAmount / stopLossDistance
if (posSizeMethod == "% Based")
qty := strategy.equity * riskPerTrade / (atr * atrMultiplierSL)
else if (posSizeMethod == "Capital %")
qty := strategy.equity * capitalPctPerTrade / close
else if (posSizeMethod == "Fixed Capital Based")
qty := fixedCapitalAmount / close
else if (posSizeMethod == "Fixed Contract Size")
qty := fixedContractSize
qty := qty * leverage // Умножаем на плечо
// === СТОП-ЛОСС И ТЕЙК-ПРОФИТ ===
entryPrice = close
stopLossLong = entryPrice - atrMultiplierSL * atr
stopLossShort = entryPrice + atrMultiplierSL * atr
takeProfit1 = entryPrice + atrMultiplierTP * atr * (longEntry ? 1 : -1)
takeProfit2 = entryPrice + atrMultiplierTP * atr * (longEntry ? 2 : -2) / 1.5
// === ТРЕЙЛИНГ-СТОП ===
trailStopDistance = atr * atrMultiplierSL
if (longEntry)
strategy.entry("Long", strategy.long, qty=qty)
strategy.exit("Exit Long", "Long", stop=stopLossLong, limit=takeProfit1, trail_points=trailStopDistance)
alertMessage = syminfo.ticker + " LONG\n" +
"Leverage: Cross " + str.tostring(leverage) + "x\n" +
"➡️ Entry: " + str.tostring(entryPrice) + "\n" +
"🟢 Take profit 1: " + str.tostring(takeProfit1) + "\n" +
"🛑 Stop loss: " + str.tostring(stopLossLong)
alert(alertMessage, alert.freq_once_per_bar_close)
if (shortEntry)
strategy.entry("Short", strategy.short, qty=qty)
strategy.exit("Exit Short", "Short", stop=stopLossShort, limit=takeProfit1, trail_points=trailStopDistance)
alertMessage = syminfo.ticker + " SHORT\n" +
"Leverage: Cross " + str.tostring(leverage) + "x\n" +
"➡️ Entry: " + str.tostring(entryPrice) + "\n" +
"🟢 Take profit 1: " + str.tostring(takeProfit1) + "\n" +
"🛑 Stop loss: " + str.tostring(stopLossShort)
alert(alertMessage, alert.freq_once_per_bar_close)
// === ВИЗУАЛИЗАЦИЯ ===
plotshape(longEntry, color=color.green, style=shape.labelup, location=location.belowbar, text="BUY")
plotshape(shortEntry, color=color.red, style=shape.labeldown, location=location.abovebar, text="SELL")
plot(ema, color=color.blue, title="EMA")
bgcolor(rsi > rsiOverbought or rsi < rsiOversold ? color.new(color.gray, 80) : na)