Estrategia de trading cuantitativo de RePaNoCHa


Fecha de creación: 2023-09-25 18:29:33 Última modificación: 2023-09-25 18:29:33
Copiar: 0 Número de Visitas: 779
1
Seguir
1617
Seguidores

Descripción general

La estrategia RePaNoCHa es una estrategia de comercio cuantitativa que integra varios indicadores y mecanismos de gestión de riesgos. Emite señales de compra y venta principalmente mediante la determinación de la dirección de la tendencia y los posibles puntos de reversión. La estrategia tiene al mismo tiempo un stop loss móvil, un stop loss fijo y un stop loss para bloquear los beneficios y controlar el riesgo.

Principio de estrategia

La estrategia incluye los siguientes indicadores:

  • T3 promedio: mide la dirección de la tendencia de los precios.

  • Indicador de rango de fluctuación promedio: identifique las fluctuaciones de precios y establezca zonas objetivo.

  • El indicador ADX: juzgar la tendencia como fuerte.

  • Indicador SAR: muestra el potencial punto de inflexión.

  • El RSI es un indicador para determinar las zonas de sobrecompra y sobreventa.

  • Indicador MACD: muestra el movimiento de los precios.

Cuando los indicadores anteriores dan una señal de coincidencia, la estrategia determina la tendencia de inicio, generando una señal de compra y venta. Después de la entrada, la estrategia utiliza un stop loss móvil lineal que sigue un determinado porcentaje de precios máximos / mínimos y se mueve gradualmente hacia arriba a medida que aumenta la ganancia, para bloquear las ganancias. También tiene un stop loss porcentual fijo para limitar la máxima pérdida.

Concretamente, cuando el precio está por encima de la línea de la zona objetivo, el aumento de T3, el aumento de ADX, el aumento de SAR, el aumento de RSI por encima de la línea media y el valor positivo de MACD, se produce una señal de pluralidad. Las condiciones opuestas generan una señal de parálisis.

Análisis de las ventajas

  • Aumentar la precisión de las evaluaciones basadas en múltiples indicadores

Se puede evitar el riesgo de error de un solo indicador considerando varios indicadores, como tendencias, sobrecompras y revisiones.

  • El mecanismo móvil de detención de pérdidas permite un seguimiento flexible y el bloqueo de ganancias

El movimiento de los límites de pérdidas se ajusta a los cambios en las ganancias, lo que permite un mejor seguimiento de las fluctuaciones de los precios para bloquear las ganancias.

  • Detención fija para controlar la máxima pérdida

La configuración de un porcentaje fijo de stop loss permite limitar el máximo de pérdidas por partida y evitar que las pérdidas se extiendan.

  • Combinaciones de parámetros personalizables

Los parámetros del indicador se pueden ajustar libremente y se pueden personalizar los parámetros óptimos según las diferentes variedades de transacciones.

Análisis de riesgos

  • La combinación de múltiples indicadores hace que la toma de decisiones sea más difícil

El exceso de indicadores puede provocar la exclusión de indicadores, lo que aumenta la dificultad para tomar decisiones y requiere una evaluación cuidadosa de la eficacia de los indicadores.

  • Bloqueo o pérdidas por fuertes fluctuaciones en el mercado

En tiempos de fuertes fluctuaciones en los precios, es fácil ser bloqueado o activar el stop loss con frecuencia, y el stop loss es difícil de usar.

  • Las transacciones frecuentes aumentan los costos de las transacciones

Las operaciones con líneas más cortas aumentan la frecuencia de las transacciones y los costos de los puntos de deslizamiento, lo que afecta a las ganancias reales.

  • Optimización de parámetros muy difícil

Se necesitan pruebas de varias combinaciones de parámetros indicadores, la optimización es más difícil y se necesita suficiente soporte de datos históricos.

Dirección de optimización

  • Evaluar el efecto real de los indicadores y evitar la redundancia

A través de pruebas de control, se examina la contribución real de cada indicador a la mejora de la señal, eliminando los indicadores redundantes.

  • Optimización de los algoritmos móviles de pérdidas

Prueba diferentes algoritmos de trailing de pérdidas para encontrar mejores formas de seguir los beneficios de las pérdidas.

  • Tenga en cuenta el deslizamiento del disco y las comisiones

La introducción de la retroevaluación de los costos reales de las transacciones y la inclusión de la toma de decisiones auxiliares.

  • Optimización de los parámetros de las franjas horarias

Optimización de los parámetros de los períodos de alta y baja volatilidad, respectivamente, para mejorar la estabilidad de la estrategia.

Resumir

La estrategia de RePaNoCHa, mediante la integración de una variedad de indicadores y mecanismos de stop loss/stop, permite una toma de decisiones de negociación cuantitativa y un manejo de pérdidas y ganancias más estables. Sin embargo, su frecuencia de negociación es más alta y el proceso de optimización de los parámetros es más complejo.

Código Fuente de la Estrategia
/*backtest
start: 2022-09-18 00:00:00
end: 2023-09-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4

strategy(title = "RePaNoCHa V4 [Backtest]", overlay = true, initial_capital = 1000, pyramiding = 100,
   calc_on_order_fills = false, calc_on_every_tick = false, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_value = 0.075)

//study(title="RePaNoCHa V4 [Alerts]", overlay=true)

// 
// Copyright by XaviZ v1.0 26/07/2019 
//
// Script for automatic trading with Alerts (Use Backtest to customize your own settings)
//
// LG --> Long (green:not confirmed) (lime: confirmed)
// ST --> Short (maroon: not confirmed) (red: confirmed)
// TS --> Trailing Stop
// xL --> Close Long Position
// xS --> Close Short Position
// SL --> Stop Loss
//
// The trailing stop closes the trade if the price changes direction by a specified percentage or offset. 
// There is no ideal distance because markets and price are always changing and we know that is impossible to exit on the top or bottom. 
// This script interpolate the trailing Stop Offset with profit, higher profit --> higher Trailing Stop Offset. Despite this, it's difficult to catch the price but not impossible.
// It has a TS delay too. It take a snapshot every X seconds, if the TS is activated the alert is triggered, otherwise the price keeps fluctuating until a new snapshot. 
//
// Thanks...
//
// BTC: 3LEUP3WjQctdbFjBavcmRGUVRBje8bptCd
// ETH: 0x518AAD4746912ae506c82B747488306186c4d546
// 

// INITIAL SETTINGS
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

Position = input("BOTH", "POSITIONS", options = ["BOTH","LONG","SHORT"])
src = input(hlc3, "SOURCE", type = input.source)

// T3
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

T3_len = input(3, "T3 LENGTH", minval = 2)
a1 = input(0.4, "T3 VOLUME FACTOR", step = 0.1, minval = 0.1)

T3(_src,_T3_len,_a1)=>
    e1=ema(_src, _T3_len)
    e2=ema(e1,_T3_len)
    e3=ema(e2,_T3_len)
    e4=ema(e3,_T3_len)
    e5=ema(e4,_T3_len)
    e6=ema(e5,_T3_len)
    c1=-_a1*_a1*_a1
    c2=3*_a1*_a1+3*_a1*_a1*_a1
    c3=-6*_a1*_a1-3*_a1-3*_a1*_a1*_a1
    c4=1+3*_a1+_a1*_a1*_a1+3*_a1*_a1
    _T3=c1*e6+c2*e5+c3*e4+c4*e3
    _T3

T3_Rising = T3(src,T3_len,a1) > T3(src,T3_len,a1)[1]
T3_Falling = T3(src,T3_len,a1) < T3(src,T3_len,a1)[1]

T3_color = T3_Rising ? color.green : T3_Falling ? color.red : color.yellow

plot(T3(src,T3_len,a1), color=T3_color, linewidth = 3, title= "T3")

// RANGE FILTER
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

per = input(defval=23, title="SAMPLING PERIOD", minval=1)
mult = input(defval=1.5, title="RANGE MULTIPLIER", minval=0.1, step = 0.1)

Range_filter(_src, _per, _mult)=>
    var float _upward = 0.0
    var float _downward = 0.0
    wper      = (_per*2) - 1
    avrng     = ema(abs(_src - _src[1]), _per)
    _smoothrng = ema(avrng, wper)*_mult
    _filt  = _src
    _filt := _src > nz(_filt[1]) ? ((_src-_smoothrng) < nz(_filt[1]) ? nz(_filt[1]) : (_src-_smoothrng)) : ((_src+_smoothrng) > nz(_filt[1]) ? nz(_filt[1]) : (_src+_smoothrng))
    _upward := _filt > _filt[1] ? nz(_upward[1]) + 1 : _filt < _filt[1] ? 0 : nz(_upward[1])
    _downward := _filt < _filt[1] ? nz(_downward[1]) + 1 : _filt > _filt[1] ? 0 : nz(_downward[1])
    [_smoothrng,_filt,_upward,_downward]

[smoothrng, filt, upward, downward] = Range_filter(src, per, mult)

hband = filt + smoothrng
lband = filt - smoothrng

filtcolor = upward > 0 ? color.lime : downward > 0 ? color.red : color.orange
filtplot = plot(filt, color = filtcolor, linewidth = 3, title="Range Filter", editable = false)

hbandplot = plot(hband, color = color.aqua, transp = 60, title = "High Target", editable = false)
lbandplot = plot(lband, color = color.aqua, transp = 60, title = "Low Target", editable = false)

fill(hbandplot, filtplot, color = color.aqua, title = "High Target Range", editable = false)
fill(lbandplot, filtplot, color = color.aqua, title = "Low Target Range", editable = false)

// ADX MasaNakamura version
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

ADX_len = input(12, title="ADX LENGTH", type=input.integer, minval = 1)
th = input(8, title="ADX THRESHOLD", type=input.integer, minval = 0)

calcADX(_ADX_len)=>
    var float SmoothedTrueRange = 0.0
    var float SmoothedDirectionalMovementPlus = 0.0
    var float SmoothedDirectionalMovementMinus = 0.0
    TrueRange = max(max(high-low, abs(high-nz(close[1]))), abs(low-nz(close[1])))
    DirectionalMovementPlus = high-nz(high[1]) > nz(low[1])-low ? max(high-nz(high[1]), 0): 0
    DirectionalMovementMinus = nz(low[1])-low > high-nz(high[1]) ? max(nz(low[1])-low, 0): 0
    SmoothedTrueRange := nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1])/_ADX_len) + TrueRange
    SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1])/_ADX_len) + DirectionalMovementPlus
    SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1])/_ADX_len) + DirectionalMovementMinus
    _DIPlus = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100
    _DIMinus = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100
    DX = abs(_DIPlus-_DIMinus) / (_DIPlus+_DIMinus)*100
    _ADX = sma(DX, _ADX_len)
    [_DIPlus,_DIMinus,_ADX]
 
[DIPlus, DIMinus, ADX] = calcADX(ADX_len)

macol = DIPlus > DIMinus and ADX > th ? color.lime : DIPlus < DIMinus and ADX > th ? color.red : color.orange
barcolor(color = macol, title = "ADX")

// SAR
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

Sst = input (0.07, "SAR STAR", step=0.01, minval = 0.01)
Sinc = input (0.05, "SAR INC", step=0.01, minval = 0.01)
Smax = input (0.15, "SAR MAX", step=0.05, minval = 0.01)

CalcSARwithoutSAR(_Sst, _Sinc, _Smax)=>
    P = 1
    EP = max(high, high[1])
    _SAR = min(low, low[1])
    AF = _Sst
    EPnew = 0.0
    AFnew = _Sst
    if nz(P[1]) == 0
        P := 1
    else
        if (P[1] == 1)
            EPnew := max(high, EP[1])
        else
            EPnew := min(low, EP[1]) 
    
        if EPnew != EP[1]
            AFnew := min(_Smax, AF[1] + _Sinc)
        else
            AFnew := AF[1]
        
    if nz(P[1]) == 0
        P := 1
    else 
        if P[1] == 1 and _SAR[1] + AF[1] * (EPnew - _SAR[1]) <= low
            P := 1
            _SAR := _SAR[1] + AFnew * (EPnew - _SAR[1])
            EP := EPnew
            AF := AFnew
        else        
            if P[1] == 1 and _SAR[1] + AF[1] * (EPnew - _SAR[1]) > low
                if low >= _SAR[1]
                    P := 1
                    _SAR := low
                    EP := EPnew
                    AF := AFnew
                else
                    P := -1
                    _SAR := max(high, EP[1])
                    EP := min(low, low[1])
                    AF := _Sst
            else 
                if P[1] == -1 and _SAR[1] - AF[1] * (_SAR[1] - EPnew) >= high
                    P := -1
                    _SAR := _SAR[1] - AFnew * (_SAR[1] - EPnew)
                    EP := EPnew
                    AF := AFnew
                else
                    if P[1] == -1 and _SAR[1] - AF[1] * (_SAR[1] - EPnew) < high
                        if high <= _SAR[1]
                            P := -1
                            _SAR := high
                            EP := EPnew
                            AF := AFnew
                        else
                            P := 1
                            _SAR := min(low, EP[1])
                            EP := max(high, high[1])
                            AF := _Sst
    _SAR

SAR = CalcSARwithoutSAR(Sst, Sinc, Smax)
plot(SAR, color = macol, style = plot.style_cross, title = "SAR") 

// RSI 
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

RSI_len = input(14, "RSI LENGHT", minval = 1)
RSI_obos = input(52,title="RSI CENTER LINE", type=input.integer, minval = 1)

RSI(len)=>
    up_rsi = rma(max(change(close), 0), len)
    down_rsi = rma(-min(change(close), 0), len)
    rsi = down_rsi == 0 ? 100 : up_rsi == 0 ? 0 : 100 - (100 / (1 + up_rsi / down_rsi))
    rsi

// MACD
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

fast_length = input(title="MACD FAST LENGTH", type=input.integer, minval = 1, defval=10)
slow_length = input(title="MACD SLOW LENGTH", type=input.integer, minval = 1, defval=19)
signal_length = input(title="MACD SIGNAL SMOOTHING", type=input.integer, minval = 1, maxval = 50, defval = 9)
sma_source = input(title="MACD SIMPLE MA(Oscillator)", type=input.bool, defval=false)

MACD(_src,_fast_length,_slow_length)=>
    fast_ma = sma_source ? sma(_src, _fast_length) : ema(_src, _fast_length)
    slow_ma = sma_source ? sma(_src, _slow_length) : ema(_src, _slow_length)
    macd = fast_ma - slow_ma
    signal = sma_source ? sma(macd, signal_length) : ema(macd, signal_length)
    _hist = macd - signal
    _hist

hist = MACD(src,fast_length,slow_length)
    
// STRATEGY
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

var bool longCond = na
var bool shortCond = na
longCond := (high > hband and upward > 0) and not (DIPlus < DIMinus and ADX > th) and (SAR < close) and (T3_Rising) and (RSI(RSI_len) > RSI_obos) and (hist > 0) and (timenow > time + 10000)
shortCond := (low < lband and downward > 0) and not (DIPlus > DIMinus and ADX > th) and (SAR > close) and (T3_Falling) and (RSI(RSI_len) < RSI_obos) and (hist < 0) and (timenow > time + 10000)

var bool XlongCond = na
var bool XshortCond = na
XlongCond := (low < hband and downward > 0) and (DIPlus > DIMinus and ADX > th) and (SAR > close) and (T3_Falling) and (timenow > time + 10000)
XshortCond := (high > lband and upward > 0) and (DIPlus < DIMinus and ADX > th) and (SAR < close) and (T3_Rising) and (timenow > time + 10000)

var int CondIni_long = 0
CondIni_long := longCond ? 1 : shortCond ? -1 : CondIni_long[1]

var int CondIni_short = 0
CondIni_short := longCond ? 1 : shortCond ? -1 : CondIni_short[1]

longCondition = (longCond and CondIni_long[1] == -1)
shortCondition = (shortCond and CondIni_short[1] == 1)

var int CondIniX = 0
CondIniX := XlongCond ? 1 : XshortCond ? -1 : CondIniX[1]
XlongCondition = XlongCond and CondIniX[1] == -1
XshortCondition = XshortCond and CondIniX[1] == 1

// Get the price of the last opened long or short

var float last_open_longCondition = na
var float last_open_shortCondition = na
last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1])
last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1])

// Check if your last postion was a long or a short

var int last_longCondition = na
var int last_shortCondition = na
last_longCondition := longCondition ? time : nz(last_longCondition[1])
last_shortCondition := shortCondition ? time : nz(last_shortCondition[1])

in_longCondition = last_longCondition > last_shortCondition
in_shortCondition = last_shortCondition > last_longCondition

var int last_XlongCondition = na
var int last_XshortCondition = na
last_XlongCondition := XlongCondition ? time : nz(last_XlongCondition[1])
last_XshortCondition := XshortCondition ? time : nz(last_XshortCondition[1])

in_longConditionX = last_longCondition > last_XlongCondition
in_shortConditionX = last_shortCondition > last_XshortCondition

// TRAILING STOP
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

isTSl = Position == "SHORT" ? na : true
isTSs = Position == "LONG" ? na : true
tsi = input(0.5, "TRAILING STOP ACTIVATION %", type = input.float, step = 0.1) 
ts_low_profit = input(0.25, "TRAILING STOP OFFSET % --> WHEN PROFIT=0.5% (MINIMUM)", type = input.float, step = 0.05, minval = 0.01)
ts_high_profit = input(1.0, "TRAILING STOP OFFSET % --> WHEN PROFIT=10% (LINEAR_EXTRAPOLATION)", type = input.float, step = 0.1, minval = 0.1)
delay = input(120, "TRAILING STOP DELAY (SECONDS BETWEEN SNAPSHOTS)", type = input.integer, minval = 30, maxval = 300, step = 30)*1000

// Dynamic Trailing Stop linear extrapolation / interpolation according with profit

ts_dynamic(x)=> 
    ts_dynamic = 0.0
    ts_dynamic := max(((((ts_high_profit-ts_low_profit)/9.5)*(x-0.5)) + ts_low_profit), ts_low_profit)

long_profit = abs(((high-last_open_longCondition)/last_open_longCondition)*100)
short_profit = abs(((low-last_open_shortCondition)/last_open_shortCondition)*100)

var float ts = 0.0
ts := in_longCondition ? ts_dynamic(long_profit) : ts_dynamic(short_profit)

// Time between snapshots

round = (floor(timenow/(delay)))*(delay)

var bool ts_delay = 0
if timenow < (time + (timeframe.multiplier*60000) - 60000)
    ts_delay := (timenow >= round + (delay)-7500) ? 1 : 0
else
    if timenow > (time + (timeframe.multiplier*60000) - 60000) 
       or ((in_longCondition and high > ((last_open_longCondition*(1+(tsi/100)))*(1+(ts/100)))) and (close < (last_open_longCondition*(1+(tsi/100))))) 
       or ((in_shortCondition and low < (last_open_shortCondition*(1-(tsi/100)))) and (close > (last_open_shortCondition*(1-(tsi/100)))))
        ts_delay := 1

// TS Conditions

var bool long_ts = na
var bool short_ts = na

if high > ((last_open_longCondition*(1+(tsi/100)))*(1+(ts/100)))
    long_ts := isTSl and high >= (close*(1+(ts/100))) and high >= (last_open_longCondition*(1+(tsi/100))) and (high >= hband*(1+(ts/100))) and in_longCondition and in_longConditionX and not longCondition
else
    if high <= ((last_open_longCondition*(1+(tsi/100)))*(1+(ts/100)))
        long_ts := isTSl and high >= (close*(1+(ts/100))) and high >= (last_open_longCondition*(1+(tsi/100))) and close >= (last_open_longCondition*(1+(tsi/100))) and (high >= hband*(1+(ts/100)))
           and in_longCondition and in_longConditionX and not longCondition

if (timenow > (time + (timeframe.multiplier*60000) - 60000)) and high < (close*(1+(ts/100))) and (high > ((last_open_longCondition*(1+(tsi/100)))*(1+(ts/100)))) and (high >= hband*(1+(ts/100)))
    long_ts := isTSl and in_longCondition and in_longConditionX and not longCondition

if low < ((last_open_shortCondition*(1-(tsi/100)))*(1-(ts/100)))      
    short_ts := isTSs and low <= (close*(1-(ts/100))) and low <= (last_open_shortCondition*(1-(tsi/100))) and (low <= lband*(1-(ts/100))) and in_shortCondition and in_shortConditionX and not shortCondition
else
    if low >= ((last_open_shortCondition*(1-(tsi/100)))*(1-(ts/100)))
        short_ts := isTSs and low <= (close*(1-(ts/100))) and low <= (last_open_shortCondition*(1-(tsi/100))) and close <= (last_open_shortCondition*(1-(tsi/100))) and (low <= lband*(1-(ts/100)))
           and in_shortCondition and in_shortConditionX and not shortCondition

if (timenow > (time + (timeframe.multiplier*60000) - 60000)) and low > (close*(1-(ts/100))) and (low < ((last_open_shortCondition*(1-(tsi/100)))*(1-(ts/100)))) and (low <= lband*(1-(ts/100)))
    short_ts := isTSs and in_shortCondition and in_shortConditionX and not shortCondition
    
// Ts Antiliquidation. For pumps on same candle of entry.

last_open_long = max(SAR[1],hband)
last_open_short = min(SAR[1],lband)

ts_antiliq_long_profit = abs(((high-last_open_long)/last_open_long)*100)
ts_antiliq_short_profit = abs(((low-last_open_short)/last_open_short)*100)

ts_antiliq = in_longCondition ? ts_dynamic(ts_antiliq_long_profit) : ts_dynamic(ts_antiliq_short_profit)

var bool long_ts_antiliq = na
var bool short_ts_antiliq = na

Act_ts_antiliq = input(2.0, "TRAILING STOP ANTI-LIQUIDATION ACTIVATION % ", type = input.float, step = 0.1)

long_ts_antiliq := isTSl and longCondition and high > ((last_open_long*(1+(Act_ts_antiliq/100)))*(1+(ts_antiliq/100))) and high > last_open_long*(1+(Act_ts_antiliq/100)) and (DIPlus > DIMinus and ADX > th) 
   and high >= (close*(1+(ts_antiliq/100))) and in_longCondition and in_longConditionX

short_ts_antiliq := isTSs and shortCondition and low < ((last_open_short*(1-(Act_ts_antiliq/100)))*(1-(ts_antiliq/100))) and low < last_open_short*(1-(Act_ts_antiliq/100)) and (DIPlus < DIMinus and ADX > th) 
   and low <= (close*(1-(ts_antiliq/100))) and in_shortCondition and in_shortConditionX
    
// Get the time of the last ts close

var int last_long_ts = na
var int last_short_ts = na
last_long_ts := long_ts ? time : nz(last_long_ts[1])
last_short_ts := short_ts ? time : nz(last_short_ts[1])

Final_Long_ts = (long_ts and last_longCondition > nz(last_long_ts[1]))
Final_Short_ts = (short_ts and last_shortCondition > nz(last_short_ts[1]))

var int last_long_ts_antiliq = na
var int last_short_ts_antiliq = na
last_long_ts_antiliq := long_ts_antiliq ? time : nz(last_long_ts_antiliq[1])
last_short_ts_antiliq := short_ts_antiliq ? time : nz(last_short_ts_antiliq[1])

Final_Long_ts_antiliq = (long_ts_antiliq and last_longCondition > nz(last_long_ts_antiliq[1]))
Final_Short_ts_antiliq = (short_ts_antiliq and last_shortCondition > nz(last_short_ts_antiliq[1]))

// STOP LOSS
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

Act_sl = input(false, "STOP LOSS")
isSLl = Position == "SHORT" ? na : true
isSLs = Position == "LONG" ? na : true
sl = input(3.0, "STOP LOSS %", type = input.float, step = 0.1)

long_sl = Act_sl and isSLl and low <= ((1-(sl/100))*last_open_longCondition) and not (open < ((1-(sl/100))*last_open_longCondition)) and in_longCondition and not longCondition
short_sl = Act_sl and isSLs and high >= ((1+(sl/100))*last_open_shortCondition) and not (open > ((1+(sl/100))*last_open_shortCondition)) and in_shortCondition and not shortCondition

// Get the time of the last sl close

var int last_long_sl = na
var int last_short_sl = na
last_long_sl := long_sl ? time : nz(last_long_sl[1])
last_short_sl := short_sl ? time : nz(last_short_sl[1])

// Sl counter

var int CondIni_long_sl = 0
CondIni_long_sl := long_sl or Final_Long_ts ? 1 : longCondition ? -1 : CondIni_long_sl[1]

var int CondIni_short_sl = 0
CondIni_short_sl := short_sl or Final_Short_ts ? 1 : shortCondition ? -1 : CondIni_short_sl[1]

Final_Long_sl = long_sl and CondIni_long_sl[1] == -1 and in_longConditionX and not XlongCondition and not Final_Long_ts
Final_Short_sl = short_sl and CondIni_short_sl[1] == -1 and in_shortConditionX and not XshortCondition and not Final_Short_ts

// Final Long & Short Counter

if Final_Long_ts or Final_Long_sl or XlongCondition
    CondIni_long := -1

if Final_Short_ts or Final_Short_sl or XshortCondition
    CondIni_short := 1

// SIGNALS
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

// long & short

Final_longCondition_notconfirmed = Position == "SHORT" ? na : longCondition and (DIPlus > DIMinus and ADX > th)
Final_shortCondition_notconfirmed = Position == "LONG" ? na : shortCondition and (DIPlus < DIMinus and ADX > th)

//plotshape(Final_longCondition_notconfirmed, title = "Long Signal", text = "LG", style=shape.triangleup, location=location.belowbar, color = #2E8B57, transp = 0, size=size.tiny)
//plotshape(Final_shortCondition_notconfirmed, title = "Short Signal", text = "ST", style=shape.triangledown, location=location.abovebar, color = #B22222, transp = 0, size=size.tiny)

Final_longCondition = Position == "SHORT" ? na : longCondition[1] and not (shortCondition and (DIPlus < DIMinus and ADX > th))
Final_shortCondition = Position == "LONG" ? na : shortCondition[1] and not (longCondition and (DIPlus > DIMinus and ADX > th))

//plotshape(Final_longCondition, title = "Long Signal", text = "LG", style=shape.triangleup, location=location.belowbar, color = color.lime, transp = 0, size=size.tiny)
//plotshape(Final_shortCondition, title = "Short Signal", text = "ST", style=shape.triangledown, location=location.abovebar, color = color.red, transp = 0, size=size.tiny)

// Xlong & Xshort

var int CondIni_Xlong = 0
CondIni_Xlong := Final_Long_ts or XlongCondition or Final_shortCondition ? 1 : Final_longCondition ? -1 : CondIni_Xlong[1]

var int CondIni_Xshort = 0
CondIni_Xshort := Final_Short_ts or XshortCondition or Final_longCondition ? 1 : Final_shortCondition ? -1 : CondIni_Xshort[1]

var bool Final_XlongCondition = na
var bool Final_XshortCondition = na

Final_XlongCondition := Position == "SHORT" ? na : 
   ((shortCondition and last_longCondition > last_shortCondition[1]) or (XlongCondition and last_longCondition > last_XlongCondition[1])) and CondIni_Xlong[1] == -1 
   and not Final_shortCondition_notconfirmed and not Final_shortCondition
Final_XshortCondition := Position == "LONG" ? na : 
   ((longCondition and last_shortCondition > last_longCondition[1]) or (XshortCondition and last_shortCondition > last_XshortCondition[1])) and CondIni_Xshort[1] == -1 
   and not Final_longCondition_notconfirmed and not Final_longCondition
   
F_XLONG = Final_XlongCondition[1] and not Final_shortCondition and not Final_shortCondition_notconfirmed and not Final_longCondition_notconfirmed
F_XSHORT = Final_XshortCondition[1] and not Final_longCondition and not Final_longCondition_notconfirmed and not Final_shortCondition_notconfirmed

//plotshape(F_XLONG, title = "xL Signal", text = "xL", style=shape.triangledown, location=location.abovebar, color = color.orange, transp = 0, size=size.tiny)
//plotshape(F_XSHORT, title = "xS Signal", text = "xS", style=shape.triangleup, location=location.belowbar, color = color.aqua, transp = 0, size=size.tiny)

// Ts

//plotshape(Final_Long_ts, text ="TS", title="Trailing Stop Long", style=shape.triangledown, location=location.abovebar, color = color.red, editable = false, transp = 0) 
//plotshape(Final_Short_ts, text ="TS", title="Trailing Stop Short", style=shape.triangleup, location=location.belowbar, color = color.lime, editable = false, transp = 0) 

//lts = iff(Final_Long_ts, high*(1-(ts/100)), na), plot(lts, style = plot.style_cross, linewidth=3, color = color.white, editable = false)
//sts = iff(Final_Short_ts, low*(1+(ts/100)), na), plot(sts, style = plot.style_cross, linewidth=3, color = color.white, editable = false)

// Ts anti-liquidation

//plotshape(Final_Long_ts_antiliq, text ="TSA", title="Trailing Stop Long Antiliq", style=shape.triangledown, location=location.abovebar, color = color.red, editable = false, transp = 0) 
//plotshape(Final_Short_ts_antiliq, text ="TSA", title="Trailing Stop Short Antiliq", style=shape.triangleup, location=location.belowbar, color = color.lime, editable = false, transp = 0) 

//lts_antiliq = iff(Final_Long_ts_antiliq, high*(1-(ts_antiliq/100)), na), plot(lts_antiliq, style = plot.style_cross, linewidth=3, color = color.white, editable = false)
//sts_antiliq = iff(Final_Short_ts_antiliq, low*(1+(ts_antiliq/100)), na), plot(sts_antiliq, style = plot.style_cross, linewidth=3, color = color.white, editable = false)

// Sl

//plotshape(Final_Long_sl, text ="SL", title="Stop Loss Long", style=shape.triangledown, location=location.abovebar, color = color.fuchsia, editable = false, transp = 0) 
//plotshape(Final_Short_sl, text ="SL", title="Stop Loss Short", style=shape.triangleup, location=location.belowbar, color = color.fuchsia, editable = false, transp = 0) 

//lsl = iff(Final_Long_sl, (1-(sl/100))*last_open_longCondition, na), plot(lsl, style = plot.style_cross, linewidth=2, color = color.white, editable = false)
//ssl = iff(Final_Short_sl, (1+(sl/100))*last_open_shortCondition, na), plot(ssl, style = plot.style_cross, linewidth=2, color = color.white, editable = false)

// Levels

plot(isTSl and in_longCondition == 1 ? (last_open_longCondition*(1+(tsi/100))) : na, "Long Trailing", color = color.white, style=3, linewidth=1, editable = false)
plot(isTSs and in_shortCondition == 1 ? (last_open_shortCondition*(1-(tsi/100))) : na, "Short Trailing", color = color.white, style=3, linewidth=1, editable = false)

//plot(isTSl and longCondition and high > last_open_long*(1+(Act_ts_antiliq/100)) and (DIPlus > DIMinus and ADX > th) ? 
//   last_open_long*(1+(Act_ts_antiliq/100)) : na, "Long TSA", color = color.lime, style=3, linewidth=2, editable = false)
//plot(isTSs and shortCondition and low < last_open_short*(1-(Act_ts_antiliq/100)) and (DIPlus < DIMinus and ADX > th) ? 
//   last_open_short*(1-(Act_ts_antiliq/100)) : na, "Short TSA", color = color.red, style=3, linewidth=2, editable = false)

// Weekend

Weekend = input(true, "SHOW WEEKEND")
W_color = Weekend and (dayofweek == dayofweek.sunday or dayofweek == dayofweek.saturday) ? color.teal : na
bgcolor(W_color, title = "WEEKEND")

// ALERTS
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

// or Final_longCondition_notconfirmed (green signals)
//alertcondition(
//   Final_longCondition,  
//   title="Long Alert", 
//   message = "LONG"
//   )
   
// or Final_shortCondition_notconfirmed (maroon signals)
//alertcondition(
//   Final_shortCondition, 
//   title="Short Alert", 
//   message = "SHORT"
//   )

//alertcondition(
//   (Final_Long_ts and ts_delay)
//   or F_XLONG 
//   or Final_Long_sl 
//   or (Final_Long_ts_antiliq and close >= (last_open_long*(1+(Act_ts_antiliq/100)))), 
//   title="XLong TS/XL/SL Alert", 
//   message = "XLONG TS/XL/SL"
//   )

//alertcondition(
//   (Final_Short_ts and ts_delay) 
//   or F_XSHORT 
//   or Final_Short_sl 
//   or (Final_Short_ts_antiliq and close <= (last_open_short*(1-(Act_ts_antiliq/100)))), 
//   title="XShort TS/XL/SL Alert", 
//   message = "XSHORT TS/XL/SL"
//   )

// BOT SYNTAX (DERIBIT EXAMPLE)
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

// message = "LONG | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=order | delay=1 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=position b=short t=market | delay=2 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL b=long q=50% t=market | delay=2 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=position b=long sl=-3.1% p=-3%"
// message = "SHORT | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=order | delay=1 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=position b=long t=market | delay=2 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL b=short q=50% t=market | delay=2 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=position b=short sl=3% p=3.1%"
// message = "XSHORT/TS/SL | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=order | delay=2 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=position b=short t=market"
// message = "XLONG/TS/SL | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=order | delay=2 | e=DERIBIT a=ACCOUNT s=BTC-PERPETUAL c=position b=long t=market"
//
// Using t=limit on entries --> comission_value = 0.025

// BACKTESTING
// ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

BT_Final_longCondition = Position == "SHORT" ? na : longCondition
BT_Final_shortCondition = Position == "LONG" ? na : shortCondition

testStartYear = input(2019, "BACKTEST START YEAR", minval = 1, maxval = 2222) 
testStartMonth = input(01, "BACKTEST START MONTH", minval = 1, maxval = 12)
testStartDay = input(01, "BACKTEST START DAY", minval = 1, maxval = 31)
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)

if (BT_Final_longCondition)
    strategy.entry("long", strategy.long, when = time >= testPeriodStart)
if (BT_Final_shortCondition) 
    strategy.entry("short", strategy.short, when = time >= testPeriodStart)
    
pips_corection = input(2, "(TICKS/PIPS CORRECTION)")

strategy.exit("Tsl", "long", trail_points = (abs((last_open_longCondition*(1+(tsi/100)))-last_open_longCondition)*pips_corection),
   trail_offset = (high*(ts/100))*pips_corection, loss = Act_sl ? (abs((last_open_longCondition*(1-(sl/100)))-last_open_longCondition)*pips_corection) : na) 
strategy.exit("Tss", "short", trail_points = (abs((last_open_shortCondition*(1-(tsi/100)))-last_open_shortCondition)*pips_corection),
   trail_offset = (low*(ts/100))*pips_corection, loss = Act_sl ? (abs((last_open_shortCondition*(1+(sl/100)))-last_open_shortCondition)*pips_corection) : na) 

strategy.close_all(when = Final_XlongCondition or Final_XshortCondition or Final_Long_sl or Final_Short_sl)