
Стратегия основана на широкоспектровых движущихся средних, которые формируют торговые сигналы с помощью быстро и медленно движущихся средних. Широкоспектровые движущиеся средние охватывают несколько типов, от простых движущихся средних до колебательных движущихся средних, которые могут быть скорректированы с помощью параметров свободной комбинации, имея сильную адаптивность.
Эта стратегия использует функцию переменных скользящих средних, которая может генерировать 12 различных типов скользящих средних. Основная идея заключается в том, чтобы рассчитать две скользящие средние (быстрый ((Close MA) и медленный ((Open MA)), которые генерируют сигнал покупки при прохождении медленной линии на быстрой линии и сигнал продажи при прохождении медленной линии под быстрой линией.
Ключевая логика состоит в том, чтобы с помощью вариантных функций генерировать две скользящие средние:closeSeries = variant(basisType, close, basisLen, offsetSigma, offsetALMA)иopenSeries = variant(basisType, open, basisLen, offsetSigma, offsetALMA)。 функция Variant включает в себя 12 различных типов средних вычислений, которые могут быть выбраны с помощью параметров BasisType. 。 Таким образом, реализуется комбинация широкоспектровых движущихся средних 。
Основная логика генерирования торговых сигналов:longCond = xlong и shortCond = xshortЭто означает, что если вы будете работать на короткой линии, вы будете делать больше, а если вы будете работать на короткой линии, вы будете делать меньше.
Правило входа в стратегию заключается в том, что при выполнении условий длинного конда или короткого конда делается дополнительное открытие. Правило остановки убытков заключается в том, что при движении цены до установленного количества остановок убытков или остановки убытков.
Самым большим преимуществом этой стратегии является то, что она позволяет свободно комбинировать несколько различных типов скользящих средних. В разных рынках, в разных циклах, какая скользящая средняя наиболее подходит, неизвестно, и эта стратегия предоставляет мощную возможность настройки. Пользователь может определить оптимальную комбинацию параметров путем повторного тестирования, что позволяет разработать оптимальные программы для конкретного рынка.
Еще одно преимущество заключается в том, что логика стратегии проста и понятна, но предлагает мощные функции. Пользователям легко понять и использовать эту стратегию. В то же время, богатые параметры ввода также предоставляют достаточный простор для оптимизации для продвинутых пользователей.
Наибольший риск этой стратегии заключается в том, что широкоспектровая скользящая средняя сама по себе имеет определенный уровень отставания. При появлении аномального ценового прорыва это может привести к значительным потерям. Кроме того, если параметры выбраны неправильно, это может привести к чрезмерной частоте торговли или созданию избыточных сигналов.
Для снижения риска рекомендуется оценивать эффективность сигнала в сочетании с другими показателями, чтобы избежать ложных прорывов. Кроме того, оптимизация и отсчет параметров также необходимы, требуется повторное тестирование, чтобы найти оптимальную комбинацию параметров.
Стратегия включает в себя следующие основные направления оптимизации:
Оптимизация этих направлений позволяет постоянно повышать эффективность стратегии.
Стратегия торговли, основанная на широкоспектровых движущихся средних, обеспечивает высокую гибкость. Она предоставляет мощные возможности настройки, пользователи могут свободно выбирать и комбинировать различные типы средних. Логика стратегии проста и понятна, удобна в использовании, а также предоставляет богатую возможность оптимизации.
/*backtest
start: 2023-01-18 00:00:00
end: 2024-01-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
//
strategy(title="Long/Short", shorttitle="Banana Maker", overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=100, calc_on_every_tick=false)
// === INPUTS ===
useRes = input(defval=true, title="Use Alternate Resolution?")
intRes = input(defval=7, title="Multiplier for Alernate Resolution")
stratRes = timeframe.ismonthly ? tostring(timeframe.multiplier * intRes, "###M") :
timeframe.isweekly ? tostring(timeframe.multiplier * intRes, "###W") :
timeframe.isdaily ? tostring(timeframe.multiplier * intRes, "###D") :
timeframe.isintraday ? tostring(timeframe.multiplier * intRes, "####") : '60'
basisType = input(defval="DEMA", title="MA Type: ", options=["SMA", "EMA", "DEMA", "TEMA", "WMA", "VWMA", "SMMA", "HullMA", "LSMA", "ALMA", "SSMA", "TMA"])
basisLen = input(defval=8, title="MA Period", minval=1)
offsetSigma = input(defval=6, title="Offset for LSMA / Sigma for ALMA", minval=0)
offsetALMA = input(defval=0.85, title="Offset for ALMA", minval=0, step=0.01)
scolor = input(false, title="Show coloured Bars to indicate Trend?")
delayOffset = input(defval=0, title="Delay Open/Close MA (Forces Non-Repainting)", minval=0, step=1)
tradeType = input("BOTH", title="What trades should be taken : ", options=["LONG", "SHORT", "BOTH", "NONE"])
// === /INPUTS ===
// Constants colours that include fully non-transparent option.
green100 = #008000FF
lime100 = #6ad279
red100 = #FF0000FF
blue100 = #0000FFFF
aqua100 = #00FFFFFF
darkred100 = #8B0000FF
gray100 = #808080FF
// === BASE FUNCTIONS ===
variant(type, src, len, offSig, offALMA) =>
v1 = sma(src, len) // Simple
v2 = ema(src, len) // Exponential
v3 = 2 * v2 - ema(v2, len) // Double Exponential
v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len) // Triple Exponential
v5 = wma(src, len) // Weighted
v6 = vwma(src, len) // Volume Weighted
v7 = 0.0
sma_1 = sma(src, len) // Smoothed
v7 := na(v7[1]) ? sma_1 : (v7[1] * (len - 1) + src) / len
v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len))) // Hull
v9 = linreg(src, len, offSig) // Least Squares
v10 = alma(src, len, offALMA, offSig) // Arnaud Legoux
v11 = sma(v1, len) // Triangular (extreme smooth)
// SuperSmoother filter
// © 2013 John F. Ehlers
a1 = exp(-1.414 * 3.14159 / len)
b1 = 2 * a1 * cos(1.414 * 3.14159 / len)
c2 = b1
c3 = -a1 * a1
c1 = 1 - c2 - c3
v12 = 0.0
v12 := c1 * (src + nz(src[1])) / 2 + c2 * nz(v12[1]) + c3 * nz(v12[2])
type == "EMA" ? v2 : type == "DEMA" ? v3 :
type == "TEMA" ? v4 : type == "WMA" ? v5 : type == "VWMA" ? v6 :
type == "SMMA" ? v7 : type == "HullMA" ? v8 : type == "LSMA" ? v9 :
type == "ALMA" ? v10 : type == "TMA" ? v11 : type == "SSMA" ? v12 : v1
// security wrapper for repeat calls* NEEDS REFINEMENT- backtesting this shows repaint. need new wrapper
reso(exp, use, res) =>
security_1 = security(syminfo.tickerid, res, exp, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
use ? security_1 : exp
// === /BASE FUNCTIONS ===
// === SERIES SETUP ===
closeSeries = variant(basisType, close[delayOffset], basisLen, offsetSigma, offsetALMA)
openSeries = variant(basisType, open[delayOffset], basisLen, offsetSigma, offsetALMA)
// === /SERIES ===
// === PLOTTING ===
// alt resulution
closeSeriesAlt = reso(closeSeries, useRes, stratRes)
openSeriesAlt = reso(openSeries, useRes, stratRes)
//
trendColour = closeSeriesAlt > openSeriesAlt ? color.green : color.red
bcolour = closeSeries > openSeriesAlt ? lime100 : red100
barcolor(scolor ? bcolour : na, title="Bar Colours")
closeP = plot(closeSeriesAlt, title="Close Series", color=trendColour, linewidth=0, style=plot.style_line, transp=1)
openP = plot(openSeriesAlt, title="Open Series", color=trendColour, linewidth=0, style=plot.style_line, transp=1)
fill(closeP, openP, color=trendColour, transp=80)
// === /PLOTTING ===
//
//
// === ALERT conditions
xlong = crossover(closeSeriesAlt, openSeriesAlt)
xshort = crossunder(closeSeriesAlt, openSeriesAlt)
longCond = xlong // alternative: longCond[1]? false : (xlong or xlong[1]) and close>closeSeriesAlt and close>=open
shortCond = xshort // alternative: shortCond[1]? false : (xshort or xshort[1]) and close<closeSeriesAlt and close<=open
// === /ALERT conditions. needs work in study mode. the banana maker is the study script.
// Create alert for cross, shunt back 1 if source is not 'open', this should prevent repaint issue.
//shunt = RSIsrc == open ? 0 : 1
//shunt = 0
//c_alert = (buy[shunt]==1 or sell[shunt]==1)
//alertcondition(c_alert, title="QQECROSS Alert", message="QQECROSS Alert")
// show only when alert condition is met and bar closed.
//plotshape(c_alert,title= "Alert Indicator Closed", location=location.bottom, color=sell[shunt]==1?red:green, transp=0, style=shape.circle)
//Repaint city, study mode will help but wont trigger the alerts
// === STRATEGY ===
// stop loss
slPoints = input(defval=0, title="Initial Stop Loss Points (zero to disable)", minval=0)
tpPoints = input(defval=0, title="Initial Target Profit Points (zero for disable)", minval=0)
// Include bar limiting algorithm
ebar = input(defval=1000, title="Number of Bars for Back Testing", minval=0)
dummy = input(false, title="- SET to ZERO for Daily or Longer Timeframes")
//
// Calculate how many mars since last bar
tdays = (timenow - time) / 60000.0 // number of minutes since last bar
tdays := timeframe.ismonthly ? tdays / 1440.0 / 5.0 / 4.3 / timeframe.multiplier :
timeframe.isweekly ? tdays / 1440.0 / 5.0 / timeframe.multiplier :
timeframe.isdaily ? tdays / 1440.0 / timeframe.multiplier :
tdays / timeframe.multiplier // number of bars since last bar
//
//set up exit parameters
TP = tpPoints > 0 ? tpPoints : na
SL = slPoints > 0 ? slPoints : na
// Make sure we are within the bar range, Set up entries and exit conditions
if (ebar == 0 or tdays <= ebar) and tradeType != "NONE"
strategy.entry("long", strategy.long, when=longCond == true and tradeType != "SHORT")
strategy.entry("short", strategy.short, when=shortCond == true and tradeType != "LONG")
strategy.close("long", when=shortCond == true and tradeType == "LONG")
strategy.close("short", when=longCond == true and tradeType == "SHORT")
strategy.exit("XL", from_entry="long", profit=TP, loss=SL)
strategy.exit("XS", from_entry="short", profit=TP, loss=SL)
// === /STRATEGY ===
// eof