La estrategia de negociación de VWAP de BabyShark basada en los indicadores RSI VWAP y OBV

El autor:¿ Qué pasa?, Fecha: 2024-03-08 16:39:28
Las etiquetas:

img

Resumen de la estrategia

La estrategia de negociación BabyShark VWAP es una estrategia de negociación cuantitativa basada en el precio promedio ponderado por volumen (VWAP) y el índice de fuerza relativa del volumen en el balance (OBV RSI).

Principio de la estrategia

El principio básico de esta estrategia es utilizar los indicadores VWAP y OBV RSI para capturar las tendencias del mercado y los cambios de impulso. VWAP es un promedio móvil dinámico basado en el precio y el volumen, que refleja las principales áreas de negociación del mercado. Cuando el precio se desvía significativamente de VWAP, generalmente indica condiciones de sobrecompra o sobreventa en el mercado.

Específicamente, la estrategia utiliza 60 velas como período de cálculo para VWAP, con el precio de cierre como datos de entrada. Luego construye zonas de sobrecompra y sobreventa basadas en desviaciones de precios de 3 desviaciones estándar positivas y negativas de VWAP. Para OBV RSI, utiliza 5 velas como período de cálculo y establece umbrales de 70 y 30 como criterios para determinar las condiciones de sobrecompra y sobreventa.

En términos de lógica de negociación, cuando el precio está en la zona de sobreventa por debajo de la banda inferior de VWAP y OBV RSI es menor a 30, la estrategia genera una señal larga. Por el contrario, cuando el precio está en la zona de sobrecompra por encima de la banda superior de VWAP y OBV RSI es mayor a 70, genera una señal corta. Además, la estrategia establece una relación de toma de ganancias y stop loss del 0,6% e introduce un período de enfriamiento de 10 velas después de pérdidas consecutivas para controlar los riesgos.

Ventajas estratégicas

  1. Combina múltiples factores de mercado como el precio y el volumen para capturar de manera integral las tendencias y el impulso del mercado.
  2. Adopta indicadores dinámicos de VWAP y OBV RSI para adaptarse a los cambios en los diferentes ciclos de mercado.
  3. Establece ratios razonables de ganancias y pérdidas y períodos de reflexión para controlar eficazmente los riesgos y aprovechar las oportunidades.
  4. Una lógica clara, fácil de entender e implementar, con cierto nivel de interpretabilidad.
  5. Parámetros ajustables, adecuados para que los operadores con diferentes estilos puedan optimizar y mejorar.

Riesgos estratégicos

  1. Para los mercados oscilantes o repetitivos, las señales de negociación frecuentes pueden conducir a un exceso de negociación y a un aumento de los costes de deslizamiento.
  2. En los mercados de tendencia, confiar únicamente en el VWAP para obtener ganancias puede hacer que la estrategia salga demasiado pronto, perdiendo las ganancias de tendencia posteriores.
  3. Es posible que los parámetros fijos no se adapten a los cambios en las condiciones del mercado, lo que requiere una optimización para diferentes instrumentos y plazos.
  4. El indicador OBV depende en gran medida de los datos de volumen; cuando los datos de volumen son inexactos o manipulados, las distorsiones del indicador pueden inducir a error los juicios.
  5. La estrategia carece de consideración de factores externos como la macroeconomía y las noticias, y puede fallar en condiciones extremas de mercado.

Direcciones de optimización

  1. Introducir más condiciones de filtrado para los mercados oscilantes, como indicadores de confirmación de tendencias e indicadores de volatilidad, para reducir la frecuencia de las operaciones.
  2. Optimizar las condiciones de salida, como el uso de paradas de seguimiento o la combinación con otros indicadores de tendencia para captar mejor los mercados de tendencia.
  3. Realizar una optimización adaptativa de los parámetros VWAP y OBV RSI, ajustando dinámicamente los períodos de cálculo y los ajustes de umbral.
  4. Introducir mecanismos de verificación de la autenticidad del volumen para mejorar la fiabilidad del indicador OBV RSI.
  5. Considere la posibilidad de incorporar análisis de datos macroeconómicos, indicadores de sentimiento, etc., para mejorar la adaptabilidad y la solidez de la estrategia.

Resumen de las actividades

La estrategia de negociación BabyShark VWAP es una estrategia de negociación cuantitativa que combina el precio promedio ponderado por volumen y el índice de fuerza relativa del volumen en el balance para generar señales de negociación al capturar las condiciones de sobrecompra y sobreventa y los cambios en el impulso de la tendencia. La estrategia tiene una lógica clara, integrando múltiples factores de mercado como el precio y el volumen para captar de manera integral el pulso del mercado. Al mismo tiempo, ajustes razonables de toma de ganancias y parada de pérdidas y mecanismos de control de riesgos permiten que la estrategia busque rendimientos mientras se considera la gestión de riesgos. Sin embargo, la estrategia también tiene problemas potenciales como la adaptabilidad inadecuada a los mercados oscilantes y tendentes y los optimizadores fijos. Las mejoras futuras pueden centrarse en los adaptadores de entrada, la toma de ganancias dinámicas, los parámetros de optimización, la mejora del análisis de datos externos y la mejora de la robustez y rentabilidad de la estrategia. En general, la


/*backtest
start: 2024-02-01 00:00:00
end: 2024-02-29 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © GreatestUsername

//@version=5
strategy("BabyShark VWAP Strategy", overlay=true, margin_long=100, margin_short=100, calc_on_every_tick = true)


// VWAP
ls = input(false, title='Log-space', group = "Optional")
type = 'Average Deviation'
length = input(60, group="Strategy Modification")
source = input(close, group="Strategy Modification")
_low = ls == true ? math.log(low) : low
_high = ls == true ? math.log(high) : high
src = ls == true ? math.log(source) : source

//weighted mean
pine_vwmean(x, y) =>
    cw = 0.0
    cd = 0.0
    w_sum = 0.0
    d_sum = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw := volume[i]
        d_sum += cw * cd
        w_sum += cw
        w_sum
    d_sum / w_sum

//weighted standard deviation
pine_vwstdev(x, y, b) =>
    d_sum = 0.0
    w_sum = 0.0
    cd = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw = volume[i]
        d_sum += cw * math.pow(cd - b, 2)
        w_sum += cw
        w_sum
    math.sqrt(d_sum / w_sum)

//weighted average deviation
pine_vwavdev(x, y, b) =>
    d_sum = 0.0
    w_sum = 0.0
    cd = 0.0
    for i = 0 to y - 1 by 1
        cd := x[i]
        cw = volume[i]
        d_sum += cw * math.abs(cd - b)
        w_sum += cw
        w_sum
    d_sum / w_sum

vwmean = pine_vwmean(src, length)

//consider using Average Deviation instead of Standard Deviatio if there are values outside of 3rd upper & lower bands within a rolling window
dev = if type == 'Standard Deviation'
    dev = pine_vwstdev(src, length, vwmean)
    dev
else if type == 'Average Deviation'
    dev = pine_vwavdev(src, length, vwmean)
    dev

basis = ls == true ? math.exp(vwmean) : vwmean
plot(basis, color=color.new(#b7b7b7, 60), title='Basis')

upper_dev_2 = vwmean + dev * 2
upper_dev_3 = vwmean + dev * 3

lower_dev_2 = vwmean - dev * 2
lower_dev_3 = vwmean - dev * 3

fill(
     plot1=plot(ls == true ? math.exp(upper_dev_2) : upper_dev_2, color=color.new(#B20000, 0), title='Upper dev 2'), 
     plot2=plot(ls == true ? math.exp(upper_dev_3) : upper_dev_3, color=color.new(#FF6666, 0), title='Upper dev 3', display=display.none), 
     color=color.new(#FF4D4D, 80), title='Upper band'
     )
fill(
     plot1=plot(ls == true ? math.exp(lower_dev_3) : lower_dev_3, color=color.new(#00CC00, 0), title='Lower dev 3', display=display.none), 
     plot2=plot(ls == true ? math.exp(lower_dev_2) : lower_dev_2, color=color.new(#008000, 0), title='Lower dev 2'), 
     color=color.new(#006600, 80), title='Lower band'
     )


// Input to enable or disable the table visibility
table_visible = input(false, title="Show Table", group="Deviation Cross Monitor")
// Input for the number of candles to look back
table_length = input(300, title="Table Lookback Length", group="Deviation Cross Monitor")

// Custom count function
count_occurrences(cond, length) =>
    count = 0
    for i = 0 to length - 1
        if cond[i]
            count := count + 1
    count

// Count occurrences of prices above Upper dev 2 and below Lower dev 2

above_upper_dev_2 = count_occurrences(close > upper_dev_2, table_length)
below_lower_dev_2 = count_occurrences(close < lower_dev_2, table_length)

// Create table in the bottom right corner
var table tbl = table.new(position=position.bottom_right, rows=2, columns=2)

if table_visible
    if barstate.islast
        // Update the table headers
        table.cell(tbl, 0, 0, "Above Upper Dev 2", bgcolor=color.gray, text_color=color.white)
        table.cell(tbl, 0, 1, "Below Lower Dev 2", bgcolor=color.gray, text_color=color.white)
        
        // Update the table values
        table.cell(tbl, 1, 0, str.tostring(above_upper_dev_2), bgcolor=color.new(color.green, 90), text_color=color.green)
        table.cell(tbl, 1, 1, str.tostring(below_lower_dev_2), bgcolor=color.new(color.red, 90), text_color=color.red)
else
    table.delete(tbl)

// RSI
obvsrc = close
change_1 = ta.change(obvsrc)
obv = ta.cum(ta.change(obvsrc) > 0 ? volume : change_1 < 0 ? -volume : 0 * volume)

src2 = obv
len = input.int(5, minval=1, title="RSI Length", group="Strategy Modification")
up = ta.rma(math.max(ta.change(src2), 0), len)
down = ta.rma(-math.min(ta.change(src2), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)
higherlvl = input(70, title="Higher Level", group="Strategy Modification")
lowerlvl = input(30, title="Lower Level", group="Strategy Modification")


plot_color = rsi >= higherlvl ? color.red : rsi <= lowerlvl ? color.green : color.new(#b7b7b7, 60)
// plot(rsi, color=plot_color)

//plot(rsi, color=color.white)



// Count occurrences of RSI crossing higher level and lower level
cross_above_higher = ta.crossover(rsi, higherlvl)
cross_below_lower = ta.crossunder(rsi, lowerlvl)
above_higher_count = count_occurrences(cross_above_higher, table_length)
below_lower_count = count_occurrences(cross_below_lower, table_length)

// Create table in the bottom right corner
if (table_visible)
    var table tbl2 = table.new(position=position.bottom_right, rows=2, columns=2)
    if (barstate.islast)
        // Update the table headers
        table.cell(tbl2, 0, 0, "Higher Level Cross", bgcolor=color.gray, text_color=color.white)
        table.cell(tbl2, 0, 1, "Lower Level Cross", bgcolor=color.gray, text_color=color.white)
        
        // Update the table values
        table.cell(tbl2, 1, 0, str.tostring(above_higher_count), bgcolor=color.new(color.red, 90), text_color=color.red)
        table.cell(tbl2, 1, 1, str.tostring(below_lower_count), bgcolor=color.new(color.green, 90), text_color=color.green)


// Entries

// Long Entry:
// Price is in the shaded GREEN area of [Hoss] VWAP Deviation
// and the [Hoss] OBV RSI is GREEN.
longCondition1 = close <= lower_dev_3
longConditions = plot_color == color.green and longCondition1 and strategy.position_size == 0

// Short Entry:
// Price is in the shaded RED area of [Hoss] VWAP Deviation
// and the [Hoss] OBV RSI is RED.
shortCondition1 = close >= upper_dev_3
shortConditions = plot_color == color.red and shortCondition1 and strategy.position_size == 0

var int lastEntryBar = 0


shortEMA = ta.ema(close, 12)
longEMA = ta.ema(close, 21)
uptrend = shortEMA > longEMA

if longConditions and lastEntryBar < bar_index - 10 //and uptrend
    strategy.entry("Long", strategy.long, stop=close * 0.994)
    lastEntryBar := bar_index

if shortConditions and lastEntryBar < bar_index - 10 //and not uptrend
    strategy.entry("Short", strategy.short, stop=close * 1.006)
    lastEntryBar := bar_index


if strategy.position_size > 0 and (ta.crossover(close, basis) or strategy.opentrades.entry_price(strategy.opentrades - 1) * 0.994 > close)
    strategy.close("Long", immediately = true)
if strategy.position_size < 0 and (ta.crossunder(close, basis) or strategy.opentrades.entry_price(strategy.opentrades - 1) * 1.006 < close)
    strategy.close("Short", immediately = true)

// Stop Loss:
// 0.6%
// After 1 Loss => NO more Trades for 10 Candles (10 minutes) (usually a breakout will happen, and it takes average 10min till it ranges again. So basically wait for range to form again)

// Take Profit:
// Grey line on [Hoss] VWAP Deviation or 0.6%



Más.