Estrategia de negociación de criptomonedas alcista/bajista basada en correlación basada en el índice CCI de Wall Street

El autor:¿ Qué pasa?, Fecha: 2023-11-01 11: 27:20
Las etiquetas:

img

Resumen general

Se trata de una estrategia de negociación automatizada que genera señales largas/cortas/cerradas en la criptomoneda objetivo basada en la tendencia calculada de una criptomoneda de referencia considerada correlacionada con ella, utilizando el índice de anillo de persecución de Wall Street.

Con parámetros predeterminados y ETH/USDT como símbolo base, la estrategia muestra buenos resultados de backtest en símbolos como DENT/USDT, BTT/USDT, FTT/USDT, DOT/USDT, etc. Esto tiene sentido ya que ETH es bastante influyente en los criptomercados, por lo que muchas criptomonedas tienden a seguir los principales movimientos de ETH.

Nota: La estrategia con parámetros predeterminados está destinada a un marco de tiempo de 4 horas. En otros marcos de tiempo, pruebe una duración de soporte diferente.

Cómo funciona la estrategia

  1. Una WMA se calcula sobre el símbolo base, con longitud 200 por defecto.

  2. Cuando el WMA está subiendo, vaya largo, cuando caiga, vaya corto.

  3. TakeProfit para Long/Short y StopLoss para Long/Short son porcentajes calculados, por lo que 0.05 = 5% etc. Además, TakeProfit/StopLoss se calculan en el símbolo base y no en el símbolo del gráfico.

  4. La estrategia utiliza órdenes de mercado para la entrada y salida basadas en la siguiente lógica:

    • Cuando WMA suba y no haya posición, entrada larga

    • Cuando la WMA cae y no hay posición, entrada corta

    • Cuando el beneficio de la posición larga >= TakeProfitLong por ciento, cierre largo

    • Cuando el beneficio de la posición corta >= TakeProfitShort en porcentaje, cierre corto

    • Cuando la pérdida de posición larga >= StopLossLong por ciento, cierre larga

    • Cuando la pérdida de posición corta >= StopLossShort en porcentaje, cierre corta

  5. Los precios de TakeProfit y StopLoss se actualizan en tiempo real en función de los cambios en los precios del símbolo base.

Análisis de ventajas

  1. La estrategia es altamente adaptable para su uso en múltiples criptomonedas ajustando los parámetros.

  2. El uso del CCI de Wall Street para determinar la tendencia evita operaciones erróneas conducidas por el ruido.

  3. La incorporación de TakeProfit y StopLoss permite seguir la tendencia mientras se controla la pérdida por operación.

  4. El comercio totalmente automatizado sin intervención manual permite un tiempo de ejecución 24/7.

Análisis de riesgos

  1. Riesgo de desacoplamiento del precio del cripto objetivo del cripto base, lo que conduce al fracaso de la estrategia. Puede optimizar utilizando múltiples criptos base y eligiendo el más correlacionado.

  2. Puede ajustar el porcentaje de StopLoss o usar trailing stops.

  3. El riesgo de TakeProfit porcentaje demasiado pequeño para capturar suficientes ganancias de tendencia.

  4. Puede ajustar los parámetros CCI o añadir la lógica de reentrada.

Direcciones de optimización

  1. Utilice el análisis de correlación entre criptomonedas de base múltiple y combine indicadores para reducir el riesgo de criptomonedas de base única.

  2. Añadir seguimiento de tendencias para ajustar dinámicamente TakeProfit/StopLoss en función de la volatilidad.

  3. Agregue paradas escalonadas para evitar movimientos extremos que detengan posiciones.

  4. Añadir una lógica de reingreso para evitar perder tendencias posteriores después de la salida de stop loss.

  5. Optimizar los parámetros y ajustes de CCI para mejorar la eficacia de la señal.

  6. Optimizar los parámetros por separado para cada cripto objetivo para mejorar la adaptabilidad.

  7. Optimizar el tamaño de las posiciones en función del tamaño de la cuenta.

Resumen de las actividades

En general, esta es una estrategia típica de seguimiento de tendencias. La idea central es determinar la dirección de tendencia de una criptomoneda de referencia utilizando el CCI de Wall Street y comerciar la criptomoneda objetivo en consecuencia. La estrategia tiene algunas ventajas, pero también riesgos a tener en cuenta.


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

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © levieux

//@version=5
strategy(title='Correlation Strategy', shorttitle='Correlation Strategy', 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)

supportLength = input.int(200, minval=1, title='Support Length')
supportSymbol = input('BTC_USDT:swap', title='Correlated Symbol')
supportSource = input(hlc3, title='Price Source')
takeprofitLong = input.float(0.2, 'Take Profit Long', step=0.01)
takeprofitShort = input.float(0.15, 'Take Profit Short', step=0.01)
stoplossLong = input.float(0.1, 'Stop Loss Long', step=0.01)
stoplossShort = input.float(0.04, 'Stop Loss Short', step=0.01)
start = input(defval = timestamp("01 Jan 2016 00:00 +0000"), title = "Start Time")
end = input(defval = timestamp("31 Dec 2050 23:59 +0000"), title = "End Time")

supportTicker = request.security(supportSymbol, timeframe.period, supportSource, lookahead=barmerge.lookahead_off)  //input(close, title="Source")
supportLine = ta.wma(supportTicker, supportLength)

window() => true

if not window()
    strategy.cancel_all()

supportLongPrice = close
supportShortPrice = close

if strategy.position_size > 0
    supportLongPrice := supportLongPrice[1]
if strategy.position_size < 0
    supportShortPrice := supportShortPrice[1]

longCondition = ta.rising(supportLine, 5) and window() and strategy.position_size <= 0
shortCondition = ta.falling(supportLine, 5) and window() and window() and strategy.position_size > 0
takeprofitLongCondition = takeprofitLong > 0 and window() and strategy.position_size > 0 and supportTicker > supportLongPrice * (1 + takeprofitLong)
stoplossLongCondition = stoplossLong > 0 and window() and strategy.position_size > 0 and supportTicker < supportLongPrice * (1 - stoplossLong)
takeprofitShortCondition = takeprofitShort > 0 and window() and strategy.position_size < 0 and supportTicker > supportShortPrice * (1 + takeprofitShort)
stoplossShortCondition = stoplossShort > 0 and window() and strategy.position_size < 0 and supportTicker < supportShortPrice * (1 - stoplossShort)

if longCondition
    strategy.entry('Long', strategy.long)
    supportLongPrice := supportTicker

if shortCondition
    strategy.entry('Short', strategy.short)
    supportShortPrice := supportTicker

if takeprofitLongCondition
    strategy.close('Long')
if stoplossLongCondition
    strategy.close('Long')
if takeprofitShortCondition
    strategy.close('Short')
if stoplossShortCondition
    strategy.close('Short')

///////////////////
// 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)

end_time = false

end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory

if (not na(cur_month_pnl[1]) and (new_month or end_time))
    if (end_time[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 end_time))
    if (end_time[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])

// 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 or pnl < 2 * bh
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if end_time
    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, str.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, str.tostring(math.round(array.get(year_pnl, yi) * 100)) + " (" + str.tostring(math.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, str.tostring(math.round(array.get(month_pnl, mi) * 100)) + " (" + str.tostring(math.round(array.get(month_bh, mi) * 100)) +")", bgcolor = m_color)

Más.