Estrategia cuantitativa basada en la tasa de cambio de precios y la media móvil


Fecha de creación: 2023-12-11 11:18:56 Última modificación: 2023-12-11 11:18:56
Copiar: 1 Número de Visitas: 454
1
Seguir
1235
Seguidores

Estrategia cuantitativa basada en la tasa de cambio de precios y la media móvil

Descripción general

La estrategia combina el índice de variación de precios y el indicador técnico de la línea media para lograr la ubicación precisa de los puntos de compra y venta. Se establece un umbral de compra cuando los precios caen claramente y se abren posiciones de más cabeza cuando caen aún más. Se establece un umbral de venta cuando los precios aumentan y se liquida cuando continúan aumentando.

Principio de estrategia

Comprar la lógica

  1. Calcula el ROC del cambio de precio y establece una línea de amortización de compra.
  2. Cuando el precio cae por debajo de la línea de brecha de compra, se registra el punto y se inicia la línea de límite de compra.
  3. La compra de líneas limitadas tiene una duración establecida según los parámetros de entrada y se cierra después de la expiración.
  4. Cuando el precio continúa bajando y se cae por encima de la línea de límite de compra, se abre la primera posición de más cabeza.

Vendiendo la lógica

  1. Calcula el ROC de cambio de precio y establece una línea de pérdida de valor para vender.
  2. Cuando el precio rompe la línea de pérdida de valor, registre el punto y inicie la línea de pérdida de valor.
  3. Vender líneas limitadas de duración establecida según los parámetros de entrada, cerradas después de la expiración.
  4. Cuando el precio continúe subiendo y se rompa la línea de venta limitada, elimine todas las posiciones de más cabeza.

Control de riesgos

La estrategia tiene una función de stop loss y stop stop, con parámetros personalizables, control de riesgo de posiciones en tiempo real.

Cómo se acumula

Cada vez que se abre una posición de negociación, se establece el precio de compra posterior en una proporción determinada de acuerdo con los parámetros de entrada, para lograr el efecto de comprar y aumentar la posición en lotes.

Análisis de las ventajas

  1. Utiliza el indicador de la tasa de cambio de precios ROC para buscar puntos de compra y venta, ROC es muy sensible a los cambios de precio y la ubicación de los puntos de compra y venta es precisa.
  2. El uso de líneas limitadas para confirmar el tiempo de compra y venta, evita falsos brechas.
  3. El acondicionamiento permite el seguimiento del valor de mercado sobre una base que garantiza el control del riesgo.
  4. El bloqueo de pérdidas integrado controla estrictamente el riesgo de una sola posición.

Riesgos y soluciones

  1. La estrategia puede abrir demasiadas posiciones cuando el mercado fluctúa fuertemente. La solución es establecer razonablemente los parámetros para aumentar la posición y controlar el número total de posiciones.
  2. Cuando la tendencia de la oscilación de los precios no está clara, el precio de parada o de parada puede ser activado con frecuencia. Se puede relajar la amplitud de parada de parada de manera adecuada o apagar la función.

Recomendaciones para la optimización

  1. En combinación con otros indicadores, se filtra el momento de entrada. Por ejemplo, el indicador ROC se utiliza solo cuando el precio cae por debajo de la línea media.
  2. Optimización de la lógica de la subida de posiciones, que se inicia solo si se cumplen ciertas condiciones. Por ejemplo, solo se continúa la subida de posiciones si el precio vuelve a caer por encima de un cierto margen.
  3. La configuración de los parámetros de las diferentes variedades puede ser muy diferente, y se requiere una adecuada retroalimentación y simulación del disco duro para obtener la mejor combinación de parámetros.
  4. Se puede configurar un Stop Loss Adaptable, que establece un Stop Loss diferente según la volatilidad del mercado.

Resumir

La estrategia utiliza el indicador ROC para determinar los puntos de venta y venta, limitar las señales de filtración de la línea, prevenir el riesgo de pérdidas de parada, y ampliar las ganancias mediante el aumento de la posición. Si los parámetros se establecen de manera razonable, se puede obtener un beneficio adicional al tiempo que se garantiza el riesgo en un rango controlable. En el futuro, se puede optimizar aún más el filtro de señales y el mecanismo de control de ventas, para que la estrategia se adapte a más entornos de mercado.

Código Fuente de la Estrategia
/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 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/
// @version=4
// © A3Sh

// Rate of price change / Price averaging strategy //
// When the price drops to a specified percentage, a Long Entry Threshold is setup.
// The Long Entry Threshold is only active for a specified number of bars and will de-activate when not crossed. 
// When the price drops further and crosses the Entry Threshold with a minimum of a specified percentage, a Long Position is entered. 
// The same reverse logic used to close the Long Position.
// Stop loss and take profit are active by default. With proper tweaking of the settings it is possible to de-activate SL and TP.

// The strategy is inspired by the following strategies:
// Price Change Scalping Strategy developed by Prosum Solutions, https://www.tradingview.com/script/ue7Uc3sN-Price-Change-Scalping-Strategy-v1-0-0/
// Scalping Dips On Trend Strategy developed by Coinrule, https://www.tradingview.com/script/iHHO0PJA-Scalping-Dips-On-Trend-by-Coinrule/

strategy(title = "ROC_PA_Strategy_@A3Sh", overlay = true )

// Portfolio & Leverage Example
// credit: @RafaelZioni, https://www.tradingview.com/script/xGk5K4DE-BTC-15-min/
ge(value, precision) => round(value * (pow(10, precision))) / pow(10, precision)

port     = input(25, group = "Risk", title = "Portfolio Percentage", type = input.float, step = 0.1, minval = 0.1, maxval = 200)
leverage = input(1,  group = "Risk", title = "Leverage", minval = 1, maxval = 100)
mm       = input(5,  group = "Risk", title = "Broker Maintenance Margin Percentage", type = input.float, step = 0.1, minval = 0.1, maxval = 200)

c = ge((strategy.equity * leverage / open) * (port  / 100), 4)

// Take Profit
tpa = input(true, type = input.bool,  title = "Take Profit", group = "Risk", inline = "Take Profit")
tpp = input(5.6,    type = input.float, title = "Percentage" , group = "Risk", step = 0.1, minval = 0.1, inline = "Take Profit")
tp  = strategy.position_avg_price + (strategy.position_avg_price / 100 * tpp)
plot (tpa and strategy.position_size > 0 ? tp : na, color = color.gray, title = "take profit", style= plot.style_linebr, linewidth = 1)

// Stop Loss
sla = input(true, type = input.bool, title = "Stop Lossss ", group = "Risk", inline = "Stop Loss")
slp = input(2.5,   type = input.float, title = "Percentage",   group = "Risk", step = 0.1, minval = 0.1, inline = "Stop Loss")
sl  = strategy.position_avg_price - (strategy.position_avg_price / 100 *slp)
plot (sla and strategy.position_size > 0 ? sl : na, color = color.red, title = "stopp loss", style= plot.style_linebr, linewidth = 1)

stopLoss = sla ? sl : na

// Long position entry layers. Percentage from the entry price of the the first long
ps2 = input(2, group = "Price Averaging Layers", title = "2nd Layer Long Entry %", step = 0.1)
ps3 = input(5, group = "Price Averaging Layers", title = "3rd Layer Long Entry %", step = 0.1)
ps4 = input(9, group = "Price Averaging Layers", title = "4th Layer Long Entry %", step = 0.1)

// ROC_Trigger Logic to open Long Position
rocLookBack  = input(3,   group = "ROC Logic to OPEN Long Entry", title="Rate of Change bar lookback")
rocThreshold = input(0.5, group = "ROC Logic to OPEN Long Entry", title="ROC Threshold % to Setup Long Entry", step = 0.1)
entryLimit   = input(0.5, group = "ROC Logic to OPEN Long Entry", title="Price Drop Threshold % to OPEN Long Entry", step = 0.1)
entryTime    = input(3,   group = "ROC Logic to OPEN Long Entry", title="Duration of Long Entry Threshold Line in bars")
minLimit     = input(0.8, group = "ROC Logic to OPEN Long Entry", title="Min % of Price Drop to OPEN Long Entry", step = 0.1)

//ROC calculation based to the price level of previous X bars
roc = close[rocLookBack]  - (close / 100 * rocThreshold)
plot (roc, color = color.gray, title = "roc threshold", linewidth = 1 , transp = 20)

rocT1      = open > roc and close < roc ? 1 : 0 // When the price CROSSES the Entry Limit
rocT2      = (open < roc) and (close < roc) ? 1 : 0 // When the price is BELOW the Entry Limit
rocTrigger = rocT1 or rocT2

// Condition for Setting Up a Long Entry Thershold Line
rocCrossed    = false
var SetUpLong = false

if rocTrigger and not SetUpLong

    rocCrossed := true
    SetUpLong  := true

// Defining the Value of the Long Entry Thershold
condforValue = rocCrossed and (open - low) / (open / 100) > 0 or (open < roc and close < roc) ? low - (close / 100 * entryLimit) : roc - (close / 100 * entryLimit)
openValue    = valuewhen (rocCrossed, condforValue, 0)

// Defining the length of the Long Entry Thershold in bars, specified with an input parameter
sincerocCrossed = barssince (rocCrossed)
plotLineOpen    = (sincerocCrossed <= entryTime) ? openValue : na
endLineOpen     = sincerocCrossed == entryTime  ? 1 : 0

// Set the conditions back to false when the Entry Limit Threshold Line ends after specied number of bars
if endLineOpen and SetUpLong
    
    rocCrossed := false
    SetUpLong  := false    

// Set minimum percentage of price drop to open a Long Position.
minThres = (open - close) / (open / 100) > minLimit ? 1 : 0

// Open Long Trigger
openLong = crossunder (close, plotLineOpen) and strategy.position_size == 0 and minThres

plot (strategy.position_size == 0 ? plotLineOpen : na, title = "Long Entry Threshold", color= color.yellow, style= plot.style_linebr, linewidth = 2)

// Show vertical dashed line when long condition is triggered 
// credit: @midtownsk8rguy, https://www.tradingview.com/script/EmTkvfCM-vline-Function-for-Pine-Script-v4-0/
vline(BarIndex, Color, LineStyle, LineWidth) => 
    return = line.new(BarIndex, low - tr, BarIndex, high + tr, xloc.bar_index, extend.both, Color, LineStyle, LineWidth) 
// if (openLong)
//     vline(bar_index, color.blue, line.style_dashed, 1)

// ROC_Trigger Logic to close Long Position
rocLookBackL    = input(3,   group = "ROC Logic to CLOSE Long Entry", title = "Rate of Change bar lookback")
entryThresholdL = input(0.8, group = "ROC Logic to CLOSE Long Entry", title = "ROC Threshold % to Setup Close Threshold", step = 0.1) // Percentage from close price
entryLimit_CL   = input(1.7, group = "ROC Logic to CLOSE Long Entry", title = "Price Rise Threshold % to CLOSE Long Entry", step = 0.1) // Percentage from roc threshold
entryTime_CL    = input(3,   group = "ROC Logic to CLOSE Long Entry", title = "Duration of Entry Limit in bars")

roc_CL = close[rocLookBackL]  + (close/100 *entryThresholdL)
//plot(rocL, color=color.gray, linewidth=1, transp=20)

rocT1_CL = open < roc_CL and close > roc_CL ? 1 : 0
rocT2_CL = (open > roc_CL) and (close > roc_CL)  ? 1 : 0 
rocTrigger_CL = rocT1_CL or rocT2_CL

// Condition for Setting Up a Long CLOSE Thershold Line
rocCrossed_CL  = false

var SetUpClose = false

if rocTrigger_CL and not SetUpClose
    // The trigger for condA occurs and the last condition set was condB.
    rocCrossed_CL := true
    SetUpClose    := true

// Defining the Value of the Long CLOSE Thershold
condforValue_CL= rocCrossed_CL and (high - open) / (open / 100) > 0 or (open > roc_CL and close > roc_CL) ? high + (close / 100 * entryLimit_CL) : roc_CL + (close / 100 * entryLimit_CL)
closeValue = valuewhen (rocCrossed_CL, condforValue_CL, 0)

// Defining the length of the Long CLOSE Thershold in bars, specified with an input parameter
sincerocCrossed_CL = barssince(rocCrossed_CL)
plotLineClose = (sincerocCrossed_CL <= entryTime_CL) ? closeValue : na
endLineClose = (sincerocCrossed_CL == entryTime_CL)  ? 1 : 0

// Set the conditions back to false when the CLOSE Limit Threshold Line ends after specied number of bars
if endLineClose and SetUpClose

    rocCrossed_CL := false
    SetUpClose := false    

plot(strategy.position_size > 0 ? plotLineClose : na, color = color.white, title = "Close Long Threshold", style = plot.style_linebr, linewidth = 2)

// ROC Close + Take Profit combined
closeCondition = close < tp ? plotLineClose : tpa ? tp : plotLineClose

// Store values to create and plot the different PA layers
long1 = valuewhen(openLong, close, 0)
long2 = valuewhen(openLong, close - (close / 100 * ps2), 0)
long3 = valuewhen(openLong, close - (close / 100 * ps3), 0)
long4 = valuewhen(openLong, close - (close / 100 * ps4), 0)

eps1 = 0.00
eps1 := na(eps1[1]) ? na : eps1[1]

eps2 = 0.00
eps2 := na(eps2[1]) ? na : eps2[1]

eps3 = 0.00
eps3 := na(eps3[1]) ? na : eps3[1]

eps4 = 0.00
eps4 := na(eps4[1]) ? na : eps4[1]

plot (strategy.position_size > 0 ? eps1 : na, title = "Long 1 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps2 : na, title = "Long 2 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps3 : na, title = "Long 3 Layer", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps4 : na, title = "Long 4 Layer", style = plot.style_linebr)

// Ener Long Positions
if (openLong and strategy.opentrades == 0) 
    eps1 := long1
    eps2 := long2
    eps3 := long3
    eps4 := long4
    strategy.entry("Long1", strategy.long, c, comment = "a=binance2 e=binance s=bnbusdt b=buy q=20% t=market")

if (strategy.opentrades == 1)
    strategy.entry("Long2", strategy.long, c, limit = eps2, comment = "a=binance2 e=binance s=bnbusdt b=buy q=25% t=market")

if (strategy.opentrades == 2)
    strategy.entry("Long3", strategy.long, c, limit = eps3, comment = "a=binance2 e=binance s=bnbusdt b=buy q=33.3% t=market")

if (strategy.opentrades == 3)
    strategy.entry("Long4", strategy.long, c, limit = eps4, comment = "a=binance2 e=binance s=bnbusdt b=buy q=50% t=market")

// Setup Limit Close / Take Profit / Stop Loss order 
strategy.exit("Exit", stop = stopLoss, limit = closeCondition, when =(rocTrigger_CL and strategy.position_size > 0), comment= "a=binance2 e=binance s=bnbusdt b=sell q=100% t=market")

// Make sure that all open limit orders are canceled after exiting all the positions 
longClose = strategy.position_size[1] > 0 and strategy.position_size == 0 ? 1 : 0   

if longClose
    strategy.cancel_all()