La estrategia de reversión de rango latente utiliza períodos de disminución de la volatilidad como señales de entrada y tiene como objetivo obtener ganancias cuando la volatilidad vuelve a aumentar.
La estrategia primero identifica un rango inactivo, que es cuando el precio está contenido dentro del rango de precios del día de negociación anterior. Esto indica que la volatilidad ha disminuido en comparación con hace unos días.
Una vez que se identifica un rango latente, la estrategia coloca dos órdenes pendientes: una parada de compra cerca de la parte superior del rango y una parada de venta cerca de la parte inferior del rango. Luego espera que el precio rompa el rango hacia arriba o hacia abajo. Si el precio se rompe hacia arriba, la orden de compra se activa para ir largo. Si el precio se rompe hacia abajo, la orden de venta se activa para ir corto.
Después de la entrada, se colocan órdenes de stop loss y take profit. El stop loss controla el riesgo a la baja y el take profit cierra la operación para obtener ganancias. El stop loss se coloca a una distancia del precio de entrada según lo definido en los parámetros de riesgo. El take profit se coloca a una distancia igual al tamaño del rango latente ya que esperamos que el precio se mueva de manera similar a la volatilidad anterior.
Por último, un modelo de tamaño de posición fraccionario fijo gestiona el tamaño de la operación. Aumenta el tamaño de las ganancias y reduce el tamaño de las pérdidas para mejorar los rendimientos ajustados al riesgo.
Las ventajas de esta estrategia son:
Captura la tendencia próxima utilizando como señal la volatilidad disminuida.
Las órdenes bidireccionales atrapan la tendencia alcista o bajista.
Las operaciones de stop loss y take profit controlan el riesgo de una sola operación.
El tamaño fraccionado fijo mejora la eficiencia del capital.
Una lógica sencilla, fácil de implementar.
Los riesgos a tener en cuenta son:
Dirección de escape incorrecta si el alcance de escape no está claro.
La ruptura puede ser sólo una inversión corta, no una tendencia duradera.
El riesgo de ser eliminado por movimientos enormes.
El tamaño de la fracción fija puede amplificar las pérdidas cuando se añade a las operaciones perdedoras.
Desempeño deficiente si los parámetros no se establecen correctamente.
Algunas formas de mejorar la estrategia:
Agregue filtros como divergencia para evitar falsos brotes.
Mejorar el stop loss con pérdidas de seguimiento o de orden.
Añadir un filtro de tendencia para evitar entradas contra tendencia.
Optimizar las relaciones de fracción fija para un equilibrio riesgo/recompensa.
Mira varios marcos de tiempo para mejorar la ventaja.
Utilice el aprendizaje automático para la optimización automática de parámetros.
La estrategia de inversión de rango latente tiene una lógica clara y potencial de ganancia. El ajuste fino a través de optimizaciones, gestión de riesgos y filtrado de señales puede mejorar aún más la consistencia. Pero todas las estrategias de inversión media conllevan riesgos inherentes y el tamaño de la posición debe controlarse.
/*backtest start: 2023-09-29 00:00:00 end: 2023-10-29 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/ // © gsanson66 //This code is based on the Narrow Range strategy //Interactive Broker fees are applied on this strategy //@version=5 strategy("NARROW RANGE BACKTESTING", shorttitle="NR BACKTESTING", overlay=true, initial_capital=1000, default_qty_type=strategy.fixed, commission_type=strategy.commission.percent, commission_value=0.18) //--------------------------------FUNCTIONS------------------------------------// //@function to print label debugLabel(txt, color) => label.new(bar_index, high, text = txt, color=color, style = label.style_label_lower_right, textcolor = color.black, size = size.small) //@function which looks if the close date of the current bar falls inside the date range inBacktestPeriod(start, end) => (time >= start) and (time <= end) //--------------------------------USER INPUTS------------------------------------// //Narrow Range Length nrLength = input.int(4, minval=2, title="Narrow Range Length", group="Strategy parameters") //Risk Management stopLossInput = input.float(0.5, title="Stop Loss (in percentage of reference range)", group="Strategy parameters") //Money Management fixedRatio = input.int(defval=400, minval=1, title="Fixed Ratio Value ($)", group="Money Management") increasingOrderAmount = input.int(defval=200, minval=1, title="Increasing Order Amount ($)", group="Money Management") //Backtesting period startDate = input(title="Start Date", defval=timestamp("1 Janv 2020 00:00:00"), group="Backtesting Period") endDate = input(title="End Date", defval=timestamp("1 July 2024 00:00:00"), group="Backtesting Period") //--------------------------------VARIABLES INITIALISATION--------------------------// strategy.initial_capital = 50000 bool nr = na var bool long = na var bool short = na var float stopPriceLong = na var float stopLossLong = na var float takeProfitLong = na var float stopPriceShort = na var float stopLossShort = na var float takeProfitShort = na var float takeProfit = na var float stopLoss = na bool inRange = na int closedtrades = strategy.closedtrades equity = math.abs(strategy.equity - strategy.openprofit) var float capital_ref = strategy.initial_capital var float cashOrder = strategy.initial_capital * 0.95 //------------------------------CHECKING SOME CONDITIONS ON EACH SCRIPT EXECUTION-------------------------------// //Checking if the date belong to the range inRange := true //Checking performances of the strategy if equity > capital_ref + fixedRatio spread = (equity - capital_ref)/fixedRatio nb_level = int(spread) increasingOrder = nb_level * increasingOrderAmount cashOrder := cashOrder + increasingOrder capital_ref := capital_ref + nb_level*fixedRatio if equity < capital_ref - fixedRatio spread = (capital_ref - equity)/fixedRatio nb_level = int(spread) decreasingOrder = nb_level * increasingOrderAmount cashOrder := cashOrder - decreasingOrder capital_ref := capital_ref - nb_level*fixedRatio //We check if a trade has been closed to cancel all previous orders if closedtrades > closedtrades[1] strategy.cancel("Long") strategy.cancel("Short") stopPriceLong := na stopPriceShort := na //Checking if we close all trades in case where we exit the backtesting period if strategy.position_size!=0 and not inRange debugLabel("END OF BACKTESTING PERIOD : we close the trade", color=color.rgb(116, 116, 116)) strategy.close_all() long := na short := na stopPriceLong := na stopLossLong := na takeProfitLong := na stopPriceShort := na stopLossShort := na takeProfitShort := na takeProfit := na stopLoss := na //----------------------------------FINDING NARROW RANGE DAY------------------------------------------// // We find the Narrow Range Day if low > low[nrLength] and high < high[nrLength] nr := true //------------------------------------STOP ORDERS--------------------------------------------// // We handle plotting of stop orders and cancellation of other side order if one order is triggered if strategy.position_size > 0 and not na(stopPriceLong) and not na(stopPriceShort) long := true strategy.cancel("Short") stopPriceLong := na stopPriceShort := na takeProfit := takeProfitLong stopLoss := stopLossLong if strategy.position_size < 0 and not na(stopPriceLong) and not na(stopPriceShort) short := true strategy.cancel("Long") stopPriceLong := na stopPriceShort := na takeProfit := takeProfitShort stopLoss := stopLossShort //------------------------------------STOP LOSS & TAKE PROFIT--------------------------------// // If an order is triggered we plot TP and SL if not na(takeProfit) and not na(stopLoss) and long if high >= takeProfit and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na long := na if low <= stopLoss and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na long := na if not na(takeProfit) and not na(stopLoss) and short if high >= stopLoss and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na short := na if low <= takeProfit and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na short := na //-----------------------------LONG/SHORT CONDITION-------------------------// // Conditions to create two stop orders (one for Long and one for Short) and SL & TP calculation if nr and inRange and strategy.position_size == 0 stopPriceLong := high[4] takeProfitLong := high[4] + (high[4] - low[4]) stopLossLong := high[4] - (high[4] - low[4])*stopLossInput qtyLong = cashOrder/stopPriceLong strategy.entry("Long", strategy.long, qtyLong, stop=stopPriceLong) strategy.exit("Exit Long", "Long", limit=takeProfitLong ,stop=stopLossLong) stopPriceShort := low[4] takeProfitShort := low[4] - (high[4] - low[4]) stopLossShort := low[4] + (high[4] - low[4])*stopLossInput qtyShort = cashOrder/stopPriceShort strategy.entry("Short", strategy.short, qtyShort, stop=stopPriceShort) strategy.exit("Exit Short", "Short", limit=takeProfitShort ,stop=stopLossShort) //--------------------------PLOTTING ELEMENT----------------------------// plotshape(nr, "NR", shape.arrowdown, location.abovebar, color.rgb(255, 132, 0), text= "NR4", size=size.huge) plot(stopPriceLong, "Stop Order", color.blue, 3, plot.style_linebr) plot(stopPriceShort, "Stop Order", color.blue, 3, plot.style_linebr) plot(takeProfit, "Take Profit", color.green, 3, plot.style_linebr) plot(stopLoss, "Stop Loss", color.red, 3, plot.style_linebr)