Chiến lược giao dịch kết hợp chỉ báo động lượng SSL


Ngày tạo: 2023-09-23 15:44:29 sửa đổi lần cuối: 2023-09-23 15:44:29
sao chép: 0 Số nhấp chuột: 1027
1
tập trung vào
1617
Người theo dõi

Tổng quan

Chiến lược này kết hợp các chỉ số kênh SSL với các chỉ số động lực QQE, tạo thành một hệ thống phán đoán xu hướng toàn diện hơn. Khi giá vượt qua kênh SSL, kết hợp với các chỉ số QQE để tham gia. Đồng thời thiết lập Stop Loss Stop Exit, thực hiện quản lý rủi ro.

Nguyên tắc chiến lược

Chiến lược này bao gồm:

  1. Đường SSL: Xác định xu hướng giá

  2. Chỉ số QQE: Hỗ trợ đánh giá xu hướng động lực.

  3. Breakthrough Entry: Giá phá vỡ SSL lên xuống đường và kết hợp với tín hiệu QQE để đánh giá.

  4. Chặn lỗ: thiết lập số ATR Exit, kiểm soát lỗ đơn.

  5. Xây dựng lô hàng: Xây dựng vị thế theo từng bước nhiều lần, chuyển vị trí sau khi kiếm được lợi nhuận.

Chiến lược này kết hợp đầy đủ các phán đoán về xu hướng và động lực, tạo thành một hệ thống chiến lược có khả năng theo dõi xu hướng và kiểm soát rủi ro.

Phân tích lợi thế

Chiến lược này có những lợi thế so với chiến lược chỉ số đơn:

  1. Đường SSL đánh giá xu hướng, QQE xác định thời điểm đảo ngược, chỉ số phù hợp chặt chẽ.

  2. Tiếp theo, các nhà đầu tư có thể mua một số cổ phiếu từ các nhà đầu tư khác.

  3. Lệnh dừng lỗ được thiết lập một cách hợp lý và có thể kiểm soát một khoản lỗ.

  4. Xây dựng lô hàng giảm rủi ro, sau khi kiếm được lợi nhuận, chuyển nhà kho cố định lợi nhuận.

  5. Các tham số được tối ưu hóa có thể được điều chỉnh thành Solution tối ưu.

  6. Có thể sử dụng linh hoạt trong nhiều giống và nhiều chu kỳ.

  7. Có thể giới thiệu học máy để tối ưu hóa trí thông minh.

  8. Tỷ lệ rủi ro ổn định và lợi nhuận tổng thể tốt hơn so với chiến lược chỉ số đơn.

Phân tích rủi ro

Tuy nhiên, chiến lược này cũng có những rủi ro chính:

  1. Nhiều tham số tối ưu hóa khó hơn, có nguy cơ Overfitting.

  2. Các kênh SSL và QQE đều có sự chậm trễ.

  3. Một sự kết hợp của nhiều chỉ số làm tăng sự phức tạp của chiến lược.

  4. Việc xây dựng nhà kho theo từng lô sẽ làm tăng chi phí của các điểm trượt.

  5. Cần chú ý đến tỷ lệ thu hồi tối đa thu nhập.

  6. Hiệu quả có thể thay đổi theo môi trường thị trường.

  7. Cần xác minh tính ổn định của tham số trong các chu kỳ và giống khác nhau.

  8. Tần suất giao dịch cao, ảnh hưởng đến chi phí giao dịch.

Hướng tối ưu hóa

Dựa trên những phân tích trên, chiến lược này có thể được tối ưu hóa như sau:

  1. Đánh giá sức khỏe của các giống khác nhau và các tham số chu kỳ.

  2. Thiết lập tỷ lệ dừng lỗ động.

  3. Tối ưu hóa chiến lược quản lý tài chính.

  4. Xây dựng mô hình quản lý vị thế động.

  5. Giới thiệu máy học tạo ra thời gian tốt hơn để nhập học.

  6. Đánh giá độ ổn định của các tham số.

  7. Đánh giá tác động của chi phí giao dịch và điều chỉnh tần suất.

  8. Tối ưu hóa tỷ lệ quy mô của kho hàng loạt.

  9. Tiếp tục tối ưu hóa để duy trì chiến lược phù hợp với thị trường

Tóm tắt

Chiến lược này được kết hợp chặt chẽ với các chỉ số SSL và QQE, tạo thành một hệ thống chiến lược xu hướng ổn định. Tuy nhiên, bất kỳ chiến lược nào cũng cần phải liên tục tối ưu hóa và lặp lại, duy trì sự nhạy cảm với thị trường. Chỉ có chiến lược định lượng, học tập và xác minh liên tục mới có thể ổn định lợi nhuận lâu dài.

Mã nguồn chiến lược
/*backtest
start: 2023-08-23 00:00:00
end: 2023-09-22 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4

// Strategy based on the SSL Hybrid indicator by Mihkel00
// Designed for the purpose of back testing
// Strategy:
//  - Enters both long and short trades based on SSL1 crossing the baseline
//  - Stop Loss calculated based on ATR multiplier
//  - Take Profit calculated based on 2 ATR multipliers and exits percentage of position on TP1 and TP2
//
// Credits:
// SSL Hybrid Mihkel00 https://www.tradingview.com/u/Mihkel00/

// -------------------------------- SSL HYBRID ---------------------------------
strategy("SSL Hybrid + QQE Strategy", overlay=true, initial_capital=5000, default_qty_value=10, default_qty_type=strategy.percent_of_equity, commission_type = "percent", commission_value=0.04, max_labels_count=500, calc_on_every_tick=true, pyramiding=10)
show_Baseline = input(title="Show Baseline", type=input.bool, defval=true, group="SSL Hybrid Indicator Settings")
show_SSL1 = input(title="Show SSL1", type=input.bool, defval=true, group="SSL Hybrid Indicator Settings")
show_atr = input(title="Show ATR bands", type=input.bool, defval=false, group="SSL Hybrid Indicator Settings")
//ATR
atrlen = input(14, "ATR Period", group="SSL Hybrid Indicator Settings")
mult = input(1, "ATR Multi", step=0.1, group="SSL Hybrid Indicator Settings")
smoothing = input(title="ATR Smoothing", defval="WMA", options=["RMA", "SMA", "EMA", "WMA"], group="SSL Hybrid Indicator Settings")

ma_function(source, atrlen) => 
    if smoothing == "RMA"
        rma(source, atrlen)
    else
        if smoothing == "SMA"
            sma(source, atrlen)
        else
            if smoothing == "EMA"
                ema(source, atrlen)
            else
                wma(source, atrlen)
atr_slen = ma_function(tr(true), atrlen)
////ATR Up/Low Bands
upper_band = atr_slen * mult + close
lower_band = close - atr_slen * mult

////BASELINE / SSL1 / SSL2 / EXIT MOVING AVERAGE VALUES
maType = input(title="SSL1 / Baseline Type", type=input.string, defval="HMA", options=["SMA","EMA","DEMA","TEMA","LSMA","WMA","MF","VAMA","TMA","HMA", "JMA", "Kijun v2", "EDSMA","McGinley"], group="SSL Hybrid Indicator Settings")
len = input(title="SSL1 / Baseline Length", defval=60, group="SSL Hybrid Indicator Settings")

SSL2Type = input(title="SSL2 / Continuation Type", type=input.string, defval="JMA", options=["SMA","EMA","DEMA","TEMA","WMA","MF","VAMA","TMA","HMA", "JMA","McGinley"], group="SSL Hybrid Indicator Settings")
len2 = input(title="SSL 2 Length", defval=5, group="SSL Hybrid Indicator Settings")
//
SSL3Type = input(title="EXIT Type", type=input.string, defval="HMA", options=["DEMA","TEMA","LSMA","VAMA","TMA","HMA","JMA", "Kijun v2", "McGinley", "MF"], group="SSL Hybrid Indicator Settings")
len3 = input(title="EXIT Length", defval=15, group="SSL Hybrid Indicator Settings")
src = input(title="Source", type=input.source, defval=close, group="SSL Hybrid Indicator Settings")

//
tema(src, len) =>
    ema1 = ema(src, len)
    ema2 = ema(ema1, len)
    ema3 = ema(ema2, len)
    (3 * ema1) - (3 * ema2) + ema3
kidiv = input(defval=1,maxval=4,  title="Kijun MOD Divider", group="SSL Hybrid Indicator Settings")

jurik_phase = input(title="* Jurik (JMA) Only - Phase", type=input.integer, defval=3, group="SSL Hybrid Indicator Settings")
jurik_power = input(title="* Jurik (JMA) Only - Power", type=input.integer, defval=1, group="SSL Hybrid Indicator Settings")
volatility_lookback = input(10, title="* Volatility Adjusted (VAMA) Only - Volatility lookback length", group="SSL Hybrid Indicator Settings")
//MF
beta = input(0.8,minval=0,maxval=1,step=0.1,  title="Modular Filter, General Filter Only - Beta", group="SSL Hybrid Indicator Settings")
feedback = input(false, title="Modular Filter Only - Feedback", group="SSL Hybrid Indicator Settings")
z = input(0.5,title="Modular Filter Only - Feedback Weighting",step=0.1, minval=0, maxval=1, group="SSL Hybrid Indicator Settings")
//EDSMA
ssfLength = input(title="EDSMA - Super Smoother Filter Length", type=input.integer, minval=1, defval=20, group="SSL Hybrid Indicator Settings")
ssfPoles = input(title="EDSMA - Super Smoother Filter Poles", type=input.integer, defval=2, options=[2, 3], group="SSL Hybrid Indicator Settings")

//----

//EDSMA
get2PoleSSF(src, length) =>
    PI = 2 * asin(1)
    arg = sqrt(2) * PI / length
    a1 = exp(-arg)
    b1 = 2 * a1 * cos(arg)
    c2 = b1
    c3 = -pow(a1, 2)
    c1 = 1 - c2 - c3
    
    ssf = 0.0
    ssf := c1 * src + c2 * nz(ssf[1]) + c3 * nz(ssf[2])

get3PoleSSF(src, length) =>
    PI = 2 * asin(1)

    arg = PI / length
    a1 = exp(-arg)
    b1 = 2 * a1 * cos(1.738 * arg)
    c1 = pow(a1, 2)

    coef2 = b1 + c1
    coef3 = -(c1 + b1 * c1)
    coef4 = pow(c1, 2)
    coef1 = 1 - coef2 - coef3 - coef4

    ssf = 0.0
    ssf := coef1 * src + coef2 * nz(ssf[1]) + coef3 * nz(ssf[2]) + coef4 * nz(ssf[3])

ma(type, src, len) =>
    float result = 0
    if type=="TMA"
        result := sma(sma(src, ceil(len / 2)), floor(len / 2) + 1)
    if type=="MF"
        ts=0.,b=0.,c=0.,os=0.
        //----
        alpha = 2/(len+1)
        a = feedback ? z*src + (1-z)*nz(ts[1],src) : src
        //----
        b := a > alpha*a+(1-alpha)*nz(b[1],a) ? a : alpha*a+(1-alpha)*nz(b[1],a)
        c := a < alpha*a+(1-alpha)*nz(c[1],a) ? a : alpha*a+(1-alpha)*nz(c[1],a)
        os := a == b ? 1 : a == c ? 0 : os[1]
        //----
        upper = beta*b+(1-beta)*c
        lower = beta*c+(1-beta)*b 
        ts := os*upper+(1-os)*lower
        result := ts
    if type=="LSMA"
        result := linreg(src, len, 0)
    if type=="SMA" // Simple
        result := sma(src, len)
    if type=="EMA" // Exponential
        result := ema(src, len)
    if type=="DEMA" // Double Exponential
        e = ema(src, len)
        result := 2 * e - ema(e, len)
    if type=="TEMA" // Triple Exponential
        e = ema(src, len)
        result := 3 * (e - ema(e, len)) + ema(ema(e, len), len)
    if type=="WMA" // Weighted
        result := wma(src, len)
    if type=="VAMA" // Volatility Adjusted
        /// Copyright © 2019 to present, Joris Duyck (JD)
        mid=ema(src,len)
        dev=src-mid
        vol_up=highest(dev,volatility_lookback)
        vol_down=lowest(dev,volatility_lookback)
        result := mid+avg(vol_up,vol_down)
    if type=="HMA" // Hull
        result := wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))
    if type=="JMA" // Jurik
        /// Copyright © 2018 Alex Orekhov (everget)
        /// Copyright © 2017 Jurik Research and Consulting.
        phaseRatio = jurik_phase < -100 ? 0.5 : jurik_phase > 100 ? 2.5 : jurik_phase / 100 + 1.5
        beta = 0.45 * (len - 1) / (0.45 * (len - 1) + 2)
        alpha = pow(beta, jurik_power)
        jma = 0.0
        e0 = 0.0
        e0 := (1 - alpha) * src + alpha * nz(e0[1])
        e1 = 0.0
        e1 := (src - e0) * (1 - beta) + beta * nz(e1[1])
        e2 = 0.0
        e2 := (e0 + phaseRatio * e1 - nz(jma[1])) * pow(1 - alpha, 2) + pow(alpha, 2) * nz(e2[1])
        jma := e2 + nz(jma[1])
        result := jma
    if type=="Kijun v2"
        kijun = avg(lowest(len), highest(len))//, (open + close)/2)
        conversionLine = avg(lowest(len/kidiv), highest(len/kidiv))
        delta = (kijun + conversionLine)/2
        result :=delta
    if type=="McGinley"
        mg = 0.0
        ema = ema(src, len)
        mg := na(mg[1]) ? ema : mg[1] + (src - mg[1]) / (len * pow(src/mg[1], 4))
        result :=mg
    if type=="EDSMA"
    
        zeros = src - nz(src[2])
        avgZeros = (zeros + zeros[1]) / 2
        
        // Ehlers Super Smoother Filter 
        ssf = ssfPoles == 2
             ? get2PoleSSF(avgZeros, ssfLength)
             : get3PoleSSF(avgZeros, ssfLength)
        
        // Rescale filter in terms of Standard Deviations
        stdev = stdev(ssf, len)
        scaledFilter = stdev != 0
             ? ssf / stdev
             : 0
        
        alpha = 5 * abs(scaledFilter) / len
        
        edsma = 0.0
        edsma := alpha * src + (1 - alpha) * nz(edsma[1])
        result :=  edsma
    result
    
///SSL 1 and SSL2
emaHigh = ma(maType, high, len)
emaLow = ma(maType, low, len)

maHigh = ma(SSL2Type, high, len2)
maLow = ma(SSL2Type, low, len2)

///EXIT
ExitHigh = ma(SSL3Type, high, len3)
ExitLow = ma(SSL3Type, low, len3)

///Keltner Baseline Channel
BBMC = ma(maType, close, len)
useTrueRange = input(true, group="SSL Hybrid Indicator Settings")
multy = input(0.2, step=0.05, title="Base Channel Multiplier", group="SSL Hybrid Indicator Settings")
Keltma = ma(maType, src, len)
range = useTrueRange ? tr : high - low
rangema = ema(range, len)
upperk =Keltma + rangema * multy
lowerk = Keltma - rangema * multy

//Baseline Violation Candle
open_pos =  open*1
close_pos = close*1
difference = abs(close_pos-open_pos)
atr_violation = difference > atr_slen
InRange = upper_band > BBMC and lower_band < BBMC
candlesize_violation = atr_violation and InRange
plotshape(candlesize_violation, color=color.new(color.white, transp=0), size=size.tiny,style=shape.diamond, location=location.top, title="Candle Size > 1xATR")


//SSL1 VALUES
Hlv = int(na)
Hlv := close > emaHigh ? 1 : close < emaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? emaHigh : emaLow

//SSL2 VALUES
Hlv2 = int(na)
Hlv2 := close > maHigh ? 1 : close < maLow ? -1 : Hlv2[1]
sslDown2 = Hlv2 < 0 ? maHigh : maLow

//EXIT VALUES
Hlv3 = int(na)
Hlv3 := close > ExitHigh ? 1 : close < ExitLow ? -1 : Hlv3[1]
sslExit = Hlv3 < 0 ? ExitHigh : ExitLow
base_cross_Long = crossover(close, sslExit)
base_cross_Short = crossover(sslExit, close)
codiff = base_cross_Long ? 1 : base_cross_Short ? -1 : na 

//COLORS
show_color_bar = input(title="Color Bars", type=input.bool, defval=true, group="SSL Hybrid Indicator Settings")
color_bar = close > upperk ? #00c3ff : close < lowerk ? #ff0062 : color.gray
color_ssl1 = close > sslDown ? #00c3ff : close < sslDown ? #ff0062 : na

//PLOTS
plotarrow(codiff, colorup=color.rgb(0, 195, 255, transp=0), colordown=color.rgb(255, 0, 98, transp=0),title="Exit Arrows", maxheight=20, offset=0, display=display.none)
p1 = plot(show_Baseline ? BBMC : na, color=color.new(color_bar, transp=0), linewidth=4, title='MA Baseline')
DownPlot = plot( show_SSL1 ? sslDown : na, title="SSL1", linewidth=3, color=color.new(color_ssl1, transp=10))
barcolor(show_color_bar ? color_bar : na)
up_channel = plot(show_Baseline ? upperk : na, color=color_bar, title="Baseline Upper Channel")
low_channel = plot(show_Baseline ? lowerk : na, color=color_bar, title="Basiline Lower Channel")
fill(up_channel, low_channel, color=color.new(color_bar, transp=90))

////SSL2 Continiuation from ATR
atr_crit = input(0.9, step=0.1, title="Continuation ATR Criteria", group="SSL Hybrid Indicator Settings")
upper_half = atr_slen * atr_crit + close
lower_half = close - atr_slen * atr_crit
buy_inatr =  lower_half < sslDown2
sell_inatr = upper_half > sslDown2
sell_cont = close < BBMC and close < sslDown2
buy_cont = close > BBMC and close > sslDown2
sell_atr = sell_inatr and sell_cont
buy_atr = buy_inatr and buy_cont
atr_fill = buy_atr ? color.green : sell_atr ? color.purple : color.white
LongPlot = plot(sslDown2, title="SSL2", linewidth=2, color=color.new(atr_fill, transp=0), style=plot.style_circles, display=display.none)
u = plot(show_atr ? upper_band : na, "+ATR", color=color.new(color.white, transp=80), display=display.none)
l = plot(show_atr ? lower_band : na, "-ATR", color=color.new(color.white, transp=80), display=display.none)

// ---------------------------- QQE MOD INDICATOR ------------------------------
RSI_Period = input(6, title='RSI Length')
SF = input(5, title='RSI Smoothing')
QQE = input(3, title='Fast QQE Factor')
ThreshHold = input(3, title="Thresh-hold")

rsi_src = input(close, title="RSI Source")

Wilders_Period = RSI_Period * 2 - 1


Rsi = rsi(rsi_src, RSI_Period)
RsiMa = ema(Rsi, SF)
AtrRsi = abs(RsiMa[1] - RsiMa)
MaAtrRsi = ema(AtrRsi, Wilders_Period)
dar = ema(MaAtrRsi, Wilders_Period) * QQE

longband = 0.0
shortband = 0.0
trend = 0

DeltaFastAtrRsi = dar
RSIndex = RsiMa
newshortband = RSIndex + DeltaFastAtrRsi
newlongband = RSIndex - DeltaFastAtrRsi
longband := RSIndex[1] > longband[1] and RSIndex > longband[1] ? 
   max(longband[1], newlongband) : newlongband
shortband := RSIndex[1] < shortband[1] and RSIndex < shortband[1] ? 
   min(shortband[1], newshortband) : newshortband
cross_1 = cross(longband[1], RSIndex)
trend := cross(RSIndex, shortband[1]) ? 1 : cross_1 ? -1 : nz(trend[1], 1)
FastAtrRsiTL = trend == 1 ? longband : shortband
////////////////////


length = input(50, minval=1, title="Bollinger Length")
bb_mult = input(0.35, minval=0.001, maxval=5, step=0.1, title="BB Multiplier")
basis = sma(FastAtrRsiTL - 50, length)
dev = bb_mult * stdev(FastAtrRsiTL - 50, length)
upper = basis + dev
lower = basis - dev
rsi_ma_color_bar = RsiMa - 50 > upper ? #00c3ff : RsiMa - 50 < lower ? #ff0062 : color.gray


// Zero cross
QQEzlong = 0
QQEzlong := nz(QQEzlong[1])
QQEzshort = 0
QQEzshort := nz(QQEzshort[1])
QQEzlong := RSIndex >= 50 ? QQEzlong + 1 : 0
QQEzshort := RSIndex < 50 ? QQEzshort + 1 : 0

////////////////////////////////////////////////////////////////

RSI_Period2 = input(6, title='RSI Length')
SF2 = input(5, title='RSI Smoothing')
QQE2 = input(1.61, title='Fast QQE2 Factor')
ThreshHold2 = input(3, title="Thresh-hold")

src2 = input(close, title="RSI Source")

Wilders_Period2 = RSI_Period2 * 2 - 1


Rsi2 = rsi(src2, RSI_Period2)
RsiMa2 = ema(Rsi2, SF2)
AtrRsi2 = abs(RsiMa2[1] - RsiMa2)
MaAtrRsi2 = ema(AtrRsi2, Wilders_Period2)
dar2 = ema(MaAtrRsi2, Wilders_Period2) * QQE2
longband2 = 0.0
shortband2 = 0.0
trend2 = 0

DeltaFastAtrRsi2 = dar2
RSIndex2 = RsiMa2
newshortband2 = RSIndex2 + DeltaFastAtrRsi2
newlongband2 = RSIndex2 - DeltaFastAtrRsi2
longband2 := RSIndex2[1] > longband2[1] and RSIndex2 > longband2[1] ? 
   max(longband2[1], newlongband2) : newlongband2
shortband2 := RSIndex2[1] < shortband2[1] and RSIndex2 < shortband2[1] ? 
   min(shortband2[1], newshortband2) : newshortband2
cross_2 = cross(longband2[1], RSIndex2)
trend2 := cross(RSIndex2, shortband2[1]) ? 1 : cross_2 ? -1 : nz(trend2[1], 1)
FastAtrRsi2TL = trend2 == 1 ? longband2 : shortband2

// Zero cross
QQE2zlong = 0
QQE2zlong := nz(QQE2zlong[1])
QQE2zshort = 0
QQE2zshort := nz(QQE2zshort[1])
QQE2zlong := RSIndex2 >= 50 ? QQE2zlong + 1 : 0
QQE2zshort := RSIndex2 < 50 ? QQE2zshort + 1 : 0

hcolor2 = RsiMa2 - 50 > ThreshHold2 ? color.silver :
   RsiMa2 - 50 < 0 - ThreshHold2 ? color.silver : na
// plot(FastAtrRsi2TL - 50, title='QQE Line', color=color.white, transp=0, linewidth=2)
// plot(RsiMa2 - 50, color=hcolor2, transp=50, title='Histo2', style=plot.style_columns)

Greenbar1 = RsiMa2 - 50 > ThreshHold2
Greenbar2 = RsiMa - 50 > upper

Redbar1 = RsiMa2 - 50 < 0 - ThreshHold2
Redbar2 = RsiMa - 50 < lower

qqe_line = FastAtrRsi2TL - 50
qqe_blue_bar = Greenbar1 and Greenbar2 == 1
qqe_red_bar = Redbar1 and Redbar2 == 1
// plot(Greenbar1 and Greenbar2 == 1 ? RsiMa2 - 50 : na, title="QQE Up", style=plot.style_columns, color=#00c3ff, transp=0)
// plot(Redbar1 and Redbar2 == 1 ? RsiMa2 - 50 : na, title="QQE Down", style=plot.style_columns, color=#ff0062, transp=0)

// ----------------------------------STRATEGY ----------------------------------

atr_length = input(title="ATR Length", type=input.integer, defval=14, inline="1", group="Strategy Back Test Settings")
atr = atr(atr_length)

// Back test time range
from_date = input(title="From", type=input.time, defval=timestamp("01 Aug 2021 00:00 +0100"), inline="1", group="Date Range")
to_date = input(title="To", type=input.time, defval=timestamp("01 Sep 2021 00:00 +0100"), inline="1", group="Date Range")
in_date = true

// Strategy exit settings

// Stop-Loss Settings
use_tp_sl = input(title="Use TP & SL", type=input.bool, defval=true, inline="1", group="Exit Settings")
sl_atr_multiplier = input(title="SL ATR Multiplier", type=input.float, defval=1.6, step=0.1, inline="2", group="Exit Settings")
move_sl_on_tp = input(title="Move SL on TP1", type=input.bool, defval=true, inline="2", group="Exit Settings")

// Take Profit Settings
tp1_atr_multiplier = input(title="TP1 ATR Multiplier", type=input.float, defval=1.8, step=0.1, inline="3", group="Exit Settings")
tp1_exit_percentage = input(title="TP1 Exit Percentage", type=input.integer, defval=20, step=1, maxval=100, inline="3", group="Exit Settings")

tp2_atr_multiplier = input(title="TP2 ATR Multiplier", type=input.float, defval=2.2, step=0.1, inline="4", group="Exit Settings")
tp2_exit_percentage = input(title="TP2 Exit Percentage", type=input.integer, defval=30, step=1, maxval=100, inline="4", group="Exit Settings")

tp3_atr_multiplier = input(title="TP3 ATR Multiplier", type=input.float, defval=2.6, step=0.1, inline="5", group="Exit Settings")
tp3_exit_percentage = input(title="TP3 Exit Percentage", type=input.integer, defval=30, step=1, maxval=100, inline="5", group="Exit Settings")

tp4_atr_multiplier = input(title="TP4 ATR Multiplier", type=input.float, defval=4, step=0.1, inline="6", group="Exit Settings")
tp4_exit_percentage = input(title="TP4 Exit Percentage", type=input.integer, defval=10, step=1, maxval=100, inline="6", group="Exit Settings")

tp5_atr_multiplier = input(title="TP5 ATR Multiplier", type=input.float, defval=8, step=0.1, inline="7", group="Exit Settings")
tp5_exit_percentage = input(title="TP5 Exit Percentage", type=input.integer, defval=10, step=1, maxval=100, inline="7", group="Exit Settings")

var long_sl = close - (atr * sl_atr_multiplier)
var long_tp1 = close + (atr * tp1_atr_multiplier)
var long_tp2 = close + (atr * tp2_atr_multiplier)
var long_tp3 = close + (atr * tp3_atr_multiplier)
var long_tp4 = close + (atr * tp4_atr_multiplier)
var long_tp5 = close + (atr * tp5_atr_multiplier)

var short_sl = close + (atr * sl_atr_multiplier)
var short_tp1 = close - (atr * tp1_atr_multiplier)
var short_tp2 = close - (atr * tp2_atr_multiplier)
var short_tp3 = close - (atr * tp3_atr_multiplier)
var short_tp4 = close - (atr * tp4_atr_multiplier)
var short_tp5 = close - (atr * tp5_atr_multiplier)

var is_long_sl_moved = false
var is_short_sl_moved = false

is_open_long = strategy.position_size > 0
is_open_short = strategy.position_size < 0

var in_ssl_long = false
var in_ssl_short = false

var start_trading = false
var ssl_long_entry = false
var ssl_short_entry = false

var did_prev_bar_ssl_flip = false

// Ensure crossover occurrs before entering first position. This ensures first entry after chosen start date is an actual entry and not just entering on start date
if not ssl_long_entry and not ssl_short_entry and in_date and not start_trading
    start_trading := crossover(close, sslDown) or crossunder(close, sslDown)

if in_date and start_trading
    ssl_long_entry := close > sslDown and qqe_blue_bar and qqe_line > 0
    ssl_short_entry := close < sslDown and qqe_red_bar and qqe_line < 0

remaining_percent = 100
var total_tokens = float(na)
total_tokens := strategy.equity * 0.10 / close

tp1_percent = tp1_exit_percentage <= remaining_percent ? tp1_exit_percentage : remaining_percent
remaining_percent -= tp1_percent
entry_1 = total_tokens * (tp1_percent / 100)

tp2_percent = tp2_exit_percentage <= remaining_percent ? tp2_exit_percentage : remaining_percent
remaining_percent -= tp2_percent
entry_2 = total_tokens * (tp2_percent / 100)

tp3_percent = tp3_exit_percentage <= remaining_percent ? tp3_exit_percentage : remaining_percent
remaining_percent -= tp3_percent
entry_3 = total_tokens * (tp3_percent / 100)

tp4_percent = tp4_exit_percentage <= remaining_percent ? tp4_exit_percentage : remaining_percent
remaining_percent -= tp4_percent
entry_4 = total_tokens * (tp4_percent / 100)

tp5_percent = tp5_exit_percentage <= remaining_percent ? tp5_exit_percentage : remaining_percent
remaining_percent -= tp5_percent
entry_5 = total_tokens * (tp5_percent / 100)

if not is_long_sl_moved and high >= long_tp1 and move_sl_on_tp and use_tp_sl
    is_long_sl_moved := true
    strategy.exit("LongExit2", "LongEntry2", stop=strategy.position_avg_price, limit=long_tp2)
    strategy.exit("LongExit3", "LongEntry3", stop=strategy.position_avg_price, limit=long_tp3)
    strategy.exit("LongExit4", "LongEntry4", stop=strategy.position_avg_price, limit=long_tp4)
    strategy.exit("LongExit5", "LongEntry5", stop=strategy.position_avg_price, limit=long_tp5)
if not is_short_sl_moved and low <= short_tp1 and move_sl_on_tp and use_tp_sl
    is_short_sl_moved := true
    strategy.exit("ShortExit2", "ShortEntry2", stop=strategy.position_avg_price, limit=short_tp2)
    strategy.exit("ShortExit3", "ShortEntry3", stop=strategy.position_avg_price, limit=short_tp3)
    strategy.exit("ShortExit4", "ShortEntry4", stop=strategy.position_avg_price, limit=short_tp4)
    strategy.exit("ShortExit5", "ShortEntry5", stop=strategy.position_avg_price, limit=short_tp5)
    
if did_prev_bar_ssl_flip
    did_prev_bar_ssl_flip := false
    position_value = abs(strategy.position_size * close)
    if in_ssl_long
        label.new(x=bar_index, y=close, xloc=xloc.bar_index, yloc=yloc.abovebar, text=tostring(position_value), style=label.style_label_down, size=size.tiny)
    else
        label.new(x=bar_index, y=close, xloc=xloc.bar_index, yloc=yloc.belowbar, text=tostring(position_value), style=label.style_label_up, size=size.tiny)

if ssl_long_entry and in_date and not in_ssl_long
    in_ssl_long := true
    in_ssl_short := false
    did_prev_bar_ssl_flip := true
    long_sl := close - (atr * sl_atr_multiplier)
    long_tp1 := close + (atr * tp1_atr_multiplier)
    long_tp2 := close + (atr * tp2_atr_multiplier)
    long_tp3 := close + (atr * tp3_atr_multiplier)
    long_tp4 := close + (atr * tp4_atr_multiplier)
    long_tp5 := close + (atr * tp5_atr_multiplier)

    strategy.entry("LongEntry1", strategy.long, qty=entry_1)
    strategy.entry("LongEntry2", strategy.long, qty=entry_2)
    strategy.entry("LongEntry3", strategy.long, qty=entry_3)
    strategy.entry("LongEntry4", strategy.long, qty=entry_4)
    strategy.entry("LongEntry5", strategy.long, qty=entry_5)

    if use_tp_sl
        strategy.exit("LongExit1", "LongEntry1", stop=long_sl, limit=long_tp1)
        strategy.exit("LongExit2", "LongEntry2", stop=long_sl, limit=long_tp2)
        strategy.exit("LongExit3", "LongEntry3", stop=long_sl, limit=long_tp3)
        strategy.exit("LongExit4", "LongEntry4", stop=long_sl, limit=long_tp4)
        strategy.exit("LongExit5", "LongEntry5", stop=long_sl, limit=long_tp5)
        is_long_sl_moved := false

if ssl_short_entry and in_date and not in_ssl_short
    in_ssl_short := true
    in_ssl_long := false
    did_prev_bar_ssl_flip := true
    short_sl := close + (atr * sl_atr_multiplier)
    short_tp1 := close - (atr * tp1_atr_multiplier)
    short_tp2 := close - (atr * tp2_atr_multiplier)
    short_tp3 := close - (atr * tp3_atr_multiplier)
    short_tp4 := close - (atr * tp4_atr_multiplier)
    short_tp5 := close - (atr * tp5_atr_multiplier)
    
    strategy.entry("ShortEntry1", strategy.short, qty=entry_1)
    strategy.entry("ShortEntry2", strategy.short, qty=entry_2)
    strategy.entry("ShortEntry3", strategy.short, qty=entry_3)
    strategy.entry("ShortEntry4", strategy.short, qty=entry_4)
    strategy.entry("ShortEntry5", strategy.short, qty=entry_5)
    
    if use_tp_sl
        strategy.exit("ShortExit1", "ShortEntry1", stop=short_sl, limit=short_tp1)
        strategy.exit("ShortExit2", "ShortEntry2", stop=short_sl, limit=short_tp2)
        strategy.exit("ShortExit3", "ShortEntry3", stop=short_sl, limit=short_tp3)
        strategy.exit("ShortExit4", "ShortEntry4", stop=short_sl, limit=short_tp4)
        strategy.exit("ShortExit5", "ShortEntry5", stop=short_sl, limit=short_tp5)
        is_short_sl_moved := false