Radar de operaciones institucionales para TradingView

Radar de operaciones institucionales para TradingView

Manual de uso y guía de estudio.

Momentum + Estructura + VWAP + Liquidez + Confirmación + Riesgo
Diseñado para lectura intradía de XAUUSD y adaptación a otros mercados.
Principios ATC: Precisión > frecuencia , Evidencia > predicción , Proceso > resultado

1. ¿Qué es el ATC Radar Institucional?

Una herramienta de lectura, no una máquina de señales

El ATC Radar Institucional organiza varias capas de evidencia en un solo gráfico. Su objetivo es responder, en orden, seis preguntas: ¿qué dirección domina?, ¿qué está haciendo el momentum?, ¿dónde está el precio respecto al valor ponderado?, ¿dónde está la liquidez?, ¿la estructura confirma? y ¿el riesgo permite operar?

CapaHerramientaPregunta
Momentum tácticoSet A: EMA 9/21¿Qué está cambiando ahora?
Estructura intradíaSet B: EMA 50/100¿Cuál es la dirección dominante?
ValorVWAP¿Precio por encima o debajo del valor ponderado?
LiquidezAsia / Londres / NY H-L¿Dónde pueden estar los stops y objetivos?
EstructuraBOS / CHOCH-MSS¿El precio confirmó el cambio?
EjecuciónFVG / OB + RR + ATR¿Existe una entrada defendible?

Regla principal

Nunca convertir una sola señal en una operación. El valor del Radar aparece cuando varias evidencias independientes convergen.

2. Anatomía del gráfico

Lectura visual de la versión consolidada

En la captura se observan simultáneamente el precio, las cuatro EMAs, VWAP, cruces A/B, panel MTF, volumen y niveles de sesión. El objetivo no es mirar todo al mismo tiempo: se lee por capas.

  1. Primero: Set B 50/100 para establecer la estructura dominante.
    1. Segundo: Set A 9/21 para identificar aceleración, corrección o giro táctico.
    1. Tercero: VWAP para ubicar el precio respecto al valor ponderado de la sesión.
    1. Cuarto: máximos y mínimos de sesiones previas para localizar liquidez.
    1. Quinto: estructura, volumen y zonas FVG/OB para confirmar.

3. Set A — EMA 9/21 (los periodos pueden ser cambiados)

La capa rápida: momentum táctico

Las EMA 9 y 21 reaccionan relativamente rápido al precio. Por eso el Set A sirve para detectar cambios de momentum antes que el Set B.

SituaciónLectura sencillaUso
EMA 9 > EMA 21Momentum alcistaBuscar confirmaciones de compra, no comprar automáticamente.
EMA 9 < EMA 21Momentum bajistaBuscar confirmaciones de venta, no vender automáticamente.
Cruce ▲ Alcista ACambio táctico hacia arribaPuede ser inicio de impulso o solo corrección.
Cruce ▼ Bajista ACambio táctico hacia abajoPuede ser inicio de caída o solo retroceso.
A = rápido. Detecta antes, pero también produce más señales falsas.

Ejemplo fácil

Si Set B sigue alcista y aparece ▼ Bajista A, la lectura inicial no es ‘vender’. Es: el mercado alcista está corrigiendo. Esperamos ver si esa corrección rompe estructura o si encuentra soporte y retoma la tendencia.

4. Set B — EMA 50/100 (los periodos pueden ser cambiados)

La capa lenta: estructura intradía

Las EMA 50 y 100 filtran más ruido. Sus cruces son menos frecuentes y representan cambios más estructurales. En el gráfico se distinguen visualmente del Set A.

SituaciónInterpretación
EMA 50 > EMA 100Estructura intradía predominantemente alcista
EMA 50 < EMA 100Estructura intradía predominantemente bajista
▲ Alcista BConfirmación estructural alcista más lenta
▼ Bajista BConfirmación estructural bajista más lenta
B = contexto estructural. No necesariamente da la entrada; ayuda a decidir qué señales A merecen atención.

Ejemplo fácil

Set A puede cruzar varias veces mientras Set B conserva la misma dirección. Eso es normal: A describe oscilaciones tácticas dentro de una estructura más lenta.

5. Matriz A × B

La lectura más importante del indicador

Set A 9/21Set B 50/100Lectura ATCConducta
🟢 Alcista🟢 AlcistaImpulso alcista alineadoPriorizar largos con confirmación.
🔴 Bajista🔴 BajistaImpulso bajista alineadoPriorizar cortos con confirmación.
🟢 Alcista🔴 BajistaCorrección alcista en estructura bajistaCuidado con comprar tarde.
🔴 Bajista🟢 AlcistaCorrección bajista en estructura alcistaCuidado con vender tarde.
Alineación A+B aumenta coherencia; divergencia A/B describe transición o corrección.

Idea para principiantes

Imagine un automóvil: Set B indica la carretera por la que viaja; Set A indica si en este momento acelera o frena. Frenar en una carretera ascendente no significa necesariamente que el viaje cambió de dirección.

6. VWAP

El eje de valor ponderado por volumen

VWAP significa Volume Weighted Average Price. Resume el precio medio de la sesión ponderando por volumen. En el Radar se utiliza como referencia de valor y como filtro adicional.

Precio vs VWAPLectura
Precio sobre VWAPSesgo táctico favorable a compradores
Precio bajo VWAPSesgo táctico favorable a vendedores
Cruces repetidos de VWAPEquilibrio / rango / baja claridad
Rechazo claro en VWAPVWAP actuando como referencia dinámica
VWAP confirma contexto; no sustituye estructura.

Ejemplo

A y B están alcistas, pero el precio cae bajo VWAP. La tendencia puede seguir siendo alcista, pero la ejecución perdió calidad. Esperar recuperación y aceptación sobre VWAP suele ser más disciplinado que comprar inmediatamente.

7. Cruces A y B

El marcador representa el evento técnico.

Los marcadores se anclan al nivel aproximado donde las dos EMAs coinciden en la vela que confirma el cruce. Así el evento visual se relaciona con las medias, no con la altura de la vela.

MarcadorSignificado
▲ Alcista AEMA 9 cruza sobre EMA 21
▼ Bajista AEMA 9 cruza bajo EMA 21
▲ Alcista BEMA 50 cruza sobre EMA 100
▼ Bajista BEMA 50 cruza bajo EMA 100
▲ verde NO significa ‘BUY’. ▼ rojo NO significa ‘SELL’. Significa: ocurrió un cambio observable; ahora buscamos confirmación.

Nota sobre timeframe

El marcador queda anclado al evento EMA/EMA, pero las EMAs siguen dependiendo del timeframe. Un cruce M15 no equivale a un cruce H1. Siempre leer el timeframe activo y el panel MTF.

8. Panel MTF

D1 → H4 → H1 → M15 → Actual

MTF significa Multi-Timeframe. El panel resume la dirección de los Set A y B en varios marcos temporales y muestra una medida relativa de separación/fuerza.

TFFunción didáctica
D1Contexto mayor
H4Estructura swing
H1Sesgo intradía
M15Ejecución / transición
ActualLectura inmediata del gráfico

Cómo leer 3/4 TF

Si tres de cuatro marcos están bajistas, el sesgo MTF es bajista. No significa certeza; significa predominio de evidencia

No necesitamos unanimidad. Necesitamos saber dónde está el desacuerdo y qué timeframe lo está produciendo..

9. Liquidez de sesiones

Asia, Londres y Nueva York

El Radar conserva los máximos y mínimos de las últimas sesiones completas. Estos niveles funcionan como referencias de liquidez porque alrededor de máximos y mínimos visibles suelen concentrarse órdenes.

NivelLectura habitual
Asia HLiquidez compradora potencial sobre el máximo asiático
Asia LLiquidez vendedora potencial bajo el mínimo asiático
London HReferencia importante para expansión hacia NY
London LReferencia importante para barridos/rechazos
NY HLiquidez sobre el máximo de NY previo
NY LLiquidez bajo el mínimo de NY previo

BSL y SSL

BSL (Buy-Side Liquidity) suele referirse a liquidez por encima de máximos. SSL (Sell-Side Liquidity) suele referirse a liquidez por debajo de mínimos.

Un nivel de liquidez es un lugar para observar comportamiento, no una orden automática.

10. Sweep vs Breakout

Dos comportamientos que un principiante debe distinguir

ComportamientoQué ocurreLectura
Sweep / barridoEl precio perfora el nivel y vuelve a cerrar dentroPosible captura de liquidez y rechazo.
Breakout / rupturaEl precio rompe y logra aceptación fuera del nivelPosible continuación.

Ejemplo sencillo

London H está en 4,180. El precio sube a 4,182 pero cierra nuevamente en 4,178: eso se parece a un sweep. Si rompe 4,180, consolida arriba y vuelve a defenderlo, se parece más a aceptación/continuación.

La mecha por sí sola no basta. Observe cierre, estructura posterior, volumen y reacción en VWAP/FVG/OB.

11. Estructura: BOS, CHOCH y MSS

El precio debe demostrar, no solo insinuar

TérminoDefinición para principiantesPregunta
  BOSBreak of Structure: ruptura de una estructura previa en la dirección dominante.  ¿La tendencia continuó?
CHOCHChange of Character: cambio inicial en el comportamiento estructural.¿Algo empezó a cambiar?
  MSSMarket Structure Shift: desplazamiento que confirma un cambio estructural relevante.  ¿El cambio tiene suficiente evidencia?

En la práctica, la nomenclatura puede variar entre metodologías. En ATC interesa más la evidencia objetiva: qué máximo/mínimo fue roto, con qué desplazamiento y qué ocurrió después.

Cruce EMA + ruptura estructural es más informativo que cruce EMA aislado.

12. FVG y OB

Zonas de interés para la ejecución

TérminoExplicación sencillaUso
FVGFair Value Gap: desequilibrio dejado por un desplazamiento rápido.Zona donde el precio puede regresar a reequilibrar.
OBOrder Block: zona estructural asociada al origen de un desplazamiento.Área de reacción potencial; requiere contexto.

Secuencia útil

Liquidez barrida → desplazamiento → cambio estructural → regreso a FVG/OB → confirmación con A/B y VWAP. Esta secuencia es mucho más robusta que entrar solo porque apareció un triángulo.

FVG y OB son zonas, no garantías.

13. Volumen, ATR y RR

Tres filtros para evitar buenas ideas en malas condiciones

ConceptoQué mideUso ATC
VolumenParticipación negociadaAyuda a validar expansión o agotamiento.
ATRRango verdadero promedioIndica régimen de volatilidad; no dirección.
RRReward/RiskCompara recompensa potencial contra riesgo asumido.

Un setup puede tener buena dirección y mala ejecución. Si el stop necesario es demasiado amplio o el objetivo razonable no permite RR suficientes, se descarta.

Regla operativa ATC: RR objetivo ≥ 1.5 cuando la estructura permite definirlo de forma coherente.

Ejemplo

Si arriesgar 10 unidades permite aspirar razonablemente a 15 o más, RR ≥ 1.5. Si para evitar ruido el stop necesita 20 pero el siguiente objetivo está a 15, la operación pierde calidad aunque el sesgo sea correcto.

14. Secuencia operativa ATC

CONTEXTO → ESTRUCTURA → MOMENTUM → VWAP → LIQUIDEZ → CONFIRMACIÓN → RIESGO

  • CONTEXTO: leer D1/H4/H1 y Set B. Definir si el mercado está alcista, bajista o mixto.
  • ESTRUCTURA: identificar swings, BOS/CHOCH/MSS y rango operativo.
  • MOMENTUM: observar Set A y si acelera a favor o contra Set B.
  • VWAP: comprobar dónde opera el precio respecto al valor ponderado.
  • LIQUIDEZ: marcar Asia/Londres/NY H-L y otros EQH/EQL relevantes.
  • CONFIRMACIÓN: buscar desplazamiento, volumen, FVG/OB y reacción.
  • RIESGO: definir invalidación, stop, objetivo y RR antes de ejecutar.

Si una capa crítica contradice la hipótesis, no se fuerza la operación.

15. Checklist de 30 segundos

Antes de hacer clic

✓Pregunta
□¿Set B define una estructura clara?
□¿Set A está alineado o sé que estoy operando una corrección?
□¿El precio está del lado correcto del VWAP para mi hipótesis?
□¿Sé qué liquidez está buscando el precio?
□¿Hubo BOS / CHOCH / MSS o desplazamiento válido?
□¿Existe FVG/OB o zona técnica defendible para ejecución?
□¿Volumen/ATR permiten operar sin perseguir precio?
□¿Stop e invalidación son estructurales, no emocionales?
□¿RR es al menos 1.5?
□¿Estoy entrando antes de que el movimiento ya esté extendido?
Una respuesta ‘no sé’ cuenta como NO. La ausencia de claridad es información.

16. Calificación del setup

A+ / A / B / NO TRADE

GradoCaracterísticasAcción
  A+A+B alineados, VWAP favorable, liquidez clara, estructura confirmada, entrada limpia, RR sólido.  Setup prioritario.
AMayoría de capas alineadas; una condición secundaria imperfecta.Operable con disciplina.
BContexto razonable pero transición, confirmación débil o RR justo.Esperar mejora / reducir interés.
  NO TRADEContradicciones importantes, rango confuso, entrada tardía o riesgo mal definido.  No operar.

La calificación no pretende predecir el resultado de una operación individual. Evalúa la calidad del proceso y de la evidencia disponible antes de entrar.

17. Casos prácticos fáciles

Aprender a narrar el gráfico

CasoLectura paso a paso
1. A alcista + B alcista + sobre VWAPContexto favorable. Buscar liquidez objetivo y confirmación estructural antes del largo.
  2. A bajista + B alcistaProbable corrección bajista dentro de estructura alcista. No vender tarde; observar soporte/liquidez y posible reanudación.
3. A alcista + B bajistaRebote/corrección contra estructura bajista. Comprar exige evidencia excepcional; vigilar rechazo en VWAP/OB.
4. A bajista + B bajista + bajo VWAPContexto bajista alineado. Esperar pullback/confirmación; no perseguir una vela ya extendida.
5. Sweep de London H + A gira bajistaPosible rechazo. Confirmar MSS/BOS, VWAP y espacio hasta siguiente liquidez antes de considerar corto.
El objetivo del alumno es poder contar la historia del mercado en una frase antes de pensar en una entrada.

 

Glosario para principiantes

Referencia rápida

TérminoDefinición
EMAExponential Moving Average. Media móvil que da más peso a datos recientes.
VWAPVolume Weighted Average Price. Precio medio ponderado por volumen.
MomentumVelocidad y dirección inmediata del movimiento.
EstructuraSecuencia de máximos y mínimos que organiza la tendencia.
Timeframe / TFMarco temporal de cada vela: M15, H1, H4, D1, etc.
MTFMulti-Timeframe. Lectura simultánea de varios marcos temporales.
BOSBreak of Structure. Ruptura de estructura.
CHOCHChange of Character. Cambio inicial del carácter estructural.
MSSMarket Structure Shift. Cambio estructural con desplazamiento.
Liquidity / LiquidezZonas donde pueden concentrarse órdenes y stops.
BSLBuy-Side Liquidity. Liquidez normalmente situada sobre máximos.
SSLSell-Side Liquidity. Liquidez normalmente situada bajo mínimos.
SweepBarrido de un nivel seguido de rechazo/retorno.
FVGFair Value Gap. Desequilibrio de precio dejado por desplazamiento.
OBOrder Block. Zona asociada al origen de un desplazamiento.
ATRAverage True Range. Medida de volatilidad/rango.
RRReward/Risk. Relación entre beneficio potencial y riesgo.
SesgoHipótesis direccional basada en evidencia.
PullbackRetroceso dentro de un movimiento mayor.
BreakoutRuptura con posible aceptación fuera de un rango/nivel.

18. Errores frecuentes y reglas finales

Qué evitar cuando el gráfico se ve convincente

  • Comprar únicamente porque apareció ▲ Alcista A.
  • Vender únicamente porque apareció ▼ Bajista B.
  • Confundir una corrección de Set A con reversión estructural de Set B.
  • Ignorar VWAP cuando el precio está oscilando repetidamente alrededor de él.
  • Tratar un High/Low de sesión como soporte/resistencia garantizado.
  • Entrar después de una expansión grande sin esperar retroceso o nueva estructura.
  • Mover el stop porque ‘seguro regresa’. La invalidación debe definirse antes.
  • Buscar unanimidad absoluta entre todos los timeframes.
  • Sobreoperar cuando ATR/volumen muestran condiciones pobres.
  • Evaluar el método por una sola operación en vez de por una muestra de ejecuciones disciplinadas.

Ejercicio final

Abra un gráfico M15 sin operar. En voz alta o por escrito complete: (1) Set B dice…, (2) Set A dice…, (3) VWAP dice…, (4) la liquidez más cercana está…, (5) la estructura confirma/no confirma…, (6) por tanto mi decisión es… Esperar también es una decisión.

Anexo- Script para Pine

RadarATC.pine
Texto plano
//@version=6
indicator("ATC - Radar Institucional - Mercado Global Sesiones XAUUSD", overlay=true, max_labels_count=500, max_lines_count=500)
//=====================================================================
// ATC RADAR INSTITUCIONAL
// Pine Script v6
//
// SET A 9/21 = Momentum tactico
// SET B 50/100 = Estructura intradia
// VWAP = Precio medio ponderado
//
// IMPORTANTE:
// EMAs + VWAP se dibujan directamente SOBRE EL PRECIO.
//=====================================================================
//=====================================================================
// 01. INPUTS GENERALES
//=====================================================================
showPanelEMAs = input.bool(
true,
"Panel EMAs MTF A/B",
group="01 - Paneles"
)
showPanelSMR = input.bool(
false,
"Panel SMR",
group="01 - Paneles"
)
showPanelSMC = input.bool(
false,
"Panel SMC Institucional",
group="01 - Paneles"
)
//=====================================================================
// 02. EMAs SET A
//=====================================================================
showEMAsA = input.bool(
true,
"Mostrar Set A",
group="02 - EMA Set A"
)
emaShortALen = input.int(
9,
"EMA corta A",
minval=1,
group="02 - EMA Set A"
)
emaLongALen = input.int(
21,
"EMA larga A",
minval=1,
group="02 - EMA Set A"
)
emaShortAColor = input.color(
color.lime,
"Color corta A",
group="02 - EMA Set A",
inline="A"
)
emaLongAColor = input.color(
color.orange,
"Color larga A",
group="02 - EMA Set A",
inline="A"
)
emaAWidth = input.int(
2,
"Grosor A",
minval=1,
maxval=5,
group="02 - EMA Set A"
)
//=====================================================================
// 03. EMAs SET B
//=====================================================================
showEMAsB = input.bool(
true,
"Mostrar Set B",
group="03 - EMA Set B"
)
emaShortBLen = input.int(
50,
"EMA corta B",
minval=1,
group="03 - EMA Set B"
)
emaLongBLen = input.int(
100,
"EMA larga B",
minval=1,
group="03 - EMA Set B"
)
emaShortBColor = input.color(
color.lime,
"Color corta B",
group="03 - EMA Set B",
inline="B"
)
emaLongBColor = input.color(
color.orange,
"Color larga B",
group="03 - EMA Set B",
inline="B"
)
emaBWidth = input.int(
2,
"Grosor B",
minval=1,
maxval=5,
group="03 - EMA Set B"
)
//=====================================================================
// 04. VWAP
//=====================================================================
showVWAP = input.bool(
true,
"Mostrar VWAP",
group="04 - VWAP"
)
vwapColor = input.color(
color.purple,
"Color VWAP",
group="04 - VWAP"
)
vwapWidth = input.int(
2,
"Grosor VWAP",
minval=1,
maxval=5,
group="04 - VWAP"
)
//=====================================================================
// 05. CRUCES
//=====================================================================
showCrossA = input.bool(
true,
"Mostrar cruces Set A",
group="05 - Cruces"
)
showCrossB = input.bool(
true,
"Mostrar cruces Set B",
group="05 - Cruces"
)
mostrarSoloUltimosCruces = input.bool(
true,
"Solo ultimos cruces A/B",
group="05 - Cruces",
tooltip="Activado: solo ultimo cruce alcista y bajista de cada Set. Desactivado: todos los cruces."
)
//=====================================================================
// 06. ALERTAS
//=====================================================================
alertEmaCrossA = input.bool(
true,
"Alertas cruces Set A",
group="06 - Alertas"
)
alertEmaCrossB = input.bool(
true,
"Alertas cruces Set B",
group="06 - Alertas"
)
alertVwapCross = input.bool(
true,
"Alertas cruces VWAP",
group="06 - Alertas"
)
alertRequireBias = input.bool(
false,
"Requerir sesgo institucional",
group="06 - Alertas"
)
alertRequireATR = input.bool(
false,
"Requerir ATR operativo",
group="06 - Alertas"
)
//=====================================================================
// 07. TRH
//=====================================================================
syncTRHwithPanel = input.bool(
true,
"Sincronizar TRH con Sesgo Institucional",
group="07 - Integracion TRH"
)
minTFbias = input.int(
3,
"Minimo TFs a favor",
minval=1,
maxval=4,
group="07 - Integracion TRH"
)
requireVWAP = input.bool(
true,
"Requerir Sesgo VWAP a favor",
group="07 - Integracion TRH"
)
//=====================================================================
// 08. CALCULO EMAs + VWAP
//=====================================================================
emaShortA = ta.ema(close, emaShortALen)
emaLongA = ta.ema(close, emaLongALen)
emaShortB = ta.ema(close, emaShortBLen)
emaLongB = ta.ema(close, emaLongBLen)
vwapLine = ta.vwap
// Alias de compatibilidad
emaShort = emaShortA
emaLong = emaLongA
emaShortLen = emaShortALen
emaLongLen = emaLongALen
//=====================================================================
// 09. DIBUJO SOBRE EL GRAFICO PRINCIPAL
//=====================================================================
// SET A - CONTINUAS
plot(
showEMAsA ? emaShortA : na,
title="EMA corta A",
color=emaShortAColor,
linewidth=emaAWidth,
style=plot.style_line
)
plot(
showEMAsA ? emaLongA : na,
title="EMA larga A",
color=emaLongAColor,
linewidth=emaAWidth,
style=plot.style_line
)
// SET B - PUNTEADAS VISUALES
// plot.style_circles mantiene el Set B claramente distinguible.
plot(
showEMAsB ? emaShortB : na,
title="EMA corta B",
color=emaShortBColor,
linewidth=emaBWidth,
style=plot.style_circles
)
plot(
showEMAsB ? emaLongB : na,
title="EMA larga B",
color=emaLongBColor,
linewidth=emaBWidth,
style=plot.style_circles
)
// VWAP - CONTINUA
plot(
showVWAP ? vwapLine : na,
title="VWAP",
color=vwapColor,
linewidth=vwapWidth,
style=plot.style_line
)
//=====================================================================
// 10. DETECCION DE CRUCES
//=====================================================================
cruceAlcistaA = ta.crossover(emaShortA, emaLongA)
cruceBajistaA = ta.crossunder(emaShortA, emaLongA)
cruceAlcistaB = ta.crossover(emaShortB, emaLongB)
cruceBajistaB = ta.crossunder(emaShortB, emaLongB)
cruceVWAPup = ta.crossover(close, vwapLine)
cruceVWAPdown = ta.crossunder(close, vwapLine)
//=====================================================================
// 11. ULTIMOS CRUCES SET A - ANCLADOS AL PRECIO DE LAS EMAs
//=====================================================================
var label ultimoCruceAlcistaA = na
var label ultimoCruceBajistaA = na
// Nivel visual del evento A.
// En la vela donde Pine confirma el crossover/crossunder,
// usamos el punto medio entre EMA 9 y EMA 21.
precioCruceA = (emaShortA + emaLongA) / 2
if cruceAlcistaA and mostrarSoloUltimosCruces
if not na(ultimoCruceAlcistaA)
label.delete(ultimoCruceAlcistaA)
if showCrossA
ultimoCruceAlcistaA := label.new(
bar_index,
precioCruceA,
"▲ Alcista A",
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_none,
textcolor=color.lime,
size=size.normal
)
if cruceBajistaA and mostrarSoloUltimosCruces
if not na(ultimoCruceBajistaA)
label.delete(ultimoCruceBajistaA)
if showCrossA
ultimoCruceBajistaA := label.new(
bar_index,
precioCruceA,
"▼ Bajista A",
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_none,
textcolor=color.red,
size=size.normal
)
//=====================================================================
// 12. ULTIMOS CRUCES SET B - ANCLADOS AL PRECIO DE LAS EMAs
//=====================================================================
var label ultimoCruceAlcistaB = na
var label ultimoCruceBajistaB = na
// Nivel visual del evento B.
// En la vela donde Pine confirma el crossover/crossunder,
// usamos el punto medio entre EMA 50 y EMA 100.
precioCruceB = (emaShortB + emaLongB) / 2
if cruceAlcistaB and mostrarSoloUltimosCruces
if not na(ultimoCruceAlcistaB)
label.delete(ultimoCruceAlcistaB)
if showCrossB
ultimoCruceAlcistaB := label.new(
bar_index,
precioCruceB,
"▲ Alcista B",
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_none,
textcolor=color.lime,
size=size.normal
)
if cruceBajistaB and mostrarSoloUltimosCruces
if not na(ultimoCruceBajistaB)
label.delete(ultimoCruceBajistaB)
if showCrossB
ultimoCruceBajistaB := label.new(
bar_index,
precioCruceB,
"▼ Bajista B",
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_none,
textcolor=color.red,
size=size.normal
)
//=====================================================================
// 13. TODOS LOS CRUCES - ANCLADOS AL EVENTO EMA/EMA
//=====================================================================
plotshape(
showCrossA and not mostrarSoloUltimosCruces and cruceAlcistaA ?
precioCruceA :
na,
title="Alcista A Historico",
style=shape.triangleup,
location=location.absolute,
color=color.lime,
size=size.normal,
text="Alcista A",
textcolor=color.lime
)
plotshape(
showCrossA and not mostrarSoloUltimosCruces and cruceBajistaA ?
precioCruceA :
na,
title="Bajista A Historico",
style=shape.triangledown,
location=location.absolute,
color=color.red,
size=size.normal,
text="Bajista A",
textcolor=color.red
)
plotshape(
showCrossB and not mostrarSoloUltimosCruces and cruceAlcistaB ?
precioCruceB :
na,
title="Alcista B Historico",
style=shape.triangleup,
location=location.absolute,
color=color.lime,
size=size.normal,
text="Alcista B",
textcolor=color.lime
)
plotshape(
showCrossB and not mostrarSoloUltimosCruces and cruceBajistaB ?
precioCruceB :
na,
title="Bajista B Historico",
style=shape.triangledown,
location=location.absolute,
color=color.red,
size=size.normal,
text="Bajista B",
textcolor=color.red
)
//=====================================================================
// 14. LIMPIEZA CRUCES
//=====================================================================
if not showCrossA or not mostrarSoloUltimosCruces
if not na(ultimoCruceAlcistaA)
label.delete(ultimoCruceAlcistaA)
ultimoCruceAlcistaA := na
if not na(ultimoCruceBajistaA)
label.delete(ultimoCruceBajistaA)
ultimoCruceBajistaA := na
if not showCrossB or not mostrarSoloUltimosCruces
if not na(ultimoCruceAlcistaB)
label.delete(ultimoCruceAlcistaB)
ultimoCruceAlcistaB := na
if not na(ultimoCruceBajistaB)
label.delete(ultimoCruceBajistaB)
ultimoCruceBajistaB := na
//=====================================================================
// 15. PANEL EMA MTF A/B
//=====================================================================
diff = math.abs(emaShortA - emaLongA)
maxDiff = ta.highest(diff, 200)
intensity =
maxDiff == 0.0 ?
0.0 :
diff / maxDiff
fuerzaPct = math.round(intensity * 100)
tendencia =
emaShortA > emaLongA ?
"Alcista" :
emaShortA < emaLongA ?
"Bajista" :
"Neutral"
tendenciaB =
emaShortB > emaLongB ?
"Alcista" :
emaShortB < emaLongB ?
"Bajista" :
"Neutral"
vwapEstado =
close > vwapLine ?
"Sobre VWAP" :
close < vwapLine ?
"Bajo VWAP" :
"En VWAP"
colorActual =
emaShortA > emaLongA ?
color.lime :
emaShortA < emaLongA ?
color.red :
color.yellow
colorActualB =
emaShortB > emaLongB ?
color.lime :
emaShortB < emaLongB ?
color.red :
color.yellow
colorVWAP =
close > vwapLine ?
color.lime :
close < vwapLine ?
color.red :
color.yellow
fuerzaIcon =
fuerzaPct >= 66 ?
"🟢" :
fuerzaPct >= 33 ?
"🟡" :
"🔴"
//=====================================================================
// 16. FUNCION MTF
//=====================================================================
f_tfData(tf, shortLen, longLen) =>
emaS = request.security(
syminfo.tickerid,
tf,
ta.ema(close, shortLen)
)
emaL = request.security(
syminfo.tickerid,
tf,
ta.ema(close, longLen)
)
d = math.abs(emaS - emaL)
maxD = request.security(
syminfo.tickerid,
tf,
ta.highest(
math.abs(
ta.ema(close, shortLen) -
ta.ema(close, longLen)
),
200
)
)
inten =
maxD == 0.0 ?
0.0 :
d / maxD
fuerza = math.round(inten * 100)
tend =
emaS > emaL ?
"Alcista" :
emaS < emaL ?
"Bajista" :
"Neutral"
col =
emaS > emaL ?
color.lime :
emaS < emaL ?
color.red :
color.yellow
icon =
fuerza >= 66 ?
"🟢" :
fuerza >= 33 ?
"🟡" :
"🔴"
[tend, fuerza, col, icon]
// SET A
[d1TA, d1FA, d1CA, d1IA] = f_tfData("D", emaShortALen, emaLongALen)
[h4TA, h4FA, h4CA, h4IA] = f_tfData("240", emaShortALen, emaLongALen)
[h1TA, h1FA, h1CA, h1IA] = f_tfData("60", emaShortALen, emaLongALen)
[m15TA, m15FA, m15CA, m15IA] = f_tfData("15", emaShortALen, emaLongALen)
// SET B
[d1TB, d1FB, d1CB, d1IB] = f_tfData("D", emaShortBLen, emaLongBLen)
[h4TB, h4FB, h4CB, h4IB] = f_tfData("240", emaShortBLen, emaLongBLen)
[h1TB, h1FB, h1CB, h1IB] = f_tfData("60", emaShortBLen, emaLongBLen)
[m15TB, m15FB, m15CB, m15IB] = f_tfData("15", emaShortBLen, emaLongBLen)
// Alias
d1T = d1TA
h4T = h4TA
h1T = h1TA
m15T = m15TA
//=====================================================================
// 17. SESGO GENERAL
//=====================================================================
alcistas =
(d1TA == "Alcista" ? 1 : 0) +
(h4TA == "Alcista" ? 1 : 0) +
(h1TA == "Alcista" ? 1 : 0) +
(m15TA == "Alcista" ? 1 : 0)
bajistas =
(d1TA == "Bajista" ? 1 : 0) +
(h4TA == "Bajista" ? 1 : 0) +
(h1TA == "Bajista" ? 1 : 0) +
(m15TA == "Bajista" ? 1 : 0)
alcistasB =
(d1TB == "Alcista" ? 1 : 0) +
(h4TB == "Alcista" ? 1 : 0) +
(h1TB == "Alcista" ? 1 : 0) +
(m15TB == "Alcista" ? 1 : 0)
bajistasB =
(d1TB == "Bajista" ? 1 : 0) +
(h4TB == "Bajista" ? 1 : 0) +
(h1TB == "Bajista" ? 1 : 0) +
(m15TB == "Bajista" ? 1 : 0)
sesgoGeneral =
alcistas > bajistas ?
"🟢 Alcista " + str.tostring(alcistas) + "/4 TF" :
bajistas > alcistas ?
"🔴 Bajista " + str.tostring(bajistas) + "/4 TF" :
"🟡 Mixto"
sesgoGeneralB =
alcistasB > bajistasB ?
"🟢 Alcista " + str.tostring(alcistasB) + "/4 TF" :
bajistasB > alcistasB ?
"🔴 Bajista " + str.tostring(bajistasB) + "/4 TF" :
"🟡 Mixto"
sesgoColor =
alcistas > bajistas ?
color.lime :
bajistas > alcistas ?
color.red :
color.yellow
sesgoColorB =
alcistasB > bajistasB ?
color.lime :
bajistasB > alcistasB ?
color.red :
color.yellow
lecturaAB =
tendencia == tendenciaB ?
"A/B alineados" :
tendencia == "Alcista" and tendenciaB == "Bajista" ?
"Correccion alcista / estructura bajista" :
tendencia == "Bajista" and tendenciaB == "Alcista" ?
"Correccion bajista / estructura alcista" :
"A/B mixtos"
lecturaABColor =
tendencia == tendenciaB ?
color.lime :
color.orange
//=====================================================================
// 18. PANEL A/B
//=====================================================================
panelBgGreenSoft = color.new(color.rgb(0,60,40), 60)
panelBgGreenHard = color.new(color.rgb(0,60,40), 40)
panelTextColor = color.white
var table infoPanel =
table.new(
position.bottom_left,
3,
8
)
if barstate.islast
if showPanelEMAs
table.cell(infoPanel, 0, 0, "TF", text_color=color.white, bgcolor=panelBgGreenHard)
table.cell(
infoPanel,
1,
0,
"SET A " + str.tostring(emaShortALen) + "/" + str.tostring(emaLongALen) + "\nMomentum",
text_color=color.white,
bgcolor=panelBgGreenHard
)
table.cell(
infoPanel,
2,
0,
"SET B " + str.tostring(emaShortBLen) + "/" + str.tostring(emaLongBLen) + "\nEstructura",
text_color=color.white,
bgcolor=panelBgGreenHard
)
table.cell(infoPanel, 0, 1, "Actual", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 1, fuerzaIcon + " " + tendencia + " " + str.tostring(fuerzaPct) + "%", text_color=colorActual, bgcolor=color.white)
table.cell(infoPanel, 2, 1, tendenciaB, text_color=colorActualB, bgcolor=color.white)
table.cell(infoPanel, 0, 2, "D1", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 2, d1IA + " " + d1TA + " " + str.tostring(d1FA) + "%", text_color=d1CA, bgcolor=color.white)
table.cell(infoPanel, 2, 2, d1IB + " " + d1TB + " " + str.tostring(d1FB) + "%", text_color=d1CB, bgcolor=color.white)
table.cell(infoPanel, 0, 3, "H4", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 3, h4IA + " " + h4TA + " " + str.tostring(h4FA) + "%", text_color=h4CA, bgcolor=color.white)
table.cell(infoPanel, 2, 3, h4IB + " " + h4TB + " " + str.tostring(h4FB) + "%", text_color=h4CB, bgcolor=color.white)
table.cell(infoPanel, 0, 4, "H1", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 4, h1IA + " " + h1TA + " " + str.tostring(h1FA) + "%", text_color=h1CA, bgcolor=color.white)
table.cell(infoPanel, 2, 4, h1IB + " " + h1TB + " " + str.tostring(h1FB) + "%", text_color=h1CB, bgcolor=color.white)
table.cell(infoPanel, 0, 5, "M15", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 5, m15IA + " " + m15TA + " " + str.tostring(m15FA) + "%", text_color=m15CA, bgcolor=color.white)
table.cell(infoPanel, 2, 5, m15IB + " " + m15TB + " " + str.tostring(m15FB) + "%", text_color=m15CB, bgcolor=color.white)
table.cell(infoPanel, 0, 6, "VWAP", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 6, vwapEstado, text_color=colorVWAP, bgcolor=color.white)
table.cell(infoPanel, 2, 6, lecturaAB, text_color=lecturaABColor, bgcolor=color.white)
table.cell(infoPanel, 0, 7, "Sesgo", text_color=color.black, bgcolor=color.white)
table.cell(infoPanel, 1, 7, sesgoGeneral, text_color=sesgoColor, bgcolor=color.white)
table.cell(infoPanel, 2, 7, sesgoGeneralB, text_color=sesgoColorB, bgcolor=color.white)
else
table.clear(
infoPanel,
0,
0,
2,
7
)
//=====================================================================
// 19. SMR
//=====================================================================
// Calculados en todas las velas para evitar warnings de consistencia.
highest3_smr = ta.highest(high, 3)
lowest3_smr = ta.lowest(low, 3)
highest5_smr = ta.highest(high, 5)
lowest5_smr = ta.lowest(low, 5)
bosBull_smr =
ta.crossover(
close,
highest3_smr
)
bosBear_smr =
ta.crossunder(
close,
lowest3_smr
)
var string lastChoch_smr = na
if bosBull_smr
lastChoch_smr := "CHOCH UP"
if bosBear_smr
lastChoch_smr := "CHOCH DOWN"
entry_smr = close
sl_smr =
bosBull_smr ?
lowest5_smr :
bosBear_smr ?
highest5_smr :
na
tp_smr =
bosBull_smr ?
entry_smr + (entry_smr - sl_smr) * 2 :
bosBear_smr ?
entry_smr - (sl_smr - entry_smr) * 2 :
na
rrRatio_smr =
not na(sl_smr) and not na(tp_smr) ?
math.abs(tp_smr - entry_smr) /
math.abs(entry_smr - sl_smr) :
na
smrLong =
bosBull_smr and
lastChoch_smr == "CHOCH UP"
smrShort =
bosBear_smr and
lastChoch_smr == "CHOCH DOWN"
entryLongCond_smr =
smrLong and
rrRatio_smr >= 1.5 and
close > vwapLine
entryShortCond_smr =
smrShort and
rrRatio_smr >= 1.5 and
close < vwapLine
atrValue = ta.atr(14)
atrOperativo =
atrValue < 2.0
sesgoAlineado =
(tendencia == "Alcista" and alcistas > bajistas) or
(tendencia == "Bajista" and bajistas > alcistas)
escenarioActivo =
entryLongCond_smr ?
"🟢 LONG (SMR)" :
entryShortCond_smr ?
"🔴 SHORT (SMR)" :
"🟡 Consolidacion"
rrClass_smr =
na(rrRatio_smr) ?
"N/A" :
rrRatio_smr < 1.0 ?
"🔴 BAJO" :
rrRatio_smr < 1.5 ?
"🟡 MEDIO" :
"🟢 ALTO"
rrColor_smr =
na(rrRatio_smr) ?
color.gray :
rrRatio_smr < 1.0 ?
color.red :
rrRatio_smr < 1.5 ?
color.yellow :
color.lime
liqEstado_smr =
close > vwapLine ?
"🟢 Sesgo VWAP Bullish" :
"🔴 Sesgo VWAP Bearish"
atrSignal =
atrValue < 1.0 ?
"🔴 BAJA" :
atrValue < 2.0 ?
"🟡 MEDIA" :
"🟢 ALTA"
var table panelSMR =
table.new(
position.top_right,
1,
8
)
if barstate.islast
if showPanelSMR
table.cell(panelSMR, 0, 0, "SMR", text_color=color.white, bgcolor=panelBgGreenHard)
table.cell(
panelSMR,
0,
1,
"ChOCh: " + (na(lastChoch_smr) ? "Neutral" : lastChoch_smr),
text_color=panelTextColor,
bgcolor=panelBgGreenSoft
)
table.cell(
panelSMR,
0,
2,
"RR: " + (na(rrRatio_smr) ? "N/A" : str.tostring(rrRatio_smr, format.mintick)) + " | " + rrClass_smr,
text_color=rrColor_smr,
bgcolor=panelBgGreenSoft
)
table.cell(panelSMR, 0, 3, "Escenario: " + escenarioActivo, text_color=color.white, bgcolor=panelBgGreenHard)
table.cell(panelSMR, 0, 4, liqEstado_smr, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelSMR, 0, 5, "ATR: " + str.tostring(atrValue, format.mintick), text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelSMR, 0, 6, "Vol: " + atrSignal, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelSMR, 0, 7, "", bgcolor=color.white)
else
table.clear(
panelSMR,
0,
0,
0,
7
)
//=====================================================================
// 20. SMC
//=====================================================================
left = input.int(
2,
"Left bars",
group="08 - SMC"
)
right = input.int(
2,
"Right bars",
group="08 - SMC"
)
htfChochTF = input.string(
"60",
"Timeframe CHOCH HTF",
options=["D","240","60","30","15","5","3"],
group="08 - SMC"
)
htfSwingHigh =
request.security(
syminfo.tickerid,
htfChochTF,
ta.pivothigh(high, left, right)
)
htfSwingLow =
request.security(
syminfo.tickerid,
htfChochTF,
ta.pivotlow(low, left, right)
)
var float htfLastHigh = na
var float htfLastLow = na
if not na(htfSwingHigh)
htfLastHigh := htfSwingHigh
if not na(htfSwingLow)
htfLastLow := htfSwingLow
htfBosBull =
not na(htfLastHigh) and
close > htfLastHigh
htfBosBear =
not na(htfLastLow) and
close < htfLastLow
var string lastHTFChoch = na
if htfBosBull
lastHTFChoch := "UP"
if htfBosBear
lastHTFChoch := "DOWN"
swingHigh = ta.pivothigh(high, left, right)
swingLow = ta.pivotlow(low, left, right)
var float lastHigh = na
var float lastLow = na
if not na(swingHigh)
lastHigh := swingHigh
if not na(swingLow)
lastLow := swingLow
liqBuy =
not na(lastHigh) and
high > lastHigh
liqSell =
not na(lastLow) and
low < lastLow
bosBull_smc =
liqBuy and
close > lastHigh
bosBear_smc =
liqSell and
close < lastLow
var float rrRatio_smc = na
if bosBull_smc and not na(lastLow) and not na(lastHigh)
rrRatio_smc :=
(close - lastLow) /
(lastHigh - lastLow)
if bosBear_smc and not na(lastLow) and not na(lastHigh)
rrRatio_smc :=
(lastHigh - close) /
(lastHigh - lastLow)
entryLongCond_smc =
bosBull_smc and
rrRatio_smc >= 1.5
entryShortCond_smc =
bosBear_smc and
rrRatio_smc >= 1.5
//=====================================================================
// 21. FILTRO TRH
//=====================================================================
if syncTRHwithPanel
allowLong =
alcistas >= minTFbias
allowShort =
bajistas >= minTFbias
allowLong :=
requireVWAP ?
allowLong and close > vwapLine :
allowLong
allowShort :=
requireVWAP ?
allowShort and close < vwapLine :
allowShort
entryLongCond_smc :=
entryLongCond_smc and
allowLong
entryShortCond_smc :=
entryShortCond_smc and
allowShort
//=====================================================================
// 22. VWAP MTF
//=====================================================================
dClose = request.security(syminfo.tickerid, "D", close)
dVWAP = request.security(syminfo.tickerid, "D", ta.vwap)
h4Close = request.security(syminfo.tickerid, "240", close)
h4VWAP = request.security(syminfo.tickerid, "240", ta.vwap)
h1Close = request.security(syminfo.tickerid, "60", close)
h1VWAP = request.security(syminfo.tickerid, "60", ta.vwap)
m15Close = request.security(syminfo.tickerid, "15", close)
m15VWAP = request.security(syminfo.tickerid, "15", ta.vwap)
bullCount =
(dClose > dVWAP ? 1 : 0) +
(h4Close > h4VWAP ? 1 : 0) +
(h1Close > h1VWAP ? 1 : 0) +
(m15Close > m15VWAP ? 1 : 0)
bearCount =
4 - bullCount
sesgoMTF =
bullCount > bearCount ?
"🟢 Alcista " + str.tostring(bullCount) + "/4 TF" :
bearCount > bullCount ?
"🔴 Bajista " + str.tostring(bearCount) + "/4 TF" :
"🟡 Neutral"
//=====================================================================
// 23. ESTRUCTURA MTF
//=====================================================================
dHigh5 = request.security(syminfo.tickerid, "D", ta.highest(high, 5))
dLow5 = request.security(syminfo.tickerid, "D", ta.lowest(low, 5))
h4High5 = request.security(syminfo.tickerid, "240", ta.highest(high, 5))
h4Low5 = request.security(syminfo.tickerid, "240", ta.lowest(low, 5))
h1High5 = request.security(syminfo.tickerid, "60", ta.highest(high, 5))
h1Low5 = request.security(syminfo.tickerid, "60", ta.lowest(low, 5))
m15High5 = request.security(syminfo.tickerid, "15", ta.highest(high, 5))
m15Low5 = request.security(syminfo.tickerid, "15", ta.lowest(low, 5))
bosD =
close > dHigh5 ?
"🟢 BOS UP" :
close < dLow5 ?
"🔴 BOS DOWN" :
"🟡 Rango"
bosH4 =
close > h4High5 ?
"🟢 BOS UP" :
close < h4Low5 ?
"🔴 BOS DOWN" :
"🟡 Rango"
bosH1 =
close > h1High5 ?
"🟢 BOS UP" :
close < h1Low5 ?
"🔴 BOS DOWN" :
"🟡 Rango"
bosM15 =
close > m15High5 ?
"🟢 BOS UP" :
close < m15Low5 ?
"🔴 BOS DOWN" :
"🟡 Rango"
//=====================================================================
// 24. PANEL SMC
//=====================================================================
var table panelInst =
table.new(
position.bottom_right,
1,
10
)
if barstate.islast
if showPanelSMC
table.cell(panelInst, 0, 0, "SMC INSTITUCIONAL", text_color=color.white, bgcolor=panelBgGreenHard)
table.cell(
panelInst,
0,
1,
"HTF CHOCH: " + (na(lastHTFChoch) ? "N/A" : lastHTFChoch + " (" + htfChochTF + ")"),
text_color=panelTextColor,
bgcolor=panelBgGreenSoft
)
table.cell(
panelInst,
0,
2,
"RR SMC: " + (na(rrRatio_smc) ? "N/A" : str.tostring(rrRatio_smc, format.mintick)),
text_color=panelTextColor,
bgcolor=panelBgGreenSoft
)
table.cell(
panelInst,
0,
3,
"Escenario: " + (entryLongCond_smc ? "🟢 LONG" : entryShortCond_smc ? "🔴 SHORT" : "🟡 Neutral"),
text_color=panelTextColor,
bgcolor=panelBgGreenHard
)
table.cell(panelInst, 0, 4, "Sesgo MTF: " + sesgoMTF, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelInst, 0, 5, "D1: " + bosD, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelInst, 0, 6, "H4: " + bosH4, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelInst, 0, 7, "H1: " + bosH1, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelInst, 0, 8, "M15: " + bosM15, text_color=panelTextColor, bgcolor=panelBgGreenSoft)
table.cell(panelInst, 0, 9, "", bgcolor=color.white)
else
table.clear(
panelInst,
0,
0,
0,
9
)
//=====================================================================
// 25. RADAR INSTITUCIONAL
//=====================================================================
// OFF POR DEFECTO
showRadar = input.bool(
false,
"Mostrar Radar Institucional",
group="09 - Radar Institucional"
)
modoNocturno = input.bool(
true,
"Modo nocturno",
group="09 - Radar Institucional"
)
geoRiskMode = input.string(
"Normal",
"Riesgo Geopolitico",
options=["Normal","Elevado","Critico"],
group="09 - Radar Institucional"
)
operacionManual = input.bool(
false,
"Activar operacion manualmente",
group="10 - Operacion"
)
var string operacionActiva = ""
if entryLongCond_smc
operacionActiva := "LONG"
if entryShortCond_smc
operacionActiva := "SHORT"
if operacionManual and operacionActiva == ""
operacionActiva := "MANUAL"
if not operacionManual and not entryLongCond_smc and not entryShortCond_smc
operacionActiva := ""
panelBgDarkSoft = color.new(color.rgb(20,20,20), 40)
panelBgDarkHard = color.new(color.rgb(20,20,20), 20)
bgSoft =
modoNocturno ?
panelBgDarkSoft :
panelBgGreenSoft
bgHard =
modoNocturno ?
panelBgDarkHard :
panelBgGreenHard
recBias =
bullCount > bearCount ?
"Sesgo Alcista. Buscar compras." :
bearCount > bullCount ?
"Sesgo Bajista. Buscar ventas." :
"Sesgo mixto. Priorizar gestion de riesgo."
recGeo =
geoRiskMode == "Critico" ?
"Riesgo geopolitico critico." :
geoRiskMode == "Elevado" ?
"Riesgo geopolitico elevado." :
"Riesgo geopolitico normal."
recVol =
atrValue < 1.0 ?
"Volatilidad baja." :
atrValue < 2.0 ?
"Volatilidad media." :
"Volatilidad alta."
var table radarPanel =
table.new(
position.top_left,
1,
7
)
if barstate.islast
if showRadar
table.cell(radarPanel, 0, 0, "ATC RADAR", text_color=color.white, bgcolor=bgHard)
table.cell(radarPanel, 0, 1, "Sesgo: " + sesgoMTF, text_color=color.white, bgcolor=bgSoft)
table.cell(radarPanel, 0, 2, recBias, text_color=color.white, bgcolor=bgSoft)
table.cell(radarPanel, 0, 3, recGeo, text_color=color.white, bgcolor=bgSoft)
table.cell(radarPanel, 0, 4, recVol, text_color=color.white, bgcolor=bgSoft)
table.cell(radarPanel, 0, 5, "Operacion: " + operacionActiva, text_color=color.white, bgcolor=bgHard)
table.cell(radarPanel, 0, 6, lecturaAB, text_color=color.white, bgcolor=bgSoft)
else
table.clear(
radarPanel,
0,
0,
0,
6
)
//=====================================================================
// 26. SESIONES
//=====================================================================
// TODO APAGADO POR DEFECTO
showSessions = input.bool(
false,
"Mostrar sesiones institucionales",
group="11 - Sesiones"
)
asiaBgCfg = input.bool(
false,
"Fondo Asia",
group="11 - Sesiones"
)
londonBgCfg = input.bool(
false,
"Fondo Londres",
group="11 - Sesiones"
)
nyBgCfg = input.bool(
false,
"Fondo Nueva York",
group="11 - Sesiones"
)
asiaSessionColor = input.color(
color.new(color.yellow, 88),
"Color fondo Asia",
group="11 - Sesiones"
)
londonSessionColor = input.color(
color.new(color.orange, 88),
"Color fondo Londres",
group="11 - Sesiones"
)
nySessionColor = input.color(
color.new(color.aqua, 88),
"Color fondo NY",
group="11 - Sesiones"
)
// UTC-6
asiaRange = "1700-0200"
londonRange = "0200-1000"
nyRange = "0700-1600"
asiaInSession =
not na(
time(
timeframe.period,
asiaRange,
"Etc/GMT+6"
)
)
londonInSession =
not na(
time(
timeframe.period,
londonRange,
"Etc/GMT+6"
)
)
nyInSession =
not na(
time(
timeframe.period,
nyRange,
"Etc/GMT+6"
)
)
bgcolor(
showSessions and asiaBgCfg and asiaInSession ?
asiaSessionColor :
na
)
bgcolor(
showSessions and londonBgCfg and londonInSession ?
londonSessionColor :
na
)
bgcolor(
showSessions and nyBgCfg and nyInSession ?
nySessionColor :
na
)
//=====================================================================
// 27. MAPA DE LIQUIDEZ - SESIONES ANTERIORES
//=====================================================================
showPreviousSessionHL = input.bool(
true,
"Mostrar H/L sesiones anteriores",
group="12 - Liquidez Sesiones"
)
showAsiaHL = input.bool(
true,
"Asia H/L",
group="12 - Liquidez Sesiones"
)
showLondonHL = input.bool(
true,
"London H/L",
group="12 - Liquidez Sesiones"
)
showNyHL = input.bool(
true,
"NY H/L",
group="12 - Liquidez Sesiones"
)
showSessionHLLabels = input.bool(
true,
"Mostrar vinetas grandes",
group="12 - Liquidez Sesiones"
)
sessionHLDecimals = input.int(
2,
"Decimales en viñetas H/L",
options=[0, 1, 2],
group="12 - Liquidez Sesiones"
)
asiaHLColor = input.color(
color.yellow,
"Color Asia",
group="12 - Liquidez Sesiones"
)
londonHLColor = input.color(
color.orange,
"Color Londres",
group="12 - Liquidez Sesiones"
)
nyHLColor = input.color(
color.aqua,
"Color Nueva York",
group="12 - Liquidez Sesiones"
)
sessionHLWidth = input.int(
2,
"Grosor H/L",
minval=1,
maxval=4,
group="12 - Liquidez Sesiones"
)
//=====================================================================
// 28. INICIO / FIN SESIONES
//=====================================================================
asiaStart =
asiaInSession and
not asiaInSession[1]
asiaEnd =
not asiaInSession and
asiaInSession[1]
londonStart =
londonInSession and
not londonInSession[1]
londonEnd =
not londonInSession and
londonInSession[1]
nyStart =
nyInSession and
not nyInSession[1]
nyEnd =
not nyInSession and
nyInSession[1]
//=====================================================================
// 29. ACUMULADORES
//=====================================================================
var float asiaCurrentHigh = na
var float asiaCurrentLow = na
var float asiaPreviousHigh = na
var float asiaPreviousLow = na
var float londonCurrentHigh = na
var float londonCurrentLow = na
var float londonPreviousHigh = na
var float londonPreviousLow = na
var float nyCurrentHigh = na
var float nyCurrentLow = na
var float nyPreviousHigh = na
var float nyPreviousLow = na
// ASIA
if asiaStart
asiaCurrentHigh := high
asiaCurrentLow := low
else if asiaInSession
asiaCurrentHigh :=
na(asiaCurrentHigh) ?
high :
math.max(asiaCurrentHigh, high)
asiaCurrentLow :=
na(asiaCurrentLow) ?
low :
math.min(asiaCurrentLow, low)
if asiaEnd
asiaPreviousHigh := asiaCurrentHigh
asiaPreviousLow := asiaCurrentLow
// LONDRES
if londonStart
londonCurrentHigh := high
londonCurrentLow := low
else if londonInSession
londonCurrentHigh :=
na(londonCurrentHigh) ?
high :
math.max(londonCurrentHigh, high)
londonCurrentLow :=
na(londonCurrentLow) ?
low :
math.min(londonCurrentLow, low)
if londonEnd
londonPreviousHigh := londonCurrentHigh
londonPreviousLow := londonCurrentLow
// NUEVA YORK
if nyStart
nyCurrentHigh := high
nyCurrentLow := low
else if nyInSession
nyCurrentHigh :=
na(nyCurrentHigh) ?
high :
math.max(nyCurrentHigh, high)
nyCurrentLow :=
na(nyCurrentLow) ?
low :
math.min(nyCurrentLow, low)
if nyEnd
nyPreviousHigh := nyCurrentHigh
nyPreviousLow := nyCurrentLow
//=====================================================================
// 30. LINEAS H/L VIVAS
//=====================================================================
var line asiaHighLine = na
var line asiaLowLine = na
var line londonHighLine = na
var line londonLowLine = na
var line nyHighLine = na
var line nyLowLine = na
// ASIA
if asiaEnd
if not na(asiaHighLine)
line.delete(asiaHighLine)
if not na(asiaLowLine)
line.delete(asiaLowLine)
if showPreviousSessionHL and showAsiaHL
asiaHighLine := line.new(
bar_index,
asiaPreviousHigh,
bar_index + 1,
asiaPreviousHigh,
xloc=xloc.bar_index,
extend=extend.right,
color=asiaHLColor,
width=sessionHLWidth,
style=line.style_solid
)
asiaLowLine := line.new(
bar_index,
asiaPreviousLow,
bar_index + 1,
asiaPreviousLow,
xloc=xloc.bar_index,
extend=extend.right,
color=asiaHLColor,
width=sessionHLWidth,
style=line.style_dotted
)
// LONDRES
if londonEnd
if not na(londonHighLine)
line.delete(londonHighLine)
if not na(londonLowLine)
line.delete(londonLowLine)
if showPreviousSessionHL and showLondonHL
londonHighLine := line.new(
bar_index,
londonPreviousHigh,
bar_index + 1,
londonPreviousHigh,
xloc=xloc.bar_index,
extend=extend.right,
color=londonHLColor,
width=sessionHLWidth,
style=line.style_solid
)
londonLowLine := line.new(
bar_index,
londonPreviousLow,
bar_index + 1,
londonPreviousLow,
xloc=xloc.bar_index,
extend=extend.right,
color=londonHLColor,
width=sessionHLWidth,
style=line.style_dotted
)
// NY
if nyEnd
if not na(nyHighLine)
line.delete(nyHighLine)
if not na(nyLowLine)
line.delete(nyLowLine)
if showPreviousSessionHL and showNyHL
nyHighLine := line.new(
bar_index,
nyPreviousHigh,
bar_index + 1,
nyPreviousHigh,
xloc=xloc.bar_index,
extend=extend.right,
color=nyHLColor,
width=sessionHLWidth,
style=line.style_solid
)
nyLowLine := line.new(
bar_index,
nyPreviousLow,
bar_index + 1,
nyPreviousLow,
xloc=xloc.bar_index,
extend=extend.right,
color=nyHLColor,
width=sessionHLWidth,
style=line.style_dotted
)
//=====================================================================
// FORMATO DE PRECIOS H/L
//=====================================================================
f_sessionPrice(value) =>
sessionHLDecimals == 0 ?
str.tostring(value, "#") :
sessionHLDecimals == 1 ?
str.tostring(value, "#.0") :
str.tostring(value, "#.00")
//=====================================================================
// 31. VINETAS GRANDES H/L
//=====================================================================
var label asiaHighLabel = na
var label asiaLowLabel = na
var label londonHighLabel = na
var label londonLowLabel = na
var label nyHighLabel = na
var label nyLowLabel = na
if barstate.islast
// Limpiar las etiquetas de la vela anterior
if not na(asiaHighLabel)
label.delete(asiaHighLabel)
if not na(asiaLowLabel)
label.delete(asiaLowLabel)
if not na(londonHighLabel)
label.delete(londonHighLabel)
if not na(londonLowLabel)
label.delete(londonLowLabel)
if not na(nyHighLabel)
label.delete(nyHighLabel)
if not na(nyLowLabel)
label.delete(nyLowLabel)
asiaHighLabel := na
asiaLowLabel := na
londonHighLabel := na
londonLowLabel := na
nyHighLabel := na
nyLowLabel := na
// ASIA
if showPreviousSessionHL and showSessionHLLabels and showAsiaHL and not na(asiaPreviousHigh)
asiaHighLabel := label.new(
bar_index + 3,
asiaPreviousHigh,
"● ASIA H " + f_sessionPrice(asiaPreviousHigh),
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_label_left,
color=color.new(asiaHLColor, 80),
textcolor=asiaHLColor,
size=size.large
)
asiaLowLabel := label.new(
bar_index + 3,
asiaPreviousLow,
"● ASIA L " + f_sessionPrice(asiaPreviousLow),
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_label_left,
color=color.new(asiaHLColor, 80),
textcolor=asiaHLColor,
size=size.large
)
// LONDON
if showPreviousSessionHL and showSessionHLLabels and showLondonHL and not na(londonPreviousHigh)
londonHighLabel := label.new(
bar_index + 3,
londonPreviousHigh,
"● LONDON H " + f_sessionPrice(londonPreviousHigh),
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_label_left,
color=color.new(londonHLColor, 80),
textcolor=londonHLColor,
size=size.large
)
londonLowLabel := label.new(
bar_index + 3,
londonPreviousLow,
"● LONDON L " + f_sessionPrice(londonPreviousLow),
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_label_left,
color=color.new(londonHLColor, 80),
textcolor=londonHLColor,
size=size.large
)
// NY
if showPreviousSessionHL and showSessionHLLabels and showNyHL and not na(nyPreviousHigh)
nyHighLabel := label.new(
bar_index + 3,
nyPreviousHigh,
"● NY H " + f_sessionPrice(nyPreviousHigh),
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_label_left,
color=color.new(nyHLColor, 80),
textcolor=nyHLColor,
size=size.large
)
nyLowLabel := label.new(
bar_index + 3,
nyPreviousLow,
"● NY L " + f_sessionPrice(nyPreviousLow),
xloc=xloc.bar_index,
yloc=yloc.price,
style=label.style_label_left,
color=color.new(nyHLColor, 80),
textcolor=nyHLColor,
size=size.large
)
//=====================================================================
// 32. LIQUIDITY SWEEPS
//=====================================================================
asiaHighSweep =
showPreviousSessionHL and
showAsiaHL and
not na(asiaPreviousHigh) and
high > asiaPreviousHigh and
close < asiaPreviousHigh
asiaLowSweep =
showPreviousSessionHL and
showAsiaHL and
not na(asiaPreviousLow) and
low < asiaPreviousLow and
close > asiaPreviousLow
londonHighSweep =
showPreviousSessionHL and
showLondonHL and
not na(londonPreviousHigh) and
high > londonPreviousHigh and
close < londonPreviousHigh
londonLowSweep =
showPreviousSessionHL and
showLondonHL and
not na(londonPreviousLow) and
low < londonPreviousLow and
close > londonPreviousLow
nyHighSweep =
showPreviousSessionHL and
showNyHL and
not na(nyPreviousHigh) and
high > nyPreviousHigh and
close < nyPreviousHigh
nyLowSweep =
showPreviousSessionHL and
showNyHL and
not na(nyPreviousLow) and
low < nyPreviousLow and
close > nyPreviousLow
//=====================================================================
// 33. ALERTAS
//=====================================================================
f_alertAllowed() =>
condBias =
alertRequireBias ?
sesgoAlineado :
true
condATR =
alertRequireATR ?
atrOperativo :
true
condBias and condATR
alertcondition(
alertEmaCrossA and cruceAlcistaA and f_alertAllowed(),
"Cruce EMA Alcista A",
"EMA corta A cruzo ARRIBA de EMA larga A"
)
alertcondition(
alertEmaCrossA and cruceBajistaA and f_alertAllowed(),
"Cruce EMA Bajista A",
"EMA corta A cruzo ABAJO de EMA larga A"
)
alertcondition(
alertEmaCrossB and cruceAlcistaB and f_alertAllowed(),
"Cruce EMA Alcista B",
"EMA corta B cruzo ARRIBA de EMA larga B"
)
alertcondition(
alertEmaCrossB and cruceBajistaB and f_alertAllowed(),
"Cruce EMA Bajista B",
"EMA corta B cruzo ABAJO de EMA larga B"
)
alertcondition(
alertVwapCross and cruceVWAPup and f_alertAllowed(),
"Cruce VWAP Alcista",
"Precio cruzo ARRIBA del VWAP"
)
alertcondition(
alertVwapCross and cruceVWAPdown and f_alertAllowed(),
"Cruce VWAP Bajista",
"Precio cruzo ABAJO del VWAP"
)
alertcondition(
asiaHighSweep,
"Asia High Sweep",
"Barrido de liquidez sobre Asia High"
)
alertcondition(
asiaLowSweep,
"Asia Low Sweep",
"Barrido de liquidez bajo Asia Low"
)
alertcondition(
londonHighSweep,
"London High Sweep",
"Barrido de liquidez sobre London High"
)
alertcondition(
londonLowSweep,
"London Low Sweep",
"Barrido de liquidez bajo London Low"
)
alertcondition(
nyHighSweep,
"NY High Sweep",
"Barrido de liquidez sobre NY High"
)
alertcondition(
nyLowSweep,
"NY Low Sweep",
"Barrido de liquidez bajo NY Low"
)

Impacto de la nueva ley de economía circular en México 2026: Un caso práctico

Impacto de la nueva ley de economía circular en México 2026: Un caso práctico

Marco Legal y Mandato de Transformación

La Ley General de Economía Circular (LGEC), publicada en el Diario Oficial de la Federación el 19 de enero de 2026, no es solo una normativa ambiental, sino un mandato de reestructuración operativa. Bajo el principio de Responsabilidad Extendida del Productor (REP) (Art. 3, XXXI), la ley vincula legalmente a los fabricantes con el ciclo de vida completo de sus envases. Como especialistas en cumplimiento, es imperativo entender que el Artículo 10 faculta a la Secretaría (SEMARNAT) para emitir acuerdos generales de implementación por sector.  Acción Estratégica:  Los supervisores de planta deben coordinarse con sus cámaras industriales de representación, ya que el Art. 10 mandata que el sector productivo debe ser convocado para la elaboración de dichos acuerdos. El incumplimiento de la Gestión Circular inscrita derivará en sanciones administrativas severas bajo la LGEEPA (Arts. 44 y 45 de la LGEC), que incluyen multas y clausuras.

Análisis de Riesgo: El Polietileno (PE) como Pasivo Regulatorio

Técnicamente, el cartón con recubrimiento de Polietileno (PE) se clasifica hoy como un “plástico de difícil aprovechamiento” o multicapa compleja. Su permanencia en el catálogo de materiales de la empresa representa un riesgo crítico de continuidad de negocio.

Riesgos Específicos del PE:
  • Inviabilidad Técnica de Reciclaje:  La infraestructura actual no permite la separación eficiente de la fibra de celulosa y el polímero, contraviniendo el principio de Jerarquización (Art. 4, B, VII).
  • Zonas de Riesgo Regulatorio Crítico:  La distribución en la Ciudad de México, Estado de México, Jalisco y Baja California es actualmente vulnerable. Estas entidades han liderado prohibiciones a materiales de baja reciclabilidad y poliestireno expandido (EPS), estableciendo precedentes para el PE multicapa.
  • Denegación de Registro (Art. 13, III, b):  Para mitigar el riesgo de rechazo, el Análisis de Ciclo de Vida (ACV) debe demostrar una reducción significativa de la Huella Ambiental (Art. 3, XI). Si el uso de PE mantiene o incrementa el impacto ambiental, SEMARNAT negará la inscripción de la Gestión Circular, invalidando la comercialización legal del producto.
  • Riesgo Comercial (Tier 1 Estatus):  Grandes conglomerados alimentarios ya están exigiendo a sus proveedores la eliminación de plásticos no reciclables. Mantener el PE implica perder la viabilidad como proveedor preferente.

La Meta Estratégica: Ácido Poliláctico (PLA) y Biopolímeros

El paso al PLA representa una transición del «Ciclo Técnico» al «Ciclo Biológico” (Art. 3, VIII), alineándose con la regeneración de sistemas naturales. Mientras que el PP (Polipropileno) y el PET se mantienen como opciones de bajo riesgo por su alta reciclabilidad técnica, el PLA se posiciona como la solución Premium para envases de cartón.

Comparativa Estratégica de Transición

CriterioRecubrimiento PERecubrimiento PLAPP / PET (Alternativa)
Clasificación LGECPlástico de difícil aprovechamientoBiopolímero / Barrera CompostableCiclo Técnico Reciclable
Ciclo de CircularidadLineal / Multicapa complejoCiclo Biológico (Art. 3, VIII)Ciclo Técnico
Viabilidad 2030Crítica (Probable eliminación)Muy Alta (Certificada)Alta
Riesgo de MultasAlto por metas REPMuy Bajo (Cumplimiento Progresivo)Bajo
Incentivo EconómicoNinguno (Pasivo fiscal)Preferencia en Contrataciones (Art. 23/25)Estímulos Art. 48

Protocolo Operativo para la Operación

Para garantizar la continuidad operativa, el supervisor debe ejecutar los siguientes hitos de cumplimiento:

  1. Inscripción y Afirmativa Ficta (Art. 12 y 14):  Se debe solicitar la inscripción de la Gestión Circular en la Plataforma Nacional.  Nota crítica:  Bajo el Artículo 14, si la Secretaría no resuelve la solicitud en 60 días hábiles, la inscripción se considera otorgada por Afirmativa Ficta.
  2. Análisis de Ciclo de Vida (ACV) Granular (Art. 15):  Es obligatorio para cada categoría de envase. Las Micro y Pequeñas Empresas pueden optar por Modalidades Simplificadas (Art. 15, I) según lo establezca el reglamento.
  3. Trazabilidad de Materiales (Art. 4, XV):  Implementar sistemas de auditoría interna para documentar el flujo de PLA desde el proveedor hasta el posconsumo.
  4. Uso del Distintivo Nacional (Art. 23):  Una vez validado el PLA, se debe tramitar el Distintivo Nacional de Economía Circular, el cual otorga preferencia legal en procesos de licitación y adquisiciones gubernamentales (Art. 25).

Requisitos Sanitarios y de Inocuidad (COFEPRIS)

La transición a materiales biológicos no exime de la seguridad alimentaria. Para envases de un solo uso, el cumplimiento con la COFEPRIS es paralelo y obligatorio:

  • NOM-120-SSA1 y NOM-251-SSA1:  Marcos obligatorios para garantizar buenas prácticas de higiene y evitar la migración de contaminantes del PLA al producto lácteo.
  • Certificación de Grado Alimentario:  El proveedor de PLA debe entregar certificados de laboratorio que avalen la aptitud de contacto alimentario bajo condiciones de congelación.

Hoja de Ruta de Transición (Hoja de Ruta 2026-2030)

2026: Ventana de Adecuación Legal

  • 19 de enero:  Entrada en vigor de la LGEC.
  • Hito 180 días (Transitorio Segundo): El Ejecutivo Federal debe expedir el Reglamento de la Ley. Esta fecha sirve como límite para actualizar los manuales internos.
  • Registro de Planes de Responsabilidad Extendida (REP).

2027-2028: Fase de Restricción Progresiva

  • Publicación del Programa Nacional 2026-2030 (Transitorio Tercero).
  • Implementación de metas obligatorias de contenido reciclado o tasas de recuperación para multicapas.
  • Vigilancia estricta en zonas de alto riesgo (CDMX, Edomex, Jalisco).

2030: Consolidación del Mercado Formal

  • Eliminación proyectada del EPS (Unicel) y envases con bajo índice de aprovechamiento (PE) del mercado alimentario formal.
  • Obligatoriedad de certificación de compostabilidad técnica real para todos los biopolímeros.

Conclusión y lista de comprobación de cumplimiento

La transición de PE a PLA no es una mejora estética, es una defensa de la viabilidad comercial. La falta de cumplimiento del Art. 13 (III, b) respecto a la huella ambiental dará como resultado la denegación de permisos de operación industrial.

Lista de comprobación:

  •   Certificación de Compostabilidad: Validar certificaciones del proveedor de PLA (ciclo biológico).
  •   Representación Sectorial (Art. 10): Confirmar participación en las mesas de trabajo para el Acuerdo General de su sector.
  •   Registro en Plataforma SEMARNAT:  Documentar la fecha de carga para el conteo de los 60 días de Afirmativa Ficta.
  •   Análisis de Ciclo de Vida (ACV): Presentar estudio (o modalidad simplificada para PyMEs) que demuestre reducción de huella de carbono.
  •   Validación COFEPRIS: Asegurar dictámenes de migración química para contacto con alimentos.
  •   Plan de Responsabilidad Extendida (REP): Establecer mecanismos directos o indirectos (compensación) financiados y reportables.

Guía práctica sobre la Ley de Economía Circular en México

Guía práctica sobre la Ley de Economía Circular en México

Marco jurídico y fundamentos de la LGEC

La Ley General de Economía Circular (LGEC), publicada en el Diario Oficial de la Federación el 19 de enero de 2026, representa un cambio de paradigma en la responsabilidad corporativa en México. Como Consultor Senior, es imperativo advertir que esta ley establece una jerarquía federal predominante. Según el Transitorio Quinto, si las legislaturas locales no armonizan sus leyes en un plazo de 180 días naturales, las disposiciones de la LGEC se aplicarán de forma directa. Esto invalida cualquier normativa estatal que contradiga los estándares federales mínimos.

Objetivos centrales de la Ley (Art. 2)

  • Implementación de la REP:  Establecer Acuerdos Generales para obligar a sectores específicos a obtener la inscripción de su Gestión Circular.
  • Valorización de Residuos:  Minimizar, recuperar y aprovechar materiales para incrementar su vida útil (Art. 1).
  • Responsabilidad Compartida:  Articular la participación de productores, importadores, consumidores y autoridades (Art. 2, IV).
  • Reducción de Desperdicio:  Fomentar específicamente la disminución de desperdicio de alimentos y su aprovechamiento (Art. 2, VIII).

Distribución de Competencias (Art. 6, 8 y 9)

Nivel de Gobierno, Competencias Clave y Atribuciones Técnicas

  • Federación (SEMARNAT)
    «Formular política nacional; expedir Acuerdos Generales de Implementación de la REP (Art. 6, X); operar la Plataforma Nacional y autorizar la Gestión Circular.»
  • Entidades Federativas
    «Implementar políticas estatales alineadas al Programa Nacional (Art. 8, I); evaluar la circularidad sectorial en su territorio y promover la investigación técnica.»
  • Municipios / Alcaldías
    «Aplicar principios de circularidad en el manejo de residuos sólidos urbanos (RSU) según la LGPGIR (Art. 9, I) e impulsar mercados locales sostenibles.»

Responsabilidad Extendida del Productor (REP) y Sujetos Obligados

La REP redefine el costo operativo de comercializar productos envasados, trasladando la carga ambiental íntegramente al agente económico.

Definición Legal (Art. 3, XXXI):  «Responsabilidad Extendida del Productor o REP: Medio por el cual la persona productora o importadora es responsable ambientalmente de su Producto en su Ciclo de Vida, en términos de la Gestión Circular que inscriba ante la Secretaría.»

Sujetos Obligados y Corresponsabilidad Estratégica

  • Productores e Importadores:  responsables directos de la fabricación o introducción de productos al mercado nacional (Art. 3, XXV).
  • Organismos Coordinadores (Art. 3, XXII / Art. 38):  Entes asociativos (Cámaras como CANAINTRA o CONMEXICO) que actúan como corresponsables en la elaboración y cumplimiento de la Gestión Circular de sus agremiados. La afiliación a estos organismos es una decisión estratégica para diluir costos operativos de recuperación.

Diagrama de Flujo de Responsabilidades (Art. 40)

La inscripción en el Registro de Economía Circular (Art. 29) es pública y obligatoria para todos los sujetos bajo un Acuerdo General de implementación de la REP.

Proceso Operativo de Registro

  1. Preparación Técnica:  Elaboración del plan de Gestión Circular que integre aspectos ambientales, funcionales y sociales (Art. 11).
  2. Carga en Plataforma:  Envío de solicitud a través de la Plataforma Nacional (Art. 12).
  3. Evaluación de SEMARNAT:  La autoridad dispone de un plazo de 60 días hábiles para autorizar, prevenir o negar.
  4. Afirmativa Ficta (Art. 14):  Si tras 60 días hábiles no existe resolución ni notificación de observaciones, la Gestión Circular se considera legalmente inscrita.  Nota de riesgo: Esto no exime de auditorías posteriores por falsedad de información.

Documentos Obligatorios para la Inscripción (Art. 15)

  • Análisis del Ciclo de Vida (ACV) por categoría de producto. Se permiten modalidades simplificadas si se justifica inviabilidad técnica o económica (Art. 15, I).
  • Mecanismos de circularidad (directos o indirectos) y metas cuantificables.
  • Convenio de Concertación (Art. 48) si se ha suscrito con la Secretaría para establecer metas de gradualidad específicas.
  • Documentación técnica adicional requerida por el Acuerdo General de la REP sectorial.

Requisitos Técnicos: Análisis de Ciclo de Vida (ACV) e Indicadores

El cumplimiento se rige por indicadores cuantitativos obligatorios que deben reportarse periódicamente (Art. 16).

Matriz de Indicadores de Economía Circular (Art. 3, XII)

Nombre del IndicadorDefinición TécnicaMétodo de CuantificaciónMeta de Gradualidad (Art. 21, XII)
MaterialesÍndice de materiales circulares vs. masa total.(Masa recuperada / Masa total utilizada) x 100.Incorporación progresiva de resina posconsumo; sustitución de sustancias tóxicas.
CarbonoValor neto de emisiones de GEI y Carbono Negro (Art. 3, XII, b).Emisiones netas generadas menos remociones en el ciclo de vida.Reducción de emisiones alineada a la Ley General de Cambio Climático.
HídricaHuella de uso eficiente y sustentable del recurso agua.Volumen de agua consumida por unidad de producto.Aprovechamiento sostenible y reducción de vertimientos.
EnergéticaÍndice de aprovechamiento y sustitución calórica.Porcentaje de energía de fuentes renovables o circulares.Transición hacia fuentes de energía limpia en procesos productivos.

Clasificación Estratégica de Materiales para Envases (Sector Alimentos)

Esta clasificación se basa en la viabilidad estratégica al 2030 y el rigor de la Ley de Residuos Sólidos de la CDMX.

MaterialRiesgo RegulatorioJustificación TécnicaSituación en CDMX / Edomex
PP (Polipropileno)BajoAlta reciclabilidad; ideal para helado industrial (3-10L) por resistencia a bajas temperaturas y seguridad alimentaria.Permitido; preferido por su facilidad de integración en cadenas de reciclaje.
PET / rPETBajoEl polímero con mayor infraestructura de reciclaje en México; alta viabilidad para envases de bebidas y alimentos.Altamente compatible; sujeto a metas de contenido reciclado (2029).
HDPEBajoExcelente barrera sanitaria y alta reciclabilidad mecánica.Permitido y recomendado para envases rígidos.
Cartón (Barrera Compostable)Muy BajoAlineado con criterios de biodegradabilidad; requiere certificación de compostabilidad para evitar el estatus de «plástico oculto».Ideal para cumplimiento en mercados con restricciones severas.
PS rígidoAltoBaja tasa de recuperación efectiva en México; riesgo de ser incluido en listas de eliminación gradual.Bajo vigilancia; riesgo de transición obligatoria al PP.
Unicel (EPS)CríticoNula reciclabilidad económica; alto impacto por fragmentación.Prohibido para uso alimentario en CDMX; prohibiciones progresivas en Edomex y Baja California.
Multicapa no reciclableAltoDificultad técnica para separar componentes (ej. BOPP/PE/Aluminio).Sujeto a penalizaciones y obligación de compensación ambiental (Art. 41).

Distintivo Nacional de Economía Circular y Beneficios

El Distintivo Nacional (Art. 23) no es solo un sello de marketing, es un escudo legal y una ventaja competitiva en licitaciones.

  1. Inscripción vigente en el Registro de Economía Circular (Art. 13).
  2. Cumplimiento total de las metas del Acuerdo General de la REP y convenios suscritos.
  3. Auditoría Ambiental Voluntaria ante la PROFEPA aprobada (Art. 35).
  4. Vigencia: 3 años, renovable bajo auditoría de cumplimiento.
  5. Incentivos Económicos (Art. 26, 27):  Acceso a estímulos fiscales federales y estatales, además de preferencia absoluta en contrataciones públicas (Art. 25).

Régimen de Sanciones y Cálculo de Riesgo Económico

El incumplimiento de la LGEC activa la aplicación supletoria de la LGEEPA, con consecuencias que trascienden lo administrativo.

Puntos Críticos de Riesgo:

  • Art. 43, I y II:  Generar información falsa sobre ACV o características ambientales conlleva sanciones graves y revocación del registro.
  • Art. 44:  La falta de reportes de cumplimiento de la Gestión Circular activa multas según los Art. 171 y 173 de la LGEEPA.
  • Auditoría de Afirmativa Ficta:  Si una empresa opera bajo afirmativa ficta pero su ACV es técnicamente fraudulento, la SEMARNAT puede cancelar la inscripción retroactivamente.
  • Riesgo Comercial:  Empresas tractoras están obligadas a reportar su Cadena de Valor; proveedores sin registro de Gestión Circular serán deslistados por riesgo de contagio legal.

Hoja de Ruta de Implementación (marco de tiempo 2026-2030)

2026: Entrada en Vigor y Armonización

  • Publicación (19 de enero).
  • Plazo de 180 días para expedir el Reglamento (Transitorio Segundo).
  • Plazo de 180 días para que estados armonicen sus leyes (Transitorio Cuarto).

2027: Registros Obligatorios

  • Publicación del Programa Nacional de Economía Circular.
  • Inscripción obligatoria de la Gestión Circular para sectores prioritarios (Plásticos/Alimentos).

2028-2029: Metas Intermedias

  • Restricciones totales al EPS en canales formales de alimentos.

2029:  Cumplimiento de porcentajes mínimos obligatorios de contenido reciclado en envases plásticos.

2030: Consolidación y Reconversión

  • Eliminación de materiales no circulares.
  • Cierre del plazo de 5 años para que rellenos sanitarios inicien su reconversión progresiva (Transitorio Sexto).

Protocolo de Cumplimiento

  •   Suscripción de Convenios de Concertación (Art. 48):  Negociar con SEMARNAT plazos de gradualidad antes de que los Acuerdos Generales sean vinculantes.
  •   Auditoría de Portafolio de Empaque:  Sustitución inmediata de EPS y plásticos multicapa por PP, HDPE o rPET.
  •   Validación Sanitaria (COFEPRIS):  Asegurar cumplimiento con NOM-120/NOM-251 para materiales reciclados en contacto con alimentos.
  •   Formalización con Organismos Coordinadores:  Evaluar si el cumplimiento de la REP será individual o colectivo (Art. 38).
  •   Expediente de Trazabilidad:  Implementar sistemas de registro de datos del ciclo de vida (Art. 4, XV) para alimentar la Plataforma Nacional periódicamente.