
The High-Frequency Dip Buying Strategy is a technical indicator-based quantitative trading system specifically designed to capitalize on price retracements in bull market environments. This strategy is a comprehensive optimization and rewrite of the “Buy The Dips in Bull Market” strategy released by Coinrule in 2020, reconstructed using Pine Script v6. Through deep analysis of Bitcoin’s hourly data spanning more than two years, the optimized version provides an additional 312.6% return compared to the original strategy, achieving a 74.8% win rate.
Core Philosophy: The strategy leverages temporary price dips in bull market environments, entering long positions when the RSI indicator shows oversold conditions while the market structure remains bullish, then exiting when prices recover above key moving averages.
The strategy employs a multi-condition judgment system, including the following core logic:
Entry Logic: The strategy enters a long position when all of the following conditions are simultaneously met: 1. RSI Oversold Condition: RSI indicator drops below the configurable threshold (default: 45) 2. Bull Market Structure Confirmation: Long-term moving average (150-period) is below the medium-term moving average (40-period), indicating an overall bullish momentum 3. Date Range: The trade occurs within the specified backtesting period
Exit Logic: The strategy closes positions when both of the following conditions are met: 1. Price Recovery: Current price moves above the fast moving average (15-period) 2. MA Alignment: Fast moving average crosses above slow moving average, confirming trend continuation
Optional Short Trading: When enabled, the strategy can also perform short trades using inverse logic: 1. Short Entry: RSI overbought (above 55 by default) plus bearish market structure 2. Short Exit: Price decline below fast MA, along with bearish MA alignment
Risk Management: The strategy utilizes ATR-based stop-loss/take-profit settings, using volatility to dynamically determine risk levels. It employs a default 2:1 risk-reward ratio with fully customizable options. Additionally, it offers a fixed percentage-based risk management alternative.
High Win Rate Performance: Through optimized parameter settings, the strategy achieves a high win rate of 74.8%, which is very impressive for quantitative trading strategies. This high win rate results in a smoother equity curve, helping to reduce psychological pressure.
Dynamic Risk Management: The strategy employs an ATR-based stop-loss and take-profit mechanism that automatically adjusts risk levels according to market volatility. This approach is more scientific than fixed percentages and maintains consistent risk control in environments with different volatility levels.
Optimized Parameter Combination:
Bidirectional Trading Capability: The strategy offers optional short trading functionality, allowing it to adapt to different market environments rather than being limited to unidirectional trading.
Comprehensive Visualization: The strategy provides enhanced charting functions, including risk level displays, helping traders intuitively understand trading logic and risk management.
Bull Market Dependency: The strategy is specifically designed for bull market conditions and may significantly underperform in prolonged bear market environments. In unclear trend or sideways markets, the strategy may generate frequent false signals.
Trend Following Characteristics: As a trend-following strategy, it may experience significant drawdowns during strong trend reversals. Particularly when markets rapidly transition from bull to bear markets, the strategy may fail to adjust in time.
High-Frequency Trading Challenges: The strategy generates multiple signals requiring active monitoring, which may increase trading costs and operational complexity. High-frequency trading can lead to increased slippage and fees, affecting actual returns.
Parameter Sensitivity: Strategy performance is sensitive to parameter settings, and different markets and timeframes may require different parameter optimizations. Improper parameter selection may lead to overfitting or decreased signal quality.
Risk Management Limitations: While ATR risk management is a superior method, in extreme market conditions (such as flash crashes or gaps), stop-losses may not execute at expected prices, resulting in actual losses exceeding expectations.
Adaptive Parameter Adjustment: Consider implementing an adaptive parameter system that automatically adjusts RSI thresholds and moving average periods based on market volatility and trend strength. For example, use lower RSI thresholds and longer moving average periods in high-volatility environments to reduce false signals.
Market State Classification: Add more sophisticated market state recognition algorithms to clearly distinguish between bull markets, bear markets, and sideways markets, applying different trading logic for different market states. Additional indicators such as ADX (Average Directional Index) can be introduced to measure trend strength.
Machine Learning Optimization: Utilize machine learning algorithms to automatically identify optimal parameter combinations, or even build dynamic prediction models to improve signal quality. This can be achieved through training on historical data and periodic retraining to adapt to market changes.
Multi-Timeframe Confirmation: Add multi-timeframe analysis to ensure entry signals are supported by trends in larger timeframes. This can be implemented by checking moving average alignments and RSI readings across multiple time periods, thereby reducing false signals.
Volatility Filters: Implement volatility filtering mechanisms to pause trading or adjust risk parameters in extremely high volatility environments. ATR historical percentiles can be used as a measure of volatility, adopting more conservative trading strategies when volatility exceeds specific thresholds.
Capital Management Optimization: Implement more advanced capital management systems that dynamically adjust position sizes based on account size, recent strategy performance, and market conditions. For example, gradually increase positions after consecutive profits and reduce positions after consecutive losses.
The High-Frequency Dip Buying Strategy is a quantitative trading system specifically designed for bull market environments, capturing price retracement opportunities by identifying oversold conditions in combination with moving average trend confirmations. Compared to the original version, this strategy achieves significant performance improvements through parameter optimization and enhanced risk management features, delivering an additional 312.6% return and a 74.8% win rate.
The core advantages of the strategy lie in its dynamic risk management system and high win rate performance, making it excel in bull market environments. However, the strategy also has risks such as strong dependency on market environments and potential large drawdowns during trend reversals.
Future optimization directions primarily focus on adaptive parameter adjustment, market state classification, machine learning applications, multi-timeframe analysis, and more advanced capital management systems. Through these optimizations, the strategy aims to maintain stable performance across different market environments, further improving its robustness and profitability.
Regardless of which optimization measures are adopted, traders should always remember market risks, conduct thorough backtesting verification, and adjust strategy parameters and capital allocation according to personal risk tolerance and investment objectives.
/*backtest
start: 2025-06-13 00:00:00
end: 2025-07-13 00:00:00
period: 10m
basePeriod: 10m
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT","balance":200000}]
*/
// === DESCRIPTION ===
// Buy The Dips Bull Market Strategy - Optimized
// Modified strategy based on the original 2020 strategy from Coinrule
// Optimized parameters based on 2+ years of BTC hourly data analysis
// Performance improvement: 312.6% better returns with 74.8% win rate
// Enters long when RSI is oversold and we're in a bull market structure
// Exits when price recovers above fast MA and fast MA > slow MA
// Quant Trading Pro
//@version=6
strategy(title="High Freq Buy The Dips Bull Market [Quant Trading]",
shorttitle="High Freq Buy The Dips BUll Market",
overlay=true,
initial_capital=1000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=100,
commission_type=strategy.commission.percent,
commission_value=0.1,
slippage=3,
margin_long=0,
margin_short=0)
// === INPUT PARAMETERS ===
// RSI Settings
lengthRSI = input.int(14, "RSI Period", minval=1, maxval=50, group="📊 RSI Settings")
rsiBuySignal = input.int(45, "RSI Buy Signal", minval=20, maxval=50, group="📊 RSI Settings")
// Moving Average Settings
maFastLength = input.int(15, "Fast MA Length", minval=1, maxval=50, group="📈 Moving Averages")
maSlowLength = input.int(40, "Slow MA Length", minval=10, maxval=100, group="📈 Moving Averages")
maLongLength = input.int(150, "Long MA Length", minval=50, maxval=300, group="📈 Moving Averages")
// Trade Settings
allowShortTrades = input.bool(false, "Allow Short Trades?", group="🚫 Short Trades")
// Risk Management - ATR Based
enableATRRisk = input.bool(true, "Enable ATR Risk Management", group="🛡️ Risk Management")
atrLength = input.int(14, "ATR Period", minval=1, maxval=50, group="🛡️ Risk Management")
atrMultiplier = input.float(2.0, "ATR Stop Loss Multiplier", minval=0.5, maxval=5.0, step=0.1, group="🛡️ Risk Management")
riskRewardRatio = input.float(2.0, "Risk Reward Ratio", minval=1.0, maxval=10.0, step=0.1, group="🛡️ Risk Management")
// Optional Percentage-based Risk Management
usePercentageRisk = input.bool(false, "Use Percentage Instead of ATR", group="🛡️ Risk Management")
stopLossPercent = input.float(5.0, "Stop Loss (%)", minval=1.0, maxval=20.0, step=0.5, group="🛡️ Risk Management")
takeProfitPercent = input.float(10.0, "Take Profit (%)", minval=2.0, maxval=50.0, step=0.5, group="🛡️ Risk Management")
// === 1️⃣ CALCULATIONS ===
// RSI Calculation
rsiValue = ta.rsi(close, lengthRSI)
// Moving Averages
maFast = ta.sma(close, maFastLength)
maSlow = ta.sma(close, maSlowLength)
maLong = ta.sma(close, maLongLength)
// ATR Calculation for Risk Management
atrValue = ta.atr(atrLength)
// === 2️⃣ ENTRY & EXIT LOGIC ===
// Long Entry Conditions
rsiOversold = rsiValue < rsiBuySignal
bullMarketStructure = maLong < maSlow // Long MA below slow MA indicates bullish structure
longCondition = rsiOversold and bullMarketStructure
// Long Exit Conditions
priceRecovery = close > maFast
maAlignment = maFast > maSlow
longExitCondition = priceRecovery and maAlignment
// Short Entry Conditions (reverse logic)
rsiOverbought = rsiValue > (100 - rsiBuySignal) // If RSI buy signal is 35, short when RSI > 65
bearMarketStructure = maLong > maSlow // Long MA above slow MA indicates bearish structure
shortCondition = rsiOverbought and bearMarketStructure and allowShortTrades
// Short Exit Conditions (reverse logic)
priceDecline = close < maFast
maAlignmentBear = maFast < maSlow
shortExitCondition = priceDecline and maAlignmentBear and allowShortTrades
// === 3️⃣ TRADE EXECUTIONS ===
// Long Trades
if longCondition
strategy.entry("Long", strategy.long)
// Long Exits
if longExitCondition
strategy.close("Long")
// Short Trades (if enabled)
if shortCondition
strategy.entry("Short", strategy.short)
// Short Exits
if shortExitCondition
strategy.close("Short")
// ATR-Based Risk Management (if enabled)
if enableATRRisk and not usePercentageRisk
// Calculate ATR-based stop loss and take profit levels
longStopLoss = close - (atrValue * atrMultiplier)
longTakeProfit = close + (atrValue * atrMultiplier * riskRewardRatio)
shortStopLoss = close + (atrValue * atrMultiplier)
shortTakeProfit = close - (atrValue * atrMultiplier * riskRewardRatio)
// Long position risk management
strategy.exit("Long Exit", from_entry="Long",
stop=longStopLoss,
limit=longTakeProfit)
// Short position risk management
if allowShortTrades
strategy.exit("Short Exit", from_entry="Short",
stop=shortStopLoss,
limit=shortTakeProfit)
// Percentage-Based Risk Management (Alternative)
else if enableATRRisk and usePercentageRisk
strategy.exit("Long Exit", from_entry="Long",
stop=strategy.position_avg_price * (1 - stopLossPercent / 100),
limit=strategy.position_avg_price * (1 + takeProfitPercent / 100))
if allowShortTrades
strategy.exit("Short Exit", from_entry="Short",
stop=strategy.position_avg_price * (1 + stopLossPercent / 100),
limit=strategy.position_avg_price * (1 - takeProfitPercent / 100))
// === 4️⃣ VISUALIZATIONS ===
// Moving Averages - ensure they're properly connected to price data
plot(maFast, "Fast MA", color=color.new(color.purple, 0), linewidth=2, display=display.all)
plot(maSlow, "Slow MA", color=color.new(color.orange, 0), linewidth=2, display=display.all)
plot(maLong, "Long MA", color=color.new(color.blue, 0), linewidth=3, display=display.all)
// Entry/Exit Signals - ensure they're anchored to bars
//plotshape(longCondition, title="Long Entry", location=location.belowbar,
// color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
//plotshape(longExitCondition, title="Long Exit", location=location.abovebar,
// color=color.new(color.red, 0), style=shape.triangledown, size=size.small)
// Short signals (if enabled)
//plotshape(shortCondition, title="Short Entry", location=location.abovebar,
// color=color.new(color.red, 0), style=shape.triangledown, size=size.small)
//plotshape(shortExitCondition, title="Short Exit", location=location.belowbar,
// color=color.new(color.green, 0), style=shape.triangleup, size=size.small)
// Risk Management Visualization
var float longSL = na
var float longTP = na
var float shortSL = na
var float shortTP = na
// Set risk levels only when entering new positions
if longCondition and enableATRRisk
if not usePercentageRisk
longSL := close - (atrValue * atrMultiplier)
longTP := close + (atrValue * atrMultiplier * riskRewardRatio)
else
longSL := close * (1 - stopLossPercent / 100)
longTP := close * (1 + takeProfitPercent / 100)
if shortCondition and enableATRRisk
if not usePercentageRisk
shortSL := close + (atrValue * atrMultiplier)
shortTP := close - (atrValue * atrMultiplier * riskRewardRatio)
else
shortSL := close * (1 + stopLossPercent / 100)
shortTP := close * (1 - takeProfitPercent / 100)
// Clear levels when positions are closed
if strategy.position_size == 0
longSL := na
longTP := na
shortSL := na
shortTP := na
// Plot risk levels only when in position
plot(strategy.position_size > 0 ? longSL : na, "Long Stop Loss", color=color.new(color.red, 0), style=plot.style_linebr, linewidth=2)
plot(strategy.position_size > 0 ? longTP : na, "Long Take Profit", color=color.new(color.green, 0), style=plot.style_linebr, linewidth=2)
plot(strategy.position_size < 0 ? shortSL : na, "Short Stop Loss", color=color.new(color.red, 50), style=plot.style_linebr, linewidth=2)
plot(strategy.position_size < 0 ? shortTP : na, "Short Take Profit", color=color.new(color.green, 50), style=plot.style_linebr, linewidth=2)