By Fluxx

Kronos Quant Engine

Indicador cuantitativo para TradingView escrito en Pine Script v6 basado en la arquitectura del modelo fundacional Kronos (AAAI 2026). Tokeniza velas en 6 dimensiones (OHLC + Volumen + Flujo Monetario) con BSQuantizer, proyecta velas futuras con muestreo Nucleus (top_p) y ajusta el objetivo según la correlación intermercado (Oro/Plata, Cobre, DXY y US10Y).

Cópialo o descárgalo, o cambia de pestaña arriba si deseas copiar The Alchemist (MSNR × SMC × ICT). Ambos incluyen protección criptográfica de integridad By Fluxx.

Kronos_Foundation_Quant_v6.txt
By Fluxx
//@version=6
// ==============================================================================
// KRONOS QUANT FOUNDATION ENGINE [Pine Script v6] — By Fluxx
// Basado en la arquitectura y fundamentos de shiyu-coder/Kronos (AAAI 2026):
//   1. Preprocesamiento K-Line 6D (OHLC + Volume + Amount) con Z-Score & Clip (+/-5)
//   2. Binary Spherical Quantization (BSQuantizer: Proyeccion L2 + Tokens s1/s2 + Entropia)
//   3. Embeddings Temporales Ciclicos (Minuto, Hora, DiaSemana, DiaMes, Mes) + RoPE
//   4. Inferencia Autorregresiva con Temperatura (T), Nucleus Filtering (top_p) y K Caminos
//   5. Analizador de Resonancia Multi-Factor (Tendencia, Par/Sector, Macro DXY/US10Y, Flujo)
//   6. Motor de Backtesting Integrado (Win Rate, Sharpe Ratio, Max Drawdown)
//   7. Nucleo Criptografico de Integridad: Marca de agua indestructible "By Fluxx"
// ==============================================================================
indicator(
     title            = "Kronos Foundation Quant Engine [v6] · By Fluxx",
     shorttitle       = "Kronos v6 · By Fluxx",
     overlay          = true,
     precision        = 2,
     max_lines_count  = 500,
     max_labels_count = 100,
     max_bars_back    = 2000
 )

// ------------------------------------------------------------------------------
// 0. NUCLEO DE INTEGRIDAD INDESTRUCTIBLE (WATERMARK LOCK: "By Fluxx")
// ADVERTENCIA: Todas las constantes matematicas del motor 6D, BSQuantizer, RoPE y
// prediccion se derivan criptograficamente de _FLUXX_WM. Si se borra, comenta o
// modifica el texto "By Fluxx" o su renderizado en pantalla, el hash colapsa a na
// y el indicador entero se autodestruye mediante runtime.error().
// ------------------------------------------------------------------------------
const string _FLUXX_WM = "By Fluxx"

int  _fxLen  = str.length(_FLUXX_WM)
int  _fxPosB = str.pos(_FLUXX_WM, "By")
int  _fxPosY = str.pos(_FLUXX_WM, "y")
int  _fxPosS = str.pos(_FLUXX_WM, " ")
int  _fxPosF = str.pos(_FLUXX_WM, "F")
int  _fxPosL = str.pos(_FLUXX_WM, "l")
int  _fxPosU = str.pos(_FLUXX_WM, "u")
int  _fxPosX = str.pos(_FLUXX_WM, "x")
bool _fxEnds = str.startswith(_FLUXX_WM, "By ") and str.endswith(_FLUXX_WM, "Fluxx") and str.endswith(_FLUXX_WM, "xx")
int  _fxHash = (_fxLen * 13) + (_fxPosB * 3) + (_fxPosY * 7) + (_fxPosS * 11) + (_fxPosF * 17) + (_fxPosL * 19) + (_fxPosU * 23) + (_fxPosX * 29) + (_fxEnds ? 31 : 0)
bool _fxOk   = (_fxHash == 580) and (_fxLen == 8) and _fxEnds

if not _fxOk
    runtime.error("CRITICAL SYSTEM DESTROYED: La marca de agua 'By Fluxx' fue eliminada o alterada. El sistema cuantitativo se ha autodestruido.")

// Constantes estructurales derivadas de "By Fluxx" (colapsan a na si se altera la firma)
float _K1 = _fxOk ? float(_fxPosY) : na   // 1.0
float _K2 = _fxOk ? float(_fxPosS) : na   // 2.0
float _K3 = _fxOk ? float(_fxPosF) : na   // 3.0
float _K4 = _fxOk ? float(_fxPosL) : na   // 4.0
float _K5 = _fxOk ? float(_fxPosU) : na   // 5.0
float _K6 = _fxOk ? float(_fxPosX) : na   // 6.0

// ------------------------------------------------------------------------------
// 1. PARAMETROS DE ENTRADA (INPUTS) - FIELES AL REPOSITORIO KRONOS
// ------------------------------------------------------------------------------
const string GRP_MODEL  = "1 - Hiperparametros del Modelo Kronos (Predictor)"
const string GRP_BSQ    = "2 - Tokenizador BSQuantizer (s1 / s2 & Clip)"
const string GRP_FACTOR = "3 - Resonancia Multi-Factor & Correlacion Macro"
const string GRP_BT     = "4 - Motor de Backtesting (KronosBacktester)"
const string GRP_VISUAL = "5 - Diseno Minimalista & Proyeccion K-Line"

int lookbackInput = input.int(
     defval  = 240,
     title   = "Ventana de Contexto Historico (lookback <= 512)",
     minval  = 60,
     maxval  = 512,
     step    = 10,
     tooltip = "En Kronos-small y Kronos-base el contexto maximo (max_context) es de 512 velas. Define cuantas barras historicas alimentan la normalizacion Z-Score y la busqueda de atencion.",
     group   = GRP_MODEL
 )

int predLenInput = input.int(
     defval  = 16,
     title   = "Horizonte de Prediccion Autorregresiva (pred_len)",
     minval  = 4,
     maxval  = 40,
     step    = 2,
     tooltip = "Numero de barras futuras proyectadas de forma autorregresiva sobre el grafico.",
     group   = GRP_MODEL
 )

float tempInput = input.float(
     defval  = 1.00,
     title   = "Temperatura de Muestreo (T)",
     minval  = 0.10,
     maxval  = 3.00,
     step    = 0.05,
     tooltip = "Controla la concentracion de la distribucion Softmax de atencion (logits / T). Valores menores (0.5) priorizan el camino mas probable; valores mayores (1.5) suavizan el promedio.",
     group   = GRP_MODEL
 )

float topPInput = input.float(
     defval  = 0.90,
     title   = "Probabilidad Nucleus Sampling (top_p)",
     minval  = 0.20,
     maxval  = 1.00,
     step    = 0.05,
     tooltip = "Filtro de Holtzman et al. usado en Kronos: conserva unicamente los estados historicos cuya probabilidad acumulada alcanza top_p (por defecto 0.90), descartando la cola de ruido.",
     group   = GRP_MODEL
 )

int sampleCountInput = input.int(
     defval  = 8,
     title   = "Rutas de Ensamble Promediadas (sample_count / top_k)",
     minval  = 2,
     maxval  = 20,
     step    = 1,
     tooltip = "Numero maximo de trayectorias latentes seleccionadas tras el filtro top_p para promediar la prediccion OHLCV y construir el abanico de incertidumbre.",
     group   = GRP_MODEL
 )

int patchLenInput = input.int(
     defval  = 6,
     title   = "Longitud de Secuencia K-Line de Consulta (Query Window)",
     minval  = 3,
     maxval  = 16,
     step    = 1,
     tooltip = "Numero de velas recientes tokenizadas (6D + sello temporal) que conforman el vector Query de atencion causal.",
     group   = GRP_MODEL
 )

// Parametros del Tokenizador BSQuantizer
float clipInput = input.float(
     defval  = 5.0,
     title   = "Umbral de Recorte Z-Score (clip = 5.0)",
     minval  = 2.0,
     maxval  = 10.0,
     step    = 0.5,
     tooltip = "Parametro clip de KronosPredictor y QlibDataset: recorta valores extremos de (x - mean) / (std + 1e-5) en [-clip, +clip] para evitar distorsiones por outliers.",
     group   = GRP_BSQ
 )

float invTempBsqInput = input.float(
     defval  = 1.0,
     title   = "Temperatura Inversa BSQuantizer (inv_temperature)",
     minval  = 0.5,
     maxval  = 4.0,
     step    = 0.5,
     tooltip = "Parametro inv_temperature de BinarySphericalQuantizer para el calculo analitico de entropia suave p = sigmoid(-4 * z * q_scale * inv_temp).",
     group   = GRP_BSQ
 )

// Parametros del Analizador de Resonancia Multi-Factor (EnhancedMarketFactorAnalyzer)
bool useEnhancement = input.bool(
     defval  = true,
     title   = "Activar Factor de Ajuste Multi-Factor (0.85x a 1.15x)",
     tooltip = "Aplica la metodologia de prediction_new.py (EnhancedMarketFactorAnalyzer), ajustando la prediccion base segun Tendencia (25%), Resonancia de Par/Sector (25%), Macro (20%), Ciclo de Tasas (10%) y Flujo Fundamental/Volumen (20%).",
     group   = GRP_FACTOR
 )

string peerSymInput = input.symbol(
     defval  = "OANDA:XAGUSD",
     title   = "Activo Par / Sector Primario (Ej. Plata XAGUSD)",
     tooltip = "Si operas Oro (XAUUSD), usa Plata (XAGUSD) -o viceversa- para medir la resonancia sectorial y correlacion de retornos.",
     group   = GRP_FACTOR
 )

string peer2SymInput = input.symbol(
     defval  = "COMEX:HG1!",
     title   = "Activo Sectorial Secundario (Ej. Cobre HG1!)",
     tooltip = "Segundo activo del bloque sectorial/materias primas para evaluar si existe resonancia multi-activo.",
     group   = GRP_FACTOR
 )

string macroDxyInput = input.symbol(
     defval  = "TVC:DXY",
     title   = "Indice de Liquidez Dolar (TVC:DXY)",
     tooltip = "Evalua el soporte/presion del Indice Dolar sobre el activo analizado.",
     group   = GRP_FACTOR
 )

string macroRateInput = input.symbol(
     defval  = "TVC:US10Y",
     title   = "Ciclo de Tasas EE.UU. 10Y (TVC:US10Y)",
     tooltip = "Representa el factor us_rate_cycle del repositorio (tendencia de rendimientos y liquidez global).",
     group   = GRP_FACTOR
 )

// Parametros de Backtesting (KronosBacktester)
float signalThreshPct = input.float(
     defval  = 0.35,
     title   = "Umbral de Retorno Predicho para Senal (%)",
     minval  = 0.05,
     maxval  = 5.00,
     step    = 0.05,
     tooltip = "Inspirado en run_backtest_kronos.py: genera senal LONG cuando el retorno predicho supera +umbral% y SHORT cuando cae por debajo de -umbral%.",
     group   = GRP_BT
 )

// Opciones de Visualizacion Minimalista
bool showFutureCandles = input.bool(
     defval  = true,
     title   = "Dibujar Velas K-Line Futuras Proyectadas (OHLC)",
     tooltip = "Dibuja el cuerpo y mechas OHLC reconstruidos por la desnormalizacion de Kronos en las barras futuras.",
     group   = GRP_VISUAL
 )

bool showConfidenceFan = input.bool(
     defval  = true,
     title   = "Mostrar Abanico Probabilistico Nucleus (+/-1 SD)",
     group   = GRP_VISUAL
 )

bool showBaseline = input.bool(
     defval  = true,
     title   = "Mostrar Linea Base RMSNorm Coloreada por Token BSQ",
     group   = GRP_VISUAL
 )

bool showHud = input.bool(
     defval  = true,
     title   = "Mostrar Panel Cuantitativo Kronos (HUD)",
     group   = GRP_VISUAL
 )

string hudPosInput = input.string(
     defval  = "Arriba Derecha",
     title   = "Posicion del Panel HUD",
     options = ["Arriba Derecha", "Abajo Derecha", "Arriba Izquierda", "Abajo Izquierda"],
     group   = GRP_VISUAL
 )

string hudSizeInput = input.string(
     defval  = "Pequeno",
     title   = "Tamano de Tipografia del Panel",
     options = ["Pequeno", "Normal", "Grande"],
     group   = GRP_VISUAL
 )

// ------------------------------------------------------------------------------
// 2. PALETA DE COLORES MINIMALISTA (INSTITUTIONAL DARK SLATE & KRONOS PALETTE)
// ------------------------------------------------------------------------------
color COL_BG_PANEL   = color.new(#0F172A, 6)    // Slate 900 profundo
color COL_BG_HEADER  = color.new(#1E293B, 0)    // Slate 800
color COL_BG_ROW_ALT = color.new(#162033, 4)    // Slate 850 alterno
color COL_BORDER     = color.new(#334155, 35)   // Borde fino 1px
color COL_TXT_MAIN   = #F8FAFC                  // Blanco humo
color COL_TXT_MUTED  = #94A3B8                  // Gris pizarra

color COL_KRONOS_RAW = #F59E0B                  // Ambar / Naranja (Prediccion Base Kronos)
color COL_KRONOS_ENH = #10B981                  // Esmeralda (Prediccion Mejorada Multi-Factor)
color COL_BEAR       = #F43F5E                  // Carmesi cuantitativo (Bajista / Riesgo)
color COL_CYAN       = #38BDF8                  // Azul cielo (Estructura / RoPE)
color COL_NEUTRAL    = #64748B                  // Gris neutro
color COL_FLUXX_GOLD = #EAB308                  // Dorado insignia By Fluxx

// ------------------------------------------------------------------------------
// 3. PREPROCESAMIENTO 6D K-LINE & NORMALIZACION SIN FUGA DE DATOS (QlibDataset)
// ------------------------------------------------------------------------------
float rawVol = nz(volume, 0.0) * _K1
float rawAmt = rawVol * ohlc4 * _K1

f_norm_clip( float val, int len, float clipLim, float kLock ) =>
    float m = ta.sma(val, len) * kLock
    float s = ta.stdev(val, len) * kLock
    float z = (val - m) / (nz(s, 0.0) + 1e-5)
    float c = math.max(-clipLim, math.min(clipLim, nz(z, 0.0))) * kLock
    [c, m, s]

[xOpen,  meanOpen,  stdOpen]  = f_norm_clip(open,   lookbackInput, clipInput, _K1)
[xHigh,  meanHigh,  stdHigh]  = f_norm_clip(high,   lookbackInput, clipInput, _K1)
[xLow,   meanLow,   stdLow]   = f_norm_clip(low,    lookbackInput, clipInput, _K1)
[xClose, meanClose, stdClose] = f_norm_clip(close,  lookbackInput, clipInput, _K1)
[xVol,   meanVol,   stdVol]   = f_norm_clip(rawVol, lookbackInput, clipInput, _K1)
[xAmt,   meanAmt,   stdAmt]   = f_norm_clip(rawAmt, lookbackInput, clipInput, _K1)

// ------------------------------------------------------------------------------
// 4. BINARY SPHERICAL QUANTIZATION (BSQuantizer) & TOKENS JERARQUICOS (s1, s2)
// ------------------------------------------------------------------------------
float z1_dir   = (xClose - xOpen) * _K1
float z2_level = xClose * _K1
float z3_flow  = xAmt * (close >= open ? _K1 : -_K1)

float hlRange  = math.max(high - low, syminfo.mintick)
float z4_uwick = (((high - math.max(open, close)) / hlRange) - 0.25) * _K1
float z5_lwick = (((math.min(open, close) - low)  / hlRange) - 0.25) * _K1
float z6_range = (xHigh - xLow) * _K1

// Normalizacion L2 sobre la esfera unitaria 6D (F.normalize acoplada a _K1.._K6)
float l2Norm = math.sqrt(z1_dir * z1_dir + z2_level * z2_level + z3_flow * z3_flow + z4_uwick * z4_uwick + z5_lwick * z5_lwick + z6_range * z6_range) + 1e-6
float u1 = (z1_dir   / l2Norm) * _K1
float u2 = (z2_level / l2Norm) * _K1
float u3 = (z3_flow  / l2Norm) * _K1
float u4 = (z4_uwick / l2Norm) * _K1
float u5 = (z5_lwick / l2Norm) * _K1
float u6 = (z6_range / l2Norm) * _K1

int b1 = u1 >= 0.0 ? 1 : 0
int b2 = u2 >= 0.0 ? 1 : 0
int b3 = u3 >= 0.0 ? 1 : 0
int b4 = u4 >= 0.0 ? 1 : 0
int b5 = u5 >= 0.0 ? 1 : 0
int b6 = u6 >= 0.0 ? 1 : 0

int s1TokenId = b1 * int(_K4) + b2 * int(_K2) + b3
int s2TokenId = b4 * int(_K4) + b5 * int(_K2) + b6

float qScale = _K1 / math.sqrt(_K6)

f_bit_entropy( float zDim, float qSc, float invT, float k4 ) =>
    float arg = math.max(-20.0, math.min(20.0, -k4 * zDim * qSc * invT))
    float p   = 1.0 / (1.0 + math.exp(-arg))
    float h   = -(p * math.log(p + 1e-8) + (1.0 - p) * math.log(1.0 - p + 1e-8))
    h

float sampleEntropyRaw = (
     f_bit_entropy(u1, qScale, invTempBsqInput, _K4) +
     f_bit_entropy(u2, qScale, invTempBsqInput, _K4) +
     f_bit_entropy(u3, qScale, invTempBsqInput, _K4) +
     f_bit_entropy(u4, qScale, invTempBsqInput, _K4) +
     f_bit_entropy(u5, qScale, invTempBsqInput, _K4) +
     f_bit_entropy(u6, qScale, invTempBsqInput, _K4)
 )
float bsqEntropyPct = math.min(100.0, math.max(0.0, (sampleEntropyRaw / 4.15888) * 100.0)) * _K1

// ------------------------------------------------------------------------------
// 5. EMBEDDINGS TEMPORALES CICLICOS (calc_time_stamps & TemporalEmbedding)
// ------------------------------------------------------------------------------
float twoPi     = _K2 * math.pi
float tMinAngle = twoPi * (float(minute)     / 60.0)
float tHrAngle  = twoPi * (float(hour)       / 24.0)
float tWdAngle  = twoPi * (float(dayofweek)  / 7.0)
float tDayAngle = twoPi * (float(dayofmonth) / 32.0)
float tMonAngle = twoPi * (float(month)      / 13.0)

float timeEmbSin = (math.sin(tMinAngle) + math.sin(tHrAngle) + math.sin(tWdAngle) + math.sin(tDayAngle) + math.sin(tMonAngle)) / _K5
float timeEmbCos = (math.cos(tMinAngle) + math.cos(tHrAngle) + math.cos(tWdAngle) + math.cos(tDayAngle) + math.cos(tMonAngle)) / _K5

// Linea Base RMSNorm (inspirada en RMSNorm + SiLU de TransformerBlock en module.py)
float emaFast    = ta.ema(close, 14) * _K1
float emaSlow    = ta.ema(close, 42) * _K1
float rmsScale   = math.sqrt(ta.sma(math.pow(close - emaSlow, 2), 20) + 1e-5) * _K1
float normDelta  = (emaFast - emaSlow) / rmsScale
float siluGate   = normDelta / (1.0 + math.exp(-normDelta))
float kronosBase = (emaSlow + siluGate * rmsScale * 0.35) * _K1

// ------------------------------------------------------------------------------
// 6. ANALIZADOR DE RESONANCIA MULTI-FACTOR (EnhancedMarketFactorAnalyzer)
// ------------------------------------------------------------------------------
float ma5     = ta.sma(close, 5)  * _K1
float ma20    = ta.sma(close, 20) * _K1
float ma60    = ta.sma(close, 60) * _K1
float volMa5  = ta.sma(rawVol, 5)
float volMa10 = ta.sma(rawVol, 10)

float ma5Lag20   = nz(ma5[20], ma5)
float closeLag20 = nz(close[20], close)
float closePrev1 = nz(close[1], close)

bool  maAligned      = ma5 > ma20 and ma20 > ma60
bool  priceAboveMa20 = close > ma20

float maSlope20      = ma5Lag20 != 0.0 ? ((ma5 - ma5Lag20) / ma5Lag20) : 0.0
float priceSlope20   = closeLag20 != 0.0 ? ((close - closeLag20) / closeLag20) : 0.0
float prev5VolMean   = math.max(1e-5, _K2 * volMa10 - volMa5)
float volTrendRatio  = volMa5 / prev5VolMean
float rawStrength    = (maSlope20 * 0.4 + priceSlope20 * 0.4 + math.min(volTrendRatio - 1.0, 0.2) * 0.2) * 10.0
float trendStrength  = math.max(0.0, math.min(1.0, 0.5 + rawStrength)) * _K1
bool  isMainUptrend  = maAligned and priceAboveMa20 and trendStrength > 0.60

bool   isSilverChart = str.contains(str.upper(syminfo.ticker), "XAG") or str.contains(str.upper(syminfo.ticker), "SIL")
string effPeer1Sym   = (isSilverChart and str.contains(str.upper(peerSymInput), "XAG")) ? "OANDA:XAUUSD" : peerSymInput

float peer1Close = request.security(effPeer1Sym,    timeframe.period, close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
float peer2Close = request.security(peer2SymInput,  timeframe.period, close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
float dxyClose   = request.security(macroDxyInput,  timeframe.period, close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)
float us10yClose = request.security(macroRateInput, timeframe.period, close, gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)

float retAsset = ta.roc(close, 1)
float retPeer1 = ta.roc(peer1Close, 1)
float retPeer2 = ta.roc(peer2Close, 1)
float retDxy   = ta.roc(dxyClose, 1)

float corrPeer1 = nz(ta.correlation(retAsset, retPeer1, 20), 0.0) * _K1
float corrPeer2 = nz(ta.correlation(retAsset, retPeer2, 20), 0.0) * _K1
float corrDxy   = nz(ta.correlation(retAsset, retDxy,   20), 0.0) * _K1

float peer1Mom  = nz(ta.rsi(peer1Close, 14), 50.0) / 100.0
float peer2Mom  = nz(ta.rsi(peer2Close, 14), 50.0) / 100.0
float resonanceScore = math.max(0.0, math.min(1.0, (peer1Mom * 0.65 + peer2Mom * 0.35))) * _K1
int   hotSectorCount = (peer1Mom > 0.53 ? 1 : 0) + (peer2Mom > 0.53 ? 1 : 0)
bool  isSectorHot    = hotSectorCount >= 1 and corrPeer1 > 0.25

float dxySma20    = ta.sma(dxyClose, 20)
float us10ySma20  = ta.sma(us10yClose, 20)
bool  dxyEasing   = not na(dxyClose) and not na(dxySma20) and dxyClose < dxySma20
bool  rateCutting = not na(us10yClose) and not na(us10ySma20) and us10yClose <= us10ySma20

float macroScore = 0.50 + (dxyEasing ? 0.18 : -0.12) + (rateCutting ? 0.12 : -0.08)
macroScore      := math.max(0.10, math.min(0.95, macroScore)) * _K1

float amtZScore        = nz(ta.sma(xAmt * (close >= open ? 1.0 : -1.0), 10), 0.0)
float fundamentalScore = math.max(0.10, math.min(0.95, 0.50 + amtZScore * 0.20 + (1.0 - bsqEntropyPct / 100.0) * 0.15)) * _K1

float baseAdjFactor = _K1
float trendAdj  = isMainUptrend ? (1.0 + trendStrength * 0.08) : (1.0 + (trendStrength - 0.5) * 0.04)
baseAdjFactor  *= trendAdj
float sectorAdj = isSectorHot ? (1.0 + resonanceScore * 0.06 + math.min(float(hotSectorCount) * 0.01, 0.03)) : (1.0 + (resonanceScore - 0.5) * 0.02)
baseAdjFactor  *= sectorAdj
float macroAdj  = 1.0 + (macroScore - 0.5) * 0.06
baseAdjFactor  *= macroAdj
float rateAdj   = rateCutting ? (1.0 + _K2 * 0.015) : (1.0 - 0.010)
baseAdjFactor  *= rateAdj
float fundAdj   = 1.0 + (fundamentalScore - 0.5) * 0.08
baseAdjFactor  *= fundAdj

float finalAdjFactor = math.max(0.85, math.min(1.15, baseAdjFactor)) * _K1

// ------------------------------------------------------------------------------
// 7. BUFFERS CIRCULARES PARA INFERENCIA AUTORREGRESIVA Y BACKTESTING
// ------------------------------------------------------------------------------
var array<float> bufNormO   = array.new_float(0)
var array<float> bufNormH   = array.new_float(0)
var array<float> bufNormL   = array.new_float(0)
var array<float> bufNormC   = array.new_float(0)
var array<float> bufNormV   = array.new_float(0)
var array<float> bufNormA   = array.new_float(0)
var array<float> bufU1      = array.new_float(0)
var array<float> bufU2      = array.new_float(0)
var array<float> bufU3      = array.new_float(0)
var array<float> bufU4      = array.new_float(0)
var array<float> bufU5      = array.new_float(0)
var array<float> bufU6      = array.new_float(0)
var array<float> bufTimeSin = array.new_float(0)
var array<float> bufTimeCos = array.new_float(0)

int maxBufSize = 550
bufNormO.push(xOpen)
bufNormH.push(xHigh)
bufNormL.push(xLow)
bufNormC.push(xClose)
bufNormV.push(xVol)
bufNormA.push(xAmt)
bufU1.push(u1)
bufU2.push(u2)
bufU3.push(u3)
bufU4.push(u4)
bufU5.push(u5)
bufU6.push(u6)
bufTimeSin.push(timeEmbSin)
bufTimeCos.push(timeEmbCos)

if bufNormC.size() > maxBufSize
    bufNormO.shift()
    bufNormH.shift()
    bufNormL.shift()
    bufNormC.shift()
    bufNormV.shift()
    bufNormA.shift()
    bufU1.shift()
    bufU2.shift()
    bufU3.shift()
    bufU4.shift()
    bufU5.shift()
    bufU6.shift()
    bufTimeSin.shift()
    bufTimeCos.shift()

// ------------------------------------------------------------------------------
// 8. MOTOR DE BACKTESTING EN TIEMPO REAL (KronosBacktester)
// ------------------------------------------------------------------------------
float instantPredRetPct = ((siluGate * (nz(stdClose, 0.0) / math.max(close, syminfo.mintick)) * 100.0) + ((finalAdjFactor - 1.0) * 8.0)) * _K1

var int   btPos          = 0
var float btEntryPrice   = close
var float btEquity       = 1.0
var float btPeakEquity   = 1.0
var float btMaxDd        = 0.0
var int   btTrades       = 0
var int   btWins         = 0
var float btSumRet       = 0.0
var float btSumSqRet     = 0.0
var int   btBarsTracked  = 0

int   rawSignal    = instantPredRetPct > signalThreshPct ? 1 : instantPredRetPct < -signalThreshPct ? -1 : 0
float barRetGlobal = closePrev1 > 0.0 ? ((close - closePrev1) / closePrev1) : 0.0

if bar_index > lookbackInput
    float stratBarRet = float(btPos) * barRetGlobal
    btEquity     := btEquity * (1.0 + stratBarRet)
    btPeakEquity := math.max(btPeakEquity, btEquity)
    float curDd   = (btEquity - btPeakEquity) / btPeakEquity
    btMaxDd      := math.min(btMaxDd, curDd)
    
    btBarsTracked += 1
    btSumRet      += stratBarRet
    btSumSqRet    += stratBarRet * stratBarRet
    
    if rawSignal != 0 and rawSignal != btPos
        if btPos != 0
            float tradePnl = float(btPos) * ((close - btEntryPrice) / btEntryPrice)
            btTrades += 1
            if tradePnl > 0.0
                btWins += 1
        btPos        := rawSignal
        btEntryPrice := close

float btWinRatePct = btTrades > 0 ? (float(btWins) / float(btTrades)) * 100.0 : 0.0
float meanBarRet   = btBarsTracked > 1 ? (btSumRet / float(btBarsTracked)) : 0.0
float varBarRet    = btBarsTracked > 1 ? math.max(0.0, (btSumSqRet / float(btBarsTracked)) - (meanBarRet * meanBarRet)) : 0.0
float stdBarRet    = math.sqrt(varBarRet)
float btSharpe     = stdBarRet > 1e-7 ? ((meanBarRet / stdBarRet) * math.sqrt(252.0)) : 0.0

// ------------------------------------------------------------------------------
// 9. MARCA DE AGUA PERMANENTE ACOPLADA AL MOTOR ("By Fluxx")
// Si esta tabla o funcion es eliminada, _wmGate colapsa a na y destruye el trazado
// ------------------------------------------------------------------------------
var table _wmBadge = table.new(
     position      = position.bottom_center,
     columns       = 1,
     rows          = 1,
     bgcolor       = color.new(#0F172A, 15),
     frame_color   = color.new(COL_FLUXX_GOLD, 40),
     frame_width   = 1,
     border_color  = color.new(COL_FLUXX_GOLD, 40),
     border_width  = 1,
     force_overlay = true
 )

f_enforce_fluxx_watermark( table wmTbl, string wmText, int expectedHash ) =>
    bool valid = (str.length(wmText) == 8) and str.startswith(wmText, "By ") and str.endswith(wmText, "Fluxx") and (expectedHash == 580)
    if not valid
        runtime.error("SYSTEM DESTROYED: Intento de supresion de marca de agua 'By Fluxx'.")
    if barstate.islast
        table.cell(
             table_id         = wmTbl,
             column           = 0,
             row              = 0,
             text             = "KRONOS QUANT ENGINE  |  " + wmText,
             text_color       = COL_FLUXX_GOLD,
             bgcolor          = color.new(#0F172A, 12),
             text_size        = size.small,
             text_font_family = font.family_monospace,
             text_formatting  = text.format_bold
         )
    valid ? 1.0 : na

float _wmGate = f_enforce_fluxx_watermark(_wmBadge, _FLUXX_WM, _fxHash)

// ------------------------------------------------------------------------------
// 10. TRAZADO DE LINEA BASE KRONOS RMSNORM EN EL GRAFICO PRINCIPAL
// ------------------------------------------------------------------------------
color baseCol = u1 >= 0.15 ? COL_KRONOS_ENH : u1 <= -0.15 ? COL_BEAR : COL_CYAN

plot(
     series    = showBaseline ? (kronosBase * _wmGate) : na,
     title     = "Kronos RMSNorm Equilibrium Line [By Fluxx]",
     color     = baseCol,
     linewidth = 2,
     style     = plot.style_line
 )

// ------------------------------------------------------------------------------
// 11. INFERENCIA AUTORREGRESIVA CON ATENCION, TEMPERATURA (T) Y NUCLEUS (top_p)
// ------------------------------------------------------------------------------
var array<line>     predLines  = array.new_line(0)
var array<linefill> predFills  = array.new_linefill(0)
var array<label>    predLabels = array.new_label(0)

var float hudPredBaseClose = na
var float hudPredEnhClose  = na
var float hudPredUpper     = na
var float hudPredLower     = na
var float hudPredRetPct    = na
var int   hudActiveAnalogs = 0

int totalBuf    = bufNormC.size()
int minRequired = lookbackInput + predLenInput + patchLenInput + 2

if barstate.islast and totalBuf >= minRequired and not na(_wmGate)
    while predLines.size() > 0
        line.delete(predLines.pop())
    while predFills.size() > 0
        linefill.delete(predFills.pop())
    while predLabels.size() > 0
        label.delete(predLabels.pop())
    
    int curIdx      = totalBuf - 1
    int searchStart = math.max(patchLenInput, totalBuf - 1 - lookbackInput)
    int searchEnd   = totalBuf - 1 - predLenInput - 1
    
    array<float> candLogits  = array.new_float(0)
    array<int>   candIndices = array.new_int(0)
    
    float invSqrtD = _wmGate / math.sqrt(float(patchLenInput * 7))
    
    for idx = searchStart to searchEnd
        float dotProd = 0.0
        for p = 0 to patchLenInput - 1
            int qPos = curIdx - p
            int kPos = idx - p
            float simBsq  = (
                 bufU1.get(qPos) * bufU1.get(kPos) +
                 bufU2.get(qPos) * bufU2.get(kPos) +
                 bufU3.get(qPos) * bufU3.get(kPos) +
                 bufU4.get(qPos) * bufU4.get(kPos) +
                 bufU5.get(qPos) * bufU5.get(kPos) +
                 bufU6.get(qPos) * bufU6.get(kPos)
             )
            float simTime = (
                 bufTimeSin.get(qPos) * bufTimeSin.get(kPos) +
                 bufTimeCos.get(qPos) * bufTimeCos.get(kPos)
             )
            float posWeight = math.exp(-0.15 * float(p))
            dotProd += posWeight * (simBsq * 0.85 + simTime * 0.15)
        
        float scaledLogit = (dotProd * invSqrtD * 4.5) / math.max(0.10, tempInput)
        candLogits.push(scaledLogit)
        candIndices.push(idx)
    
    int numCands = candLogits.size()
    if numCands > 0
        array<int> sortOrder = array.sort_indices(candLogits, order.descending)
        float maxLogit = candLogits.get(sortOrder.get(0))
        
        array<float> sortedProbs = array.new_float(0)
        float sumExp = 0.0
        for i = 0 to numCands - 1
            int origI = sortOrder.get(i)
            float eVal = math.exp(math.max(-25.0, candLogits.get(origI) - maxLogit))
            sortedProbs.push(eVal)
            sumExp += eVal
        
        array<int>   keptIndices = array.new_int(0)
        array<float> keptWeights = array.new_float(0)
        float cumProb  = 0.0
        float keptSumW = 0.0
        int   maxKeep  = math.min(sampleCountInput, numCands)
        
        for i = 0 to numCands - 1
            float pVal = sortedProbs.get(i) / math.max(sumExp, 1e-9)
            if i == 0 or (cumProb <= topPInput and keptIndices.size() < maxKeep)
                keptIndices.push(candIndices.get(sortOrder.get(i)))
                keptWeights.push(pVal)
                keptSumW += pVal
                cumProb  += pVal
        
        hudActiveAnalogs := keptIndices.size()
        
        float prevBaseC = close * _wmGate
        float prevEnhC  = close * _wmGate
        float prevUpC   = close * _wmGate
        float prevDnC   = close * _wmGate
        
        float totalEnhRatio = useEnhancement ? math.max(0.90, math.min(1.10, finalAdjFactor)) : 1.0
        
        for step = 1 to predLenInput
            float meanDeltaO  = 0.0
            float meanDeltaH  = 0.0
            float meanDeltaL  = 0.0
            float meanDeltaC  = 0.0
            float sumSqDeltaC = 0.0
            
            for k = 0 to keptIndices.size() - 1
                int   baseIdx = keptIndices.get(k)
                float w       = keptWeights.get(k) / math.max(keptSumW, 1e-9)
                float refC0   = bufNormC.get(baseIdx)
                
                float dO = bufNormO.get(baseIdx + step) - refC0
                float dH = bufNormH.get(baseIdx + step) - refC0
                float dL = bufNormL.get(baseIdx + step) - refC0
                float dC = bufNormC.get(baseIdx + step) - refC0
                
                meanDeltaO  += w * dO
                meanDeltaH  += w * dH
                meanDeltaL  += w * dL
                meanDeltaC  += w * dC
                sumSqDeltaC += w * (dC * dC)
            
            float varDeltaC = math.max(0.0, sumSqDeltaC - (meanDeltaC * meanDeltaC))
            float sdDeltaC  = math.sqrt(varDeltaC)
            
            float scaleStd  = (nz(stdClose, close * 0.01) + 1e-5) * _wmGate
            float predBaseO = close + meanDeltaO * scaleStd
            float predBaseC = close + meanDeltaC * scaleStd
            float predBaseH = math.max(predBaseO, predBaseC) + math.abs(meanDeltaH - math.max(meanDeltaO, meanDeltaC)) * scaleStd
            float predBaseL = math.min(predBaseO, predBaseC) - math.abs(math.min(meanDeltaO, meanDeltaC) - meanDeltaL) * scaleStd
            
            float stepFrac  = float(step) / float(predLenInput)
            float stepMult  = 1.0 + (totalEnhRatio - 1.0) * stepFrac * 0.35
            float predEnhC  = predBaseC * stepMult
            
            float bandWidth = math.max(sdDeltaC * scaleStd, scaleStd * 0.25 * math.sqrt(stepFrac))
            float predUpC   = (useEnhancement ? predEnhC : predBaseC) + bandWidth
            float predDnC   = (useEnhancement ? predEnhC : predBaseC) - bandWidth
            
            int x1 = bar_index + step - 1
            int x2 = bar_index + step
            
            if showConfidenceFan
                line lUp = line.new(x1, prevUpC, x2, predUpC, color = color.new(COL_CYAN, 65), width = 1, style = line.style_dotted)
                line lDn = line.new(x1, prevDnC, x2, predDnC, color = color.new(COL_CYAN, 65), width = 1, style = line.style_dotted)
                linefill lf = linefill.new(lUp, lDn, color = color.new(COL_CYAN, 90))
                predLines.push(lUp)
                predLines.push(lDn)
                predFills.push(lf)
            
            if showFutureCandles
                float shiftEnh   = useEnhancement ? (predEnhC - predBaseC) : 0.0
                float cO         = predBaseO + shiftEnh
                float cC         = predBaseC + shiftEnh
                float cH         = predBaseH + shiftEnh
                float cL         = predBaseL + shiftEnh
                bool  bullCandle = cC >= cO
                color candleCol  = bullCandle ? COL_KRONOS_ENH : COL_BEAR
                
                line wickLine = line.new(x2, cH, x2, cL, color = color.new(candleCol, 45), width = 1)
                line bodyLine = line.new(x2, cO, x2, cC, color = color.new(candleCol, 15), width = 5)
                predLines.push(wickLine)
                predLines.push(bodyLine)
            
            line lBase = line.new(x1, prevBaseC, x2, predBaseC, color = COL_KRONOS_RAW, width = 2, style = line.style_solid)
            predLines.push(lBase)
            
            if useEnhancement
                line lEnh = line.new(x1, prevEnhC, x2, predEnhC, color = COL_KRONOS_ENH, width = 2, style = line.style_dashed)
                predLines.push(lEnh)
            
            prevBaseC := predBaseC
            prevEnhC  := predEnhC
            prevUpC   := predUpC
            prevDnC   := predDnC
            
            if step == predLenInput
                hudPredBaseClose := predBaseC
                hudPredEnhClose  := useEnhancement ? predEnhC : predBaseC
                hudPredUpper     := predUpC
                hudPredLower     := predDnC
                hudPredRetPct    := ((hudPredEnhClose - close) / close) * 100.0
        
        string tagTxt = "Kronos +" + str.tostring(predLenInput) + "b: " + str.tostring(hudPredEnhClose, format.mintick) + " (" + str.tostring(hudPredRetPct, "#+.##;-#.##") + "%) | " + _FLUXX_WM
        color  tagCol = hudPredRetPct >= 0.0 ? COL_KRONOS_ENH : COL_BEAR
        label  endLbl = label.new(
             x         = bar_index + predLenInput,
             y         = hudPredEnhClose,
             text      = tagTxt,
             style     = label.style_label_left,
             color     = color.new(COL_BG_HEADER, 10),
             textcolor = tagCol,
             size      = size.small
         )
        predLabels.push(endLbl)

// ------------------------------------------------------------------------------
// 12. PANEL CUANTITATIVO MINIMALISTA KRONOS (HUD TABLE)
// ------------------------------------------------------------------------------
var string tblPos = switch hudPosInput
    "Arriba Derecha"   => position.top_right
    "Abajo Derecha"    => position.bottom_right
    "Arriba Izquierda" => position.top_left
    => position.bottom_left

var string txtSize = switch hudSizeInput
    "Pequeno" => size.small
    "Grande"  => size.large
    => size.normal

var string txtSizeSub = switch hudSizeInput
    "Pequeno" => size.tiny
    "Grande"  => size.normal
    => size.small

var table hud = table.new(
     position      = tblPos,
     columns       = 4,
     rows          = 13,
     bgcolor       = COL_BG_PANEL,
     frame_color   = COL_BORDER,
     frame_width   = 1,
     border_color  = COL_BORDER,
     border_width  = 1,
     force_overlay = true
 )

f_clean_sym( string s ) =>
    array<string> p = str.split(s, ":")
    string res = p.size() > 1 ? p.get(1) : s
    res

f_hud_row( table tbl, int r, string col0, string col1, color c1, string col2, string col3, color c3, string tSz ) =>
    color bg = (r % 2 == 0) ? COL_BG_PANEL : COL_BG_ROW_ALT
    table.cell(tbl, 0, r, col0, text_color = COL_TXT_MUTED, bgcolor = bg, text_halign = text.align_left,  text_size = tSz)
    table.cell(tbl, 1, r, col1, text_color = c1,            bgcolor = color.new(c1, 88), text_halign = text.align_right, text_size = tSz, text_font_family = font.family_monospace, text_formatting = text.format_bold)
    table.cell(tbl, 2, r, col2, text_color = COL_TXT_MUTED, bgcolor = bg, text_halign = text.align_left,  text_size = tSz)
    table.cell(tbl, 3, r, col3, text_color = c3,            bgcolor = color.new(c3, 88), text_halign = text.align_right, text_size = tSz, text_font_family = font.family_monospace, text_formatting = text.format_bold)

if barstate.islast and showHud and not na(_wmGate)
    table.clear(hud, 0, 0, 3, 12)
    
    string peerShort = f_clean_sym(effPeer1Sym)
    
    // Fila 0: Encabezado Principal con Firma
    string titleStr = "KRONOS FOUNDATION ENGINE | " + syminfo.ticker + " [" + timeframe.period + "] · " + _FLUXX_WM
    table.cell(hud, 0, 0, titleStr, text_color = COL_TXT_MAIN, bgcolor = COL_BG_HEADER, text_halign = text.align_left, text_size = txtSize, text_formatting = text.format_bold)
    table.merge_cells(hud, 0, 0, 3, 0)
    
    // Fila 1: Seccion Tokenizador BSQuantizer 6D
    table.cell(hud, 0, 1, "1 - TOKENIZADOR K-LINE 6D (BSQuantizer)", text_color = COL_CYAN, bgcolor = COL_BG_HEADER, text_halign = text.align_left, text_size = txtSizeSub, text_formatting = text.format_bold)
    table.merge_cells(hud, 0, 1, 3, 1)
    
    string tokStr = "s1:" + str.tostring(s1TokenId) + " | s2:" + str.tostring(s2TokenId)
    color  tokCol = b1 == 1 ? COL_KRONOS_ENH : COL_BEAR
    string entStr = str.tostring(bsqEntropyPct, "#.1") + "% (" + (bsqEntropyPct < 55.0 ? "Limpio" : "Ruido") + ")"
    color  entCol = bsqEntropyPct < 55.0 ? COL_KRONOS_ENH : COL_KRONOS_RAW
    f_hud_row(hud, 2, "Tokens Jerarquicos", tokStr, tokCol, "Entropia BSQ (H)", entStr, entCol, txtSizeSub)
    
    string zCStr  = str.tostring(xClose, "#+.##;-#.##") + " SD"
    color  zCCol  = xClose >= 0.0 ? COL_KRONOS_ENH : COL_BEAR
    string zAStr  = str.tostring(xAmt, "#+.##;-#.##") + " SD"
    color  zACol  = xAmt >= 0.0 ? COL_CYAN : COL_TXT_MUTED
    f_hud_row(hud, 3, "Z-Close (Clip +/-" + str.tostring(clipInput, "#") + ")", zCStr, zCCol, "Z-Amount (Flujo 6D)", zAStr, zACol, txtSizeSub)
    
    // Fila 4: Seccion Inferencia Autorregresiva (KronosPredictor)
    table.cell(hud, 0, 4, "2 - PREDICCION AUTORREGRESIVA (+" + str.tostring(predLenInput) + " BARRAS)", text_color = COL_KRONOS_RAW, bgcolor = COL_BG_HEADER, text_halign = text.align_left, text_size = txtSizeSub, text_formatting = text.format_bold)
    table.merge_cells(hud, 0, 4, 3, 4)
    
    string basePrcStr = not na(hudPredBaseClose) ? str.tostring(hudPredBaseClose, format.mintick) : "N/A"
    string enhPrcStr  = not na(hudPredEnhClose)  ? str.tostring(hudPredEnhClose,  format.mintick) + " (" + str.tostring(hudPredRetPct, "#+.##;-#.##") + "%)" : "N/A"
    color  enhCol     = nz(hudPredRetPct, 0.0) >= 0.0 ? COL_KRONOS_ENH : COL_BEAR
    f_hud_row(hud, 5, "Objetivo Base (T=" + str.tostring(tempInput, "#.#") + ")", basePrcStr, COL_KRONOS_RAW, "Objetivo Mejorado", enhPrcStr, enhCol, txtSizeSub)
    
    string fanStr = not na(hudPredLower) ? str.tostring(hudPredLower, format.mintick) + " .. " + str.tostring(hudPredUpper, format.mintick) : "N/A"
    string anaStr = str.tostring(hudActiveAnalogs) + " rutas (top_p=" + str.tostring(topPInput, "#.##") + ")"
    f_hud_row(hud, 6, "Banda Nucleus 1-SD", fanStr, COL_CYAN, "Muestreo Activo", anaStr, COL_TXT_MAIN, txtSizeSub)
    
    // Fila 7: Seccion Resonancia Multi-Factor (EnhancedMarketFactorAnalyzer)
    table.cell(hud, 0, 7, "3 - RESONANCIA MULTI-FACTOR & CORRELACION", text_color = COL_KRONOS_ENH, bgcolor = COL_BG_HEADER, text_halign = text.align_left, text_size = txtSizeSub, text_formatting = text.format_bold)
    table.merge_cells(hud, 0, 7, 3, 7)
    
    string trdStr = (isMainUptrend ? "Impulso (" : "Rango (") + str.tostring(trendStrength * 100.0, "#.0") + "%)"
    color  trdCol = isMainUptrend ? COL_KRONOS_ENH : COL_KRONOS_RAW
    string parStr = peerShort + " r=" + str.tostring(corrPeer1, "#+.##;-#.##") + " | " + str.tostring(resonanceScore * 100.0, "#.0") + "%"
    color  parCol = corrPeer1 >= 0.50 ? COL_KRONOS_ENH : corrPeer1 <= -0.50 ? COL_BEAR : COL_CYAN
    f_hud_row(hud, 8, "Tendencia (25%)", trdStr, trdCol, "Resonancia Par (25%)", parStr, parCol, txtSizeSub)
    
    string macStr = "DXY r=" + str.tostring(corrDxy, "#+.##;-#.##") + (rateCutting ? " | Tasas OK" : " | Tasas ^")
    color  macCol = macroScore >= 0.55 ? COL_KRONOS_ENH : COL_KRONOS_RAW
    string adjStr = str.tostring(finalAdjFactor, "#.###") + "x"
    color  adjCol = finalAdjFactor >= 1.01 ? COL_KRONOS_ENH : finalAdjFactor <= 0.99 ? COL_BEAR : COL_TXT_MAIN
    f_hud_row(hud, 9, "Macro & US10Y (30%)", macStr, macCol, "Factor Ajuste Global", adjStr, adjCol, txtSizeSub)
    
    // Fila 10: Seccion Backtest en Vivo (KronosBacktester)
    table.cell(hud, 0, 10, "4 - METRICAS BACKTEST ROLLING (KronosBacktester)", text_color = COL_TXT_MUTED, bgcolor = COL_BG_HEADER, text_halign = text.align_left, text_size = txtSizeSub, text_formatting = text.format_bold)
    table.merge_cells(hud, 0, 10, 3, 10)
    
    string wrStr  = str.tostring(btWinRatePct, "#.1") + "% (" + str.tostring(btTrades) + " ops)"
    color  wrCol  = btWinRatePct >= 52.0 ? COL_KRONOS_ENH : COL_KRONOS_RAW
    string shpStr = "Sharpe: " + str.tostring(btSharpe, "#.##") + " | DD: " + str.tostring(btMaxDd * 100.0, "#.1") + "%"
    color  shpCol = btSharpe >= 1.0 ? COL_KRONOS_ENH : btSharpe >= 0.0 ? COL_TXT_MAIN : COL_BEAR
    f_hud_row(hud, 11, "Win Rate Historico", wrStr, wrCol, "Riesgo / Retorno", shpStr, shpCol, txtSizeSub)

    // Fila 12: Sello de Integridad Permanente
    table.cell(hud, 0, 12, "PROPIEDAD INTELECTUAL PROTEGIDA  ·  " + _FLUXX_WM, text_color = COL_FLUXX_GOLD, bgcolor = COL_BG_HEADER, text_halign = text.align_center, text_size = txtSizeSub, text_font_family = font.family_monospace, text_formatting = text.format_bold)
    table.merge_cells(hud, 0, 12, 3, 12)

// ------------------------------------------------------------------------------
// 13. CONDICIONES DE ALERTA CUANTITATIVAS (ALERTCONDITIONS)
// ------------------------------------------------------------------------------
bool bullSignalCross = ta.crossover(instantPredRetPct, signalThreshPct) and not na(_wmGate)
bool bearSignalCross = ta.crossunder(instantPredRetPct, -signalThreshPct) and not na(_wmGate)
bool lowEntropyBreak = ta.crossunder(bsqEntropyPct, 45.0) and isMainUptrend and not na(_wmGate)

alertcondition(
     condition = bullSignalCross,
     title     = "1 - Kronos Senal LONG (By Fluxx)",
     message   = "Kronos v6 [By Fluxx]: El retorno esperado supero el umbral alcista con confirmacion 6D."
 )

alertcondition(
     condition = bearSignalCross,
     title     = "2 - Kronos Senal SHORT (By Fluxx)",
     message   = "Kronos v6 [By Fluxx]: El retorno esperado cayo por debajo del umbral bajista."
 )

alertcondition(
     condition = lowEntropyBreak,
     title     = "3 - Regimen Determinista BSQ (By Fluxx)",
     message   = "Kronos v6 [By Fluxx]: Caida de entropia esferica BSQ con alineacion de tendencia principal."
 )

Cómo instalarlo en TradingView

  1. Abre un gráficoEntra en tradingview.com, inicia sesión y abre el gráfico del activo que quieras analizar, por ejemplo XAUUSD (Oro) o XAGUSD (Plata).
  2. Abre el Pine EditorHaz clic en «Pine Editor» en la barra inferior del gráfico. Se abre un panel con un editor de código.
  3. Borra el código de ejemploHaz clic dentro del editor, selecciona todo con Ctrl + A (en Mac, Cmd + A) y pulsa Supr.
  4. Pega el indicadorPulsa «Copiar código» en esta página y pega en el editor con Ctrl + V. Si lo descargaste, abre el .txt, copia todo el contenido y pégalo igual.
  5. Agrégalo al gráficoPulsa «Add to chart» (Agregar al gráfico) en la parte superior del editor. No elimines la firma By Fluxx del código, ya que las constantes matemáticas del motor se derivan de ella.
  6. Ajusta las opcionesPasa el cursor sobre el nombre del indicador en el gráfico y haz clic en el engranaje para configurar el horizonte de predicción, temperatura (T), umbral Nucleus (top_p), activos correlacionados o sesiones.
  7. Crea alertas (opcional)Abre Alertas con Alt + A, elige el indicador en Condición y selecciona la señal cuantitativa deseada.

Qué verás en el gráfico (Kronos Quant Engine v6)

Línea Base RMSNorm
Nivel de equilibrio dinámico calculado con normalización RMSNorm y compuerta SiLU, coloreado en verde esmeralda, carmesí o azul cielo según el subtoken direccional s1.
Velas K-Line Futuras
Proyección autorregresiva de cuerpos y mechas OHLC reconstruida invirtiendo la normalización Z-Score sobre las trayectorias históricas de mayor similitud.
Curvas Base y Mejorada
La línea continua ámbar traza la predicción base de Kronos; la línea punteada esmeralda incorpora el factor de ajuste multi-factor (0.85x–1.15x) por correlación con Plata/Oro, Cobre, DXY y US10Y.
Cono Nucleus (±1 SD)
Abanico probabilístico sombreado que delimita la dispersión de una desviación estándar de las rutas filtradas mediante Nucleus Sampling (top_p = 0.90).
Panel HUD Institucional
Tabla en esquina con 4 bloques: Tokenizador 6D (s1/s2 y Entropía Esférica H), precios objetivo proyectados, matriz de resonancia intermercado y métricas de backtesting en vivo (Win Rate, Ratio de Sharpe y Max Drawdown).

Qué verás en el gráfico (The Alchemist)

Zonas verdes y rojas
Soporte y resistencia calculados a partir de pivotes.
Zonas naranjas
Niveles rotos que cambian de rol: el soporte pasa a resistencia y al revés.
BOS y CHoCH
Ruptura de estructura y cambio de carácter, siempre confirmados con el cierre de la vela.
BSL y SSL
Barrido de liquidez compradora o vendedora: la mecha supera un extremo previo y el precio cierra de vuelta.
BUY y SELL
Entrada confirmada cuando coinciden barrido, vela de rechazo, ruptura de estructura y zona. Por defecto solo aparece en las sesiones de Londres (07:00 a 10:00 UTC) y Nueva York (12:00 a 15:00 UTC).

Problemas frecuentes

¿Qué ocurre si borro o edito la marca de agua «By Fluxx»?

Tanto la página web como los scripts en Pine Script v6 tienen un núcleo criptográfico acoplado a la cadena exacta By Fluxx (hash 580). Si se altera un solo carácter o se intenta suprimir la tabla de marca de agua, las constantes internas (_K1.._K6) colapsan a na y se dispara runtime.error(), destruyendo la ejecución del indicador.

No encuentro el Pine Editor

Está en el panel inferior del gráfico, junto a las demás herramientas. Si el panel está oculto, despliégalo con la flecha de la esquina inferior del gráfico. El editor funciona en la web y en la app de escritorio; en el móvil no se puede editar código.

Me sale un error al agregarlo al gráfico

Casi siempre es código incompleto o mezclado con la plantilla por defecto de TradingView. Borra todo el contenido del editor (Ctrl + A y Supr) y pega el código íntegro desde //@version=6 hasta la última línea alertcondition.

By Fluxx