Estrategia de negociación dinámica de filtros cuánticos

El autor:¿ Qué pasa?, Fecha: 2023-12-25 11:10:09
Las etiquetas:

img

Resumen de la estrategia

Esta estrategia llamada Estrategia de Trading Cuántico de Filtro Dinámico utiliza principalmente el indicador de Filtro de Rango combinado con múltiples indicadores técnicos para implementar el comercio automatizado de seguimiento de tendencias de la criptomoneda BTCUSDT. La estrategia es adecuada para el comercio de cantidades de alta frecuencia mediante el ajuste dinámico de stop loss y take profit para bloquear las ganancias y reducir las reducciones.

Estrategia lógica

El indicador central de esta estrategia es el Range Filter, que genera una línea mediana basada en el rango estadístico de movimiento de precios. Las señales de negociación se generan cuando el precio rompe esta línea mediana. Además, la estrategia también combina el indicador RSI para juzgar sobrecomprado y sobrevendido, promedio móvil para determinar la tendencia, MACD para juzgar el impulso y otros indicadores para el filtrado combinado para formar señales de negociación más confiables.

Específicamente, la línea mediana del filtro de rango se obtiene del promedio móvil exponencial del rango de movimiento de precios, y el juicio direccional se basa en la fuerza y la velocidad de romper esta línea mediana.

El indicador RSI que juzga el estado de sobrecompra y sobreventa se utiliza para confirmar la señal del filtro. Cuando el promedio móvil apunta hacia arriba, se juzga que la tendencia es al alza, y cuando apunta hacia abajo, se juzga que la tendencia es a la baja. El indicador MACD juzga si el impulso del mercado es suficiente para formar una tendencia.

Al combinar los juicios de estos indicadores, se pueden identificar puntos de ruptura de tendencia relativamente fiables como oportunidades para establecer posiciones.

Análisis de ventajas

La mayor ventaja de esta estrategia es que combina múltiples indicadores para la toma de decisiones en lugar de depender de un único indicador técnico, lo que puede reducir efectivamente la probabilidad de operaciones incorrectas y garantizar que las señales comerciales sean más confiables.

El indicador Range Filter es muy sensible a los cambios de precios durante pequeños períodos, lo que significa que la estrategia puede abrir y cerrar posiciones en un período de tiempo relativamente corto, por lo que es muy adecuado para el comercio de alta frecuencia y permite obtener ganancias en el volátil mercado de criptomonedas.

Análisis de riesgos

Esta estrategia todavía tiene algunos riesgos. El primero es el riesgo de que los juicios de patrones técnicos fallen porque los indicadores no pueden garantizar los movimientos de precios al 100%.

Otro riesgo importante es que la línea mediana del filtro de rango no pueda filtrar completamente las fluctuaciones de precios. Cuando hay una fluctuación de precios mayor más allá del rango de la línea mediana, la línea mediana fallará, lo que resultará en el riesgo de generar señales incorrectas.

Por último, el comercio de alta frecuencia también conlleva algunos riesgos. Cuando la frecuencia de negociación es demasiado alta, los costos de transacción serán relativamente grandes, lo que puede compensar algunas ganancias. En este caso, la frecuencia de negociación y el tiempo de retención pueden reducirse adecuadamente.

Optimización

Todavía hay espacio para una mayor optimización de esta estrategia. Por ejemplo, se pueden considerar más indicadores, como indicadores de volatilidad para confirmar tendencias y establecer criterios de filtrado más estrictos para garantizar señales comerciales más precisas. O estudiar los patrones de comportamiento de precios de diferentes criptomonedas y acciones, y establecer parámetros de indicadores que mejor se adapten a ellos.

Desde la lógica de negociación, también se pueden establecer rangos dinámicos de stop loss y take profit. Es decir, cuando el tamaño de la posición aumenta, el rango de stop loss se puede ampliar para obtener más ganancias. O cuando la ganancia es relativamente grande, acelerar la velocidad de take profit. Esto puede reducir las reducciones hasta cierto punto.

Por último, los parámetros del filtro se pueden optimizar para encontrar un conjunto de parámetros para que el rango de línea mediana pueda filtrar eficazmente las fluctuaciones mientras se capturan los puntos de inflexión de la tendencia tanto como sea posible.

Resumen de las actividades

Esta estrategia combina con éxito múltiples indicadores para el juicio para formar una estrategia de negociación altamente confiable adecuada para el comercio cuantitativo de alta frecuencia.


/*backtest
start: 2022-12-18 00:00:00
end: 2023-12-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy(title='5cel Scalp Strategy BTCUSDT Long & Short 30 Min', shorttitle='BTCUSDT Long & Short Scalp 30m', precision=1, overlay=true)

//Swing Call - Based on RSI Overbought & Oversold
//#### Starts Here #####
ema_value = input(5)
sma_value = input(50)
ema1 = ta.ema(close, ema_value)
sma2 = ta.sma(close, sma_value)
rs = ta.rsi(close, 14)

iff_1 = high < sma2 ? color.red : color.yellow
iff_2 = low > sma2 ? color.lime : iff_1
mycolor = rs >= 85 or rs <= 15 ? color.yellow : iff_2

//For Main Strategy
bool swingCallGreen = false
bool swingCallRed = false
bool swingCallYellow = false

if rs >= 85 or rs <= 15
    //color.yellow
    swingCallGreen := false
    swingCallRed := false
    swingCallYellow := true
    swingCallYellow
else
    if low > sma2
        //color.lime
        swingCallGreen := true
        swingCallRed := false
        swingCallYellow := false
        swingCallYellow
        //color.red
    else if high < sma2
        swingCallGreen := false
        swingCallRed := true
        swingCallYellow := false
        swingCallYellow
    else
        //color.yellow
        swingCallGreen := false
        swingCallRed := false
        swingCallYellow := true
        swingCallYellow

hlong = input.int(80, title='Overbought limit of RSI', step=1)
ll = input.int(20, title='Oversold limit of RSI', step=1)

buyexit = ta.crossunder(rs, hlong)
sellexit = ta.crossover(rs, ll)

sellcall = ta.crossover(sma2, ema1) and open > close
buycall = ta.crossunder(sma2, ema1) and high > sma2
//#### Ends Here #####


//Parabolic SAR -  Trend Circles
//#### Starts Here #####
start = input.int(2, minval=0, maxval=10, title='Start - Default = 2 - Multiplied by .01')
increment = input.int(2, minval=0, maxval=10, title='Step Setting (Sensitivity) - Default = 2 - Multiplied by .01')
maximum = input.int(2, minval=1, maxval=10, title='Maximum Step (Sensitivity) - Default = 2 - Multiplied by .10')
sus = input(true, 'Show Up Trending Parabolic Sar')
sds = input(true, 'Show Down Trending Parabolic Sar')
disc = input(false, title='Start and Step settings are *.01 so 2 = .02 etc, Maximum Step is *.10 so 2 = .2')

startCalc = start * .01
incrementCalc = increment * .01
maximumCalc = maximum * .10

sarUp = ta.sar(startCalc, incrementCalc, maximumCalc)
sarDown = ta.sar(startCalc, incrementCalc, maximumCalc)

colUp = close >= sarDown ? color.lime : na
colDown = close <= sarUp ? color.red : na

parabolicSARGreen = ta.sar(startCalc, incrementCalc, maximumCalc)
parabolicSARRed = ta.sar(startCalc, incrementCalc, maximumCalc)
//#### Ends Here #####


//EMA Line
//#### Starts Here #####
ema100 = ta.ema(close, 100)
//#### Ends Here #####


// Ichimoku Cloud
//#### Starts Here #####
sCloud = input(false, 'Show Ichimoku lines')

// Colors
colorGreen = #00ff00
colorRed = #ff0000
colorTenkanViolet = #9400D3
colorKijun = #fdd8a0
colorLime = #006400
colorMaroon = #8b0000

//Periods are set to standard
tenkanPeriods = input.int(9, minval=1, title='Tenkan')
kijunPeriods = input.int(26, minval=1, title='Kijun')
chikouPeriods = input.int(52, minval=1, title='Chikou')
displacement = input.int(26, minval=1, title='Offset')

donchian(len) =>
    math.avg(ta.lowest(len), ta.highest(len))

tenkan = donchian(tenkanPeriods)
kijun = donchian(kijunPeriods)
senkouA = math.avg(tenkan, kijun)
senkouB = donchian(chikouPeriods)
displacedSenkouA = senkouA[displacement]
displacedSenkouB = senkouB[displacement]

bullishSignal = ta.crossover(tenkan, kijun)
bearishSignal = ta.crossunder(tenkan, kijun)

bullishSignalValues = bullishSignal ? tenkan : na
bearishSignalValues = bearishSignal ? tenkan : na


strongBullishSignal = bullishSignalValues > displacedSenkouA and bullishSignalValues > displacedSenkouB
neutralBullishSignal = bullishSignalValues > displacedSenkouA and bullishSignalValues < displacedSenkouB or bullishSignalValues < displacedSenkouA and bullishSignalValues > displacedSenkouB
weakBullishSignal = bullishSignalValues < displacedSenkouA and bullishSignalValues < displacedSenkouB

strongBearishSignal = bearishSignalValues < displacedSenkouA and bearishSignalValues < displacedSenkouB
neutralBearishSignal = bearishSignalValues > displacedSenkouA and bearishSignalValues < displacedSenkouB or bearishSignalValues < displacedSenkouA and bearishSignalValues > displacedSenkouB
weakBearishSignal = bearishSignalValues > displacedSenkouA and bearishSignalValues > displacedSenkouB
//#### Ends Here #####


//Higher High Lower Low Strategy
//#### Starts Here #####
lb = input.int(5, title='Left Bars', minval=1)
rb = input.int(5, title='Right Bars', minval=1)
showsupres = input.bool(true, title='Support/Resistance', inline='srcol')
supcol = input.color(color.lime, title='', inline='srcol')
rescol = input.color(color.red, title='', inline='srcol')
// srlinestyle = input.string(line.style_dotted, title='Line Style/Width', options=[line.style_solid, line.style_dashed, line.style_dotted], inline='style')
srlinewidth = input.int(3, title='', minval=1, maxval=5, inline='style')
changebarcol = input.bool(true, title='Change Bar Color', inline='bcol')
bcolup = input.color(color.blue, title='', inline='bcol')
bcoldn = input.color(color.black, title='', inline='bcol')

ph = ta.pivothigh(lb, rb)
pl = ta.pivotlow(lb, rb)

iff_3 = pl ? -1 : na  // Trend direction
hl = ph ? 1 : iff_3
iff_4 = pl ? pl : na  // similar to zigzag but may have multiple highs/lows
zz = ph ? ph : iff_4
valuewhen_1 = ta.valuewhen(hl, hl, 1)
valuewhen_2 = ta.valuewhen(zz, zz, 1)
zz := pl and hl == -1 and valuewhen_1 == -1 and pl > valuewhen_2 ? na : zz
valuewhen_3 = ta.valuewhen(hl, hl, 1)
valuewhen_4 = ta.valuewhen(zz, zz, 1)
zz := ph and hl == 1 and valuewhen_3 == 1 and ph < valuewhen_4 ? na : zz

valuewhen_5 = ta.valuewhen(hl, hl, 1)
valuewhen_6 = ta.valuewhen(zz, zz, 1)
hl := hl == -1 and valuewhen_5 == 1 and zz > valuewhen_6 ? na : hl
valuewhen_7 = ta.valuewhen(hl, hl, 1)
valuewhen_8 = ta.valuewhen(zz, zz, 1)
hl := hl == 1 and valuewhen_7 == -1 and zz < valuewhen_8 ? na : hl
zz := na(hl) ? na : zz

findprevious() =>  // finds previous three points (b, c, d, e)
    ehl = hl == 1 ? -1 : 1
    loc1 = 0.0
    loc2 = 0.0
    loc3 = 0.0
    loc4 = 0.0
    xx = 0
    for x = 1 to 1000 by 1
        if hl[x] == ehl and not na(zz[x])
            loc1 := zz[x]
            xx := x + 1
            break
    ehl := hl
    for x = xx to 1000 by 1
        if hl[x] == ehl and not na(zz[x])
            loc2 := zz[x]
            xx := x + 1
            break
    ehl := hl == 1 ? -1 : 1
    for x = xx to 1000 by 1
        if hl[x] == ehl and not na(zz[x])
            loc3 := zz[x]
            xx := x + 1
            break
    ehl := hl
    for x = xx to 1000 by 1
        if hl[x] == ehl and not na(zz[x])
            loc4 := zz[x]
            break
    [loc1, loc2, loc3, loc4]

float a = na
float b = na
float c = na
float d = na
float e = na
if not na(hl)
    [loc1, loc2, loc3, loc4] = findprevious()
    a := zz
    b := loc1
    c := loc2
    d := loc3
    e := loc4

_hh = zz and a > b and a > c and c > b and c > d
_ll = zz and a < b and a < c and c < b and c < d
_hl = zz and (a >= c and b > c and b > d and d > c and d > e or a < b and a > c and b < d)
_lh = zz and (a <= c and b < c and b < d and d < c and d < e or a > b and a < c and b > d)

plotshape(_hl, text='HL', title='Higher Low', style=shape.labelup, color=color.new(color.lime, 0), textcolor=color.new(color.black, 0), location=location.belowbar, offset=-rb)
plotshape(_hh, text='HH', title='Higher High', style=shape.labeldown, color=color.new(color.lime, 0), textcolor=color.new(color.black, 0), location=location.abovebar, offset=-rb)
plotshape(_ll, text='LL', title='Lower Low', style=shape.labelup, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), location=location.belowbar, offset=-rb)
plotshape(_lh, text='LH', title='Lower High', style=shape.labeldown, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), location=location.abovebar, offset=-rb)

float res = na
float sup = na
res := _lh ? zz : res[1]
sup := _hl ? zz : sup[1]

int trend = na
iff_5 = close < sup ? -1 : nz(trend[1])
trend := close > res ? 1 : iff_5

res := trend == 1 and _hh or trend == -1 and _lh ? zz : res
sup := trend == 1 and _hl or trend == -1 and _ll ? zz : sup
rechange = res != res[1]
suchange = sup != sup[1]

var line resline = na
var line supline = na
//#### Ends Here #####



//Range Filter 5Min
//#### Starts Here #####

src = input(defval=close, title='Source')
per = input.int(defval=100, minval=1, title='Sampling Period')

// Range Multiplier
mult = input.float(defval=3.0, minval=0.1, title='Range Multiplier')

// Smooth Average Range
smoothrng(x, t, m) =>
    wper = t * 2 - 1
    avrng = ta.ema(math.abs(x - x[1]), t)
    smoothrng = ta.ema(avrng, wper) * m
    smoothrng
smrng = smoothrng(src, per, mult)

// Range Filter
rngfilt(x, r) =>
    rngfilt = x
    rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r : x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
    rngfilt
filt = rngfilt(src, smrng)

// Filter Direction
upward = 0.0
upward := filt > filt[1] ? nz(upward[1]) + 1 : filt < filt[1] ? 0 : nz(upward[1])
downward = 0.0
downward := filt < filt[1] ? nz(downward[1]) + 1 : filt > filt[1] ? 0 : nz(downward[1])

// Target Bands
hband = filt + smrng
lband = filt - smrng

// Colors
filtcolor = upward > 0 ? color.lime : downward > 0 ? color.red : color.orange
barcolor = src > filt and src > src[1] and upward > 0 ? color.lime : src > filt and src < src[1] and upward > 0 ? color.green : src < filt and src < src[1] and downward > 0 ? color.red : src < filt and src > src[1] and downward > 0 ? color.maroon : color.orange

// Break Outs
longCond = bool(na)
shortCond = bool(na)
longCond := src > filt and src > src[1] and upward > 0 or src > filt and src < src[1] and upward > 0
shortCond := src < filt and src < src[1] and downward > 0 or src < filt and src > src[1] and downward > 0

CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
longCondition = longCond and CondIni[1] == -1
shortCondition = shortCond and CondIni[1] == 1
//#### Ends Here #####


//#### Starts Here #####
source = close
useCurrentRes = input(true, title='Use Current Chart Resolution?')
resCustom = input.timeframe(title='Use Different Timeframe? Uncheck Box Above', defval='60')
smd = input(true, title='Show MacD & Signal Line? Also Turn Off Dots Below')
sd = input(true, title='Show Dots When MacD Crosses Signal Line?')
sh = input(true, title='Show Histogram?')
macd_colorChange = input(true, title='Change MacD Line Color-Signal Line Cross?')
hist_colorChange = input(true, title='MacD Histogram 4 Colors?')

res1 = useCurrentRes ? timeframe.period : resCustom

fastLength = input.int(12, minval=1)
slowLength = input.int(26, minval=1)
signalLength = input.int(9, minval=1)

fastMA = ta.ema(source, fastLength)
slowMA = ta.ema(source, slowLength)

macd = fastMA - slowMA
signal = ta.sma(macd, signalLength)
hist = macd - signal

outMacD = request.security(syminfo.tickerid, res1, macd)
outSignal = request.security(syminfo.tickerid, res1, signal)
outHist = request.security(syminfo.tickerid, res1, hist)

histA_IsUp = outHist > outHist[1] and outHist > 0
histA_IsDown = outHist < outHist[1] and outHist > 0
histB_IsDown = outHist < outHist[1] and outHist <= 0
histB_IsUp = outHist > outHist[1] and outHist <= 0

//MacD Color Definitions
macd_IsAbove = outMacD >= outSignal
macd_IsBelow = outMacD < outSignal

plot_color = hist_colorChange ? histA_IsUp ? color.aqua : histA_IsDown ? color.blue : histB_IsDown ? color.red : histB_IsUp ? color.maroon : color.yellow : color.gray
macd_color = macd_colorChange ? macd_IsAbove ? color.lime : color.red : color.red
signal_color = macd_colorChange ? macd_IsAbove ? color.yellow : color.yellow : color.lime

circleYPosition = outSignal
//#### Ends Here #####


//////////////////
// Main Strategy
/////////////////
//#### Starts Here #####
var bottomText = 'Something is not ok'

bool rangeBuy = false
if longCondition
    rangeBuy := true
else
    rangeBuy := false

bool rangeSell = false
if shortCondition
    rangeSell := true
else
    rangeSell := false

bool ema100Bullish = false
bool ema100Bearish = false
bool ichimokuBearish = false
bool ichimokuBullish = false
string statusChance = 'Who knows what will happen'
string futureIchimokuTrend = 'Anything can happen'

if close > ema100
    ema100Bullish := true
    ema100Bearish := false
else
    ema100Bullish := false
    ema100Bearish := true

if displacedSenkouA > displacedSenkouB
    ichimokuBearish := false
    futureIchimokuTrend := 'Green - chance to go up'
    ichimokuBullish := true
else
    ichimokuBearish := true
    futureIchimokuTrend := 'Red - chance to go down'
    ichimokuBullish := false
    ichimokuBullish

if ema100Bullish and parabolicSARGreen
    if ichimokuBullish
        statusChance := '100%'
    else
        statusChance := '95%'
else
    if ema100Bullish and parabolicSARRed
        statusChance := '75%'
    else if ema100Bearish and parabolicSARGreen
        statusChance := '65%'
    else
        statusChance := '55%'

bool longTradePosition = false
bool shortTradePosition = false
string longTradeText = 'Now cannot say anything'

if (swingCallGreen or swingCallYellow) and ichimokuBullish and longCondition and ema100Bullish and parabolicSARGreen
    longTradePosition := true
    longTradeText := 'Bullish'

bottomText := longTradeText + ' Chance: ' + statusChance + '\n Future Trend: ' + futureIchimokuTrend
// Bottom Text

var tLog = table.new(position=position.bottom_right, rows=1, columns=2, bgcolor=color.blue, border_width=1)
table.cell(tLog, row=0, column=0, text=bottomText, text_color=color.white)
table.cell_set_text(tLog, row=0, column=0, text=bottomText)
//#### Ends Here #####

bool entryLongPosition = false
bool exitLongPosition = false

bool entryShortPosition = false
bool exitShortPosition = false

bool longPositionCount = false
bool shortPositionCount = false


if (strategy.position_size > 0)
    longPositionCount := true

if (strategy.position_size < 0)
    shortPositionCount := true
    
// Entry LONG
if (longCondition) and (not longPositionCount)
    entryLongPosition := true

// Exit LONG
if (shortCondition) and (longPositionCount)
    exitLongPosition := true
    
// Entry SHORT
if (shortCondition) and (not shortPositionCount)
    entryShortPosition := true

// Exit SHORT
if (longCondition) and (shortPositionCount)
    exitShortPosition := true

// LONG Entry & Exit
plotshape(entryLongPosition, style=shape.labeldown, location=location.abovebar, color=color.new(color.green, 0), size=size.tiny, title='buy label', text='5cel\nLONG Entry', textcolor=color.new(color.white, 0))
plotshape(exitLongPosition, style=shape.labelup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny, title='sell label', text='5cel\nExit LONG', textcolor=color.new(color.white, 0))

//SHORT Entry & Exit
plotshape(entryShortPosition, style=shape.labeldown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny, title='buy label', text='5cel\nSHORT Entry', textcolor=color.new(color.white, 0))
plotshape(exitShortPosition, style=shape.labelup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny, title='sell label', text='5cel\nExit SHORT', textcolor=color.new(color.white, 0))

//Get the Current Value
heikinashi_close = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)

if entryLongPosition
    longLabel = label.new(bar_index, high, text=str.tostring(heikinashi_close, '0.00'), color=color.orange, style=label.style_label_down, yloc=yloc.abovebar)

if entryShortPosition
    shortLabel = label.new(bar_index, high, text=str.tostring(heikinashi_close, '0.00'), color=color.orange, style=label.style_label_down, yloc=yloc.abovebar)

/// SHORT Exit
strategy.close("short", when=exitShortPosition, comment="close_short_position")

/// LONG Exit
strategy.close("long", when=exitLongPosition, comment = "close_long_position")

/// LONG Enter
strategy.entry("long", strategy.long, when=entryLongPosition, comment="open_long_position")

/// SHORT Enter
strategy.entry("short", strategy.short, when = entryShortPosition, comment="open_short_position")

Más.