Это стратегия, основанная на импульсе, которая использует индикаторы осцилляторов, такие как RSI, Stoch, MACD, для генерации торговых сигналов. Основная идея заключается в определении направления тренда, когда цена колеблется, используя индикаторы и вводить сделки на основе сигналов индикатора. Стратегия также использует задержанный супертенд для остановки потери.
Стратегия сначала вызывает пользовательскую функцию f_getOscilatorValues, чтобы получить значения различных индикаторов осциллятора, включая RSI, Stoch, MACD и т. Д. Затем она вычисляет задержанные значения супертенденции с помощью f_getSupertrend для отслеживания стоп-лосса.
После вычисления показателей стратегия вызывает f_getBuySellStops для вычисления остановок входа и целевых показателей прибыли на основе значений показателя. В частности, она вычисляет ATR и использует ATR умноженное на коэффициент стоп-лосса в качестве остановки входа, и ATR умноженное на коэффициент прибыли в качестве целевой прибыли. Остановки и цели будут корректироваться при обратном тренде.
Следующим шагом, стратегия определяет направление свечи. Свечи восходящего тренда окрашены в зеленый цвет, а свечи нисходящего тренда - в красный цвет. После составления графиков свечей и индикаторов стратегия проверяет, соблюдены ли условия входа. Условия входа - покупка, когда индикатор показывает перекупленность и цена превышает верхнюю полосу, и продажа, когда индикатор показывает перепроданность и цена превышает нижнюю полосу. Существует также условие фильтрации, требующее, чтобы цена превышала скользящую среднюю за более длительный период времени.
После входа, стоп-лосс следует за верхней/нижней полосой, в зависимости от того, что ближе. Когда стоп-лосс запускается, позиция закрывается. Когда цена достигает целевой прибыли, частичная прибыль принимается.
Преимущества этой стратегии:
Использование осцилляторов для определения направления тренда может своевременно уловить краткосрочные возможности реверсии.
Применение отсроченного стоп-лосса супертендента может остановить потерю до увеличения потерь, ограничивая потерю на одной сделке.
Расчет стоп-лосса и целевой прибыли на основе динамического ATR помогает скорректировать размер позиции.
Фильтрация с более высокими временными рамками скользящей средней позволяет избежать попадания в ловушку консолидации.
Частичное получение прибыли позволяет заработать прибыль, закрепляя прибыль.
Логика проста и понятна для начинающих торговцев.
Некоторые риски этой стратегии включают:
Осилляторы могут иметь задержки, вызывающие задержку входа и преждевременные сигналы выхода. Это может быть улучшено путем оптимизации параметров или добавления следующих индикаторов тренда.
Диапазон стоп-лосса может быть расширен или можно использовать динамические стопы, такие как Chandelier.
Оставшиеся позиции после частичного получения прибыли могут быть прекращены.
Стратегия должна быть подтверждена на разных рынках.
Неисправность фильтра скользящей средней за более длительный период времени.
Стратегия может быть оптимизирована в следующих аспектах:
Испытайте различные комбинации параметров осцилляторов и найдите те, которые обеспечивают качественные сигналы.
Попробуйте заменить частичное получение прибыли на остановку прибыли, основанную на ATR или скользящих средних.
Добавить алгоритмы машинного обучения для замены скользящей средней для анализа трендов и повышения точности.
Добавить показатели объема в качестве условий фильтрации, чтобы избежать ненужных отмен.
Сбор и взвешивание показателей оптимизации для поиска оптимальной комбинации для актива.
Добавьте модули управления рисками машинного обучения для динамической оптимизации остановок, целей и размеров позиций.
Включить треугольный арбитраж или базовые торговые сигналы с использованием спредов цен между фьючерсами и спотом.
В целом, это отличная стратегия для начинающих торговцев с четкой логикой, ориентированной на индикаторы и управление рисками. Но оптимизация параметров и снижение риска все еще необходимы для живой торговли. Она также может быть улучшена в таких аспектах, как анализ трендов, оптимизация остановки убытков, модели ансамбля и т. Д., Чтобы улучшить надежность.
/*backtest start: 2023-08-26 00:00:00 end: 2023-09-25 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © HeWhoMustNotBeNamed //@version=4 strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true) oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"]) length = input(3) shortlength = input(3) longlength = input(9) showSupertrend = input(true) AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"]) AtrLength = input(30, step=10) stopMultiplier = input(4) targetMultiplier = input(3) wicks = input(true) considerWicksForDelayByStep = input(false) colorByPreviousClose = input(true) useHTFPivot = input(false) resolution = input("12M", type=input.resolution) HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1) PivotLength = input(2, step=1) tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short]) i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time) i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time) inDateRange = true f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=> oOpen = rsi(open, length) oClose = rsi(close, length) oHigh = rsi(high, length) oLow = rsi(low, length) if(oscilatorType == "tsi") oOpen := tsi(open, shortlength, longlength) oClose := tsi(close, shortlength, longlength) oHigh := tsi(high, shortlength, longlength) oLow := tsi(low, shortlength, longlength) if(oscilatorType == "stoch") oOpen := stoch(open, longlength, shortlength, length) oClose := stoch(close, longlength, shortlength, length) oHigh := stoch(high, longlength, shortlength, length) oLow := stoch(low, longlength, shortlength, length) if(oscilatorType == "cci") oOpen := cci(open, length) oClose := cci(close, length) oHigh := cci(high, length) oLow := cci(low, length) if(oscilatorType == "cog") oOpen := cog(open, length) oClose := cog(close, length) oHigh := cog(high, length) oLow := cog(low, length) if(oscilatorType == "cmo") oOpen := cmo(open, length) oClose := cmo(close, length) oHigh := cmo(high, length) oLow := cmo(low, length) if(oscilatorType == "mfi") oOpen := mfi(open, length) oClose := mfi(close, length) oHigh := mfi(high, length) oLow := mfi(low, length) if(oscilatorType == "macd") [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length) [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length) [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length) [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length) oOpen := macdLineOpen oClose := macdLineClose oHigh := macdLineHigh oLow := macdLineLow [oOpen, oClose, oHigh, oLow] f_getMovingAverage(source, MAType, length)=> ma = sma(source, length) if(MAType == "ema") ma := ema(source,length) if(MAType == "hma") ma := hma(source,length) if(MAType == "rma") ma := rma(source,length) if(MAType == "vwma") ma := vwma(source,length) if(MAType == "wma") ma := wma(source,length) ma f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=> truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1]) averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength) atr = averagetruerange * stopMultiplier longStop = oClose - atr longStopPrev = nz(longStop[1], longStop) longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop shortStop = oClose + atr shortStopPrev = nz(shortStop[1], shortStop) shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop dir = 1 dir := nz(dir[1], dir) dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir trailingStop = dir == 1? longStop : shortStop [dir, trailingStop] f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=> barState = 0 source = oClose truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1]) atr = f_getMovingAverage(truerange, AtrMAType, AtrLength) buyStop = source - atr * stopMultiplier sellStop = source + atr * stopMultiplier buyStopDerived = buyStop sellStopDerived = sellStop highTarget = considerWicks ? oHigh : source lowTarget = considerWicks ? oLow : source highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0) buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier buyStop := source - atr * buyMultiplier sellStop := source + atr * sellMultiplier buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop buyStopDerived := buyStop sellStopDerived := sellStop buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived [buyStopDerived, sellStopDerived, barState] f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off) f_multiple_resolution(HTFMultiplier) => target_Res_In_Min = timeframe.multiplier * HTFMultiplier * ( timeframe.isseconds ? 1. / 60. : timeframe.isminutes ? 1. : timeframe.isdaily ? 1440. : timeframe.isweekly ? 7. * 24. * 60. : timeframe.ismonthly ? 30.417 * 24. * 60. : na) target_Res_In_Min <= 0.0417 ? "1S" : target_Res_In_Min <= 0.167 ? "5S" : target_Res_In_Min <= 0.376 ? "15S" : target_Res_In_Min <= 0.751 ? "30S" : target_Res_In_Min <= 1440 ? tostring(round(target_Res_In_Min)) : tostring(round(min(target_Res_In_Min / 1440, 365))) + "D" f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=> derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh) HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow) CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose) pivothi = pivothigh(HTFHigh, PivotLength, PivotLength) pivotlo = pivotlow(HTFLow, PivotLength, PivotLength) pivothi := na(pivothi)? nz(pivothi[1]) : pivothi pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo [pivothi, pivotlo] [oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength) [dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks) candleColor = colorByPreviousClose ? (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver) plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor) [buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier) trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red) [pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength) buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot) exitBuyConditin = (barState == -1) sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot) exitSellCondition = (barState == 1) // strategy.risk.allow_entry_in(tradeDirection) strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca") strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca") strategy.close("Buy", when = exitBuyConditin) strategy.close( "Sell", when = exitSellCondition)