Strategy vault / Trend following
Premium Double Trend Filter MA Ratio Strategy
This strategy is based on double moving average ratio indicator combined with Bollinger Bands filter and double trend filter indicator. It adopts chained exit mechanisms for trend following. This strategy aims to…

Overview
This strategy is based on double moving average ratio indicator combined with Bollinger Bands filter and double trend filter indicator. It adopts chained exit mechanisms for trend following. This strategy aims to identify mid-to-long term trend direction through moving average ratio indicator. It enters the market at better entry points when trend direction is clear. It also sets take profit, stop loss exit mechanisms to lock in profits and reduce losses.
Strategy Logic
- Calculate fast moving average (10-day) and slow moving average (50-day), get their ratio called price moving average ratio. This ratio can effectively identify mid-to-long term trend changes.
- Convert price moving average ratio into percentile, which represents relative strength of current ratio in past periods. This percentile is defined as oscillator.
- When oscillator crosses above buy entry threshold (10), long signal triggers. When crossing below sell threshold (90), short signal triggers for trend following.
- Combine with Bollinger Bands width index for signal filtering. Trade when BB width shrinks.
- Use double trend filter indicator, only taking long when price is in uptrend channel and short when in downtrend for avoiding reverse trading.
- Chain exit strategies are set, including take profit, stop loss, and combined exit. Multiple exit conditions can be preset with priority to maximum profit exit.
Advantages
- Double trend filter ensures reliability in identifying main trend, avoiding reverse trading.
- MA ratio indicator detects trend change better than single MA.
- BB width effectively locates low volatility periods for more reliable signals.
- Chained exit mechanism maximizes overall profit.
Risks and Solutions
- More false signals and reversals with unclear trend during ranging markets. Solution is to combine with BB width filter for tighter signals.
- MA has lagging effect, failing to detect trend reversal instantly. Solution is to shorten MA parameters properly.
- Stop loss may be hit instantly with price gaps, causing large loss. Solution is to loosely set stop loss parameter.
Optimization Directions
- Parameter optimization on MA periods, oscillator thresholds, BB parameters through exhaustive tests to find best combination.
- Incorporate other indicators judging trend reversal like KD, MACD to improve accuracy.
- Machine learning model training with historical data for dynamic parameter optimization.
Summary
This strategy integrates double MA ratio indicator and BB to determine mid-to-long term trend. It enters Market at best point after trend confirmation with chained profit-taking mechanisms. It is highly reliable and efficient. Further improvements can be achieved through parameter optimization, adding trend reversal indicators and machine learning.
Parameters
| Name | Default | What it controls |
|---|---|---|
| v_input_1 | 10 | Fast MA Length |
| v_input_2 | 50 | Slow MA Length |
| v_input_3 | 10 | Oscillator Buy Threshold |
| v_input_4 | 90 | Oscillator Sell Threshold |
| v_input_5 | 20 | Bollinger Bands Length |
| v_input_6_close | 0 | Bollinger Bands Source: close | high | low | open | hl2 | hlc3 | hlcc4 | ohlc4 |
| v_input_7 | 2 | Bollinger Bands Deviation |
| v_input_8 | 30 | BB Width Threshold |
| v_input_9 | true | Use BB Width Filter? |
| v_input_10 | true | Use Trend Filter? |
| v_input_11 | 50 | Trend Filter Period 1 |
| v_input_12 | 200 | Trend Filter Period 2 |
| v_input_13 | true | Use Second Trend Filter? |
| v_input_14 | true | Use Exit Strategies? |
| v_input_15 | true | Use Take Profit? |
| v_input_16 | 150 | Take Profit in Ticks |
| v_input_17 | true | Use Stop Loss? |
| v_input_18 | 100 | Stop Loss in Ticks |
| v_input_19 | true | Use Combined Exit Strategy? |
| v_input_20 | 50 | Combined Exit Ticks |
| v_input_21 | false | Use Time Filter? |
| v_input_22 | 8 | Start Hour |
| v_input_23 | 16 | End Hour |
Source Pine Script
/*backtest
start: 2023-12-20 00:00:00
end: 2023-12-27 00:00:00
period: 3m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
strategy("Premium MA Ratio Strategy", overlay = true)
// Input: Adjustable parameters for Premium MA Ratio
fast_length = input(10, title = "Fast MA Length")
slow_length = input(50, title = "Slow MA Length")
oscillator_threshold_buy = input(10, title = "Oscillator Buy Threshold")
oscillator_threshold_sell = input(90, title = "Oscillator Sell Threshold")
// Input: Adjustable parameters for Bollinger Bands
bb_length = input(20, title = "Bollinger Bands Length")
bb_source = input(close, title = "Bollinger Bands Source")
bb_deviation = input(2.0, title = "Bollinger Bands Deviation")
bb_width_threshold = input(30, title = "BB Width Threshold")
use_bb_filter = input(true, title = "Use BB Width Filter?")
// Input: Adjustable parameters for Trend Filter
use_trend_filter = input(true, title = "Use Trend Filter?")
trend_filter_period_1 = input(50, title = "Trend Filter Period 1")
trend_filter_period_2 = input(200, title = "Trend Filter Period 2")
use_second_trend_filter = input(true, title = "Use Second Trend Filter?")
// Input: Adjustable parameters for Exit Strategies
use_exit_strategies = input(true, title = "Use Exit Strategies?")
use_take_profit = input(true, title = "Use Take Profit?")
take_profit_ticks = input(150, title = "Take Profit in Ticks")
use_stop_loss = input(true, title = "Use Stop Loss?")
stop_loss_ticks = input(100, title = "Stop Loss in Ticks")
use_combined_exit = input(true, title = "Use Combined Exit Strategy?")
combined_exit_ticks = input(50, title = "Combined Exit Ticks")
// Input: Adjustable parameters for Time Filter
use_time_filter = input(false, title = "Use Time Filter?")
start_hour = input(8, title = "Start Hour")
end_hour = input(16, title = "End Hour")
// Calculate moving averages
fast_ma = sma(close, fast_length)
slow_ma = sma(close, slow_length)
// Calculate the premium price moving average ratio
premium_ratio = fast_ma / slow_ma * 100
// Calculate the percentile rank of the premium ratio
percentile_rank(src, length) =>
rank = 0.0
for i = 1 to length
if src > src[i]
rank := rank + 1.0
percentile = rank / length * 100
// Calculate the percentile rank for the premium ratio using slow_length periods
premium_ratio_percentile = percentile_rank(premium_ratio, slow_length)
// Calculate the oscillator based on the percentile rank
oscillator = premium_ratio_percentile
// Dynamic coloring for the oscillator line
oscillator_color = oscillator > 50 ? color.green : color.red
// Plot the oscillator on a separate subplot as a line
hline(50, "Midline", color = color.gray)
plot(oscillator, title = "Oscillator", color = oscillator_color, linewidth = 2)
// Highlight the overbought and oversold areas
bgcolor(oscillator > oscillator_threshold_sell ? color.red : na, transp = 80)
bgcolor(oscillator < oscillator_threshold_buy ? color.green : na, transp = 80)
// Plot horizontal lines for threshold levels
hline(oscillator_threshold_buy, "Buy Threshold", color = color.green)
hline(oscillator_threshold_sell, "Sell Threshold", color = color.red)
// Calculate Bollinger Bands width
bb_upper = sma(bb_source, bb_length) + bb_deviation * stdev(bb_source, bb_length)
bb_lower = sma(bb_source, bb_length) - bb_deviation * stdev(bb_source, bb_length)
bb_width = bb_upper - bb_lower
// Calculate the percentile rank of Bollinger Bands width
bb_width_percentile = percentile_rank(bb_width, bb_length)
// Plot the Bollinger Bands width percentile line
plot(bb_width_percentile, title = "BB Width Percentile", color = color.blue, linewidth = 2)
// Calculate the trend filters
trend_filter_1 = sma(close, trend_filter_period_1)
trend_filter_2 = sma(close, trend_filter_period_2)
// Strategy logic
longCondition = crossover(premium_ratio_percentile, oscillator_threshold_buy)
shortCondition = crossunder(premium_ratio_percentile, oscillator_threshold_sell)
// Apply Bollinger Bands width filter if enabled
if (use_bb_filter)
longCondition := longCondition and bb_width_percentile < bb_width_threshold
shortCondition := shortCondition and bb_width_percentile < bb_width_threshold
// Apply trend filters if enabled
if (use_trend_filter)
longCondition := longCondition and (close > trend_filter_1)
shortCondition := shortCondition and (close < trend_filter_1)
// Apply second trend filter if enabled
if (use_trend_filter and use_second_trend_filter)
longCondition := longCondition and (close > trend_filter_2)
shortCondition := shortCondition and (close < trend_filter_2)
// Apply time filter if enabled
if (use_time_filter)
longCondition := longCondition and (hour >= start_hour and hour <= end_hour)
shortCondition := shortCondition and (hour >= start_hour and hour <= end_hour)
// Generate trading signals with exit strategies
if (use_exit_strategies)
strategy.entry("Buy", strategy.long, when = longCondition)
strategy.entry("Sell", strategy.short, when = shortCondition)
// Define unique exit names for each order
buy_take_profit_exit = "Buy Take Profit"
buy_stop_loss_exit = "Buy Stop Loss"
sell_take_profit_exit = "Sell Take Profit"
sell_stop_loss_exit = "Sell Stop Loss"
combined_exit = "Combined Exit"
// Exit conditions for take profit
if (use_take_profit)
strategy.exit(buy_take_profit_exit, from_entry = "Buy", profit = take_profit_ticks)
strategy.exit(sell_take_profit_exit, from_entry = "Sell", profit = take_profit_ticks)
// Exit conditions for stop loss
if (use_stop_loss)
strategy.exit(buy_stop_loss_exit, from_entry = "Buy", loss = stop_loss_ticks)
strategy.exit(sell_stop_loss_exit, from_entry = "Sell", loss = stop_loss_ticks)
// Combined exit strategy
if (use_combined_exit)
strategy.exit(combined_exit, from_entry = "Buy", loss = combined_exit_ticks, profit = combined_exit_ticks)
Published by ChaoZhang on the FMZ strategy square · last modified 2023-12-28. 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/Premium-Double-Trend-Filter-MA-Ratio-Strategy.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
- Bollinger Bands and RSI Trend Following StrategyPine Script · Trend following · 1h
- EMA and RSI Trend Trading StrategyPine Script · Trend following · 1d
- Multi Indicator Trend Following Strategy with Dynamic Risk ManagementPine Script · Trend following · 2h
- Relative Volume Trend Following Trading StrategyPine Script · Trend following · 1d
- Trend Following Strategy Based on EMA and SMA CrossoverPine Script · Trend following · 1h
- Dual Rail Trend Tracking StrategyPine Script · Trend following · 3h