
你知道吗?大部分人用EMA只会看价格,但这个策略厉害在哪?它能从6种不同数据源计算EMA!就像做菜不只用盐调味,还能用糖、醋、酱油一样,给你更丰富的交易信号。
划重点!这6种数据源包括:普通价格、成交量、变化率、平均K线价格、平均K线成交量、平均K线变化率。每种都有不同的市场洞察力!
这个策略不是随便给信号的!它有三道”安检”:
第一道:EMA趋势判断 📈 就像看天气预报,先确定大方向是晴是雨
第二道:ADX强度过滤 💪
ADX就像测量风力的仪器,只有趋势够强(默认25以上),才发出信号。避免在震荡市中被来回打脸!
第三道:成交量确认 🔊 成交量突增就像股票在”大声说话”,证明这个信号是认真的,不是开玩笑
最贴心的是,这个策略给了3种退出方式,就像游戏有简单、普通、困难三个难度:
模式1:反向信号退出 🔄 最简单粗暴,多头信号来了就平空开多,空头信号来了就平多开空
模式2:ATR动态止盈止损 📏 根据市场波动性自动调整,波动大的时候止损放宽点,波动小的时候收紧点
模式3:固定百分比止盈止损 📊 最好理解,赚2%就跑,亏1.5%就认输(可自定义)
适用周期:中短期交易,特别适合有一定波动性的市场 避坑指南:震荡市要小心,建议开启ADX过滤 进阶玩法:可以尝试不同数据源,成交量源在放量突破时特别有效!
这个策略最大的优势就是灵活性强,你可以根据不同市场环境选择最合适的数据源和退出模式。记住,没有完美的策略,只有最适合当前市场的策略!
/*backtest
start: 2025-01-01 00:00:00
end: 2025-09-01 08:00:00
period: 2h
basePeriod: 2h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":500000}]
*/
//@version=5
//@fenyesk
strategy("EMA inFusion Pro - Source Selection", overlay=true, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10)
// =============================================
// === INPUT PARAMETERS =======================
// =============================================
// Moving Average Source Selection
maSourceSelection = input.string("Price", "Moving Average Source",
options=["Price", "Volume", "Rate of Change", "Heikin Ashi Price", "Heikin Ashi Volume", "Heikin Ashi Rate of Change"],
tooltip="Select data source for EMA calculation")
// EMA Settings
emaLength = input.int(50, title="EMA Length", minval=1, maxval=200)
rocLength = input.int(1, title="Rate of Change Length", minval=1, maxval=50, tooltip="Length for ROC calculation")
// ADX Filter Settings
useAdxFilter = input.bool(true, title="Use ADX Filter", group="ADX Settings")
adxLength = input.int(14, title="ADX Length", minval=1, maxval=50, group="ADX Settings")
adxThreshold = input.float(25, title="ADX Threshold", minval=10, maxval=50, step=0.5, group="ADX Settings")
// Volume Spike Settings
useVolumeFilter = input.bool(true, title="Use Volume Spike Filter", group="Volume Settings")
volumeMultiplier = input.float(1.0, title="Volume Spike Multiplier", minval=1.0, maxval=5.0, step=0.1, group="Volume Settings")
volumeSmaLength = input.int(20, title="Volume SMA Length", minval=5, maxval=100, group="Volume Settings")
// Trading Exit Mode Selector
tradingMode = input.int(2, title="Trading Exit Mode", minval=1, maxval=3,
tooltip="1: Exit on reverse signal\n2: ATR based TP/SL\n3: Percent based TP/SL",
group="Exit Strategy")
// Mode 3: Percent-Based Settings
takeProfitPercent = input.float(2.0, title="Take Profit %", minval=0.1, maxval=10.0, step=0.1, group="Percent Exit")
stopLossPercent = input.float(1.5, title="Stop Loss %", minval=0.1, maxval=10.0, step=0.1, group="Percent Exit")
// Mode 2: ATR-Based Settings
atrLength = input.int(14, title="ATR Length", minval=1, maxval=50, group="ATR Exit")
atrMultiplierTp = input.float(4.0, title="ATR Take Profit Multiplier", minval=0.1, maxval=10.0, step=0.1, group="ATR Exit")
atrMultiplierSl = input.float(4.0, title="ATR Stop Loss Multiplier", minval=0.1, maxval=10.0, step=0.1, group="ATR Exit")
// =============================================
// === SOURCE CALCULATIONS ====================
// =============================================
// Rate of Change calculation
roc(src, length) =>
change = src - src[length]
src[length] != 0 ? (change / src[length] * 100) : 0
// Standard Rate of Change
rocPrice = roc(close, rocLength)
rocVolume = roc(volume, rocLength)
// Heikin Ashi calculations
haClose = (open + high + low + close) / 4
var float haOpen = na
haOpen := na(haOpen[1]) ? (open + close) / 2 : (haOpen[1] + haClose[1]) / 2
haHigh = math.max(high, math.max(haOpen, haClose))
haLow = math.min(low, math.min(haOpen, haClose))
// Heikin Ashi Rate of Change
haRocPrice = roc(haClose, rocLength)
haRocVolume = roc(volume, rocLength) // Volume remains same for HA
// Define EMA source based on selection
emaSource = switch maSourceSelection
"Price" => close
"Volume" => volume
"Rate of Change" => rocPrice
"Heikin Ashi Price" => haClose
"Heikin Ashi Volume" => volume // Volume doesn't change in HA
"Heikin Ashi Rate of Change" => haRocPrice
=> close // Default fallback
// =============================================
// === INDICATOR CALCULATIONS =================
// =============================================
// Core Indicators
emaValue = ta.ema(emaSource, emaLength)
[diPlus, diMinus, adx] = ta.dmi(adxLength, adxLength)
volumeSma = ta.sma(volume, volumeSmaLength)
volumeSpike = volume > (volumeSma * volumeMultiplier)
atrValue = ta.atr(atrLength)
// Trend Conditions (adjusted for different source types)
bullishTrend = switch maSourceSelection
"Price" => close > emaValue
"Heikin Ashi Price" => haClose > emaValue
"Volume" => volume > emaValue
"Heikin Ashi Volume" => volume > emaValue
"Rate of Change" => rocPrice > emaValue
"Heikin Ashi Rate of Change" => haRocPrice > emaValue
=> close > emaValue
bearishTrend = not bullishTrend
// Cross conditions (adjusted for source type)
emaCrossUp = switch maSourceSelection
"Price" => ta.crossover(close, emaValue)
"Heikin Ashi Price" => ta.crossover(haClose, emaValue)
"Volume" => ta.crossover(volume, emaValue)
"Heikin Ashi Volume" => ta.crossover(volume, emaValue)
"Rate of Change" => ta.crossover(rocPrice, emaValue)
"Heikin Ashi Rate of Change" => ta.crossover(haRocPrice, emaValue)
=> ta.crossover(close, emaValue)
emaCrossDown = switch maSourceSelection
"Price" => ta.crossunder(close, emaValue)
"Heikin Ashi Price" => ta.crossunder(haClose, emaValue)
"Volume" => ta.crossunder(volume, emaValue)
"Heikin Ashi Volume" => ta.crossunder(volume, emaValue)
"Rate of Change" => ta.crossunder(rocPrice, emaValue)
"Heikin Ashi Rate of Change" => ta.crossunder(haRocPrice, emaValue)
=> ta.crossunder(close, emaValue)
// Filters
strongTrend = useAdxFilter ? adx >= adxThreshold : true
volumeConfirm = useVolumeFilter ? volumeSpike : true
// Entry Signals
longCondition = emaCrossUp and strongTrend and volumeConfirm
shortCondition = emaCrossDown and strongTrend and volumeConfirm
// =============================================
// === STRATEGY EXECUTION WITH EXIT MODES =====
// =============================================
// MODE 1: EXIT ON REVERSE SIGNAL
if (tradingMode == 1)
if (longCondition)
strategy.entry("Long", strategy.long)
strategy.close("Short")
if (shortCondition)
strategy.entry("Short", strategy.short)
strategy.close("Long")
// MODE 2: ATR-BASED TAKE PROFIT & STOP LOSS
else if (tradingMode == 2)
if (longCondition)
strategy.entry("Long", strategy.long)
strategy.exit("Long TP/SL", "Long",
profit=atrMultiplierTp * atrValue / syminfo.mintick,
loss=atrMultiplierSl * atrValue / syminfo.mintick)
if (shortCondition)
strategy.entry("Short", strategy.short)
strategy.exit("Short TP/SL", "Short",
profit=atrMultiplierTp * atrValue / syminfo.mintick,
loss=atrMultiplierSl * atrValue / syminfo.mintick)
// MODE 3: PERCENT-BASED TAKE PROFIT & STOP LOSS
else if (tradingMode == 3)
if (longCondition)
longTpPrice = close * (1 + takeProfitPercent / 100)
longSlPrice = close * (1 - stopLossPercent / 100)
strategy.entry("Long", strategy.long)
strategy.exit("Long TP/SL", "Long", limit=longTpPrice, stop=longSlPrice)
if (shortCondition)
shortTpPrice = close * (1 - takeProfitPercent / 100)
shortSlPrice = close * (1 + stopLossPercent / 100)
strategy.entry("Short", strategy.short)
strategy.exit("Short TP/SL", "Short", limit=shortTpPrice, stop=shortSlPrice)
// =============================================
// === VISUALIZATIONS =========================
// =============================================
// Plot EMA with dynamic color based on source type
emaColor = switch maSourceSelection
"Price" => color.blue
"Volume" => color.orange
"Rate of Change" => color.purple
"Heikin Ashi Price" => color.green
"Heikin Ashi Volume" => color.red
"Heikin Ashi Rate of Change" => color.maroon
=> color.blue
plot(emaValue, title="EMA", color=emaColor, linewidth=2)
// Plot source data for reference (in separate pane when not price-based)
sourceColor = maSourceSelection == "Price" or maSourceSelection == "Heikin Ashi Price" ? na : color.gray
plot(str.contains(maSourceSelection, "Price") ? na : emaSource, title="Source Data", color=sourceColor)
// Background color based on trend
bgcolor(bullishTrend ? color.new(color.green, 95) : color.new(color.red, 95), title="Trend Background")
// Entry signals
plotshape(longCondition, title="Long Signal", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
plotshape(shortCondition, title="Short Signal", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.small)
// Volume spikes
plotchar(useVolumeFilter and volumeSpike, title="Volume Spike", char="V", location=location.bottom, color=color.orange, size=size.tiny)
// ATR-based levels for Mode 2
plot(tradingMode == 2 and strategy.position_size > 0 ? strategy.position_avg_price + (atrMultiplierTp * atrValue) : na,
title="Long TP Level", color=color.green, style=plot.style_circles, linewidth=1)
plot(tradingMode == 2 and strategy.position_size > 0 ? strategy.position_avg_price - (atrMultiplierSl * atrValue) : na,
title="Long SL Level", color=color.red, style=plot.style_circles, linewidth=1)
plot(tradingMode == 2 and strategy.position_size < 0 ? strategy.position_avg_price - (atrMultiplierTp * atrValue) : na,
title="Short TP Level", color=color.green, style=plot.style_circles, linewidth=1)
plot(tradingMode == 2 and strategy.position_size < 0 ? strategy.position_avg_price + (atrMultiplierSl * atrValue) : na,
title="Short SL Level", color=color.red, style=plot.style_circles, linewidth=1)
// Alert conditions
alertcondition(longCondition, title="Long Entry", message="EMA Fusion Pro: Long entry signal")
alertcondition(shortCondition, title="Short Entry", message="EMA Fusion Pro: Short entry signal")