Эта стратегия основана на индикаторе Squeeze Momentum LazyBear
Вычислить среднюю полосу, верхнюю полосу и нижнюю полосу полос Боллинджера. Средняя полоса - это n-дневная простая скользящая средняя цена закрытия, верхняя и нижняя полосы - это средняя полоса плюс/минус м раз стандартное отклонение n-дневной цены закрытия.
Вычислить среднюю линию, верхнюю линию и нижнюю линию каналов Келтнера. Средняя линия - это n-дневная простая скользящая средняя цена закрытия, верхняя и нижняя линии - это средняя линия плюс/минус м умноженная на n-дневную простая скользящая средняя цена истинного диапазона.
Определить, проходит ли цена через верхнюю или нижнюю полосу полос Боллинджера и каналов Келтнера, чтобы сформировать паттерны сжатия и расширения. Сжатие образуется, когда цена проходит через нижнюю полосу, а расширение образуется, когда цена проходит через верхнюю полосу.
Вычислить значение кривой линейной регрессии в качестве индикатора импульса.
Комбинируйте модели сжатия/расширения, направление импульса, среднюю фильтрацию и другие условия для определения окончательных торговых сигналов.
Использование двойной фильтрации полос Боллинджера и каналов Келтнера для выявления качественных моделей сжатия и расширения.
Индикатор импульса может своевременно отслеживать изменение ценового тренда, дополняя индикаторы канала.
Позвольте начать раньше, чтобы увеличить возможности получения прибыли.
Adopt multiple condition judgment to avoid over-trading during ranging markets. Принять множественное условное суждение, чтобы избежать чрезмерной торговли во время различных рынков.
Параметры технических показателей могут быть настраиваются, адаптируясь к различным продуктам и комбинациям параметров.
Временные рамки обратных испытаний могут быть настроены на оптимизацию в течение конкретных периодов.
Стратегии, следующие тренду, склонны к потерям при обратном тренде.
Неправильное настройка параметров может привести к чрезмерной торговле или плохому качеству сигнала.
Опираться на исторические данные не может гарантировать стабильную будущую доходность.
Не в состоянии справиться с турбулентностью на рынке и резкими колебаниями цен, вызванными событиями черного лебедя.
Неправильные настройки окна времени обратного тестирования могут привести к перенастройке.
Оптимизировать параметры полос Боллинджера и каналов Келтнера для поиска наилучшей комбинации.
Проверка добавления стоп-лосса для контроля максимальной потери на одну сделку.
Попытки дальнейшей оптимизации для конкретных продуктов и комбинаций периодов/параметров.
Исследуйте интеграцию моделей машинного обучения для определения тенденций.
Испытать различные стратегии последовательности ввода и размеров позиций.
Исследуйте, как определить сигналы об изменениях тренда и выйти вовремя.
By customizing parameters and using multiple condition filters, it can effectively control trading frequency and improve signal quality. But reversal trades and black swan events should still be watched out for. Further exploring trend reversal signals and risk control mechanisms can be done to make the strategy more robust. Но реверсивные сделки и события черного лебедя все еще следует следить за ними.
/*backtest start: 2022-11-06 00:00:00 end: 2023-11-12 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 //Strategy based on LazyBear Squeeze Momentum Indicator //I added some custom feature and filters // // @author LazyBear // List of all my indicators: // https://docs.google.com/document/d/15AGCufJZ8CIUvwFJ9W-IKns88gkWOKBCvByMEvm5MLo/edit?usp=sharing // v2 - fixed a typo, where BB multipler was always stuck at 1.5. [Thanks @ucsgears] // strategy(shorttitle = "SQZMOM_LB", title="Strategy for Squeeze Momentum Indicator [LazyBear]", overlay=false, calc_on_every_tick=true, pyramiding=0,default_qty_type=strategy.percent_of_equity,default_qty_value=100,currency=currency.USD) length = input(14, title="BB Length") mult = input(2.0,title="BB MultFactor") lengthKC=input(16, title="KC Length") multKC = input(1.5, title="KC MultFactor") useTrueRange = input(true, title="Use TrueRange (KC)", type=bool) //FILTERS useExtremeOrders = input(false, title="Early entry on momentum change", type=bool) useMomAverage = input(false, title="Filter for Momenutum value", type=bool) MomentumMin = input(20, title="Min for momentum") // Calculate BB src = close basis = sma(src, length) dev = mult * stdev(src, length) upperBB = basis + dev lowerBB = basis - dev // Calculate KC ma = sma(src, lengthKC) range = useTrueRange ? tr : (high - low) rangema = sma(range, lengthKC) upperKC = ma + rangema * multKC lowerKC = ma - rangema * multKC sqzOn = (lowerBB > lowerKC) and (upperBB < upperKC) sqzOff = (lowerBB < lowerKC) and (upperBB > upperKC) noSqz = (sqzOn == false) and (sqzOff == false) val = linreg(src - avg(avg(highest(high, lengthKC), lowest(low, lengthKC)),sma(close,lengthKC)), lengthKC,0) bcolor = iff( val > 0, iff( val > nz(val[1]), lime, green), iff( val < nz(val[1]), red, maroon)) scolor = noSqz ? blue : sqzOn ? black : aqua plot(val, color=bcolor, style=histogram, linewidth=4) plot(0, color=scolor, style=cross, linewidth=2) //LOGIC //momentum filter filterMom=useMomAverage?abs(val)>(MomentumMin/100000)?true:false:true //standard condition longCondition = scolor[1]!=aqua and scolor==aqua and bcolor==lime and filterMom exitLongCondition = bcolor==green and not useExtremeOrders shortCondition = scolor[1]!=aqua and scolor==aqua and bcolor==red and filterMom exitShortCondition = bcolor==maroon and not useExtremeOrders //early entry extremeLong= useExtremeOrders and scolor==aqua and bcolor==maroon and bcolor[1]!=bcolor[0] and filterMom exitExtLong = scolor==black or bcolor==red extremeShort = useExtremeOrders and scolor==aqua and bcolor==green and bcolor[1]!=bcolor[0] and filterMom exitExtShort = scolor==black or bcolor==lime //STRATEGY strategy.entry("SQ_Long", strategy.long, when = longCondition) strategy.close("SQ_Long",when = exitLongCondition ) strategy.entry("SQ_Long_Ext", strategy.long, when = extremeLong) strategy.close("SQ_Long_Ext",when = exitExtLong) //strategy.exit("exit Long", "SQ_Long", when = exitLongCondition) strategy.entry("SQ_Short", strategy.short, when = shortCondition) strategy.close("SQ_Short",when = exitShortCondition) strategy.entry("SQ_Short_Ext", strategy.short, when = extremeShort) strategy.close("SQ_Short_Ext",when = exitExtShort) //strategy.exit("exit Short", "SQ_Short", when = exitShortCondition) // // === Backtesting Dates === thanks to Trost // testPeriodSwitch = input(true, "Custom Backtesting Dates") // testStartYear = input(2018, "Backtest Start Year") // testStartMonth = input(1, "Backtest Start Month") // testStartDay = input(1, "Backtest Start Day") // testStartHour = input(0, "Backtest Start Hour") // testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0) // testStopYear = input(2018, "Backtest Stop Year") // testStopMonth = input(12, "Backtest Stop Month") // testStopDay = input(14, "Backtest Stop Day") // testStopHour = input(23, "Backtest Stop Hour") // testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0) // testPeriod() => // time >= testPeriodStart and time <= testPeriodStop ? true : false // isPeriod = testPeriodSwitch == true ? testPeriod() : true // // === /END // if not isPeriod // strategy.cancel_all() // strategy.close_all()