Tres observaciones sobre la función, de mayor a menor impacto:
1. Estás leyendo la vela en formación (CopyBuffer con inicio 0 y luego buffer[0]). El ADX y las EMAs de la vela 0 cambian con cada tick, así que la fase puede ser TRENDING en un tick y SIDEWAYS al siguiente sin que haya pasado nada. Para clasificar fase de mercado usa velas cerradas: copia desde el índice 1 (CopyBuffer(handle, 0, 1, 3, buffer)) y evalúa una vez por vela nueva, no en cada tick. Solo con eso la fase deja de parpadear.
2. Agrega histéresis. Aunque uses velas cerradas, un umbral duro (ADX 25) hace que el estado oscile cuando el valor ronda el borde. La solución estándar es exigir persistencia: no cambies de fase hasta que la nueva se confirme durante 2-3 velas seguidas, o usa umbrales distintos para entrar y salir (entras a TRENDING sobre 25 y no vuelves a SIDEWAYS hasta bajo 20 — la zona 20-25 que ya tienes definida sirve exactamente para eso).
3. Separa "sin datos" de "mercado dudoso". Hoy devuelves MARKET_UNCERTAIN tanto cuando CopyBuffer falla como cuando el ADX está plano en la zona de transición. Son cosas distintas: la primera es un estado técnico transitorio (reintenta el próximo tick y no toques nada), la segunda es información de mercado legítima (quédate fuera o baja el riesgo). Un valor aparte tipo MARKET_NO_DATA evita que un fallo de copia se interprete como señal.
Detalle menor: el adxRising que calculas en el primer bloque queda sin usar (lo vuelves a calcular más abajo); puedes copiar el buffer del ADX una sola vez y reutilizarlo.
Y para saber si la clasificación "funciona": píntala. Colorea el fondo del gráfico histórico por fase (rectángulos o un buffer de color) y en segundos ves si tus fases coinciden con lo que un ojo humano llamaría tendencia o rango, antes de conectarle dinero real.
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso
Estoy creando un EA para un amigo basado en tamaños de mecha y fase de mercado usando ADX, ATR y 3 EMA, pero ahora me gustaría escuchar ideas sobre cómo llevar esto al siguiente nivel.
ENUM_MARKET_PHASE AnalyzeMarketPhase() { // Return uncertain if no filters enabled if (!UseTrendFilter && !UseADXFilter && !UseVolatilityFilter) return MARKET_UNCERTAIN; double adxValue = 0 , atrValue = 0 ; double fastMA[], slowMA[], longMA[]; ArraySetAsSeries (fastMA, true ); ArraySetAsSeries (slowMA, true ); ArraySetAsSeries (longMA, true ); // Get ADX value if (UseADXFilter) { double adxBuffer[]; ArraySetAsSeries (adxBuffer, true ); if ( CopyBuffer (adx_Handle, 0 , 0 , 3 , adxBuffer) < 3 ) return MARKET_UNCERTAIN; // Now index 0 is truly the CURRENT bar adxValue = adxBuffer[ 0 ]; bool adxRising = adxBuffer[ 0 ] > adxBuffer[ 1 ] && adxBuffer[ 1 ] > adxBuffer[ 2 ]; } // Get ATR value if (UseVolatilityFilter) { double atrBuffer[]; ArraySetAsSeries (atrBuffer, true ); if ( CopyBuffer (atr_Handle, 0 , 0 , 3 , atrBuffer) < 3 ) return MARKET_UNCERTAIN; atrValue = atrBuffer[ 0 ] / pipValue; } // Get MA values if (UseTrendFilter) { if ( CopyBuffer (fastMA_Handle, 0 , 0 , 3 , fastMA) < 3 || CopyBuffer (slowMA_Handle, 0 , 0 , 3 , slowMA) < 3 || CopyBuffer (longMA_Handle, 0 , 0 , 3 , longMA) < 3 ) return MARKET_UNCERTAIN; } // Check for extreme volatility first if (UseVolatilityFilter && atrValue > ATR_MaxMultiplier * 50 ) return MARKET_HIGH_VOLATILITY; //DX logic with proper gap handling if (UseADXFilter) { // Strong trend: ADX > ADX_MinTrend (typically 25) if (adxValue > ADX_MinTrend) { return DetermineTrendDirection(fastMA, slowMA, longMA); } // Transition zone: Between ADX_MaxRange and ADX_MinTrend (20-25) else if (adxValue >= ADX_MaxRange && adxValue <= ADX_MinTrend) { // In transition zone - check if trend is developing or weakening double adxBuffer[]; if ( CopyBuffer (adx_Handle, 0 , 0 , 3 , adxBuffer) >= 3 ) { bool adxRising = adxBuffer[ 0 ] > adxBuffer[ 1 ] && adxBuffer[ 1 ] > adxBuffer[ 2 ]; bool adxFalling = adxBuffer[ 0 ] < adxBuffer[ 1 ] && adxBuffer[ 1 ] < adxBuffer[ 2 ]; if (adxRising) { // ADX rising in transition zone - potential trend developing return DetermineTrendDirection(fastMA, slowMA, longMA); } else if (adxFalling) { // ADX falling in transition zone - trend weakening return MARKET_SIDEWAYS; } else { // ADX flat in transition zone - uncertain return MARKET_UNCERTAIN; } } return MARKET_UNCERTAIN; } // Clear ranging: ADX < ADX_MaxRange (typically 20) else if (adxValue < ADX_MaxRange) { return MARKET_SIDEWAYS; } } else if (UseTrendFilter) { // If ADX filter disabled but trend filter enabled return DetermineTrendDirection(fastMA, slowMA, longMA); } return MARKET_UNCERTAIN; }