
Un sistema de comercio cuantificado de identificación de la estructura de precios en múltiples niveles y brecha de valor justo es una estrategia de comercio automatizado basada en el comportamiento de los precios, que combina dos conceptos clave de comercio: características de cambio (CHoCH, Change of Character) y brecha de valor justo (FVG, Fair Value Gap). La estrategia capta oportunidades de comercio de alta probabilidad mediante la identificación de puntos de cambio en la estructura del mercado y áreas de desequilibrio, para entrar y tener un control preciso de entrada y salida cuando los precios retroceden a la brecha de valor justo. Este método sistemático permite a los comerciantes analizar objetivamente el mercado, eliminar los factores emocionales y tener reglas claras de gestión de riesgos.
El sistema de transacciones cuantitativas se basa en los siguientes principios centrales:
Identificación de las estructuras de preciosLa tecnología de Pivot Points identifica los altos y bajos de los movimientos en el mercado, que son componentes clave de la estructura del mercado. El sistema utiliza la longitud de oscilación parametrizada (con 5 ciclos por defecto) para determinar estos puntos clave.
Detección de características de cambio:
Identificación de la brecha en el valor justo:
Logía de entrada:
Mecanismo de gestión de riesgos:
Después de un análisis en profundidad del código, la estrategia tiene las siguientes ventajas:
Análisis estructurado del mercadoLa estrategia se basa en el principio de los cambios en la estructura de precios y los desequilibrios del mercado, en lugar de una simple cruce de indicadores, lo que le da una ventaja única en la identificación de los puntos de inflexión del mercado.
La hora exacta de ingresoLa estrategia es la siguiente: Al esperar a que se forme un FVG después de CHoCH, la estrategia permite ingresar a un nivel de precio favorable, evitar perseguir a los altos y bajos, y mejorar la calidad de la entrada.
La adaptación a la gestión de riesgosLa estrategia consiste en ajustar automáticamente la posición de stop loss en función de la estructura real del mercado, en lugar de usar un número fijo de puntos. Esta estrategia es más adecuada a las características reales de fluctuación del mercado.
Elementos de las transacciones visuales: La estrategia ofrece una completa visualización, incluyendo etiquetas CHoCH, cajas FVG, puntos de oscilación y líneas de negociación, que permiten a los comerciantes entender de forma intuitiva la estructura del mercado y la lógica de la estrategia.
Gestión de posiciones flexible: El tamaño de la posición se ajusta automáticamente a través del porcentaje de riesgo, tanto para proteger los fondos de la cuenta como para ajustar automáticamente el umbral de riesgo en función de la volatilidad.
Diseño de optimización de rendimiento: El código incluye un mecanismo para limpiar las cajas viejas de FVG, asegurando que el rendimiento del sistema no se deteriore durante largos periodos de funcionamiento.
Monitoreo integrado del desempeñoLa estrategia proporciona tablas de rendimiento en tiempo real, incluyendo indicadores clave como el estado de la estrategia, la ganancia y los factores de ganancia, para que los operadores puedan evaluar el rendimiento de la estrategia.
A pesar de la buena concepción de la estrategia, existen algunos riesgos y limitaciones potenciales:
Riesgo de una falsa brecha:La señal CHoCH puede ser una falsa ruptura, lo que lleva a que el precio retroceda rápidamente y desencadene un stop loss. Para mitigar este riesgo, se puede considerar la adición de mecanismos de confirmación, como esperar a que la línea K de Dogan confirme la ruptura.
Riesgo de la brechaEn mercados con mucha volatilidad o en operaciones nocturnas, los precios pueden saltar por encima de la posición de parada, lo que lleva a pérdidas reales superiores a las esperadas. Se recomienda el uso de órdenes de parada garantizada (si es posible) o reducir el tamaño de la posición.
Sensibilidad de los parámetrosEl rendimiento de la estrategia depende en gran medida de la configuración de parámetros como la longitud de oscilación, la distancia mínima de CHoCH y el tamaño de FVG. Diferentes mercados y marcos de tiempo pueden requerir diferentes combinaciones de parámetros, por lo que se recomienda una optimización de retroalimentación completa.
Dependencia del entorno de mercado: Esta estrategia funciona mejor en mercados de tendencia, y puede generar frecuentes señales erróneas en mercados de balance. Considere agregar filtros de tendencia o mecanismos de identificación de estado de mercado.
Complejidad computacional: La estrategia utiliza varios arrays y comprobaciones condicionales, lo que puede causar problemas de rendimiento en dispositivos de baja configuración. Aunque el código incluye un mecanismo de limpieza, el funcionamiento a largo plazo debe tener en cuenta el consumo de recursos.
La falta de gestión de las retiradas: La estrategia actual no tiene en cuenta el ajuste dinámico del tamaño de la posición en diferentes condiciones de mercado, lo que puede conducir a un retiro mayor en un entorno persistentemente desfavorable. Se recomienda implementar un límite de retiro de cuentas y un mecanismo de reducción gradual de la posición.
Basado en el análisis del código, se proponen las siguientes direcciones de optimización:
Confirmación del marco temporal múltiple: Introducción de análisis de la estructura del mercado en un marco de tiempo más alto, solo para negociar en la dirección de la tendencia principal. Por ejemplo, se puede agregar un filtro de tendencia de la línea del sol, solo para ejecutar operaciones en la dirección de la tendencia de la línea del sol.
Optimización de parámetros dinámicos: Implementación de un sistema de parámetros que se ajustan automáticamente en función de la volatilidad del mercado, por ejemplo, aumentando el tamaño mínimo de FVG y los requisitos de distancia CHoCH durante la alta volatilidad y reduciendo estos parámetros durante la baja volatilidad.
Optimización de ingreso:
Mejora de la gestión de riesgos:
Adaptación al estado del mercado:
Aprendizaje automáticoIntroducción de algoritmos de aprendizaje automático para analizar los patrones históricos de CHoCH y FVG para identificar las características de los patrones con mayor probabilidad de éxito y ajustar el peso de las decisiones de entrada de acuerdo a ello.
Filtrado por tiempo de transacción: Agregar filtros de tiempo de negociación, evitar periodos de alta volatilidad durante los anuncios de noticias importantes y los mercados de apertura/cierre, y centrarse en los momentos de negociación con mejor liquidez.
Identificación de estructuras de precios a varios niveles y brecha de valor justo Sistema de negociación cuantificado es una solución de negociación completa que combina la teoría avanzada del comportamiento de los precios. Protege el capital de negociación mediante la identificación de cambios en la estructura del mercado (CHoCH) y áreas de desequilibrio de precios (FVG), la entrada en el nivel de precios ideal y la adopción de un método sistemático de gestión de riesgos.
La mayor ventaja de esta estrategia reside en su método de análisis basado en la estructura real del mercado, en lugar de depender de indicadores atrasados, lo que le permite identificar los puntos de inflexión del mercado antes. Al mismo tiempo, las funciones de visualización y el sistema de monitoreo de rendimiento permiten a los comerciantes comprender intuitivamente la lógica de la estrategia y evaluar su eficacia.
Si bien existen riesgos como falsos brechas y sensibilidad de parámetros, la estabilidad y el rendimiento de la estrategia pueden mejorarse significativamente a través de la dirección de optimización propuesta, especialmente la confirmación de múltiples marcos de tiempo, el ajuste de parámetros dinámicos y la función de gestión de riesgos mejorada.
Esta estrategia ofrece un marco sólido para los inversores que desean operar de manera sistematizada, ya que absorbe la esencia de las operaciones tradicionales de comportamiento de precios y aprovecha las ventajas de la objetividad y la disciplina de los sistemas cuantitativos. A través de la optimización continua de los parámetros y el ajuste de la adaptabilidad al mercado, la estrategia tiene el potencial de lograr un rendimiento comercial estable en una variedad de entornos de mercado.
/*backtest
start: 2024-06-03 00:00:00
end: 2025-06-02 00:00:00
period: 2h
basePeriod: 2h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy("ICT CHoCH & FVG Strategy - NQ1!", overlay=true, pyramiding=0, calc_on_every_tick=false, calc_on_order_fills=false, max_boxes_count=500, max_lines_count=100, max_labels_count=100)
// ============================================================================
// INPUT PARAMETERS
// ============================================================================
// Strategy Settings
riskRewardRatio = input.float(2.0, title="Risk:Reward Ratio", minval=0.5, maxval=10.0, group="Strategy Settings")
fixedTarget = input.int(40, title="Fixed Target (Ticks)", minval=5, maxval=200, group="Strategy Settings")
useRRTarget = input.bool(true, title="Use Risk:Reward Target", tooltip="If false, uses fixed target", group="Strategy Settings")
riskPercent = input.float(2.0, title="Risk % of Account", minval=0.1, maxval=10.0, group="Strategy Settings")
useAutoSize = input.bool(false, title="Auto Size Positions", tooltip="Size based on risk % and stop distance", group="Strategy Settings")
// Visual Settings
showCHoCH = input.bool(true, title="Show CHoCH Labels", group="Visual Settings")
showFVG = input.bool(true, title="Show FVG Boxes", group="Visual Settings")
showSwings = input.bool(true, title="Show Swing Points", group="Visual Settings")
showTradeLines = input.bool(true, title="Show Entry/SL/TP Lines", group="Visual Settings")
// CHoCH Detection Settings
swingLength = input.int(5, title="Swing Detection Length", minval=2, maxval=20, group="CHoCH Settings")
minCHoCHDistance = input.int(10, title="Min CHoCH Distance (bars)", minval=5, maxval=50, group="CHoCH Settings")
// FVG Settings
minFVGSize = input.float(2.0, title="Min FVG Size (ticks)", minval=0.25, maxval=10.0, group="FVG Settings")
maxFVGAge = input.int(50, title="Max FVG Age (bars)", minval=10, maxval=200, group="FVG Settings")
// ============================================================================
// VARIABLES AND ARRAYS
// ============================================================================
// Swing point detection
var float lastSwingHigh = na
var float lastSwingLow = na
var int lastSwingHighBar = na
var int lastSwingLowBar = na
// CHoCH tracking
var bool bullishCHoCH = false
var bool bearishCHoCH = false
var float chochLevel = na
var int chochBar = na
var bool waitingForFVG = false
// FVG tracking
var array<box> bullishFVGs = array.new<box>()
var array<box> bearishFVGs = array.new<box>()
var float activeFVGTop = na
var float activeFVGBottom = na
var bool lookingForEntry = false
// Trade management
var float stopLossLevel = na
var float takeProfitLevel = na
var bool inPosition = false
// ============================================================================
// HELPER FUNCTIONS
// ============================================================================
// Convert ticks to price for NQ
ticksToPrice(ticks) => ticks * 0.25
// Calculate position size based on risk
calcPositionSize(stopDistance) =>
if useAutoSize and strategy.equity > 0
accountValue = strategy.equity
riskAmount = accountValue * (riskPercent / 100)
stopDistancePrice = stopDistance * syminfo.mintick
math.max(1, math.floor(riskAmount / stopDistancePrice))
else
1
// ============================================================================
// SWING POINT DETECTION
// ============================================================================
// Detect swing highs and lows
swingHigh = ta.pivothigh(high, swingLength, swingLength)
swingLow = ta.pivotlow(low, swingLength, swingLength)
// Update swing points
if not na(swingHigh)
lastSwingHigh := swingHigh
lastSwingHighBar := bar_index - swingLength
if showSwings
label.new(bar_index - swingLength, swingHigh, "SH", style=label.style_triangledown, color=color.red, size=size.tiny)
if not na(swingLow)
lastSwingLow := swingLow
lastSwingLowBar := bar_index - swingLength
if showSwings
label.new(bar_index - swingLength, swingLow, "SL", style=label.style_triangleup, color=color.green, size=size.tiny)
// ============================================================================
// CHoCH DETECTION
// ============================================================================
// Check for bullish CHoCH (break above prior swing high after making lower low)
bullishCHoCHCondition = not na(lastSwingHigh) and not na(lastSwingLow) and
high > lastSwingHigh and
lastSwingLow < lastSwingHigh and
bar_index - lastSwingHighBar > minCHoCHDistance and
strategy.position_size == 0
// Check for bearish CHoCH (break below prior swing low after making higher high)
bearishCHoCHCondition = not na(lastSwingHigh) and not na(lastSwingLow) and
low < lastSwingLow and
lastSwingHigh > lastSwingLow and
bar_index - lastSwingLowBar > minCHoCHDistance and
strategy.position_size == 0
// Process CHoCH signals
if bullishCHoCHCondition and not bullishCHoCH
bullishCHoCH := true
bearishCHoCH := false
chochLevel := lastSwingHigh
chochBar := bar_index
waitingForFVG := true
lookingForEntry := false
if bearishCHoCHCondition and not bearishCHoCH
bearishCHoCH := true
bullishCHoCH := false
chochLevel := lastSwingLow
chochBar := bar_index
waitingForFVG := true
lookingForEntry := false
// ============================================================================
// FVG DETECTION
// ============================================================================
// Check for FVG formation (3-candle pattern)
if bar_index >= 2
// Bullish FVG: low[0] > high[2]
bullishFVG = low[0] > high[2] and (low[0] - high[2]) >= ticksToPrice(minFVGSize)
// Bearish FVG: high[0] < low[2]
bearishFVG = high[0] < low[2] and (low[2] - high[0]) >= ticksToPrice(minFVGSize)
// Process bullish FVG after bullish CHoCH
if bullishFVG and bullishCHoCH and waitingForFVG and bar_index > chochBar
fvgTop = low[0]
fvgBottom = high[2]
// Set active FVG for entry
activeFVGTop := fvgTop
activeFVGBottom := fvgBottom
waitingForFVG := false
lookingForEntry := true
// Process bearish FVG after bearish CHoCH
if bearishFVG and bearishCHoCH and waitingForFVG and bar_index > chochBar
fvgTop = low[2]
fvgBottom = high[0]
// Set active FVG for entry
activeFVGTop := fvgTop
activeFVGBottom := fvgBottom
waitingForFVG := false
lookingForEntry := true
// ============================================================================
// ENTRY LOGIC
// ============================================================================
// Long entry: price touches bullish FVG after bullish CHoCH
longCondition = lookingForEntry and bullishCHoCH and
not na(activeFVGTop) and not na(activeFVGBottom) and
low <= activeFVGTop and high >= activeFVGBottom and
strategy.position_size == 0
// Short entry: price touches bearish FVG after bearish CHoCH
shortCondition = lookingForEntry and bearishCHoCH and not na(activeFVGTop) and not na(activeFVGBottom) and low <= activeFVGTop and high >= activeFVGBottom and strategy.position_size == 0
// Process long entries
if longCondition
var float entryPrice = na
var float stopLoss = na
var float takeProfit = na
entryPrice := math.avg(activeFVGTop, activeFVGBottom)
stopLoss := lastSwingLow
stopDistance = entryPrice - stopLoss
if useRRTarget
takeProfit := entryPrice + (stopDistance * riskRewardRatio)
else
takeProfit := entryPrice + ticksToPrice(fixedTarget)
// Calculate position size
qty = calcPositionSize(stopDistance / syminfo.mintick)
// Enter trade
strategy.entry("Long", strategy.long, qty=qty)
strategy.exit("Long Exit", "Long", stop=stopLoss, limit=takeProfit)
// Update tracking
stopLossLevel := stopLoss
takeProfitLevel := takeProfit
inPosition := true
lookingForEntry := false
// Reset CHoCH state
bullishCHoCH := false
activeFVGTop := na
activeFVGBottom := na
// Process short entries
if shortCondition
var float entryPrice = na
var float stopLoss = na
var float takeProfit = na
entryPrice := math.avg(activeFVGTop, activeFVGBottom)
stopLoss := lastSwingHigh
stopDistance = stopLoss - entryPrice
if useRRTarget
takeProfit := entryPrice - (stopDistance * riskRewardRatio)
else
takeProfit := entryPrice - ticksToPrice(fixedTarget)
// Calculate position size
qty = calcPositionSize(stopDistance / syminfo.mintick)
// Enter trade
strategy.entry("Short", strategy.short, qty=qty)
strategy.exit("Short Exit", "Short", stop=stopLoss, limit=takeProfit)
// Update tracking
stopLossLevel := stopLoss
takeProfitLevel := takeProfit
inPosition := true
lookingForEntry := false
// Reset CHoCH state
bearishCHoCH := false
activeFVGTop := na
activeFVGBottom := na
// ============================================================================
// POSITION MANAGEMENT
// ============================================================================
// Reset position state when trade is closed
if inPosition and strategy.position_size == 0
inPosition := false
stopLossLevel := na
takeProfitLevel := na
// ============================================================================
// VISUAL SIGNALS
// ============================================================================
// Plot entry signals
plotshape(longCondition, title="Long Entry", location=location.belowbar, color=color.green,
style=shape.triangleup, size=size.normal)
plotshape(shortCondition, title="Short Entry", location=location.abovebar, color=color.red,
style=shape.triangledown, size=size.normal)
// Plot active stop loss and take profit levels
plot(inPosition ? stopLossLevel : na, title="Stop Loss", color=color.red, linewidth=2, style=plot.style_linebr)
plot(inPosition ? takeProfitLevel : na, title="Take Profit", color=color.green, linewidth=2, style=plot.style_linebr)
// ============================================================================
// CLEANUP
// ============================================================================
// Clean up old FVG boxes (helps with performance)
if bar_index % 100 == 0
while array.size(bullishFVGs) > 20
box.delete(array.shift(bullishFVGs))
while array.size(bearishFVGs) > 20
box.delete(array.shift(bearishFVGs))
// ============================================================================
// ALERTS
// ============================================================================
// Alert conditions
alertcondition(longCondition, title="Long Entry Signal", message="ICT Strategy: Long entry at FVG - SL: {{strategy.position_avg_price}}")
alertcondition(shortCondition, title="Short Entry Signal", message="ICT Strategy: Short entry at FVG - SL: {{strategy.position_avg_price}}")