Стратегия прорыва


Дата создания: 2024-01-31 17:06:36 Последнее изменение: 2024-01-31 17:06:36
Копировать: 0 Количество просмотров: 1280
1
Подписаться
1617
Подписчики

Стратегия прорыва

Обзор

Основная идея этой стратегии заключается в том, чтобы идентифицировать направление тенденции на более крупных временных рамках и находить точки прорыва на более мелких временных рамках, а стоп-экзит отслеживает движущиеся средние на более крупных временных рамках.

Стратегический принцип

Эта стратегия основана на трех показателях:

Во-первых, рассчитывая X-дневную простую скользящую среднюю на более длительный период (например, солнечную линию), покупать разрешается только тогда, когда эта скользящая средняя находится на ценовом участке. Это может быть использовано для определения направления общей тенденции и избежания периодов колебаний торговли.

Во-вторых, рассчитывается максимальная цена Swing High в течение более короткого периода (например, 5 дней), когда цена превышает эту максимальную цену, что вызывает сигнал покупки. Здесь в сочетании с циклическим параметром lb для поиска подходящей точки прорыва.

В-третьих, создать линию стоп-убытков. После входа в позицию линия стоп-убытков замыкается на минимальной цене определенного цикла lbStop, находящейся на расстоянии от ближайшего минимума. При этом устанавливается движущаяся средняя (например, 10-дневная ЭМА на солнечной линии) в качестве механизма выхода из позиции, когда цена ниже этой движущейся средней.

В этой стратегии также устанавливается значение ATR, чтобы избежать покупки избыточного количества точек. Кроме того, существуют другие дополнительные условия, такие как диапазон времени отсчета.

Взаимодействие этих трех показателей формирует центральную логику этой стратегии.

Анализ преимуществ стратегии

Это прорывная стратегия слежения, обладающая следующими преимуществами:

  1. Используйте две временные рамки, чтобы избежать ложных прорывов в волатильных рынках. Более длинные временные рамки - для оценки общей тенденции, более короткие - для поиска конкретных точек входа.

  2. С помощью прорывов, сформированных с помощью Swing High, такие прорывы имеют определенную инерцию и легко формируют отслеживание. При этом можно скорректировать параметр lb для поиска действительно эффективных прорывов.

  3. Стойкость к убыткам является более строгой, она отслеживает недавние низкие точки и оставляет определенную буферную дистанцию, чтобы избежать потери.

  4. Использование скользящих средних как механизма выхода позволяет гибко останавливать прибыль в зависимости от ситуации.

  5. Показатель ATR позволяет избежать рисков, связанных с избыточным выбросом.

  6. Можно установить различные комбинации параметров для тестирования эффекта, есть большой простор для оптимизации.

Анализ рисков

Однако эта стратегия несет в себе определенные риски:

  1. Когда цена колеблется вверх и вниз вблизи скользящего среднего, она может быть переключена вверх и вниз. При этом существует риск более высоких комиссионных.

  2. При прорыве точки покупки, близкой к движущейся средней, существует более высокий риск вывода. Это свойственно самой стратегии.

  3. Если рынок не имеет явных тенденций, то долгое время может быть слишком длительным, что создает риски.

  4. Необходимо разумно установить параметры ATR. Если ATR слишком маленький, фильтрация будет слабой, а если он слишком большой, то шансы на поступление будут уменьшены.

  5. Необходимо проверить влияние различных параметров lb на результаты. Слишком большие параметры могут пропустить часть возможностей, слишком маленькие параметры могут идентифицировать ложные прорывы.

Решение риска:

  1. Устройство параметров скользящих средних для повышения эффекта фильтрации.
  2. Оптимизация параметров ATR и визуальное оценивание.
  3. Настройка возвращается на цикл lb, чтобы найти оптимальные параметры.
  4. Приостановка торговли в условиях потрясений.

Направление оптимизации стратегии

Эта стратегия также может быть оптимизирована в следующих аспектах:

  1. Тестирование различных комбинаций параметров для поиска оптимального значения для скользящей средней.

  2. Попробуйте различные параметры ATR, чтобы сбалансировать возможности входа и контроль риска.

  3. Оптимизируйте обратный цикл lb для выявления более эффективных прорывов.

  4. Попытка создания динамического стоп-ущерба, с учетом риска волатильности и снятия.

  5. Эффективность прорыва оценивается в сочетании с другими факторами, такими как показатель объема торгов.

  6. Разработать методы поиска критических точек в качестве ориентира.

  7. Попробуйте Machine Learning для обучения параметров, чтобы получить оптимальные параметры

Подвести итог

Стратегия в целом является типичной стратегией отслеживания прорыва. Судьба двойных временных рамок, Swing High, идентифицирующая входный момент, стоп-линию и двойную страховку для выхода из движущейся средней, образует целостную логическую систему. Характеристика риска и прибыли стратегии более четкая и подходит для инвесторов среднего и длинного типа.

Исходный код стратегии
/*backtest
start: 2023-01-24 00:00:00
end: 2024-01-30 00:00:00
period: 1d
basePeriod: 1h
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/
// © millerrh

// The intent of this strategy is to buy breakouts with a tight stop on smaller timeframes in the direction of the longer term trend.
// Then use a trailing stop of a close below either the 10 MA or 20 MA (user choice) on that larger timeframe as the position 
// moves in your favor (i.e. whenever position price rises above the MA).
// Option of using daily ATR as a measure of finding contracting ranges and ensuring a decent risk/reward.
// (If the difference between the breakout point and your stop level is below a certain % of ATR, it could possibly find those consolidating periods.)

//@version=4
strategy("Qullamaggie Breakout", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)
   
// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", type = input.time)
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", type = input.time)

// Inputs
lb = input(defval = 3, title = "Lookback Period for Swing High", minval = 1,
   tooltip = "Lookback period for defining the breakout level.")
lbStop = input(defval = 3, title = "Lookback Bars for Stop Level", minval = 1,
   tooltip = "Initial stop placement is the lowest low this many bars back. Allows for tighter stop placement than referencing swing lows.")  
htf = input(defval="D", title="Timeframe of Moving Averages", type=input.resolution,
  tooltip = "Allows you to set a different time frame for the moving averages. The default behavior is to identify good tightening setups on a larger timeframe
  (like daily) and enter the trade on a breakout occuring on a smaller timeframe, using the moving averages of the larger timeframe to trail your stop.")
maType = input(defval="SMA", options=["EMA", "SMA"], title = "Moving Average Type")
ma1Length = input(defval = 10, title = "1st Moving Average Length", minval = 1)
ma2Length = input(defval = 20, title = "2nd Moving Average Length", minval = 1)
ma3Length = input(defval = 50, title = "3rd Moving Average Length", minval = 1)
useMaFilter = input(title = "Use 3rd Moving Average for Filtering?", type = input.bool, defval = true,
  tooltip = "Signals will be ignored when price is under this slowest moving average.  The intent is to keep you out of bear periods and only
             buying when price is showing strength or trading with the longer term trend.")
trailMaInput = input(defval="2nd Moving Average", options=["1st Moving Average", "2nd Moving Average"], title = "Trailing Stop")

// MA Calculations
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
ma1 = security(syminfo.tickerid, htf, ma(maType, close, ma1Length))
ma2 = security(syminfo.tickerid, htf, ma(maType, close, ma2Length))
ma3 = security(syminfo.tickerid, htf, ma(maType, close, ma3Length))

plot(ma1, color=color.purple, style=plot.style_line, title="MA1", linewidth=2, transp = 60)
plot(ma2, color=color.yellow, style=plot.style_line, title="MA2", linewidth=2, transp = 60)
plot(ma3, color=color.white, style=plot.style_line, title="MA3", linewidth=2, transp = 60)

// === USE ATR FOR FILTERING ===
// The idea here is that you want to buy in a consolodating range for best risk/reward. So here you can compare the current distance between 
// support/resistance vs.the ATR and make sure you aren't buying at a point that is too extended from normal.
useAtrFilter = input(title = "Use ATR for Filtering?", type = input.bool, defval = false,
  tooltip = "Signals will be ignored if the distance between support and resistance is larger than a user-defined percentage of Daily ATR. 
             This allows the user to ensure they are not buying something that is too extended and instead focus on names that are consolidating more.")
atrPerc = input(defval = 100, title = "% of Daily ATR Value", minval = 1)
atrValue = security(syminfo.tickerid, "D", atr(14))*atrPerc*.01

// === PLOT SWING HIGH/LOW AND MOST RECENT LOW TO USE AS STOP LOSS EXIT POINT ===
// Change these values to adjust the look back and look forward periods for your swing high/low calculations
pvtLenL = lb
pvtLenR = lb

// Get High and Low Pivot Points
pvthi_ = pivothigh(high, pvtLenL, pvtLenR)
pvtlo_ = pivotlow(low, pvtLenL, pvtLenR)

// Force Pivot completion before plotting.
Shunt = 1 //Wait for close before printing pivot? 1 for true 0 for flase
maxLvlLen = 0 //Maximum Extension Length
pvthi = pvthi_[Shunt]
pvtlo = pvtlo_[Shunt]

// Count How many candles for current Pivot Level, If new reset.
counthi = barssince(not na(pvthi))
countlo = barssince(not na(pvtlo))
 
pvthis = fixnan(pvthi)
pvtlos = fixnan(pvtlo)
hipc = change(pvthis) != 0 ? na : color.maroon
lopc = change(pvtlos) != 0 ? na : color.green

// Display Pivot lines
plot((maxLvlLen == 0 or counthi < maxLvlLen) ? pvthis : na, color=hipc, transp=0, linewidth=1, offset=-pvtLenR-Shunt, title="Top Levels")
// plot((maxLvlLen == 0 or countlo < maxLvlLen) ? pvtlos : na, color=lopc, transp=0, linewidth=1, offset=-pvtLenR-Shunt, title="Bottom Levels")
plot((maxLvlLen == 0 or counthi < maxLvlLen) ? pvthis : na, color=hipc, transp=0, linewidth=1, offset=0, title="Top Levels 2")
// plot((maxLvlLen == 0 or countlo < maxLvlLen) ? pvtlos : na, color=lopc, transp=0, linewidth=1, offset=0, title="Bottom Levels 2")

// BUY CONDITIONS
stopLevelCalc = valuewhen(pvtlo_, low[pvtLenR], 0) //Stop Level at Swing Low
buyLevel = valuewhen(pvthi_, high[pvtLenR], 0) //Buy level at Swing High
plot(buyLevel, style=plot.style_line, color=color.blue, title = "Current Breakout Level", show_last=1, linewidth=1, transp=50, trackprice=true)

// Conditions for entry and exit
stopLevel = float(na) // Define stop level here as "na" so that I can reference it in the inPosition 
  // variable and the ATR calculation before the stopLevel is actually defined.
buyConditions = (useMaFilter ? buyLevel > ma3 : true) and
  (useAtrFilter ? (buyLevel - stopLevel[1]) < atrValue : true)
// buySignal = high > buyLevel and buyConditions
buySignal = crossover(high, buyLevel) and buyConditions
trailMa = trailMaInput == "1st Moving Average" ? ma1 : ma2
sellSignal = crossunder(close, trailMa)
// sellSignal = security(syminfo.tickerid, htf, close < trailMa) and security(syminfo.tickerid, htf, close[1] < trailMa)


// STOP AND PRICE LEVELS
inPosition = bool(na)
inPosition := buySignal[1] ? true : sellSignal[1] ? false : low <= stopLevel[1] ? false : inPosition[1]

lowDefine = lowest(low, lbStop)
stopLevel := inPosition ? stopLevel[1] : lowDefine
// plot(stopLevel)

buyPrice = buyLevel
buyPrice := inPosition ? buyPrice[1] : buyLevel
plot(stopLevel, style=plot.style_line, color=color.orange, title = "Current Stop Level", show_last=1, linewidth=1, transp=50, trackprice=true)
plot(inPosition ? stopLevel : na, style=plot.style_circles, color=color.orange, title = "Historical Stop Levels", transp=50, trackprice=false)
// plot(buyPrice, style=plot.style_line, color=color.blue, linewidth=1, transp=50, trackprice=true)

// (STRATEGY ONLY) Comment out for Study
strategy.entry("Long", strategy.long, stop = buyLevel, when = buyConditions)
strategy.exit("Exit Long", from_entry = "Long", stop=stopLevel[1])
if (low[1] > trailMa)
    strategy.close("Long", when = sellSignal)
// if (low[1] > trailMa)
//     strategy.exit("Exit Long", from_entry = "Long", stop=trailMa) //to get this to work right, I need to reference highest highs instead of swing highs
    //because it can have me buy right back in after selling if the stop level is above the last registered swing high point.