Estrategia cuantitativa basada en el indicador de súper tendencia y el trading con curvas de acciones


Fecha de creación: 2024-01-15 11:41:53 Última modificación: 2024-01-15 11:41:53
Copiar: 1 Número de Visitas: 601
1
Seguir
1617
Seguidores

Estrategia cuantitativa basada en el indicador de súper tendencia y el trading con curvas de acciones

Descripción general

La idea central de esta estrategia es combinar el indicador de hipertrend con el comercio de la curva de valor neto, y cuando el indicador de hipertrend emite una señal de compra o venta, no ejecutamos directamente la operación, sino que juzgamos si la curva de valor neto actual está por debajo de su promedio móvil. Solo abrimos una posición cuando la curva de valor neto es superior a la media móvil.

Principio de estrategia

La estrategia tiene dos partes principales:

  1. Indicador de las tendencias
  2. Negociación de la curva de valor neto

La fórmula para calcular el indicador de tendencia es la siguiente:

El precio de salida = el precio de salida - ATR multiplicado por ATR La línea inferior = precio de origen + ATR multiplicado por ATR

En este caso, el ATR representa la amplitud real promedio. El indicador de tendencia hiper utiliza el ATR para establecer el alza y bajada, como una señal de venta cuando el precio se rompe en la vía superior y una señal de compra cuando el precio se rompe en la vía inferior.

La idea de negociar en la curva de la rentabilidad es que tomamos el promedio móvil de la curva de la rentabilidad de la estrategia, y cuando la curva de la rentabilidad es inferior a la media móvil, suspendemos el comercio de la estrategia actual y esperamos a que la curva de la rentabilidad suba por encima de la media móvil para volver a abrir el comercio.

Esta estrategia combina los dos, y después de que el indicador de tendencia excesiva genera una señal de negociación, no negociamos directamente, sino que juzgamos si la curva de valor neto actual es superior a la media móvil. Sólo si ambos cumplen las condiciones al mismo tiempo, abriremos una posición. Esto puede evitar eficazmente el riesgo del indicador de tendencia excesiva en sí mismo y evitar pérdidas excesivas.

Análisis de las ventajas

Las principales ventajas de esta estrategia son:

  1. Los indicadores de tendencia excesiva no pueden evitar las pérdidas por sí mismos, y las operaciones de curva de valor neto pueden compensar esta deficiencia.

  2. Cuando las operaciones son desfavorables, se puede suspender la operación de la estrategia para evitar pérdidas excesivas. Se puede esperar a que el cambio de mercado se pueda reabrir.

  3. Puede administrar automáticamente las posiciones sin necesidad de intervención manual. Se suspende automáticamente cuando la curva de valor neto está por debajo de la media móvil y se abre automáticamente cuando está por encima de ella.

Análisis de riesgos

La estrategia también tiene ciertos riesgos:

  1. El error en la configuración de los parámetros puede causar que la curva de la rentabilidad no funcione de manera eficiente. Se debe elegir el ciclo de media móvil adecuado.

  2. Cuando la tendencia del mercado cambia, es posible que no se pueda ajustar la posición a tiempo. Esto puede causar cierta pérdida.

  3. La necesidad de esperar a que la curva de patrimonio se eleve podría hacer que se pierda el mejor momento para ingresar.

Respuesta:

  1. Optimización de los parámetros para seleccionar el mejor promedio móvil.

  2. En combinación con otros indicadores para evaluar las tendencias, ajuste de posición a tiempo.

  3. Reducir adecuadamente el tiempo de suspensión de la operación para reducir la probabilidad de perder la entrada.

Dirección de optimización

Esta estrategia puede ser optimizada en los siguientes aspectos:

  1. Prueba diferentes combinaciones de parámetros para encontrar el mejor ciclo ATR y el multiplicador ATR.

  2. Pruebe otros tipos de medias móviles, como las medias móviles de índices, las medias móviles de Hull, etc.

  3. Añadir otros indicadores para juzgar la tendencia del mercado y ajustar la posición a tiempo cuando la tendencia cambia.

  4. Optimice el ciclo de la media móvil para encontrar el punto de equilibrio óptimo. El ciclo demasiado largo pierde oportunidades, el más corto se suspende con frecuencia.

  5. Optimización de las condiciones para la suspensión de la operación, como el establecimiento de una línea de parada de pérdidas, que se suspende solo después de que las pérdidas alcancen un cierto nivel.

Resumir

Esta estrategia combina hábilmente el indicador de hipertrend con la negociación de la curva de valor neto. Se mantiene la ventaja de que el indicador de hipertrend determina la tendencia, pero el riesgo se controla eficazmente a través de la negociación de la curva de valor neto. Los resultados de las pruebas muestran que en la mayoría de los casos, la aplicación de la negociación de la curva de valor neto reduce los niveles de ganancias.

Código Fuente de la Estrategia
/*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])