资源加载中... loading...

斐波那契趋势反转策略

Author: ChaoZhang, Date: 2024-04-28 14:05:45
Tags: ATRTSOTRMA

斐波那契趋势反转策略

概述

“斐波那契趋势反转策略”是一种利用斐波那契回撤水平和趋势强度指标(TSOT)来捕捉市场趋势反转点的交易策略。该策略通过动态ATR止损和部分止盈,实现了风险管理和利润的最大化。策略适用于5分钟的可扩展市场。

策略原理

该策略使用斐波那契回撤水平(0.236、0.5和0.786)来识别潜在的趋势反转点。同时,利用TSOT指标通过价格的百分位数排名来衡量趋势强度。当价格突破中间的斐波那契水平(0.5)并且TSOT指标显示看涨/看跌信号时,策略开仓做多/做空。止损位置使用动态ATR计算,止盈则设置了部分止盈和风险回报比。此外,策略还允许根据新的TSOT信号反转仓位。

策略优势

  1. 结合斐波那契回撤和趋势强度指标,能够更准确地捕捉趋势反转点。
  2. 动态ATR止损根据当前市场波动率调整,实现了有效的风险管理。
  3. 部分止盈设置可以在达到目标盈利时及时获利了结,同时让利润继续奔跑。
  4. 允许根据新信号反转仓位,提高了策略的适应性和灵活性。

策略风险

  1. 在震荡市或趋势不明朗时,频繁的反转信号可能导致过度交易和损失。
  2. 虽然动态止损和部分止盈有助于控制风险,但极端行情下仍可能出现较大回撤。
  3. 策略参数(如斐波那契水平、TSOT计算等)的选择需要根据不同市场和时间周期进行优化,不恰当的参数可能影响策略表现。

策略优化方向

  1. 引入更多确认信号(如交易量、动量指标等)来过滤假信号,提高开仓准确性。
  2. 优化止盈止损逻辑,如结合趋势强度动态调整止盈目标,或者引入追踪止损等。
  3. 对于频繁反转的情况,可以设置反转次数限制或加入反转过滤条件,以减少过度交易。
  4. 针对不同的市场特点和交易品种,对策略参数进行细致的优化和测试。

总结

“斐波那契趋势反转策略”通过斐波那契回撤水平和TSOT指标的结合,能够有效捕捉趋势反转点,并通过动态止损和部分止盈实现风险控制和利润目标。策略在趋势明确的市场中表现出色,但在震荡市需要谨慎应对。未来可以从信号确认、止盈止损优化、反转管理等方面对策略进行进一步的改进和完善,以提升其稳健性和盈利能力。


/*backtest
start: 2023-04-22 00:00:00
end: 2024-04-27 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © nioboi

//@version=5
strategy("Fibonacci Trend Reversals", overlay=true, process_orders_on_close = true, commission_value = 0.055, initial_capital = 1000)

// =========================================
// Input Groups
// =========================================
string rsi_group = "RSI"
string main_group = "Fib Sensitivity"
string atr_sl_finder_group = "ATR SL Finder"
string trade_execution_group = "Strategy Execution"

// =========================================
// Fibonacci Retracement Trend Reversal
// =========================================
sensitivity_input = input.float(title = 'Sensitive', step = 0.1, defval = 18, group = main_group)
var bool is_long_trend_started = false
var bool is_short_trend_started = false
var bool is_trend_change = na
var bool is_long_trend = false
var bool is_short_trend = false
var bool can_long = false
var bool can_short = false

sensitivity = sensitivity_input
sensitivity *= 10

high_line = ta.highest(high, int(sensitivity))
low_line = ta.lowest(low, int(sensitivity))
channel_range = high_line - low_line
fib_236 = high_line - channel_range * (0.236)
fib_5 = high_line - channel_range * 0.5
fib_786 = high_line - channel_range * (0.786)
imba_trend_line = fib_5

// =========================================
// TSOT | Trend Strength Over Time
// =========================================

// Calculate 75th percentile of price for each length
percentile_13H = ta.percentile_nearest_rank(high, 13, 75) 
percentile_21H = ta.percentile_nearest_rank(high, 21, 75) 
percentile_34H = ta.percentile_nearest_rank(high, 34, 75) 
percentile_55H = ta.percentile_nearest_rank(high, 55, 75) 
percentile_89H = ta.percentile_nearest_rank(high, 89, 75)

// Calculate 25th percentile of  price for each length
percentile_13L =  ta.percentile_nearest_rank(low, 13, 25) 
percentile_21L =  ta.percentile_nearest_rank(low, 21, 25) 
percentile_34L =  ta.percentile_nearest_rank(low, 34, 25) 
percentile_55L = ta.percentile_nearest_rank(low, 55, 25) 
percentile_89L = ta.percentile_nearest_rank(low, 89, 25)

// Calculate 75th and 25th for length 144 (longest length)
highest_high = ta.percentile_nearest_rank(high, 144, 75) 
lowest_low = ta.percentile_nearest_rank(low, 144, 25) 

// Calculate trend strength conditions
trendBull1 = percentile_13H > highest_high
trendBull2 = percentile_21H > highest_high
trendBull3 = percentile_34H > highest_high
trendBull4 = percentile_55H > highest_high
trendBull5 = percentile_89H > highest_high
trendBull6 = percentile_13L > highest_high
trendBull7 = percentile_21L > highest_high
trendBull8 = percentile_34L > highest_high
trendBull9 = percentile_55L > highest_high
trendBull10 = percentile_89L > highest_high

trendBear1 = percentile_13H < lowest_low
trendBear2 = percentile_21H < lowest_low
trendBear3 = percentile_34H < lowest_low
trendBear4 = percentile_55H < lowest_low
trendBear5 = percentile_89H < lowest_low
trendBear6 = percentile_13L < lowest_low
trendBear7 = percentile_21L < lowest_low
trendBear8 = percentile_34L < lowest_low
trendBear9 = percentile_55L < lowest_low
trendBear10 = percentile_89L < lowest_low

countBull =
     (trendBull1 ? 1 : 0) +
     (trendBull2 ? 1 : 0) +
     (trendBull3 ? 1 : 0) +
     (trendBull4 ? 1 : 0) +
     (trendBull5 ? 1 : 0) +
     (trendBull6 ? 1 : 0) +
     (trendBull7 ? 1 : 0) +
     (trendBull8 ? 1 : 0) +
     (trendBull9 ? 1 : 0) +
     (trendBull10 ? 1 : 0)

countBear =
     (trendBear1 ? 1 : 0) +
     (trendBear2 ? 1 : 0) +
     (trendBear3 ? 1 : 0) +
     (trendBear4 ? 1 : 0) +
     (trendBear5 ? 1 : 0) +
     (trendBear6 ? 1 : 0) +
     (trendBear7 ? 1 : 0) +
     (trendBear8 ? 1 : 0) +
     (trendBear9 ? 1 : 0) +
     (trendBear10 ? 1 : 0)

// Calculate weak bull count
weakBullCount = 
     (percentile_13L < highest_high and percentile_13L > lowest_low ? 1 : 0) +
     (percentile_21L < highest_high and percentile_21L > lowest_low ? 1 : 0) +
     (percentile_34L < highest_high and percentile_34L > lowest_low ? 1 : 0) +
     (percentile_55L < highest_high and percentile_55L > lowest_low ? 1 : 0) +
     (percentile_89L < highest_high and percentile_89L > lowest_low ? 1 : 0)

// Calculate weak bear count
weakBearCount = 
     (percentile_13H > lowest_low and percentile_13H < highest_high ? 1 : 0) +
     (percentile_21H > lowest_low and percentile_21H < highest_high ? 1 : 0) +
     (percentile_34H > lowest_low and percentile_34H < highest_high ? 1 : 0) +
     (percentile_55H > lowest_low and percentile_55H < highest_high ? 1 : 0) +
     (percentile_89H > lowest_low and percentile_89H < highest_high ? 1 : 0)

// Calculate bull strength and bear strength
bullStrength = 10 * (countBull + 0.5*weakBullCount - 0.5*weakBearCount - countBear)
bearStrength = 10 * (countBear + 0.5*weakBearCount - 0.5*weakBullCount - countBull)

// Calculate the current trend
currentTrendValue = bullStrength - bearStrength

tsot_bullish = currentTrendValue > 0
tsot_bearish = currentTrendValue < 0

// CAN LONG/SHORT
can_long := close >= imba_trend_line and close >= fib_236 and not is_long_trend and tsot_bullish
can_short := close <= imba_trend_line and close <= fib_786 and not is_short_trend and tsot_bearish

if can_long
    is_long_trend := true
    is_short_trend := false
    is_long_trend_started := is_long_trend_started ? false : true
else if can_short
    is_short_trend := true
    is_long_trend := false
    is_short_trend_started := is_short_trend_started ? false : true
else
    is_trend_change := false
    can_long := false
    can_short := false
    is_short_trend_started := false
    is_long_trend_started := false

is_trend_change := is_short_trend_started or is_long_trend_started
plotshape(is_long_trend and is_long_trend_started ? imba_trend_line : na, title="Long", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
plotshape(is_short_trend and is_short_trend_started ? imba_trend_line : na, title="Short", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.small)
plot(imba_trend_line, color = is_long_trend[1] ? color.green : color.red, linewidth = 3)

// =========================================
// ATR SL Finder
// =========================================
atrlength = input.int(title='Length', defval=14, minval=1, group = atr_sl_finder_group)
smoothing = input.string(title='Smoothing', defval='RMA', options=['RMA', 'SMA', 'EMA', 'WMA'], group = atr_sl_finder_group)
m = input(3.5, 'Multiplier', group = atr_sl_finder_group)
src1 = high
src2 = low
ma_function(source, length) =>
    if smoothing == 'RMA'
        ta.rma(source, length)
    else
        if smoothing == 'SMA'
            ta.sma(source, length)
        else
            if smoothing == 'EMA'
                ta.ema(source, length)
            else
                ta.wma(source, length)

x = ma_function(ta.tr(true), atrlength) * m + src1 // SHORT SL
x2 = src2 - ma_function(ta.tr(true), atrlength) * m // LONG SL

p1 = plot(x, title="ATR Short Stop Loss", color=color.red)
p2 = plot(x2, title="ATR Long Stop Loss", color=color.green)

// =========================================
// Strategy Execution
// =========================================

tradeDirection = input.string("Both", "Trade Direction", ["Long Only", "Short Only", "Both"], group = trade_execution_group, tooltip = "Select if you want this strategy to run only Long or Only Short positions, or Both")

risk_reward_ratio = input.float(2, "Risk Reward Ratio", group = trade_execution_group)
partialTp = input.bool(true, "Use Partial Take Profit", tooltip = "Enable this if you want to exit 50% of your position when half point of your Risk Reward is reached.", group = trade_execution_group)
allowReversePosition = input.bool(true, "Allow Reversing of Position", tooltip = "Enable this if you want to reverse position when new opposite signal occurs", group = trade_execution_group)

// Long or Short Conditions
enterLong = can_long and (tradeDirection == "Long Only" or tradeDirection == "Both")
enterShort = can_short and (tradeDirection == "Short Only" or tradeDirection == "Both")

// Long Entry Variables
var bool plotMarkers_long = false
var bool firstTPHit_long = false
var float sl_long = na
var float breakEven_long = na
var float tp1_long = na
var float tp2_long = na
var float entryPrice_long = na
var bool inLongPosition = false

// Short Entry Variables
var bool plotMarkers_short = false
var bool firstTPHit_short = false
var float sl_short = na
var float breakEven_short = na
var float tp1_short = na
var float tp2_short = na
var float entryPrice_short = na
var bool inShortPosition = false


// Reversal Logic
if inLongPosition and can_short and allowReversePosition // in a long position and signal to enter short and havent yet hit first tp
    strategy.close("Long", "Reversing Long to Short") // close Long in preparation to enter short in the next few lines
    inLongPosition := false
else if inShortPosition and can_long and allowReversePosition // in a short position and signal to enter long and havent yet hit first tp
    strategy.close("Short", "Reversing Short to Long") // close Short in preparation to enter long in the next few lines 
    inShortPosition := false

// Long Entries
if enterLong
    entryPrice_long := close 
    sl_long := x2
    risk = entryPrice_long - sl_long
    tp1_long := entryPrice_long + ((risk_reward_ratio * risk) / 2)
    tp2_long := entryPrice_long + (risk_reward_ratio * risk)
    breakEven_long := entryPrice_long + (entryPrice_long * 0.002)
    strategy.entry("Long", strategy.long)
    if not partialTp
        strategy.exit("Exit Long", "Long", limit = tp2_long, stop = sl_long)
    firstTPHit_long := false
    inLongPosition := true

// Short Entries
if enterShort
    entryPrice_short := close
    sl_short := x
    risk = sl_short - entryPrice_short
    tp1_short := entryPrice_short - ((risk_reward_ratio * risk)/2)
    tp2_short := entryPrice_short - (risk_reward_ratio * risk)
    breakEven_short := entryPrice_short - (entryPrice_short * 0.002)
    strategy.entry("Short", strategy.short)
    if not partialTp
        strategy.exit("Exit Short", "Short", limit = tp2_short, stop = sl_short)
    firstTPHit_short := false
    inShortPosition := true

// Dynamic TP and exit strategy for Longs
if inLongPosition and partialTp // in long position and partial TP for exit strategy is enabled
    if high >= tp1_long and not firstTPHit_long // high of candle hit first TP of long, and not yet hit first TP before
        strategy.close("Long", "TP-1 Long", qty_percent = 50) // close 50% of our long position
        sl_long := breakEven_long
        firstTPHit_long := true // set the first TP checker flag to true
    else if high >= tp2_long and firstTPHit_long // already hit the first TP and we hit our 2nd tp
        strategy.close("Long", "TP-2 long") // close the remaining of the long position
        inLongPosition := false // not in long position anymore
    else if low <= sl_long and not firstTPHit_long // not yet hit first TP but hit our SL
        strategy.close("Long", "SL long") // close the entire long position
        inLongPosition := false // not in long position anymore
    else if low <= breakEven_long and firstTPHit_long // already hit first TP and retraced back to breakEven
        strategy.close("Long", "BE Long")
        inLongPosition := false // not in long position anymore

// Dynamic TP and exit strategy for Shorts
if inShortPosition and partialTp // in short position and partial TP for exit strategy is enabled
    if low <= tp1_short and not firstTPHit_short // low of candle hit first TP of short, and not yet hit first TP before
        strategy.close("Short", "TP-1 Short", qty_percent = 50) // close 50% of our short position
        firstTPHit_short := true // set the first TP checker flag to true
        sl_short := breakEven_short
    else if low <= tp2_short and firstTPHit_short // already hit the first TP and we hit our 2nd tp
        strategy.close("Short", "TP-2 Short") // close the remaining of the short position
        inShortPosition := false // not in short position anymore
    else if high >= sl_short and not firstTPHit_short // not yet hit first TP but hit our SL
        strategy.close("Short", "SL Short") // close the entire long position
        inShortPosition := false // not in long position anymore
    else if high >= breakEven_short and firstTPHit_short // already hit first TP and retraced back to breakEven
        strategy.close("Short", "BE Short")
        inShortPosition := false // not in long position anymore

// =========================================
// Entry Visuals
// =========================================

// Entry Visual Flags
if inLongPosition
    plotMarkers_long := true
    plotMarkers_short := false
else if inShortPosition
    plotMarkers_long := false
    plotMarkers_short := true
    
showEntryVisuals = input.bool(true, "Show Entry Visuals", group = trade_execution_group)
plot(plotMarkers_long and showEntryVisuals?sl_long:na, "SL Marker L", color = #ff0000a4, linewidth = 1, style = plot.style_linebr)
plot(plotMarkers_long and showEntryVisuals?tp1_long:na, "TP1 Marker L", color = #00ff08a8, linewidth = 1, style = plot.style_linebr)
plot(plotMarkers_long and showEntryVisuals?tp2_long:na, "TP2 Marker L", color = #1100ffa9, linewidth = 1, style = plot.style_linebr)
plot(plotMarkers_short and showEntryVisuals?sl_short:na, "SL Marker S", color = #ff0000a4, linewidth = 1, style = plot.style_linebr)
plot(plotMarkers_short and showEntryVisuals?tp1_short:na, "TP1 Marker S", color = #00ff08a8, linewidth = 1, style = plot.style_linebr)
plot(plotMarkers_short and showEntryVisuals?tp2_short:na, "TP2 Marker S", color = #1100ffa9, linewidth = 1, style = plot.style_linebr)

相关内容

更多内容