Overview
This is a quantitative trading strategy that combines trend following and technical analysis. The strategy uses multiple technical indicators to confirm trading signals, employs a staged take-profit mechanism and dynamic position management system, aiming to capture major market trends while controlling risks. The strategy integrates multiple technical indicators including EMA, MACD, and RSI, identifying potential trading opportunities through indicator crossovers and divergences.
Strategy Principles
The core trading logic is based on the following key elements:
- Entry signals use multiple technical indicator filters: EMA crossovers, MACD crossup/crossdown, and RSI overbought/oversold indicators. Long entry requires fast EMA crossing above slow EMA, MACD golden cross, and RSI below 70; short entry requires fast EMA crossing below slow EMA, MACD death cross, and RSI above 30.
- Risk control employs fixed percentage stop-loss at 5% from entry price.
- Staged take-profit mechanism: first target at 8%, second target at 12%, with dynamic adjustment of the second target to adapt to market volatility.
- Position management is dynamically calculated based on ATR, with maximum risk per trade at 5% and maximum position size not exceeding 40% of account equity.
Strategy Advantages
- Multiple technical indicators cross-validation effectively filters false signals and improves trade quality.
- Staged take-profit mechanism both locks in partial profits and maintains exposure to continued trends.
- Dynamic position management system automatically adjusts trade size based on market volatility for effective risk control.
- Comprehensive risk management system including fixed stop-loss, dynamic positioning, and maximum position limits ensures long-term strategy stability.
- Clear strategy logic with adjustable parameters facilitates optimization for different market conditions.
Strategy Risks
- May face frequent stop-losses in highly volatile markets, requiring parameter adjustment or trading suspension during high volatility periods.
- Consecutive stop-losses possible in ranging markets, suggesting the need for range-bound market detection.
- Multiple indicator filtering may miss some opportunities, potentially underperforming single-indicator strategies in strong trends.
- Staged take-profit mechanism may not exit positions quickly enough in rapid reversals, requiring additional reversal signal detection.
Strategy Optimization Directions
- Consider introducing volatility filtering mechanism to reduce position size or suspend trading during high volatility periods.
- Add trend strength evaluation to adjust take-profit levels during strong trends for capturing more trend profits.
- Optimize position management system by incorporating dynamic position adjustment based on risk-reward ratios.
- Implement market state detection mechanism to use different parameter sets in different market conditions.
- Consider adding volume indicators to improve trading signal reliability.
Summary
This strategy constructs a relatively complete trading system through the combination of multiple technical indicators, staged take-profit mechanisms, and dynamic position management. Its strengths lie in comprehensive risk control and high signal reliability, though it may miss some opportunities. Through continuous optimization and parameter adjustment, the strategy has the potential to maintain stable performance across different market conditions.
Strategy source code
/*backtest
start: 2024-02-10 00:00:00
end: 2025-02-08 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=6
strategy("Hang Strategy Aggressive", overlay=true, initial_capital=1000, currency=currency.USDT, default_qty_type=strategy.cash, default_qty_value=100)
// === Parameter settings ===
fastLength = input.int(5, "Fast EMA length")
slowLength = input.int(15, "Slow EMA length")
rsiLength = input.int(7, "RSI length")
atrPeriod = input.int(10, "ATR period")
leverageMultiple = input.float(3.0, "Leverage", minval=1.0, step=0.5)
// === Take profit and stop loss parameters ===
stopLossPercent = input.float(5.0, "Stop loss percentage", minval=1.0, step=0.5)
firstTakeProfitPercent = input.float(8.0, "First take profit point percentage", minval=1.0, step=0.5)
secondTakeProfitPercent = input.float(12.0, "Second take profit point percentage", minval=1.0, step=0.5)
firstTakeProfitQtyPercent = input.float(50.0, "First take profit position percentage", minval=1.0, maxval=100.0, step=5.0)
// === Technical indicators ===
fastEMA = ta.ema(close, fastLength)
slowEMA = ta.ema(close, slowLength)
superFastEMA = ta.ema(close, 3)
rsi = ta.rsi(close, rsiLength)
atr = ta.atr(atrPeriod)
// === Trend judgment ===
[macdLine, signalLine, histLine] = ta.macd(close, 12, 26, 9)
macdCross = (macdLine > signalLine) and (macdLine[1] < signalLine[1])
macdCrossDown = (macdLine < signalLine) and (macdLine[1] > signalLine[1])
// === Trading signals ===
longCondition = (fastEMA > slowEMA) and macdCross and (rsi < 70)
shortCondition = (fastEMA < slowEMA) and macdCrossDown and (rsi > 30)
// === Close signal ===
exitLong = shortCondition or (fastEMA < slowEMA)
exitShort = longCondition or (fastEMA > slowEMA)
// === Position management ===
maxRiskPerTrade = 0.05
basePosition = strategy.equity * maxRiskPerTrade
atrAmount = atr * close
riskPosition = basePosition / atrAmount * leverageMultiple
positionSize = math.min(riskPosition, strategy.equity * 0.4 / close)
// === Transaction status variables ===
var isLong = false
var isShort = false
var partialTpTriggered = false
var float stopPrice = na
var float firstTpPrice = na
var float secondTpPrice = na
var float firstTpQty = na
// === Trading execution ===
// Long entry
if (longCondition and not isLong and not isShort)
strategy.entry("Long", strategy.long, qty=positionSize)
isLong := true
partialTpTriggered := false
// Short entry
if (shortCondition and not isShort and not isLong)
strategy.entry("Short", strategy.short, qty=positionSize)
isShort := true
partialTpTriggered := false
// === Take-profit and stop-loss logic ===
if (strategy.position_size > 0) // Long position
stopPrice := strategy.position_avg_price * (1 - stopLossPercent/100)
firstTpPrice := strategy.position_avg_price * (1 + firstTakeProfitPercent/100)
// The second take profit price is calculated only when the first take profit is not triggered
if not partialTpTriggered
secondTpPrice := strategy.position_avg_price * (1 + secondTakeProfitPercent/100)
if (close[1] <= stopPrice or low <= stopPrice)
strategy.close_all("Long stop-loss")
isLong := false
partialTpTriggered := false
if (not partialTpTriggered and (close[1] >= firstTpPrice or high >= firstTpPrice))
strategy.order("Long first take profit", strategy.short, qty=firstTpQty)
partialTpTriggered := true
// Recalculate the second take profit price here
secondTpPrice := high * (1 + 0.04) // Based on the current highest price, another 4% increase
if (close[1] >= secondTpPrice or high >= secondTpPrice)
strategy.close_all("Long second take profit")
isLong := false
partialTpTriggered := false
if (strategy.position_size < 0) // Short position
stopPrice := strategy.position_avg_price * (1 + stopLossPercent/100)
firstTpPrice := strategy.position_avg_price * (1 - firstTakeProfitPercent/100)
// The second take profit price is calculated only when the first take profit is not triggered
if not partialTpTriggered
secondTpPrice := strategy.position_avg_price * (1 - secondTakeProfitPercent/100)
if (close[1] >= stopPrice or high >= stopPrice)
strategy.close_all("Short stop-loss")
isShort := false
partialTpTriggered := false
if (not partialTpTriggered and (close[1] <= firstTpPrice or low <= firstTpPrice))
strategy.order("Short first take profit", strategy.long, qty=firstTpQty)
partialTpTriggered := true
// Recalculate the second take profit price here
secondTpPrice := low * (1 - 0.04) // Based on the current lowest price, it will drop by 4%.
if (close[1] <= secondTpPrice or low <= secondTpPrice)
strategy.close_all("Short second take profit")
isShort := false
partialTpTriggered := false
// === Other closing conditions ===
if (exitLong and isLong)
strategy.close_all("Long position closing")
isLong := false
partialTpTriggered := false
if (exitShort and isShort)
strategy.close_all("Short position closing")
isShort := false
partialTpTriggered := false
// === Plot ===
plot(fastEMA, "Fast EMA", color=color.blue)
plot(slowEMA, "Slow EMA", color=color.red)
plot(superFastEMA, "Superfast EMA", color=color.green)
// Plot the stop loss and take profit lines
plot(strategy.position_size != 0 ? strategy.position_avg_price : na, "Opening price", color=color.yellow)
plot(strategy.position_size != 0 ? stopPrice : na, "Stop-loss line", color=color.red)
plot(strategy.position_size != 0 ? firstTpPrice : na, "First take-profit line", color=color.green)
plot(strategy.position_size != 0 ? secondTpPrice : na, "Second take-profit line", color=color.blue)
Strategy Parameters
The original address: Dynamic Trend Following Multi-Indicator Staged Take-Profit Trading Strategy