Overview
This strategy is an intelligent Dollar-Cost Averaging (DCA) approach based on Exponential Moving Average (EMA) crossover signals, combined with adaptive volatility-responsive Safety Order (SO) deployment and an innovative dual trailing stop system. It enters the market when an uptrend is confirmed, then automatically deploys additional safety orders based on market volatility, while using both standard trailing stops and a profit-locking trailing system to protect gains. The strategy is designed to operate in volatile market environments and is specifically optimized for the 1-hour timeframe, utilizing a total capital of $4,000 for trading operations.
Strategy Principles
The core logic of this strategy revolves around several key components:
Trend Identification System: Uses a fast EMA (default 9-period) and slow EMA (default 21-period) crossover to identify potential uptrends. When the fast EMA crosses above the slow EMA, the system confirms an uptrend and triggers the base entry order.
Multi-Tier DCA Entry System: The strategy employs a three-level entry mechanism:
- Base Order ($1,000): Placed when EMA crossover signal is confirmed
- Safety Order 1 ($1,250): Triggered when price drops a predetermined amount from the base order price
- Safety Order 2 ($1,750): Triggered when price continues to drop to a lower level
Volatility Adaptive Mechanism: Safety order trigger prices can be dynamically calculated based on the ATR (Average True Range) indicator, allowing the strategy to automatically adjust entry positions according to current market volatility. Users can choose between ATR multipliers (default 1.2x ATR for SO1, 2.5x ATR for SO2) or fixed percentage drops (default 4% for SO1, 8% for SO2) to calculate safety order trigger points.
Dual Trailing Stop Protection System:
- Standard Trailing Stop: Tracks the highest price since entry, set at a fixed percentage (default 8%) from the peak
- Profit Lock-In Trailing Stop: Activated when the position reaches a specific profit threshold (default 2.5%), using a tighter trailing percentage (default 1.5%) to more aggressively lock in realized profits
Cooldown Mechanism: Implements a cooldown period (default 4 bars) after base order execution to prevent overtrading within a short time period.
Strategy Advantages
Upon analysis, this strategy demonstrates the following significant advantages:
High Adaptability: By calculating safety order trigger prices using ATR, the strategy can intelligently adapt to different market volatility environments, appropriately widening safety order spacing during high volatility periods and tightening spacing during low volatility periods.
Optimized Capital Management: Employs an increasing capital allocation approach ($1,000 → $1,250 → $1,750), following the "pyramiding" position management principle, allowing the strategy to obtain a better average entry price with larger capital scale as prices decline.
Dual Protection Mechanism: The innovative dual trailing stop system provides both basic downside risk protection and automatically switches to a more conservative stop-loss mode when profitable, effectively balancing profit maximization and risk control.
Customization Flexibility: All key parameters are customizable, including EMA periods, ATR length, safety order spacing, stop-loss percentages, and order sizes, allowing traders to optimize according to personal risk preferences and market conditions.
Integration Capability: The strategy includes built-in alert conditions formatted as JSON messages, facilitating integration with third-party automated trading platforms (such as 3Commas) for fully automated trade execution.
Strategy Risks
Despite its comprehensive design, the strategy still presents the following potential risks and challenges:
Trend Reversal Risk: The strategy relies on EMA crossover signals, which may produce false signals in rapidly changing or oscillating markets, leading to unnecessary entries. The solution is to adjust EMA period lengths or add additional confirmation indicators.
Capital Depletion Risk: In continuously declining markets, even after deploying all safety orders, the average entry price may still be far above the market price, resulting in long-term losses. It is recommended to set maximum loss limits or overall position size limits.
Overtrading Risk: In highly volatile markets, EMAs may cross frequently, triggering too many trades. Although a cooldown mechanism is built in, further optimization or additional trade frequency limitations may be needed.
Dual Stop-Loss Interference: In certain market conditions, the two stop-loss mechanisms may interfere with each other, causing premature exits or duplicate signals. Regular backtesting and adjustment of the balance between these two stop-loss parameters is advised.
Parameter Optimization Difficulty: The strategy's multiple parameters need to be coordinated with each other to achieve optimal results, increasing the complexity of parameter optimization. It is recommended to use backtesting optimization tools for comprehensive parameter analysis.
Strategy Optimization Directions
Based on in-depth analysis of the code, the following are potential optimization directions for this strategy:
Introduce Multiple Trend Confirmation Mechanisms: Currently, the strategy relies solely on a single EMA crossover signal. Consider adding additional trend confirmation indicators, such as RSI, MACD, or longer-period trend judgments, to reduce false signals. This can significantly reduce the risk of false breakouts.
Dynamic Capital Allocation System: The current strategy uses fixed dollar amounts as order sizes. This could be optimized to a dynamic adjustment system based on market volatility or account equity, ensuring appropriate risk exposure levels are maintained under different market conditions.
Optimized Stop-Loss Exit Strategy: More sophisticated stop-loss logic could be developed, such as adaptive trailing stops based on market volatility, or integrating momentum and volume indicators to optimize exit decisions, avoiding premature exits during short-term fluctuations.
Drawdown Control Enhancement: Add overall drawdown limitation functionality that automatically pauses new orders or closes existing positions when the strategy reaches a preset maximum drawdown percentage, preventing catastrophic losses under extreme market conditions.
Timeframe Optimization System: Develop automatic timeframe optimization functionality that allows the strategy to automatically adjust EMA lengths, ATR periods, and other time-related parameters based on recent market conditions, adapting to changes in market states.
Summary
The "Intelligent Volatility-Responsive DCA Strategy with Dual Trailing Stop System" is a well-designed quantitative trading solution particularly suited for capturing uptrends and managing risk in volatile markets. It cleverly combines trend following, dollar-cost averaging, and volatility-adaptive mechanisms, while protecting gains through an innovative dual trailing stop system.
The core advantage of this strategy lies in its adaptability and balanced risk management, capable of automatically adjusting entry and exit decisions across different market environments. By using ATR to dynamically calculate safety order trigger points, the strategy can respond intelligently to real-time market conditions rather than relying on preset static parameters.
While there are potential risks in trend identification and capital management, these can be effectively mitigated through the proposed optimization directions. In particular, introducing multiple trend confirmation and dynamic capital allocation systems will significantly enhance the strategy's robustness and long-term performance.
For quantitative traders seeking systematic trading methods in volatile markets, this strategy provides a comprehensive, scalable framework that can both capture uptrend opportunities and provide adequate risk protection under adverse market conditions.
Strategy source code
/*backtest
start: 2025-03-14 00:00:00
end: 2025-04-02 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy(
title="BONK/USD (1H) - $4k DCA + Dual Trailing + Date Filter", // Updated Title
overlay=true,
initial_capital=4000,
currency=currency.USD,
default_qty_type=strategy.fixed,
default_qty_value=0, // Quantity calculated dynamically based on USD value
commission_type=strategy.commission.percent, // Example: Add commission settings
commission_value=0.1 // Example: 0.1% commission
)
// 1) USER INPUTS (Defaults adjusted for 1H timeframe - REQUIRES BACKTESTING/TUNING)
// --- Trend ---
fastMALen = input.int(9, title="Fast EMA Length (Default for 1H)")
slowMALen = input.int(21, title="Slow EMA Length (Default for 1H)")
// --- Trailing Stops ---
trailStopPerc = input.float(8.0, title="Standard Trailing Stop (%) (Default for 1H)", minval=0.1) / 100
lockInThreshold = input.float(2.5, title="Profit Lock-In Trigger (%) (Default for 1H)", minval=0.1) / 100
lockInTrailPct = input.float(1.5, title="Lock-In Trail (%) after Trigger (Default for 1H)", minval=0.1) / 100
// --- Safety Orders (SO) ---
useATRSpacing = input.bool(true, title="Use ATR-Based Spacing?")
atrLength = input.int(14, title="ATR Length", minval=1)
atrSo1Multiplier = input.float(1.2, title="ATR SO1 Multiplier (Default for 1H)", minval=0.1)
atrSo2Multiplier = input.float(2.5, title="ATR SO2 Multiplier (Default for 1H)", minval=0.1)
// --- Fallback SO Spacing (if not using ATR) ---
fallbackSo1Perc = input.float(4.0, title="Fallback SO1 Drop (%) (Default for 1H)", minval=0.1) / 100
fallbackSo2Perc = input.float(8.0, title="Fallback SO2 Drop (%) (Default for 1H)", minval=0.1) / 100
// --- Entry Cooldown ---
cooldownBars = input.int(4, "Cooldown Bars After Base Entry (Default for 1H)", minval=0)
// --- Order Sizes in USD ---
baseUsd = input.float(1000.0, title="Base Order Size (USD)", minval=1.0)
so1Usd = input.float(1250.0, title="Safety Order 1 Size (USD)", minval=1.0)
so2Usd = input.float(1750.0, title="Safety Order 2 Size (USD)", minval=1.0)
// 2) CALCULATIONS
// --- Trend & Reversal Detection ---
fastMA = ta.ema(close, fastMALen)
slowMA = ta.ema(close, slowMALen)
trendUp = ta.crossover(fastMA, slowMA)
trendDown = ta.crossunder(fastMA, slowMA)
// --- ATR Value ---
atrValue = ta.atr(atrLength)
// 3) BASE ENTRY LOGIC
// Base Buy Signal: EMA crossover
baseBuySignal = trendUp
var int lastBuyBar = na // Tracks the bar index of the last base entry
inCooldown = not na(lastBuyBar) and (bar_index - lastBuyBar < cooldownBars)
var float baseEntryPrice = na // Stores the price of the initial base entry for SO calculations
// --- Execute Base Entry ---
// Added 'inDateRange' to the condition
if baseBuySignal and strategy.position_size == 0 and not inCooldown
baseQty = baseUsd / close // Calculate quantity based on USD
strategy.entry("Base Order", strategy.long, qty=baseQty, comment="Base Entry")
baseEntryPrice := close
lastBuyBar := bar_index
// 4) SAFETY ORDERS LOGIC
// --- Calculate SO Trigger Prices ---
float so1TriggerPrice = na
float so2TriggerPrice = na
if not na(baseEntryPrice) // Only calculate if a base order has been placed
so1TriggerPrice := useATRSpacing ?
(baseEntryPrice - atrValue * atrSo1Multiplier) :
(baseEntryPrice * (1 - fallbackSo1Perc))
so2TriggerPrice := useATRSpacing ?
(baseEntryPrice - atrValue * atrSo2Multiplier) :
(baseEntryPrice * (1 - fallbackSo2Perc))
// --- Conditions for SO Execution ---
// Added 'inDateRange' check
// Ensure base order exists, price trigger hit, and the specific SO hasn't filled yet
bool so1Condition = not na(baseEntryPrice) and strategy.position_size > 0 and close <= so1TriggerPrice and strategy.opentrades == 1
bool so2Condition = not na(baseEntryPrice) and strategy.position_size > 0 and close <= so2TriggerPrice and strategy.opentrades == 2
// --- Execute SO1 ---
if so1Condition
so1Qty = so1Usd / close // Calculate quantity based on USD
strategy.entry("Safety Order 1", strategy.long, qty=so1Qty, comment="SO1")
// --- Execute SO2 ---
if so2Condition
so2Qty = so2Usd / close // Calculate quantity based on USD
strategy.entry("Safety Order 2", strategy.long, qty=so2Qty, comment="SO2")
// 5) AVERAGE ENTRY PRICE
// Use the built-in variable for the average price of the open position
avgEntryPrice = strategy.position_avg_price
// 6) DUAL TRAILING STOP LOGIC
// Variables to track trailing stop levels and states
var float highestSinceEntry = na
var float trailStopPrice = na
var bool stopHitNormal = false
var bool lockInTriggered = false
var float lockInPeak = na
var float lockInStopPrice = na
var bool stopHitLockIn = false
// --- Update Trailing Logic when in a Position ---
if strategy.position_size > 0
// --- Standard Trail ---
highestSinceEntry := na(highestSinceEntry) ? close : math.max(highestSinceEntry, close)
trailStopPrice := highestSinceEntry * (1 - trailStopPerc)
stopHitNormal := close < trailStopPrice
// --- Lock-In Trail ---
if not lockInTriggered and close >= avgEntryPrice * (1 + lockInThreshold)
lockInTriggered := true
lockInPeak := close
if lockInTriggered
lockInPeak := math.max(lockInPeak, close)
lockInStopPrice := lockInPeak * (1 - lockInTrailPct)
stopHitLockIn := close < lockInStopPrice
else
stopHitLockIn := false
lockInStopPrice := na
// --- Reset Variables when Flat ---
else
highestSinceEntry := na
trailStopPrice := na
stopHitNormal := false
lockInTriggered := false
lockInPeak := na
lockInStopPrice := na
stopHitLockIn := false
baseEntryPrice := na
// lastBuyBar is intentionally NOT reset here, cooldown depends on it
// 7) EXIT CONDITIONS
// Added 'inDateRange' check
// Exit if either trailing stop is hit OR if the trend reverses downward, within the active date range
exitCondition = (stopHitNormal or stopHitLockIn or trendDown) and strategy.position_size > 0
if exitCondition
strategy.close_all(comment="Exit: SL / LockIn / TrendDown")
// 8) ALERT CONDITIONS (Potential 3Commas Integration)
// WARNING: Verify and adapt these JSON message strings for your specific 3Commas bot configuration!
// The required format ('action', parameters, etc.) can vary.
// Added 'inDateRange[1]' check for Base Alert
alertcondition(inDateRange[1] and baseBuySignal and strategy.position_size[1] == 0 and not inCooldown[1],
title="Base Buy Alert",
message='{"action":"start_deal","order":"base"} // Verify/Adapt JSON for your 3Commas bot!')
// Added 'inDateRange' check for SO1 Alert
alertcondition(so1Condition, title="SO1 Alert",
message='{"action":"add_funds","order":"so1"} // Verify/Adapt JSON for your 3Commas bot!')
// Added 'inDateRange' check for SO2 Alert
alertcondition(so2Condition, title="SO2 Alert",
message='{"action":"add_funds","order":"so2"} // Verify/Adapt JSON for your 3Commas bot!')
// Added 'inDateRange' check for Exit Alert
alertcondition(exitCondition, title="Exit Alert",
message='{"action":"close_at_market_price"} // Verify/Adapt JSON for your 3Commas bot!')
// 9) PLOTS & DEBUG TABLE
// --- Plot MAs ---
plot(fastMA, color=color.new(color.green, 0), title="Fast EMA", linewidth=2)
plot(slowMA, color=color.new(color.red, 0), title="Slow EMA", linewidth=2)
// --- Plot Trailing Stops ---
plot(strategy.position_size > 0 ? trailStopPrice : na, color=color.new(color.orange, 0), title="Standard Trailing Stop", style=plot.style_linebr, linewidth=2)
plot(lockInTriggered ? lockInStopPrice : na, color=color.new(color.fuchsia, 0), title="Lock-In Trailing Stop", style=plot.style_linebr, linewidth=2)
// --- Debug Info Table ---
var table tradeInfo = table.new(position=position.bottom_right, columns=2, rows=10, border_width=1)
Strategy parameters
The original address: Intelligent Volatility-Responsive DCA Strategy with Dual Trailing Stop System
Volatility-responsive DCA? My version is 'panic-buy the dip... then panic-sell lower' 😂. This smart system could finally cure my 'emotional averaging' addiction. Now if only it included a 'stop overthinking' algorithm!