0bps

Strategy vault / Breakout

Triple Bottom Rebound Momentum Breakthrough Strategy

This strategy is a quantitative trading system based on technical analysis, primarily focusing on identifying triple bottom patterns and momentum breakthrough signals in the market. The strategy combines multiple…

Author
ChaoZhang
Complexity
Intermediate · 119 lines
Parameters
0
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

IMG

Overview

This strategy is a quantitative trading system based on technical analysis, primarily focusing on identifying triple bottom patterns and momentum breakthrough signals in the market. The strategy combines multiple technical indicators including Moving Average (MA) crossovers, Average True Range (ATR), and price channels to build a complete trading system. Through programmatic implementation, it achieves automated identification of triple bottom rebound patterns and trade execution.

Strategy Principles

The core logic includes the following key elements:

  1. Using fast (5-period) and slow (20-period) moving average crossovers to confirm market trend direction
  2. Automatically identifying three consecutive low points (low1, low2, low3) to form a triple bottom pattern
  3. Utilizing ATR indicator to calculate volatility and set dynamic stop-loss and take-profit levels
  4. Confirming long entry signals when price breaks above previous rebound high after the third bottom, combined with MA crossover signals
  5. Establishing parallel channels to visualize price movement ranges for additional market reference
  6. Implementing ATR-based dynamic stop-loss and take-profit conditions during trade execution

Strategy Advantages

  1. Combines multiple technical indicators to enhance signal reliability
  2. Uses ATR to dynamically adjust stop-loss and take-profit levels, adapting to market volatility changes
  3. Automates triple bottom pattern identification, reducing subjective judgment
  4. Implements trade interval restrictions to prevent overtrading
  5. Provides clear market structure reference through visualization tools (parallel channels and labels)
  6. Features clear strategy logic for easy maintenance and optimization

Strategy Risks

  1. May generate false signals in highly volatile markets
  2. Triple bottom pattern identification process may be affected by market noise
  3. Fixed ATR multipliers may not suit all market conditions
  4. May experience consecutive losses during trend reversal periods
  5. Trade interval settings might miss some valid signals

Strategy Optimization Directions

  1. Incorporate volume indicators to confirm rebound validity
  2. Dynamically adjust ATR multipliers based on different market conditions
  3. Add trend strength filters to improve trading signal quality
  4. Optimize triple bottom identification algorithm to increase accuracy
  5. Incorporate market cycle analysis to optimize trade interval settings
  6. Consider adding price pattern symmetry analysis

Summary

This strategy implements a triple bottom rebound breakthrough trading system programmatically, combining multiple technical indicators and risk management measures with good practicality. Through continuous optimization and improvement, the strategy shows promise for better performance in actual trading. It is recommended to conduct thorough backtesting before live trading and adjust parameters according to specific market conditions.

Source Pine Script

/*backtest
start: 2019-12-23 08:00:00
end: 2025-01-08 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":49999}]
*/

//@version=5
strategy("Three rebounds breakout strategy", overlay=true, initial_capital=100000, commission_value=0.001425, slippage=1)

// === Parameter Settings ===
fast_length = input.int(5, title="Fast Moving Average Period")
slow_length = input.int(20, title="Slow Moving Average Period")
atr_period = input.int(14, title="ATR Cycle")
atr_factor = input.float(2.0, title="ATR Factor")
profit_factor = input.float(2.0, title="Take Profit Factor")

// === Calculate Moving Average ===
fast_ma = ta.ema(close, fast_length)
slow_ma = ta.ema(close, slow_length)

// === Moving Average Crossover Signal ===
long_signal = ta.crossover(fast_ma, slow_ma)
short_signal = ta.crossunder(fast_ma, slow_ma)

// === Calculate ATR ===
atr = ta.atr(atr_period)

// === Three rebounds breakout strategy ===
var float low1 = na
var float low2 = na
var float low3 = na
var bool trend_down = false
var bool long_breakout = false
var line lower_line = na
var line upper_line = na

if (na(low1) or na(low2) or na(low3))
    // Initialization low
    low1 := na
    low2 := na
    low3 := na

if (close < low3 or na(low3))
    // Update Low Point
    low1 := low2
    low2 := low3
    low3 := close
    trend_down := true

if (trend_down and close > low2 and close > low1)
    // Confirm reversal and that the third rebound is higher than the second
    trend_down := false
    long_breakout := true

// Clear the previous rebound channel
if (not na(lower_line))
    line.delete(lower_line)
if (not na(upper_line))
    line.delete(upper_line)

// Draw a new rebound channel
if (not na(low1) and not na(low3))    
    lower_line := line.new(x1=bar_index[2], y1=low1, x2=bar_index, y2=low3, color=color.yellow, width=2)
    upper_line := line.new(x1=bar_index[2], y1=low1 + (low3 - low1), x2=bar_index, y2=low3 + (low3 - low1), color=color.yellow, width=2)

// === Entry and exit conditions ===
var float last_long_exit = na
var float last_short_exit = na
var float stop_loss_long = na
var float take_profit_long = na
var float stop_loss_short = na
var float take_profit_short = na

var label stop_loss_label_long = na
var label take_profit_label_long = na
var label stop_loss_label_short = na
var label take_profit_label_short = na

if (long_signal or long_breakout)
    if na(last_short_exit) or (time - last_short_exit) > 2 * 60 * 60 * 1000  // Ensure there is a time interval after exiting a long position
        // go long
        strategy.entry("go long", strategy.long)
        // Set stop loss below the recent low
        stop_loss_long := low3 - atr_factor * atr
        take_profit_long := close + profit_factor * atr  // Set Take Profit Level
        strategy.exit("take profit/Stop loss", "go long", stop=stop_loss_long, limit=take_profit_long)
        last_long_exit := time  // Record long position exit time

        // Delete previous take profit and stop loss tags
        if (not na(stop_loss_label_long))
            label.delete(stop_loss_label_long)
        if (not na(take_profit_label_long))
            label.delete(take_profit_label_long)

        // Draw new take profit and stop loss labels
        stop_loss_label_long := label.new(x=bar_index, y=stop_loss_long, text=str.tostring(math.round(stop_loss_long * 10) / 10), color=color.red, style=label.style_label_down, textcolor=color.white, size=size.small)
        take_profit_label_long := label.new(x=bar_index, y=take_profit_long, text=str.tostring(math.round(take_profit_long * 10) / 10), color=color.green, style=label.style_label_up, textcolor=color.white, size=size.small)

if (short_signal)
    if na(last_long_exit) or (time - last_long_exit) > 2 * 60 * 60 * 1000  // Ensure there is a time interval after exiting a short position
        // go short
        strategy.entry("go short", strategy.short)
        // Set stop loss above the recent high
        stop_loss_short := high + atr_factor * atr
        take_profit_short := close - profit_factor * atr  // Set Take Profit Level
        strategy.exit("take profit/Stop loss", "go short", stop=stop_loss_short, limit=take_profit_short)
        last_short_exit := time  // Record short position exit time

        // Delete previous take profit and stop loss tags
        if (not na(stop_loss_label_short))
            label.delete(stop_loss_label_short)
        if (not na(take_profit_label_short))
            label.delete(take_profit_label_short)

        // Draw new take profit and stop loss labels
        stop_loss_label_short := label.new(x=bar_index, y=stop_loss_short, text=str.tostring(math.round(stop_loss_short * 10) / 10), color=color.red, style=label.style_label_down, textcolor=color.white, size=size.small)
        take_profit_label_short := label.new(x=bar_index, y=take_profit_short, text=str.tostring(math.round(take_profit_short * 10) / 10), color=color.green, style=label.style_label_up, textcolor=color.white, size=size.small)

Published by ChaoZhang on the FMZ strategy square · last modified 2025-01-10. 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.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Triple-Bottom-Rebound-Momentum-Breakthrough-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. 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

esc

Try , , or .

↑↓ move↵ open