Estrategia de negociación cuantitativa basada en el indicador de supertendencia y la negociación de curvas de renta variable

El autor:¿ Qué pasa?, Fecha: 2024-01-15 11:41:53
Las etiquetas:

img

Resumen general

La idea central de esta estrategia es combinar el indicador Supertrend con el comercio de curvas de acciones. Cuando el indicador Supertrend genera una señal de compra o venta, no ejecutamos directamente el comercio. En su lugar, verificamos si la curva de acciones actual está por debajo de su promedio móvil. Abriremos posiciones solo cuando la curva de acciones esté por encima del promedio móvil. Cuando la curva de acciones esté por debajo del promedio móvil, pausaremos el comercio para la estrategia actual. Esto puede prevenir efectivamente la expansión de las pérdidas.

Estrategia lógica

Esta estrategia consta principalmente de dos partes:

  1. Indicador de supertendencia
  2. Negociación de la curva de renta variable

La fórmula de cálculo del indicador Supertrend es:

Bandas superiores = Precio de origen - ATR multiplicador * ATR Banda inferior = Precio de origen + multiplicador ATR * ATR

El indicador de Supertrend utiliza el ATR para establecer las bandas superior e inferior. Una ruptura por encima de la banda superior significa una señal de venta, mientras que una ruptura por debajo de la banda inferior significa una señal de compra.

La idea detrás de la negociación de curvas de renta variable es que tomamos el promedio móvil de la curva de renta variable de la estrategia. Cuando la curva de renta variable cae por debajo de su promedio móvil, hacemos una pausa en la negociación de la estrategia actual y esperamos a que la curva de renta variable rebote por encima del promedio móvil antes de volver a activar la negociación.

Esta estrategia combina las dos técnicas, de modo que después de que el indicador de Supertrend genere una señal de negociación, no entramos directamente en operaciones. En su lugar, verificamos si la curva de renta variable actual está por encima de su promedio móvil. Solo cuando se cumplan ambas condiciones abriremos posiciones. Esto puede mitigar eficazmente los riesgos inherentes al indicador de Supertrend y evitar pérdidas excesivas.

Ventajas

Las principales ventajas de esta estrategia son las siguientes:

  1. El indicador de Supertrend no puede frenar las pérdidas de manera efectiva. El comercio de curvas de acciones compensa esta deficiencia.

  2. Cuando el comercio se vuelve desfavorable, se detiene el comercio para evitar pérdidas excesivas.

  3. Puede gestionar posiciones automáticamente sin intervención manual. La negociación se detiene automáticamente cuando la curva de acciones cae por debajo del promedio móvil, y se reanuda cuando la curva de acciones rebota por encima de ella.

Los riesgos

También hay algunos riesgos con esta estrategia:

  1. Si se establecen los parámetros incorrectos, la negociación de la curva de renta variable puede resultar ineficaz, por lo que es necesario seleccionar los períodos de media móvil adecuados.

  2. Es posible que no pueda ajustar las posiciones rápidamente cuando la tendencia del mercado cambie, lo que puede dar lugar a ciertas pérdidas.

  3. Puede perder buenas oportunidades comerciales mientras espera que la curva de acciones se recupere.

Las medidas de contramedida:

  1. Optimice los parámetros y seleccione el mejor período de media móvil.

  2. Incorporar otros indicadores para juzgar la tendencia y ajustar las posiciones en consecuencia.

  3. Acortar la duración de las operaciones suspendidas para reducir la probabilidad de oportunidades perdidas.

Direcciones de optimización

Podemos optimizar la estrategia desde los siguientes aspectos:

  1. Prueba diferentes combinaciones de parámetros para determinar el período y el multiplicador óptimos de ATR.

  2. Pruebe otros tipos de promedios móviles, como promedio móvil exponencial, promedio móvil Hull, etc.

  3. Añadir otros indicadores para determinar la tendencia del mercado y ajustar las posiciones cuando la tendencia cambie.

  4. Optimice el período de promedio móvil para encontrar el mejor equilibrio.

  5. Optimice las condiciones para pausar la negociación, como establecer un umbral de stop loss antes de la suspensión.

Conclusión

Esta estrategia combina hábilmente el indicador Supertrend con el trading de curvas de acciones, aprovechando las fortalezas de ambas técnicas. Los resultados de las pruebas muestran que en la mayoría de los casos, aplicar el trading de curvas de acciones en realidad disminuye la rentabilidad. Como tal, esta estrategia es más adecuada para los traders defensivos. Con la optimización de parámetros y lógica, puede convertirse en una estrategia de trading cuantitativa muy práctica.


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

//@version=5
strategy('Supertrend & Equity curve with EMA', overlay=false, format=format.price, precision=2, initial_capital=100000)

eqlen = input.int(25, "EQ EMA len", group = "New Equity Curve Settings")
shEQandMA = input.bool(true, "Show Original Equity Curve and MA")
shEQfilt = input.bool(true, "Show Filtered Equity Curve by MA")

Periods = input(title='ATR Period', defval=10, group = "SuperTrend Settings")
src = input(hl2, title='Source', group = "SuperTrend Settings")
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group = "SuperTrend Settings")
changeATR = input(title='Change ATR Calculation Method ?', defval=true, group = "SuperTrend Settings")

//SuperTrend Code
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend

// Strategy main code
buySignal = trend == 1 and trend[1] == -1
sellSignal = trend == -1 and trend[1] == 1
if buySignal
    strategy.entry('Long', strategy.long)
if sellSignal
    strategy.entry('Short', strategy.short)



//Equity Curve calcs
eq = strategy.netprofit
ch = ta.change(eq)
neq = ch != 0 ? eq : na
mova = ta.ema(neq,eqlen)

// New Equity Curve
var float neweq = 0
var int ttrades = 0
var int wintrades = 0
var int losetrades = 0

switch
    strategy.netprofit == strategy.netprofit[1]  => na
    strategy.netprofit < mova and strategy.netprofit[1] > mova  => neweq := neweq + ch
    strategy.netprofit < mova and strategy.netprofit[1] < mova => na
    strategy.netprofit > mova and strategy.netprofit[1] > mova => neweq := neweq + ch

newch = ta.change(neweq)
switch
    newch == 0 => na
    newch > 0 => 
        wintrades := wintrades +1
        ttrades := ttrades +1
    newch < 0 =>
        losetrades := losetrades +1
        ttrades := ttrades +1

//plot(eq, linewidth = 2)
//plot(mova, color=color.red)
//plot(neweq, color= color.green, linewidth = 3)


//Table 
var testTable = table.new(position = position.top_right, columns = 5, rows = 10, bgcolor = color.green, border_width = 1)
table.cell(table_id = testTable, column = 0, row = 0, text = "Strategy: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 1, row = 0, text = "Original: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 0, text = "Equity Curve EMA: ", bgcolor=color.white)     

table.cell(table_id = testTable, column = 0, row = 1, text = "Total Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 2, text = "Win Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 3, text = "Lose Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 4, text = "Win Rate: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 5, text = "Net Profit: ", bgcolor=color.white)     

//Equity Curve EMA stat
table.cell(table_id = testTable, column = 2, row = 1, text = str.tostring(ttrades), bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 2, text = str.tostring(wintrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 3, text = str.tostring(losetrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 4, text = str.tostring(math.round(100*wintrades/ttrades,2)), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 5, text = str.tostring(math.round(neweq)), bgcolor=color.white)

//Original Strategy stat
// table.cell(table_id = testTable, column = 1, row = 1, text = str.tostring(strategy.closedtrades), bgcolor=color.white)     
// table.cell(table_id = testTable, column = 1, row = 2, text = str.tostring(strategy.wintrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 3, text = str.tostring(strategy.losstrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 4, text = str.tostring(math.round(100*strategy.wintrades/strategy.closedtrades,2)), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 5, text = str.tostring(math.round(strategy.netprofit)), bgcolor=color.white)




//New Equity curve
var newcurve = array.new_float(0)
var int ida = 0
var bool printEQ = false
if newch !=0 
    array.push(newcurve, neweq)
if bar_index > last_bar_index - array.size(newcurve) - 1 - 20  and array.size(newcurve) > 20 
    printEQ := true
else
    printEQ := false

plot(printEQ and ida < strategy.closedtrades and shEQfilt ? array.get(newcurve, ida) : na, color=color.green, linewidth = 2)

if printEQ
    ida := ida + 1
if ida >= array.size(newcurve) and printEQ
    ida := array.size(newcurve) -1



//Original Equity curve
var newcurve2 = array.new_float(0)
var int ida2 = 0
var bool printEQ2 = false
if ch !=0 
    array.push(newcurve2, eq)
if bar_index > last_bar_index - array.size(newcurve2) - 1 - 20  and array.size(newcurve2) > 20 
    printEQ2 := true
else
    printEQ2 := false

plot(printEQ2 and ida2 < strategy.closedtrades and shEQandMA  ? array.get(newcurve2, ida2) : na, color=color.blue, linewidth = 2)

if printEQ2
    ida2 := ida2 + 1
if ida2 >= array.size(newcurve2) and printEQ2
    ida2 := array.size(newcurve2) -1



//Moving Average Array
var marray = array.new_float(0)
if ch
    array.push(marray, mova)

plot(printEQ2 and  array.size(marray) > 40 and shEQandMA ? array.get(marray, ida2-1) : na, color=color.red, linewidth = 1)

hline(0,"0 line", color=color.black, linestyle = hline.style_dotted)


if (last_bar_index-1) and array.size(newcurve2) > 20 and array.size(newcurve) > 20
    l = label.new(bar_index+2, array.get(newcurve2, array.size(newcurve2)-1), "Original Equity Curve", color=color.rgb(33, 149, 243, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(l[1])
    f = label.new(bar_index+2, array.get(newcurve, array.size(newcurve)-1), "Filtered Equity Curve", color=color.rgb(69, 238, 97, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(f[1])

Más.