Strategy vault / Machine learning
Dual Moving Average Matching Strategy Based on Bollinger Bands
The dual moving average matching strategy based on Bollinger Bands is a trend-following strategy that runs with price and volume in the market. It uses the crossover of Bollinger Bands and moving averages as trading…

Overview
The dual moving average matching strategy based on Bollinger Bands is a trend-following strategy that runs with price and volume in the market. It uses the crossover of Bollinger Bands and moving averages as trading signals to implement a quantitative strategy that can automatically identify market trends and trade with stop profit and stop loss rules.
Strategy Principle
This strategy is mainly based on the crossover signals of the Bollinger Bands indicator and the moving average indicator for trading. Specifically, it uses the middle rail, upper rail of Bollinger Bands, and 7 moving averages with lengths from 5 to 200 days at the same time. It generates a buy signal when the price breaks through the middle and lower rails of the Bollinger Bands from bottom to top; it generates a sell signal when the price breaks through the upper rail of the Bollinger Bands from top to bottom to achieve trend following.
In addition, the strategy also introduces the moveToFract indicator for judging long and short positions. This indicator determines whether the current market trend is up or down by calculating the order of arrangement of short-term and long-term moving averages, thus avoiding generating wrong signals in range-bound markets. Finally, combined with configurable stop profit and stop loss rules, it forms a more complete trend following trading strategy.
Advantage Analysis
- Flexible configuration that can customize parameter combinations to suit different market environments
- Combining two different indicators as filters can reduce erroneous signals
- Trend judging indicator can avoid reverse operations in volatile markets
- Tracking stop loss setting maximizes profits
Risk Analysis
- Parameters should be adjusted appropriately to suit cycles of different timeframes to avoid over-trading
- Tracking stop loss may expand losses in a fast decline
- Must ensure sufficient funds, otherwise unable to withstand the risk of continuous losses
Optimization Directions
- Add golden cross and death cross judgments to further optimize
- Different varieties have different parameters, consider machine learning for optimal parameters
- Combine with volatility index to determine trend volatility and strengthen risk control
Conclusion
In general, this is a very practical trend following strategy. It uses indicator crossover for decision making, and also incorporates a trend judging module to effectively filter out wrong signals. After configuring stop profit and stop loss, it can fully follow trends for trading and obtain good returns. By adjusting parameter combinations and adding more filters, this strategy can be further optimized to adapt to more market environments, and has great room for improvement and application prospects.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_1 | 0 | Moving Average Type: sma | ema | hma | rma | vwma | wma |
| v_input_2 | 0 | Exit Strategy: Signal | TrailingStop | Both |
| v_input_3 | 30 | LookbackPeriod |
| v_input_4 | 2 | BBStdDev |
| v_input_5 | 60 | BBLength |
| v_input_6 | 22 | atrLength |
| v_input_7 | 6 | atrMult |
| v_input_8 | 0 | Trade Direction: strategy.direction.all | strategy.direction.long | strategy.direction.short |
| v_input_9 | 10 | backtestYears |
Source Pine Script
/*backtest
start: 2023-10-24 00:00:00
end: 2023-11-23 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("BuyTheDip", overlay=true, initial_capital = 100000, 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)
MAType = input(title="Moving Average Type", defval="sma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
exitType = input(title="Exit Strategy", defval="Signal", options=["Signal", "TrailingStop", "Both"])
LookbackPeriod = input(30, minval=10,step=10)
BBStdDev = input(2, minval=1, maxval=10, step=0.5)
BBLength = input(60, minval=5, step=5)
atrLength = input(22)
atrMult = input(6)
tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
backtestYears = input(10, minval=1, step=1)
includePartiallyAligned = true
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_getTrailingStop(atr, atrMult)=>
stop = close - atrMult*atr
stop := strategy.position_size > 0 ? max(stop, stop[1]) : stop
stop
f_getMaAlignment(MAType, includePartiallyAligned)=>
ma5 = f_getMovingAverage(close,MAType,5)
ma10 = f_getMovingAverage(close,MAType,10)
ma20 = f_getMovingAverage(close,MAType,20)
ma30 = f_getMovingAverage(close,MAType,30)
ma50 = f_getMovingAverage(close,MAType,50)
ma100 = f_getMovingAverage(close,MAType,100)
ma200 = f_getMovingAverage(close,MAType,200)
upwardScore = 0
upwardScore := close > ma5? upwardScore+1:upwardScore
upwardScore := ma5 > ma10? upwardScore+1:upwardScore
upwardScore := ma10 > ma20? upwardScore+1:upwardScore
upwardScore := ma20 > ma30? upwardScore+1:upwardScore
upwardScore := ma30 > ma50? upwardScore+1:upwardScore
upwardScore := ma50 > ma100? upwardScore+1:upwardScore
upwardScore := ma100 > ma200? upwardScore+1:upwardScore
upwards = close > ma5 and ma5 > ma10 and ma10 > ma20 and ma20 > ma30 and ma30 > ma50 and ma50 > ma100 and ma100 > ma200
downwards = close < ma5 and ma5 < ma10 and ma10 < ma20 and ma20 < ma30 and ma30 < ma50 and ma50 < ma100 and ma100 < ma200
upwards?1:downwards?-1:includePartiallyAligned ? (upwardScore > 5? 0.5: upwardScore < 2?-0.5:upwardScore>3?0.25:-0.25) : 0
inDateRange = time >= timestamp(syminfo.timezone, year(timenow) - backtestYears, 01, 01, 0, 0)
exitBySignal = exitType == "Signal" or exitType == "Both"
exitByTrailingStop = exitType == "TrailingStop" or exitType == "Both"
maAlignment = f_getMaAlignment(MAType,includePartiallyAligned)
atr = atr(atrLength)
trailingStop = f_getTrailingStop(atr, atrMult)
maAligned = highest(maAlignment,LookbackPeriod)
[middle, upper, lower] = bb(close, BBLength, BBStdDev)
buyCondition = maAligned == 1 and (crossover(close, lower) or crossover(close, middle))
buyExitCondition = crossunder(close, upper)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=buyExitCondition and exitBySignal)
strategy.exit("ExitBuy", "Buy", stop = trailingStop, when=exitByTrailingStop )
Published by ChaoZhang on the FMZ strategy square · last modified 2023-11-24. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.
Build this with AgenKit
A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Dual-Moving-Average-Matching-Strategy-Based-on-Bollinger-Bands.md- npx agenkit install engineering-kit in your project
- Paste the command into your agent and approve each phase
- Get tests, backtest, risk controls and a paper-trading switch
Understand it first
Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.
Related specs
- Bull Bear Power Trading Strategy with Volume Percentile Based Dynamic Take Profit SystemPine Script · Machine learning · 1d
- Dynamic Price Swing Oscillator StrategyPine Script · Machine learning · 1m
- ADX EFI 50 Moving Average Channel Pullback StrategyPine Script · Machine learning · 1h
- Bollinger Bands and K line Combined StrategyPine Script · Machine learning · 3m
- Multi Dynamic Indicator Combination StrategyPine Script · Machine learning · 2d
- Trading Strategy Based on Bollinger Bands and MACDPine Script · Machine learning · 1h