Trendline Breaks with Multi Fibonacci Supertrend Strategy

FibonacciFlux · strategy · 364 行 · 点赞 3,147 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
// https://creativecommons.org/licenses/by-nc-sa/4.0/
// Original concepts by FibonacciFlux, rewritten for clarity and functionality
 
//@version=6
strategy('Trendline Breaks with Multi Fibonacci Supertrend Strategy', shorttitle = "TMFS Strategy", overlay = true, initial_capital = 100, default_qty_type = strategy.percent_of_equity, default_qty_value = 100)
 
//----------------------------------------------------------
// SECTION 1: FIBONACCI SUPERTREND CONFIGURATION
//----------------------------------------------------------
 
// Common ATR period for all supertrend calculations
atrPeriod = input.int(13, 'ATR Length', minval = 1, tooltip="ATR period used for volatility calculation")
 
// Fibonacci-based supertrend factor inputs
factor1 = input.float(0.618, 'Factor 1 (Weak/Fibonacci)', minval = 0.01, step = 0.01, tooltip="First Fibonacci factor (0.618)")
factor2 = input.float(1.618, 'Factor 2 (Medium/Golden Ratio)', minval = 0.01, step = 0.01, tooltip="Second Fibonacci factor (1.618)")
factor3 = input.float(2.618, 'Factor 3 (Strong/Extended Fib)', minval = 0.01, step = 0.01, tooltip="Third Fibonacci factor (2.618)")
 
// Calculate the three Supertrend lines with different sensitivity levels
[supertrend1, direction1] = ta.supertrend(factor1, atrPeriod)
[supertrend2, direction2] = ta.supertrend(factor2, atrPeriod)
[supertrend3, direction3] = ta.supertrend(factor3, atrPeriod)
 
// Handle initial values (first bar)
supertrend1 := barstate.isfirst ? na : supertrend1
supertrend2 := barstate.isfirst ? na : supertrend2
supertrend3 := barstate.isfirst ? na : supertrend3
 
// Calculate average of the three supertends and a smoothed version
superlength = input.int(21, "Smoothing Length", tooltip="EMA length for smoothing the average supertrend")
average_trend = (supertrend1 + supertrend2 + supertrend3) / 3
smoothed_trend = ta.ema(average_trend, superlength)
 
// Plot the supertrend lines and fill the area between them
trend_plot = plot(average_trend, color = average_trend > average_trend[1] ? color.green : color.red, title="Average Supertrend")
smoothed_plot = plot(smoothed_trend, linewidth = 2, color = smoothed_trend > smoothed_trend[1] ? color.green : color.red, title="Smoothed Supertrend")
fill(trend_plot, smoothed_plot, color = average_trend > smoothed_trend ? color.new(color.green, 50) : color.new(color.red, 50), title="Trend Direction Fill")
 
//----------------------------------------------------------
// SECTION 2: TRENDLINE DETECTION AND DRAWING
//----------------------------------------------------------
 
// User settings for Swing Trend Lines
swing_length = input.int(8, 'Swing Lookback Period', tooltip="Number of bars to look back for pivot points")
atr_multiplier = input.float(1.0, 'ATR Slope Multiplier', minval = 0.0, step = 0.1, tooltip="Multiplier for ATR to control trendline slope")
show_extended_lines = input.bool(true, 'Show Extended Lines', tooltip="Display dashed extensions for trendlines")
enable_backpainting = input.bool(true, 'Use Backpainting', tooltip="Enable backpainting to move indicators to pivot point")
 
// Color settings for trendlines
uptrend_color = color.new(color.teal, 0)
downtrend_color = color.new(color.red, 0)
 
// Variable initialization for trendlines
var float upper_trendline = na
var float lower_trendline = na
var float upper_slope = na
var float lower_slope = na
var line upline_extension = na
var line downline_extension = na
 
// Offset for backpainting
offset = enable_backpainting ? swing_length : 0
bar_idx = bar_index
 
// Get pivot high and low points
pivot_high = ta.pivothigh(swing_length, swing_length)
pivot_low = ta.pivotlow(swing_length, swing_length)
 
// Calculate ATR for slope
atr_value = ta.atr(swing_length)
slope = atr_value / swing_length * atr_multiplier
 
// Update upper trendline when pivot high is detected or extend existing trendline
if bool(pivot_high)
    upper_slope := slope
    upper_trendline := pivot_high
else
    upper_trendline := nz(upper_trendline) - nz(upper_slope)
 
// Update lower trendline when pivot low is detected or extend existing trendline
if bool(pivot_low)
    lower_slope := slope
    lower_trendline := pivot_low
else
    lower_trendline := nz(lower_trendline) + nz(lower_slope)
 
// Create and update extended visualization lines if enabled
if show_extended_lines
    // Initialize line objects if not already created
    if na(upline_extension)
        upline_extension := line.new(na, na, na, na, extend = extend.right, style = line.style_dashed, color = uptrend_color)
 
    if na(downline_extension)
        downline_extension := line.new(na, na, na, na, extend = extend.right, style = line.style_dashed, color = downtrend_color)
 
    // Update upper trendline extension when a new pivot high is confirmed
    if bool(pivot_high)
        line.set_xy1(upline_extension, bar_idx - offset, enable_backpainting ? pivot_high : upper_trendline)
        line.set_xy2(upline_extension, bar_idx - offset + 1, enable_backpainting ? pivot_high - slope : upper_trendline - slope)
 
    // Update lower trendline extension when a new pivot low is confirmed
    if bool(pivot_low)
        line.set_xy1(downline_extension, bar_idx - offset, enable_backpainting ? pivot_low : lower_trendline)
        line.set_xy2(downline_extension, bar_idx - offset + 1, enable_backpainting ? pivot_low + slope : lower_trendline + slope)
 
//----------------------------------------------------------
// SECTION 3: BREAKOUT DETECTION
//----------------------------------------------------------
 
// Track breakouts above upper trendline and below lower trendline
// Initialize tracking variables for breakout conditions
var int upper_breakout_state = 0  // State variable to track upper breakout condition
var int lower_breakout_state = 0  // State variable to track lower breakout condition
 
// Detect breakouts
bool upper_breakout = close > upper_trendline
bool lower_breakout = close < lower_trendline
 
// Update state variables to track when breakouts occur
upper_breakout_state := bool(pivot_high) ? 0 : upper_breakout ? 1 : upper_breakout_state
lower_breakout_state := bool(pivot_low) ? 0 : lower_breakout ? 1 : lower_breakout_state
 
// Plot trendlines with appropriate offsets
plot(enable_backpainting ? upper_trendline : upper_trendline, color = bool(pivot_high) ? na : uptrend_color, linewidth = 2, offset = -offset, title = 'Upper Trendline')
plot(enable_backpainting ? lower_trendline : lower_trendline, color = bool(pivot_low) ? na : downtrend_color, linewidth = 2, offset = -offset, title = 'Lower Trendline')
 
//----------------------------------------------------------
// SECTION 4: DIRECTIONAL MOVEMENT INDEX (DMI) CALCULATION
//----------------------------------------------------------
 
// DMI Length parameter
dmi_length = input.int(13, "DMI Length", tooltip="Length for DMI calculation")
 
// True Range calculation
true_range = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1])))
 
// Directional Movement calculations
directional_movement_plus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0
directional_movement_minus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0
 
// Smoothed calculations for DMI
var float smoothed_true_range = 0.0
smoothed_true_range := nz(smoothed_true_range[1]) - nz(smoothed_true_range[1]) / dmi_length + true_range
 
var float smoothed_directional_plus = 0.0
smoothed_directional_plus := nz(smoothed_directional_plus[1]) - nz(smoothed_directional_plus[1]) / dmi_length + directional_movement_plus
 
var float smoothed_directional_minus = 0.0
smoothed_directional_minus := nz(smoothed_directional_minus[1]) - nz(smoothed_directional_minus[1]) / dmi_length + directional_movement_minus
 
// Calculate DI+ and DI- values
di_plus = smoothed_directional_plus / smoothed_true_range * 100
di_minus = smoothed_directional_minus / smoothed_true_range * 100
 
//----------------------------------------------------------
// SECTION 5: STRATEGY DEFINITION
//----------------------------------------------------------
 
// Enable/disable long and short positions
enable_long_positions = input.bool(defval = true, title = 'Enable Long Positions', group = 'Strategy Settings')
enable_short_positions = input.bool(defval = true, title = 'Enable Short Positions', group = 'Strategy Settings')
 
// SMA settings for trend confirmation
fast_sma_length = input.int(defval = 2, title = 'Fast SMA Length', minval = 1, group = 'Strategy Settings')
slow_sma_length = input.int(defval = 3, title = 'Slow SMA Length', minval = 1, group = 'Strategy Settings')
 
// Calculate SMA crossovers
fast_sma = ta.sma(close, fast_sma_length)
slow_sma = ta.sma(close, slow_sma_length)
 
// Detect SMA crossovers
sma_cross_up = ta.crossover(fast_sma, slow_sma)
sma_cross_down = ta.crossunder(fast_sma, slow_sma)
 
//----------------------------------------------------------
// SECTION 6: ENTRY AND EXIT CONDITIONS
//----------------------------------------------------------
 
// Define entry conditions
long_entry_condition = enable_long_positions and upper_breakout_state > upper_breakout_state[1] and di_plus > di_minus and close > smoothed_trend
short_entry_condition = enable_short_positions and lower_breakout_state > lower_breakout_state[1] and di_minus > di_plus and close < smoothed_trend
 
// Define exit conditions
long_exit_condition = ta.crossunder(close[1], smoothed_trend)
short_exit_condition = ta.crossover(close[1], smoothed_trend)
 
// @function Display BUY/SELL labels on chart
plotshape(long_entry_condition, title='BUY', text='BUY', location=location.belowbar, 
         style=shape.labelup, size=size.tiny, color=color.new(color.green, 0), textcolor=color.new(color.white, 0))
plotshape(short_entry_condition, title='SELL', text='SELL', location=location.abovebar, 
         style=shape.labeldown, size=size.tiny, color=color.new(color.red, 0), textcolor=color.new(color.white, 0))
 
//----------------------------------------------------------
// SECTION 7: STOP LOSS AND TAKE PROFIT SETTINGS
//----------------------------------------------------------
 
// Common settings
atr_length = input.int(13, 'ATR Length for SL/TP', minval = 1, group = 'Risk Management')
 
// Variable to track if stop loss is triggered
var bool long_trailing_tp_executed = false
var bool short_trailing_tp_executed = false
 
// Store ATR at position entry
float entry_atr = ta.valuewhen(long_entry_condition or short_entry_condition, ta.atr(atr_length), 0)
 
// Stop Loss settings
stop_loss_method = input.string(defval = 'ATR', title = 'Stop Loss Method', options = ['PERC', 'ATR'], group = 'Stop Loss')
long_stop_loss_percent = input.float(defval = 0.75, title = 'Long Position Stop Loss %', minval = 0.05, maxval = 100, step = 0.05, group = 'Stop Loss') / 100
short_stop_loss_percent = input.float(defval = 0.75, title = 'Short Position Stop Loss %', minval = 0.05, maxval = 100, step = 0.05, group = 'Stop Loss') / 100
long_stop_loss_atr_multiplier = input.float(defval = 8.0, title = 'Long Position ATR Multiplier', minval = 0.1, step = 0.1, group = 'Stop Loss')
short_stop_loss_atr_multiplier = input.float(defval = 8.0, title = 'Short Position ATR Multiplier', minval = 0.1, step = 0.1, group = 'Stop Loss')
stop_loss_trailing_mode = input.string(defval = 'ON', title = 'Trailing Stop Loss Mode', options = ['TP', 'ON', 'OFF'], tooltip = 'ON: Always trail, TP: Trail after Take Profit hit, OFF: Fixed stop', group = 'Stop Loss')
break_even_enabled = input.bool(defval = true, title = 'Move to Break Even After TP', group = 'Stop Loss')
 
// Take Profit settings
take_profit_quantity_percent = input.float(defval = 100, title = 'Take Profit Quantity %', minval = 0.0, maxval = 100, step = 1.0, group = 'Take Profit')
take_profit_method = input.string(defval = 'PERC', title = 'Take Profit Method', options = ['PERC', 'ATR', 'RR'], group = 'Take Profit')
long_take_profit_percent = input.float(defval = 1, title = 'Long Position Take Profit %', minval = 0.05, step = 0.05, group = 'Take Profit') / 100
short_take_profit_percent = input.float(defval = 1, title = 'Short Position Take Profit %', minval = 0.05, step = 0.05, group = 'Take Profit') / 100
long_take_profit_atr_multiplier = input.float(defval = 1.5, title = 'Long Position TP ATR Multiplier', minval = 0.1, step = 0.1, group = 'Take Profit')
short_take_profit_atr_multiplier = input.float(defval = 2, title = 'Short Position TP ATR Multiplier', minval = 0.1, step = 0.1, group = 'Take Profit')
long_risk_reward_ratio = input.float(defval = 0.6, title = 'Long Position Risk/Reward Ratio', minval = 0.1, step = 0.1, group = 'Take Profit')
short_risk_reward_ratio = input.float(defval = 1, title = 'Short Position Risk/Reward Ratio', minval = 0.1, step = 0.1, group = 'Take Profit')
trailing_take_profit_enabled = input.bool(defval = true, title = 'Enable Trailing Take Profit', group = 'Take Profit')
deviation_method = input.string(defval = 'PERC', title = 'Trailing Deviation Method', options = ['PERC', 'ATR'], group = 'Take Profit')
deviation_percent = input.float(defval = 0.01, title = 'Trailing Deviation %', minval = 0.01, maxval = 100, step = 0.05, group = 'Take Profit') / 100
deviation_atr_multiplier = input.float(defval = 1.0, title = 'Trailing Deviation ATR Multiplier', minval = 0.01, step = 0.05, group = 'Take Profit')
 
//----------------------------------------------------------
// SECTION 9: CALCULATE STOP LOSS LEVELS
//----------------------------------------------------------
 
// Calculate long position stop loss price based on selected method
get_long_stop_loss_price(base_price) =>
    switch stop_loss_method
        'PERC' => base_price * (1 - long_stop_loss_percent)
        'ATR' => base_price - long_stop_loss_atr_multiplier * entry_atr
        => na
 
// Determine if trailing should be active for long position
long_tp_trailing_enabled = stop_loss_trailing_mode == 'ON' or (stop_loss_trailing_mode == 'TP' and long_trailing_tp_executed)
 
// Calculate and maintain stop loss price for long positions
var float long_stop_loss_price = na
long_stop_loss_price := if strategy.position_size > 0
    if long_entry_condition
        get_long_stop_loss_price(close)
    else
        stop_price = get_long_stop_loss_price(long_tp_trailing_enabled ? high : strategy.position_avg_price)
        stop_price := break_even_enabled and long_trailing_tp_executed ? math.max(stop_price, strategy.position_avg_price) : stop_price
        math.max(stop_price, nz(long_stop_loss_price[1]))
else
    na
 
// Calculate short position stop loss price based on selected method
get_short_stop_loss_price(base_price) =>
    switch stop_loss_method
        'PERC' => base_price * (1 + short_stop_loss_percent)
        'ATR' => base_price + short_stop_loss_atr_multiplier * entry_atr
        => na
 
// Determine if trailing should be active for short position
short_tp_trailing_enabled = stop_loss_trailing_mode == 'ON' or (stop_loss_trailing_mode == 'TP' and short_trailing_tp_executed)
 
// Calculate and maintain stop loss price for short positions
var float short_stop_loss_price = na
short_stop_loss_price := if strategy.position_size < 0
    if short_entry_condition
        get_short_stop_loss_price(close)
    else
        var float stop_price = get_short_stop_loss_price(short_tp_trailing_enabled ? low : strategy.position_avg_price) // stop_price を var float で宣言
        if break_even_enabled and short_trailing_tp_executed
            stop_price := math.min(stop_price, strategy.position_avg_price)
        short_stop_loss_price := math.min(stop_price, nz(short_stop_loss_price[1], 999999.9))
else
    na
 
//----------------------------------------------------------
// SECTION 9: CALCULATE TAKE PROFIT LEVELS
//----------------------------------------------------------
 
// Calculate long position take profit price based on selected method
get_long_take_profit_price() =>
    switch take_profit_method
        'PERC' => close * (1 + long_take_profit_percent)
        'ATR' => close + long_take_profit_atr_multiplier * entry_atr
        'RR' => close + long_risk_reward_ratio * (close - get_long_stop_loss_price(close))
        => na
 
// Calculate and maintain take profit price for long positions
var float long_take_profit_price = na
long_take_profit_price := if strategy.position_size > 0 and not long_trailing_tp_executed
    if long_entry_condition
        get_long_take_profit_price()
    else
        nz(long_take_profit_price[1], get_long_take_profit_price())
else
    na
 
// Update trailing take profit execution flag for long positions
long_trailing_tp_executed := strategy.position_size > 0 and (long_trailing_tp_executed[1] or strategy.position_size < strategy.position_size[1] or (strategy.position_size[1] == 0 and high >= long_take_profit_price))
 
// Calculate trailing step size in ticks for long positions
long_trailing_tp_step_ticks = switch deviation_method
    'PERC' => long_take_profit_price * deviation_percent / syminfo.mintick
    'ATR' => deviation_atr_multiplier * entry_atr / syminfo.mintick
    => na
 
// Calculate short position take profit price based on selected method
get_short_take_profit_price() =>
    switch take_profit_method
        'PERC' => close * (1 - short_take_profit_percent)
        'ATR' => close - short_take_profit_atr_multiplier * entry_atr
        'RR' => close - short_risk_reward_ratio * (get_short_stop_loss_price(close) - close)
        => na
 
// Calculate and maintain take profit price for short positions
var float short_take_profit_price = na
short_take_profit_price := if strategy.position_size < 0 and not short_trailing_tp_executed
    if short_entry_condition
        get_short_take_profit_price()
    else
        nz(short_take_profit_price[1], get_short_take_profit_price())
else
    na
 
// Update trailing take profit execution flag for short positions
short_trailing_tp_executed := strategy.position_size < 0 and (short_trailing_tp_executed[1] or strategy.position_size > strategy.position_size[1] or (strategy.position_size[1] == 0 and low <= short_take_profit_price))
 
// Calculate trailing step size in ticks for short positions
short_trailing_tp_step_ticks = switch deviation_method
    'PERC' => short_take_profit_price * deviation_percent / syminfo.mintick
    'ATR' => deviation_atr_multiplier * entry_atr / syminfo.mintick
    => na
 
//----------------------------------------------------------
// SECTION 11: STRATEGY EXECUTION
//----------------------------------------------------------
 
// Enter long position when conditions are met
if long_entry_condition
    strategy.entry('L', strategy.long, comment = "LONG")
 
// Enter short position when conditions are met
if short_entry_condition
    strategy.entry('S', strategy.short, comment = "SHORT")
 
// Exit long position when exit conditions are met
if long_exit_condition
    strategy.close('L', comment = "SL Triggered")
 
// Exit short position when exit conditions are met
if short_exit_condition
    strategy.close('S', comment = "SL Triggered")
 
// Set up take profit and stop loss for long positions
strategy.exit(id = 'Long Take Profit / Stop Loss', from_entry = 'L', qty_percent = take_profit_quantity_percent, limit = trailing_take_profit_enabled ? na : long_take_profit_price, stop = long_stop_loss_price, trail_price = trailing_take_profit_enabled ? long_take_profit_price : na, trail_offset = trailing_take_profit_enabled ? long_trailing_tp_step_ticks : na, comment = "TP/SL Triggered")
strategy.exit(id = 'Long Stop Loss', from_entry = 'L', stop = long_stop_loss_price, comment = "SL Triggered")
 
// Set up take profit and stop loss for short positions
strategy.exit(id = 'Short Take Profit / Stop Loss', from_entry = 'S', qty_percent = take_profit_quantity_percent, limit = trailing_take_profit_enabled ? na : short_take_profit_price, stop = short_stop_loss_price, trail_price = trailing_take_profit_enabled ? short_take_profit_price : na, trail_offset = trailing_take_profit_enabled ? short_trailing_tp_step_ticks : na, comment = "TP/SL Triggered")
strategy.exit(id = 'Short Stop Loss', from_entry = 'S', stop = short_stop_loss_price, comment = "SL Triggered")

← 返回列表