
This strategy is an advanced trading system based on support and resistance levels, combining dynamic trend channels with risk management functionality. The strategy identifies key support and resistance levels by analyzing price fluctuations’ highs and lows over a specified lookback period, and utilizes channel width parameters to construct dynamic trading ranges, providing traders with a clear market structure perspective and precise trading signals.
The core logic includes several key elements: 1. Support and resistance levels are calculated based on the lowest and highest prices within a user-defined lookback period 2. Dynamic channel width is set through percentage parameters, building upper and lower channels based on support and resistance levels 3. Buy signals are triggered when price approaches support level (within 1% distance) 4. The system automatically calculates stop-loss and take-profit levels based on user-defined percentages 5. Trades are executed only within specified backtesting time range 6. Risk-to-reward ratios are calculated and displayed in real-time to help traders evaluate potential returns against risks
This strategy combines key technical analysis concepts - support/resistance levels and trend channels - to build a logically rigorous and risk-controlled trading system. The strategy’s strengths lie in its adaptability and comprehensive risk management, but traders still need to carefully adjust parameters based on market conditions and personal risk tolerance. Through the suggested optimization directions, the strategy has room for further improvement and can develop into a more comprehensive and robust trading system.
/*backtest
start: 2019-12-23 08:00:00
end: 2025-01-04 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Support and Resistance with Trend Lines and Channels", overlay=true)
// Inputs
lookback = input.int(20, title="Lookback Period for Support/Resistance", minval=1)
channelWidth = input.float(0.01, title="Channel Width (%)", minval=0.001) / 100
startDate = input(timestamp("2023-01-01 00:00"), title="Backtesting Start Date")
endDate = input(timestamp("2023-12-31 23:59"), title="Backtesting End Date")
// Check if the current bar is within the testing range
inTestingRange = true
// Support and Resistance Levels
supportLevel = ta.lowest(low, lookback) // Swing low (support)
resistanceLevel = ta.highest(high, lookback) // Swing high (resistance)
// Trend Lines and Channels
var line supportLine = na
var line resistanceLine = na
var line upperChannelLine = na
var line lowerChannelLine = na
// Calculate channel levels
upperChannel = resistanceLevel * (1 + channelWidth) // Upper edge of channel
lowerChannel = supportLevel * (1 - channelWidth) // Lower edge of channel
// Create or update the support trend line
// if na(supportLine)
// supportLine := line.new(bar_index, supportLevel, bar_index + 1, supportLevel, color=color.green, width=2, extend=extend.right)
// else
// line.set_y1(supportLine, supportLevel)
// line.set_y2(supportLine, supportLevel)
// // Create or update the resistance trend line
// if na(resistanceLine)
// resistanceLine := line.new(bar_index, resistanceLevel, bar_index + 1, resistanceLevel, color=color.red, width=2, extend=extend.right)
// else
// line.set_y1(resistanceLine, resistanceLevel)
// line.set_y2(resistanceLine, resistanceLevel)
// // Create or update the upper channel line
// if na(upperChannelLine)
// upperChannelLine := line.new(bar_index, upperChannel, bar_index + 1, upperChannel, color=color.blue, width=1, style=line.style_dashed, extend=extend.right)
// else
// line.set_y1(upperChannelLine, upperChannel)
// line.set_y2(upperChannelLine, upperChannel)
// // Create or update the lower channel line
// if na(lowerChannelLine)
// lowerChannelLine := line.new(bar_index, lowerChannel, bar_index + 1, lowerChannel, color=color.purple, width=1, style=line.style_dashed, extend=extend.right)
// else
// line.set_y1(lowerChannelLine, lowerChannel)
// line.set_y2(lowerChannelLine, lowerChannel)
// Buy Condition: When price is near support level
buyCondition = close <= supportLevel * 1.01 and inTestingRange
if buyCondition
strategy.entry("Buy", strategy.long)
// Stop Loss and Take Profit
stopLossPercentage = input.float(1.5, title="Stop Loss Percentage", minval=0.0) / 100
takeProfitPercentage = input.float(3.0, title="Take Profit Percentage", minval=0.0) / 100
var float longStopLoss = na
var float longTakeProfit = na
if strategy.position_size > 0
longStopLoss := strategy.position_avg_price * (1 - stopLossPercentage)
longTakeProfit := strategy.position_avg_price * (1 + takeProfitPercentage)
strategy.exit("Exit Buy", "Buy", stop=longStopLoss, limit=longTakeProfit)
// Visualize Entry, Stop Loss, and Take Profit Levels
var float entryPrice = na
if buyCondition
entryPrice := close
if not na(entryPrice)
label.new(bar_index, entryPrice, text="Entry: " + str.tostring(entryPrice, "#.##"), style=label.style_label_up, color=color.green, textcolor=color.white)
if strategy.position_size > 0
line.new(bar_index, longStopLoss, bar_index + 1, longStopLoss, color=color.red, width=1, extend=extend.right)
line.new(bar_index, longTakeProfit, bar_index + 1, longTakeProfit, color=color.blue, width=1, extend=extend.right)
// Risk-to-Reward Ratio (Optional)
if not na(entryPrice) and not na(longStopLoss) and not na(longTakeProfit)
riskToReward = (longTakeProfit - entryPrice) / (entryPrice - longStopLoss)
label.new(bar_index, entryPrice, text="R:R " + str.tostring(riskToReward, "#.##"), style=label.style_label_up, color=color.yellow, textcolor=color.black, size=size.small)