Squeeze Momentum Breakout Strategy

Author: ChaoZhang, Date: 2024-01-30 17:33:49
Tags:

img

Overview

This is a quantitative trading strategy developed based on LazyBear’s Momentum Squeeze indicator. The strategy integrates Bollinger Bands, Keltner Channels, and momentum indicators to achieve high-win-rate momentum breakout trading through the combination of multiple technical indicators.

Strategy Logic

The core indicator of this strategy is LazyBear’s Momentum Squeeze indicator. This indicator determines if the Bollinger Bands are being “squeezed” by the Keltner Channels. When the squeeze occurs, it represents that the market has entered a potential outbreak point. By combining the direction of the momentum indicator, trades can be taken when the squeeze releases to capture the market outbreak.

Specifically, the strategy first calculates the 21-period Bollinger Bands, with a width of 2 standard deviations of the price. At the same time, it calculates the 20-period Keltner Channels, with a width of 1.5 times the price amplitude. When the Bollinger Bands are “squeezed” by the Keltner Channels, a squeeze signal is triggered. In addition, the strategy also calculates the momentum of the price relative to the mid-point of its own price channel over a period of time. When a squeeze occurs, combined with the directionality of the momentum indicator, it determines whether to buy or sell.

For exits, when the color of the momentum indicator changes to gray, it represents that the squeeze state has ended and the trend may reverse.

Advantages

  1. Integrates multiple technical indicators to improve accuracy

By judging the overall relationship between these indicators, the accuracy of trading decisions can be improved and the probability of erroneous trades reduced.

  1. Accurate momentum squeeze points with large profit potential

The momentum squeeze strategy can capture key points where the market is likely to outbreak. These points are often inflection points where the market makes important directional judgments. If judged correctly, the subsequent market movement will be relatively long, so the potential profit space of the strategy is great.

  1. Achieve high-success-rate breakout trading

Compared to random breakout trading, the entry point selected by this strategy is at the squeeze point between Bollinger Bands and Keltner Channels. Through the integrated indicator judgement, the trading success rate is very high.

Risks

  1. Risk of improper parameter settings

The cycle parameters and bandwidth parameters of the Bollinger Bands and Keltner Channels have a great impact on the trading results. If the parameters are set inappropriately, misjudgements may occur. This requires finding the optimal parameters through a lot of backtesting.

  1. Breakout failure risk

There is always a risk that the price may retrace after breaking through the point selected by this strategy, causing a loss. This needs to be strictly stopped out to control losses.

  1. Trend reversal risk

When the squeeze state ends, this strategy will close all positions. However, sometimes the price trend may still continue, which poses the risk of premature exit. The exit logic needs to be optimized.

Optimization Directions

  1. Optimize parameter settings

Through more backtesting data tryouts, better cycle and bandwidth parameter settings can be found to improve strategy performance.

  1. Add stop loss strategy

Set moving or oscillating stops to quickly cut losses when prices reverse.

  1. Add re-entry conditions

When the strategy exits positions, certain re-entry conditions can be set to re-enter the market if the trend continues.

  1. Incorporate more indicators

Try to incorporate more indicators of different types, such as other volatility indicators, volume indicators, etc., to establish a composite strategy of indicator integration, so as to improve the accuracy of decisions.

Summary

The strategy integrates Bollinger Bands, Keltner Channels and momentum indicators. By judging the relationships between these indicators, it enters at high success rate breakout points. There are optimization spaces in many aspects such as parameter optimization, stop loss strategies, re-entry conditions, and composite indicator integration to further improve strategy performance.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//All credits to LazyBear. All I did was turn it into a strategy!

strategy(title = "SQZMOM STRAT", overlay=false)

// --- GENERAL INPUTS ---
FromMonth = input(defval = 4, title = "From Month", minval = 1, maxval = 12)
FromYear  = input(defval = 2020, title = "From Year", minval = 2012)
ToMonth   = input(defval = 1, title = "To Month", minval = 1, maxval = 12)
ToYear    = input(defval = 9999, title = "To Year", minval = 2017)
FromDay   = 1
ToDay     = 1
start     = timestamp(FromYear, FromMonth, FromDay, 00, 00)  // backtest start window
finish    = timestamp(ToYear, ToMonth, ToDay, 23, 59)        // backtest finish window
window()  => true

get_round(value, precision) => round(value * (pow(10, precision))) / pow(10, precision)
trade_leverage = input(1, title = "Trade - Leverage", step = 0.25)
trade_risk     = input(100, title = "Trade - Risk Percent", type = input.float, step = 0.1, minval = 0.1, maxval = 100)
tradeType   = input("LONG", title="What trades should be taken : ", options=["LONG", "SHORT", "BOTH"])

// --- SQZMOM CODE

length = input(21, title="BB Length")
mult = input(2.0,title="BB MultFactor")
lengthKC=input(20, title="KC Length")
multKC = input(1.5, title="KC MultFactor")

useTrueRange = input(true, title="Use TrueRange (KC)", type=input.bool)

// Calculate BB
source = close
basis = sma(source, length)
dev = multKC * stdev(source, length)
upperBB = basis + dev
lowerBB = basis - dev

// Calculate KC
ma = sma(source, 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(source  -  avg(avg(highest(high, lengthKC), lowest(low, lengthKC)),sma(close,lengthKC)), lengthKC,0)

bcolor = color.gray
if (val > 0 and val > nz(val[1]))
    bcolor := color.green
if (val < 0 and val < nz(val[1]))
    bcolor := color.red

scolor = noSqz ? color.blue : sqzOn ? color.black : color.gray 
plot(val, color=bcolor, style=plot.style_histogram, linewidth=4)
plot(0, color=scolor, style=plot.style_cross, linewidth=2)

// --- VWMA CODE ---
useVWMA        = input(false, title = "Use VWMA to selectively long/short?", type = input.bool)
lengthVWMA=input(42, title = "VWMA Length", step = 1, minval = 1)
useCV=input(false, type=input.bool, title="Use Cumulative Volume for VWMA?")
nbfs = useCV ? cum(volume) : sum(volume, lengthVWMA)
medianSrc=close

calc_evwma(price, lengthVWMA, nb_floating_shares) => data = (nz(close[1]) * (nb_floating_shares - volume)/nb_floating_shares) + (volume*price/nb_floating_shares)

m=calc_evwma(medianSrc, lengthVWMA, nbfs)


// ---STRATEGY---
if ((tradeType == "LONG" or tradeType == "BOTH") and (m>0 or useVWMA == false))
    longCondition = (val > 0 and noSqz == 0 and sqzOn == 0 and sqzOn[1] == 1)
    if (longCondition)
        contracts = get_round((strategy.equity * trade_leverage / close) * (trade_risk / 100), 4)
        strategy.entry("LONG", strategy.long, qty = contracts, when = window())
        
if((tradeType == "SHORT" or tradeType == "BOTH") and (m<0 or useVWMA == false))
    shortCondition = (val < 0 and noSqz == 0 and sqzOn == 0 and sqzOn[1] == 1)
    if (shortCondition)
        contracts = get_round((strategy.equity * trade_leverage / close) * (trade_risk / 100), 4)
        strategy.entry("SHORT", strategy.short, qty = contracts, when = window())

if (bcolor == color.gray)
    strategy.close("LONG")
    strategy.close("SHORT")

More