这是一个结合了动态趋势反应器(Dynamic Reactor)和多核心回归(Multi-Kernel Regression)的趋势跟踪交易策略。该策略通过ATR和SMA计算动态支撑/阻力线,并利用高斯核和Epanechnikov核的组合回归来识别市场趋势。同时结合MA200均线作为长期趋势过滤器,并设置了三重获利目标和止损机制。
策略主要由四个核心部分组成: 1. 动态趋势反应器(DR):使用ATR和SMA构建动态支撑/阻力带,根据价格位置判断趋势方向。在上升趋势中使用下带作为支撑,下降趋势中使用上带作为阻力。
多核心回归(MKR):结合高斯核和Epanechnikov核进行价格回归,通过可调节的权重参数实现两种核函数的优化组合。这种方法能更好地捕捉价格走势的动态特征。
MA200趋势过滤:利用200日均线作为长期趋势指标,只在价格与MA200形成明确趋势时才允许交易,并通过consolidationRange参数识别整理期。
资金管理系统:采用三重获利目标(1.5%, 3.0%, 4.5%)和1%止损的设置,按33%-33%-34%的比例分配仓位,实现收益最大化的同时控制风险。
该策略通过融合多种技术指标和先进的统计方法,构建了一个完整的交易系统。策略的优势在于其对趋势的准确把握和完善的风险管理体系,但也需要注意参数优化和市场适应性的问题。通过建议的优化方向,策略还有进一步提升的空间。
/*backtest
start: 2024-02-25 00:00:00
end: 2024-08-07 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"SOL_USDT"}]
*/
//@version=5
strategy("DR + Multi Kernel Regression + Signals + MA200 with TP/SL (Optimized)", overlay=true, shorttitle="DR+MKR+Signals+MA200_TP_SL_Opt", pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=10)
// =====================================================================
// PARTEA 1: Dynamic Reactor – linie unică colorată în funcție de trend
// =====================================================================
// Parametri pentru Dynamic Reactor
atrLength = input.int(14, title="Lungimea ATR", minval=1)
smaLength = input.int(20, title="Lungimea SMA", minval=1)
multiplier = input.float(1.5, title="Multiplicator ATR", minval=0.1, step=0.1)
// Calculăm ATR și SMA
atrValue = ta.atr(atrLength)
smaValue = ta.sma(close, smaLength)
// Benzile de bază
basicUpper = smaValue + atrValue * multiplier
basicLower = smaValue - atrValue * multiplier
// Calculăm benzile finale (similar cu SuperTrend)
var float finalUpper = basicUpper
var float finalLower = basicLower
if bar_index > 0
finalUpper := close[1] > finalUpper[1] ? math.max(basicUpper, finalUpper[1]) : basicUpper
finalLower := close[1] < finalLower[1] ? math.min(basicLower, finalLower[1]) : basicLower
// Determinăm trendul curent:
// - Dacă prețul curent este peste finalUpper din bara anterioară → uptrend (1)
// - Dacă prețul este sub finalLower din bara anterioară → downtrend (-1)
// - Altfel, păstrăm trendul precedent.
var int trend = 1
if bar_index > 0
trend := close > finalUpper[1] ? 1 : close < finalLower[1] ? -1 : nz(trend[1], 1)
// Linia Dynamic Reactor:
// - În uptrend se utilizează finalLower (nivel de suport)
// - În downtrend se utilizează finalUpper (nivel de rezistență)
drLine = trend == 1 ? finalLower : finalUpper
// Plotăm linia Dynamic Reactor
p_dr = plot(drLine, color=trend == 1 ? color.green : color.red, title="Dynamic Reactor", linewidth=2)
// =====================================================================
// PARTEA 2: Multi Kernel Regression
// =====================================================================
// Parametri pentru regresia cu kernel
regLength = input.int(50, title="Perioada regresiei", minval=1)
h1 = input.float(10.0, title="Bandă Gaussiană (h1)", minval=0.1)
h2 = input.float(10.0, title="Bandă Epanechnikov (h2)", minval=0.1)
alpha = input.float(0.5, title="Pondere Kernel Gaussian (0-1)", minval=0, maxval=1)
// Funcție: regresie cu kernel Gaussian
f_gaussian_regression(bw) =>
num = 0.0
den = 0.0
for i = 0 to regLength - 1
// Kernel Gaussian: K(x) = exp(-0.5 * (i/bw)^2)
weight = math.exp(-0.5 * math.pow(i / bw, 2))
num += close[i] * weight
den += weight
num / (den == 0 ? 1 : den)
// Funcție: regresie cu kernel Epanechnikov
f_epanechnikov_regression(bw) =>
num = 0.0
den = 0.0
for i = 0 to regLength - 1
ratio = i / bw
// Kernel Epanechnikov: K(u) = 1 - u^2 pentru |u| <= 1, altfel 0
weight = math.abs(ratio) <= 1 ? (1 - math.pow(ratio, 2)) : 0
num += close[i] * weight
den += weight
num / (den == 0 ? 1 : den)
// Calculăm regresiile pentru fiecare kernel
regGauss = f_gaussian_regression(h1)
regEpan = f_epanechnikov_regression(h2)
// Combinăm rezultatele celor două regresii
multiKernelRegression = alpha * regGauss + (1 - alpha) * regEpan
// Plotăm linia Multi Kernel Regression
p_mkr = plot(multiKernelRegression, color=trend == 1 ? color.green : color.red, title="Multi Kernel Regression", linewidth=2)
// Adăugăm ceata (fill) între Dynamic Reactor și Multi Kernel Regression
fillColor = trend == 1 ? color.new(color.green, 80) : color.new(color.red, 80)
fill(p_dr, p_mkr, color=fillColor, title="Trend Fill")
// =====================================================================
// PARTEA 2.1: MA 200 și evidențierea consolidării
// =====================================================================
// Calculăm MA 200 pentru trend pe termen lung
ma200 = ta.sma(close, 200)
p_ma200 = plot(ma200, color=color.blue, title="MA 200", linewidth=2)
// Parametru pentru detectarea consolidării (cât de aproape trebuie să fie prețul de MA200, în %)
consolidationRange = input.float(1.0, title="Consolidation Range (%)", minval=0.1, step=0.1)
// Determinăm dacă suntem într-o fază de consolidare (prețul este în interiorul unui interval mic în jurul MA200)
isConsolidation = (math.abs(close - ma200) / ma200 * 100) < consolidationRange
// Colorăm fundalul graficului cu un gri translucid atunci când e consolidare
bgcolor(isConsolidation ? color.new(color.gray, 90) : na, title="Consolidation BG")
// =====================================================================
// PARTEA 3: Semnale Buy și Sell
// =====================================================================
// Semnale de intrare:
// - Buy Signal: când linia Multi Kernel Regression trece peste linia Dynamic Reactor
// - Sell Signal: când linia Multi Kernel Regression trece sub linia Dynamic Reactor
buySignal = ta.crossover(multiKernelRegression, drLine)
sellSignal = ta.crossunder(multiKernelRegression, drLine)
// Plotăm semnalele pe grafic
plotshape(buySignal, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.tiny, title="Buy Signal")
plotshape(sellSignal, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.tiny, title="Sell Signal")
// Setăm condiții de alertă
alertcondition(buySignal, title="Buy Alert", message="Buy Signal: Kernel is above Dynamic Reactor")
alertcondition(sellSignal, title="Sell Alert", message="Sell Signal: Kernel is below Dynamic Reactor")
// =====================================================================
// PARTEA 4: Trade Management – Intrări, 3 TP și 1 SL
// =====================================================================
// Parametrii pentru TP și SL (valori ajustate pentru un raport risc-recompensă mai favorabil)
tp1Perc = input.float(1.5, title="TP1 (%)", minval=0.1, step=0.1)
tp2Perc = input.float(3.0, title="TP2 (%)", minval=0.1, step=0.1)
tp3Perc = input.float(4.5, title="TP3 (%)", minval=0.1, step=0.1)
slPerc = input.float(1.0, title="Stop Loss (%)", minval=0.1, step=0.1)
// ---- Intrări de tranzacționare cu filtrare suplimentară pe baza trendului MA200 și consolidării ----
// Pentru poziții long, intrăm doar când prețul este peste MA200 și nu este în consolidare.
// Pentru poziții short, intrăm doar când prețul este sub MA200 și nu este în consolidare.
if (buySignal and close > ma200 and not isConsolidation)
strategy.entry("Long", strategy.long)
if (sellSignal and close < ma200 and not isConsolidation)
strategy.entry("Short", strategy.short)
// ---- Gestionarea ordinelor pentru poziții long ----
if (strategy.position_size > 0)
entryPrice = strategy.position_avg_price
// Calculăm nivelurile de TP și SL pentru poziția long
long_sl = entryPrice * (1 - slPerc / 100)
long_tp1 = entryPrice * (1 + tp1Perc / 100)
long_tp2 = entryPrice * (1 + tp2Perc / 100)
long_tp3 = entryPrice * (1 + tp3Perc / 100)
// Plasăm TP-urile (alocări: 33%, 33% și 34%)
strategy.exit("Long_TP1", from_entry="Long", limit=long_tp1, qty_percent=33, comment="TP1")
strategy.exit("Long_TP2", from_entry="Long", limit=long_tp2, qty_percent=33, comment="TP2")
strategy.exit("Long_TP3", from_entry="Long", limit=long_tp3, qty_percent=34, comment="TP3")
// Plasăm ordinul de SL pentru poziția long
strategy.exit("Long_SL", from_entry="Long", stop=long_sl, comment="SL")
// ---- Gestionarea ordinelor pentru poziții short ----
if (strategy.position_size < 0)
entryPrice = strategy.position_avg_price
// Calculăm nivelurile de TP și SL pentru poziția short
short_sl = entryPrice * (1 + slPerc / 100)
short_tp1 = entryPrice * (1 - tp1Perc / 100)
short_tp2 = entryPrice * (1 - tp2Perc / 100)
short_tp3 = entryPrice * (1 - tp3Perc / 100)
// Plasăm TP-urile (alocări: 33%, 33% și 34%)
strategy.exit("Short_TP1", from_entry="Short", limit=short_tp1, qty_percent=33, comment="TP1")
strategy.exit("Short_TP2", from_entry="Short", limit=short_tp2, qty_percent=33, comment="TP2")
strategy.exit("Short_TP3", from_entry="Short", limit=short_tp3, qty_percent=34, comment="TP3")
// Plasăm ordinul de SL pentru poziția short
strategy.exit("Short_SL", from_entry="Short", stop=short_sl, comment="SL")