Estrategia de trading bidireccional de ruptura de impulso


Fecha de creación: 2023-10-27 17:04:48 Última modificación: 2023-10-27 17:04:48
Copiar: 0 Número de Visitas: 655
1
Seguir
1617
Seguidores

Estrategia de trading bidireccional de ruptura de impulso

Descripción general

Esta estrategia utiliza un promedio móvil simple para determinar la dirección de la tendencia, hacer más en condiciones de alza continua y tomar deuda en condiciones de caída continua, para realizar operaciones bidireccionales.

Principio de estrategia

Esta estrategia utiliza el promedio móvil ponderado VWMA para determinar la dirección de la tendencia del mercado. Cuando el VWMA sube, haga más; cuando el VWMA baja, haga menos.

Concretamente, la estrategia primero calcula el VWMA de un determinado período, y luego determina si el VWMA subió más de 5 días, y si es así, abre una posición más; si el VWMA bajó más de 5 días, abre una posición en blanco. La condición de posición en blanco es que el VWMA se invierta después de más de 5 días.

Para calcular el rendimiento mensual y anual, la estrategia registra el rendimiento mensual y anual. Al comparar la estrategia con el rendimiento de referencia del mercado, se puede ver de forma intuitiva el rendimiento de la estrategia en el mercado.

Análisis de las ventajas

La estrategia tiene las siguientes ventajas:

  1. El uso de VWMA para determinar tendencias puede filtrar el ruido del mercado y capturar las principales tendencias.

  2. El riesgo de una reversión de la tendencia puede evitarse abriendo una posición solo después de que se confirme la tendencia.

  3. El comercio bidireccional permite obtener ganancias sin importar si el mercado sube o baja.

  4. Para evaluar la eficacia de las estrategias, se registran los ingresos mensuales y anuales.

  5. Añade la rentabilidad de referencia del mercado a la tabla de ganancias, para que pueda comparar intuitivamente el rendimiento relativo de la estrategia con el mercado.

Análisis de riesgos

La estrategia también tiene sus riesgos:

  1. El uso de VWMA para juzgar la tendencia puede ser un retraso y una oportunidad perdida en la etapa inicial de la tendencia.

  2. Si se abre una posición solo después de la confirmación de la tendencia, se puede perder parte del Movement.

  3. Las transacciones bidireccionales requieren la determinación de un punto de parada, de lo contrario, las pérdidas pueden aumentar.

  4. Las grandes fluctuaciones en el mercado pueden provocar que se desencadene un stop loss y no se pueda mantener una tendencia completa.

  5. El cambio de tendencia puede ser inexacto y aumentar las pérdidas.

Dirección de optimización

Esta estrategia puede ser optimizada en los siguientes aspectos:

  1. Optimización de los parámetros del ciclo VWMA para mejorar el juicio de tendencias.

  2. Ajustar el número de días de confirmación de tendencias para mejorar el tiempo de entrada y salida.

  3. Añadir estrategias de stop loss para controlar las pérdidas individuales.

  4. En combinación con otros indicadores, el cambio de tendencia aumenta la certeza.

  5. Optimizar la gestión de posiciones y ajustarlas a las condiciones del mercado.

  6. Tenga en cuenta el costo de la transacción y establezca un mínimo de ganancias.

Resumir

La idea general de esta estrategia es clara y simple, utiliza VWMA para determinar la dirección de la tendencia, el comercio de dos vías después de la confirmación de la tendencia, puede seguir eficazmente el movimiento del mercado. Pero también existe cierto riesgo, se requieren más pruebas y optimización de los parámetros, ajuste a la lógica de salida, y el control adecuado de la escala de la posición. Esta estrategia se basa en la estrategia de comercio de dos vías, sentó las bases para el comercio cuantitativo, vale la pena seguir estudiando y mejorando.

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

//@version=4
strategy(title="Monthly Returns in Strategies with Market Benchmark", shorttitle="Monthly P&L With Market", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// MONTHLY TABLE //

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_month_pnl = 0.0
cur_year_pnl  = 0.0
cur_month_bh = 0.0
cur_year_bh  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 
cur_month_bh := new_month ? 0.0 : 
                 (1 + cur_month_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)
var month_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

last_computed = false

if (not na(cur_month_pnl[1]) and (new_month or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(month_pnl)
        array.pop(month_time)
        
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])
    array.push(month_bh , cur_month_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory))
    if (last_computed[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

last_computed := (time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory) ? true : nz(last_computed[1])

// Monthly P&L Table    
var monthly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if last_computed
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(monthly_table, 13, yi + 1, tostring(round(array.get(year_pnl, yi) * 100)) + " (" + tostring(round(array.get(year_bh, yi) * 100)) + ")", bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = getCellColor(array.get(month_pnl, mi), array.get(month_bh, mi))
        
        table.cell(monthly_table, m_col, m_row, tostring(round(array.get(month_pnl, mi) * 100)) + " (" + tostring(round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)