ProRealCode - Trading & Coding with ProRealTime™
Hola, ¿seria posible programar este MACD que esta en la pagina X-Trader. net?
Gracias por adelantado.
Un saludo.
¿Podrías proporcionar más información, como el código original y capturas de pantalla de cómo se ve? ¡Esto agilizará el proceso de traducción! Gracias de antemano.
En términos simplificados, una media adaptativa se calcula así:
Media adaptativa = α × Precio actual + (1 – α) × Media anterior
La clave está en que el coeficiente α no permanece constante. El indicador lo recalcula en cada vela atendiendo a diferentes características del mercado.
Cuando las condiciones justifican una reacción más rápida, α aumenta y la media se aproxima más al precio. Cuando el mercado presenta mucho ruido, α disminuye y la media se vuelve más lenta.
De este modo, el indicador intenta acelerar durante los movimientos direccionales y frenar cuando el precio entra en una fase lateral.
El proceso seguido para construir el indicador y generar señales puede resumirse mediante la siguiente cadena:
Media adaptativa rápida → Media adaptativa lenta → Oscilador → Línea de señal suavizada → Histograma → Divergencias y señales
Veamos estos componentes de forma más detallada.
El panel muestra dos líneas:
La primera se obtiene restando la media adaptativa lenta a la media adaptativa rápida. Por tanto, su interpretación es similar a la del MACD tradicional.
Cuando el oscilador se encuentra por encima de su línea de señal, el momentum es alcista. Cuando se sitúa por debajo, el momentum es bajista.
Los cruces entre ambas líneas generan las señales principales:
No obstante, la diferencia frente al MACD tradicional es importante. Como decíamos antes, las dos medias utilizadas para calcular el oscilador modifican su velocidad en función de las condiciones del mercado.
Además, la línea de señal no es una simple media exponencial. El indicador utiliza un suavizado inspirado en las medias de Jurik, diseñado para reducir las pequeñas oscilaciones sin introducir demasiado retraso.
Esto resulta especialmente relevante porque una media adaptativa cambia constantemente de velocidad y puede producir una línea algo más irregular que una media convencional.
Una de las características más interesantes del Adaptive Momentum Fusion es que podemos seleccionar cómo queremos que se adapten sus medias móviles.
El indicador incorpora seis motores diferentes. Cada uno mide una dimensión concreta del comportamiento del mercado.
El motor Efficiency está basado en el concepto de Efficiency Ratio desarrollado por Perry Kaufman.
Este ratio compara el desplazamiento neto del precio con todo el movimiento realizado durante un período determinado.
Imaginemos que un activo sube diez puntos realizando un movimiento prácticamente recto. En ese caso, la eficiencia será elevada. Si termina en el mismo punto después de haber subido y bajado repetidamente, la eficiencia será reducida.
Cuando la eficiencia es alta, el indicador interpreta que existe una tendencia limpia y acelera las medias. Cuando la eficiencia disminuye, las ralentiza para evitar reaccionar ante el ruido.
Se trata probablemente del motor más equilibrado y del mejor punto de partida para familiarizarse con el indicador.
Este motor compara la volatilidad actual, medida mediante el ATR, con su volatilidad media reciente.
Cuando el ATR aumenta por encima de su promedio, las medias se vuelven más rápidas para seguir la expansión del precio. Cuando la volatilidad se contrae, las medias se ralentizan.
Puede ser especialmente interesante en mercados con cambios claros de régimen de volatilidad, como las criptomonedas o las materias primas.
Eso sí, volatilidad no significa necesariamente tendencia. Un mercado puede registrar movimientos muy violentos en ambas direcciones sin avanzar realmente hacia ningún sitio.
El motor Fractal intenta determinar si el comportamiento del precio es suave y tendencial o, por el contrario, irregular y propenso a la reversión a la media.
Cuando detecta una estructura más tendencial, incrementa la velocidad de las medias. Cuando la serie se vuelve más errática, aumenta el suavizado.
En teoría, este motor puede resultar útil para identificar transiciones entre regímenes tendenciales y laterales. A cambio, sus señales pueden diferir notablemente de las producidas por los demás motores durante esas fases de cambio.
En este caso, la adaptación se basa en la intensidad del Rate of Change o ROC.
Cuando el momentum actual es elevado en comparación con sus valores recientes, las medias aceleran. Cuando el precio pierde impulso, vuelven a suavizarse.
Este comportamiento puede resultar adecuado para estrategias de ruptura, ya que el indicador reacciona con mayor rapidez cuando comienza una expansión fuerte del precio.
El motor de volumen compara el volumen de cada vela con su promedio reciente.
Cuando el volumen se encuentra claramente por encima de la media, el indicador considera que existe una mayor participación en el movimiento y acelera sus medias. Cuando el volumen disminuye, las ralentiza.
Puede tener sentido en acciones, futuros o criptomonedas, donde el volumen aporta información relevante sobre la participación de los operadores.
En mercados donde no existe un volumen real centralizado, como sucede con buena parte del mercado de divisas, su utilidad será más limitada. En ausencia de datos de volumen, el indicador vuelve automáticamente a un coeficiente de suavizado básico.
Finalmente tenemos el motor Composite, que combina los cinco métodos anteriores utilizando diferentes ponderaciones.
De este modo, la velocidad de las medias no depende exclusivamente de la eficiencia, la volatilidad, la estructura fractal, el momentum o el volumen, sino de una combinación de todos ellos.
Es la opción más diversificada y robusta, aunque también puede reaccionar algo más lentamente debido a que está promediando diferentes perspectivas.
Si no tenéis claro qué motor utilizar, podéis comenzar comparando Efficiency y Composite, que probablemente sean las dos configuraciones más equilibradas.
La configuración por defecto utiliza:
Adaptive Momentum Fusion: Un MACD que se Adapta al Mercado
En el enlace todo mas detallado.
Saludos.
Aquí tienes.
//----------------------------------------------
//PRC_Adaptive Momentum Fusion
//version = 0
//27.07.26
//Ivan Gonzalez @ www.prorealcode.com
//Traducido de "Adaptive Momentum Fusion [WillyAlgoTrader]" (PineScript v6)
//Autor original: WillyAlgoTrader
//Sharing ProRealTime knowledge
//----------------------------------------------
// === PARAMETROS PRINCIPALES ===
//----------------------------------------------
srcAmf = customclose // fuente de calculo (close, (high+low)/2, ...)
engineMode = 1 // motor: 1=Efficiency 2=Volatility 3=Fractal 4=Momentum 5=Volume 6=Composite
fastLen = 8 // periodo de la media adaptativa rapida
slowLen = 21 // periodo de la media adaptativa lenta
signalLen = 7 // periodo de la linea de senal (suavizado tipo Jurik)
outMode = 0 // 0 = MACD (diferencia absoluta) 1 = PPO (diferencia en %)
jitter = 0.7 // "Jitter Reduction" del original = phase del suavizado Jurik
sigMode = 0 // linea de senal: 0 = identica al original TV 1 = Jurik canonica 2 = EMA clasica (ver ficha)
//----------------------------------------------
// === VISUALIZACION Y FILTROS ===
//----------------------------------------------
showHisto = 1 // 1 = histograma osc - senal
showSignals = 1 // 1 = flechas en los cruces osc/senal
useZeroCross = 1 // 1 = puntos en los cruces de la linea cero
useDiv = 1 // 1 = divergencias regulares precio/oscilador
divLb = 30 // barras a la izquierda del pivote
divRb = 5 // barras a la derecha del pivote (confirmacion)
showPanel = 1 // 1 = panel resumen en la esquina superior derecha
//----------------------------------------------
// === CONSTANTES INTERNAS ===
//----------------------------------------------
once hasLo = 0
once hasHi = 0
once prevOscLo = 0
once prevPrcLo = 0
once prevLoBar = 0
once prevOscHi = 0
once prevPrcHi = 0
once prevHiBar = 0
once divState = 0
once divBar = 0
warmBars = max(slowLen * 2, 50)
len2F = fastLen * 2
len2S = slowLen * 2
hlfF = max(2, floor(fastLen / 2))
hlfS = max(2, floor(slowLen / 2))
baseAF = 2 / (fastLen + 1)
baseAS = 2 / (slowLen + 1)
rbp1 = divRb + 1
absChg = abs(srcAmf - srcAmf[1])
//----------------------------------------------
// === MOTOR 1 - EFFICIENCY RATIO (Kaufman) ===
// alpha = (ER*(2/3 - 2/31) + 2/31)^2
//----------------------------------------------
dirF = abs(srcAmf - srcAmf[fastLen])
sumMovF = summation[fastLen](absChg)
if sumMovF > 0 then
erF = dirF / sumMovF
else
erF = 0.5
endif
scF = erF * (0.66666667 - 0.06451613) + 0.06451613
aEffF = min(max(scF * scF, 0.01), 1)
dirS = abs(srcAmf - srcAmf[slowLen])
sumMovS = summation[slowLen](absChg)
if sumMovS > 0 then
erS = dirS / sumMovS
else
erS = 0.5
endif
scS = erS * (0.66666667 - 0.06451613) + 0.06451613
aEffS = min(max(scS * scS, 0.01), 1)
//----------------------------------------------
// === MOTOR 2 - VOLATILITY (ATR vs su media) ===
//----------------------------------------------
if barindex < fastLen then
atrValF = high - low
else
atrValF = averagetruerange[fastLen](close)
endif
atrAvgF = average[len2F](atrValF)
if atrAvgF > 0 then
ratVolF = atrValF / atrAvgF
else
ratVolF = 1
endif
aVolF = min(max(baseAF * ratVolF, 0.01), 1)
if barindex < slowLen then
atrValS = high - low
else
atrValS = averagetruerange[slowLen](close)
endif
atrAvgS = average[len2S](atrValS)
if atrAvgS > 0 then
ratVolS = atrValS / atrAvgS
else
ratVolS = 1
endif
aVolS = min(max(baseAS * ratVolS, 0.01), 1)
//----------------------------------------------
// === MOTOR 3 - FRACTAL (dimension tipo Hurst) ===
//----------------------------------------------
rngFullF = highest[fastLen](srcAmf) - lowest[fastLen](srcAmf)
rngAF = highest[hlfF](srcAmf) - lowest[hlfF](srcAmf)
rngBF = highest[hlfF](srcAmf)[hlfF] - lowest[hlfF](srcAmf)[hlfF]
sumHF = rngAF + rngBF
if rngFullF > 0 and sumHF > 0 then
denFrF = log(2 * rngFullF)
if denFrF <> 0 then
fdF = 1 + log(sumHF) / denFrF
else
fdF = 1.5
endif
else
fdF = 1.5
endif
aFraF = min(max(exp((0 - 4.6) * (fdF - 1)), 0.01), 1)
rngFullS = highest[slowLen](srcAmf) - lowest[slowLen](srcAmf)
rngAS = highest[hlfS](srcAmf) - lowest[hlfS](srcAmf)
rngBS = highest[hlfS](srcAmf)[hlfS] - lowest[hlfS](srcAmf)[hlfS]
sumHS = rngAS + rngBS
if rngFullS > 0 and sumHS > 0 then
denFrS = log(2 * rngFullS)
if denFrS <> 0 then
fdS = 1 + log(sumHS) / denFrS
else
fdS = 1.5
endif
else
fdS = 1.5
endif
aFraS = min(max(exp((0 - 4.6) * (fdS - 1)), 0.01), 1)
//----------------------------------------------
// === MOTOR 4 - MOMENTUM (ROC normalizado) ===
//----------------------------------------------
if srcAmf[fastLen] <> 0 then
rocF = (srcAmf - srcAmf[fastLen]) / srcAmf[fastLen] * 100
else
rocF = 0
endif
rocAbsF = abs(rocF)
rocMaxF = highest[len2F](rocAbsF)
if rocMaxF > 0 then
nrmF = min(rocAbsF / rocMaxF, 1)
else
nrmF = 0.5
endif
aMomF = min(max(baseAF + nrmF * (1 - baseAF) * 0.5, 0.01), 1)
if srcAmf[slowLen] <> 0 then
rocS = (srcAmf - srcAmf[slowLen]) / srcAmf[slowLen] * 100
else
rocS = 0
endif
rocAbsS = abs(rocS)
rocMaxS = highest[len2S](rocAbsS)
if rocMaxS > 0 then
nrmS = min(rocAbsS / rocMaxS, 1)
else
nrmS = 0.5
endif
aMomS = min(max(baseAS + nrmS * (1 - baseAS) * 0.5, 0.01), 1)
//----------------------------------------------
// === MOTOR 5 - VOLUME (participacion relativa) ===
//----------------------------------------------
volAvgF = average[fastLen](volume)
if volume > 0 and volAvgF > 0 then
ratVlmF = volume / volAvgF
else
ratVlmF = 1
endif
aVlmF = min(max(baseAF * sqrt(max(ratVlmF, 0.01)), 0.01), 1)
volAvgS = average[slowLen](volume)
if volume > 0 and volAvgS > 0 then
ratVlmS = volume / volAvgS
else
ratVlmS = 1
endif
aVlmS = min(max(baseAS * sqrt(max(ratVlmS, 0.01)), 0.01), 1)
//----------------------------------------------
// === MEDIAS ADAPTATIVAS: ma = alpha*src + (1-alpha)*ma[1] ===
// Semilla obligatoria durante el warmup: una recursion que
// recibe undefined una sola vez queda rota para siempre
//----------------------------------------------
if barindex <= warmBars then
emaEffF = srcAmf
emaVolF = srcAmf
emaFraF = srcAmf
emaMomF = srcAmf
emaVlmF = srcAmf
emaEffS = srcAmf
emaVolS = srcAmf
emaFraS = srcAmf
emaMomS = srcAmf
emaVlmS = srcAmf
else
emaEffF = aEffF * srcAmf + (1 - aEffF) * emaEffF[1]
emaVolF = aVolF * srcAmf + (1 - aVolF) * emaVolF[1]
emaFraF = aFraF * srcAmf + (1 - aFraF) * emaFraF[1]
emaMomF = aMomF * srcAmf + (1 - aMomF) * emaMomF[1]
emaVlmF = aVlmF * srcAmf + (1 - aVlmF) * emaVlmF[1]
emaEffS = aEffS * srcAmf + (1 - aEffS) * emaEffS[1]
emaVolS = aVolS * srcAmf + (1 - aVolS) * emaVolS[1]
emaFraS = aFraS * srcAmf + (1 - aFraS) * emaFraS[1]
emaMomS = aMomS * srcAmf + (1 - aMomS) * emaMomS[1]
emaVlmS = aVlmS * srcAmf + (1 - aVlmS) * emaVlmS[1]
endif
//----------------------------------------------
// === SELECCION DE MOTOR ===
//----------------------------------------------
if engineMode = 1 then
fastMA = emaEffF
slowMA = emaEffS
elsif engineMode = 2 then
fastMA = emaVolF
slowMA = emaVolS
elsif engineMode = 3 then
fastMA = emaFraF
slowMA = emaFraS
elsif engineMode = 4 then
fastMA = emaMomF
slowMA = emaMomS
elsif engineMode = 5 then
fastMA = emaVlmF
slowMA = emaVlmS
else
if volume > 0 then
fastMA = emaEffF * 0.30 + emaVolF * 0.20 + emaFraF * 0.20 + emaMomF * 0.15 + emaVlmF * 0.15
slowMA = emaEffS * 0.30 + emaVolS * 0.20 + emaFraS * 0.20 + emaMomS * 0.15 + emaVlmS * 0.15
else
fastMA = emaEffF * 0.35 + emaVolF * 0.25 + emaFraF * 0.25 + emaMomF * 0.15
slowMA = emaEffS * 0.35 + emaVolS * 0.25 + emaFraS * 0.25 + emaMomS * 0.15
endif
endif
//----------------------------------------------
// === OSCILADOR ===
//----------------------------------------------
if outMode = 1 and slowMA <> 0 then
osc = (fastMA - slowMA) / slowMA * 100
else
osc = fastMA - slowMA
endif
//----------------------------------------------
// === LINEA DE SENAL - SUAVIZADO TIPO JURIK ===
//----------------------------------------------
betaJ = 0.45 * (signalLen - 1) / (0.45 * (signalLen - 1) + 2)
alfaJ = betaJ * betaJ * betaJ
om1 = (1 - alfaJ) * (1 - alfaJ)
al2 = alfaJ * alfaJ
if barindex <= warmBars then
e0j = 0
e1j = 0
e2j = 0
jmaOut = 0
sigLine = 0
else
e0j = (1 - alfaJ) * osc + alfaJ * e0j[1]
e1j = (osc - e0j) * (1 - betaJ) + betaJ * e1j[1]
if sigMode = 1 then
e2j = (e0j + jitter * e1j - jmaOut[1]) * om1 + al2 * e2j[1]
jmaOut = jmaOut[1] + e2j
sigLine = jmaOut
elsif sigMode = 2 then
e2j = 0
jmaOut = 0
sigLine = average[signalLen, 1](osc)
else
e2j = (e0j + jitter * e1j - e2j[1]) * om1 + al2 * e2j[1]
jmaOut = e2j
sigLine = e2j
endif
endif
//----------------------------------------------
// === HISTOGRAMA Y ESTADO ===
//----------------------------------------------
histVal = osc - sigLine
absOsc = abs(osc)
absHist = abs(histVal)
scaleAmf = average[50](absOsc)
maxHist = highest[50](absHist)
if maxHist > 0 then
strScore = min(absHist / maxHist * 100, 100)
else
strScore = 50
endif
strRound = round(strScore)
sigWarm = barindex > warmBars + 2
//----------------------------------------------
// === COLORES ===
//----------------------------------------------
if histVal > 0 and histVal > histVal[1] then
rh = 0
gh = 230
bh = 118
elsif histVal > 0 then
rh = 120
gh = 200
bh = 160
elsif histVal < 0 and histVal < histVal[1] then
rh = 255
gh = 82
bh = 82
elsif histVal < 0 then
rh = 235
gh = 150
bh = 150
else
rh = 150
gh = 150
bh = 150
endif
if osc > sigLine then
rc = 0
gc = 230
bc = 118
rs = 90
gs = 170
bs = 130
else
rc = 255
gc = 82
bc = 82
rs = 190
gs = 110
bs = 110
endif
colorbetween(osc, sigLine, rc, gc, bc, 45)
//----------------------------------------------
// === SENALES DE CRUCE ===
//----------------------------------------------
bullCross = osc crosses over sigLine
bearCross = osc crosses under sigLine
zeroBull = osc crosses over 0
zeroBear = osc crosses under 0
if showSignals = 1 and sigWarm and bullCross then
drawtext("▲", barindex, osc - 0.6 * scaleAmf) coloured(0, 230, 118)
endif
if showSignals = 1 and sigWarm and bearCross then
drawtext("▼", barindex, osc + 0.6 * scaleAmf) coloured(255, 82, 82)
endif
if useZeroCross = 1 and sigWarm and zeroBull then
drawpoint(barindex, 0, 3) coloured(0, 230, 118)
endif
if useZeroCross = 1 and sigWarm and zeroBear then
drawpoint(barindex, 0, 3) coloured(255, 82, 82)
endif
//----------------------------------------------
// === DIVERGENCIAS REGULARES ===
// Pivote estricto: divRb barras a la derecha, divLb a la izquierda.
// El original exige pivote de precio Y de oscilador en la MISMA barra
//----------------------------------------------
if useDiv = 1 and sigWarm then
oscPivLoOk = osc[divRb] < lowest[divRb](osc) and osc[divRb] < lowest[divLb](osc)[rbp1]
prcPivLoOk = low[divRb] < lowest[divRb](low) and low[divRb] < lowest[divLb](low)[rbp1]
oscPivHiOk = osc[divRb] > highest[divRb](osc) and osc[divRb] > highest[divLb](osc)[rbp1]
prcPivHiOk = high[divRb] > highest[divRb](high) and high[divRb] > highest[divLb](high)[rbp1]
if oscPivLoOk and prcPivLoOk then
if hasLo = 1 and low[divRb] < prevPrcLo and osc[divRb] > prevOscLo then
drawsegment(prevLoBar, prevOscLo, barindex - divRb, osc[divRb]) coloured(0, 230, 118) style(line, 2)
drawtext("Bull Div", barindex - divRb, osc[divRb] - 1.1 * scaleAmf) coloured(0, 230, 118)
divState = 1
divBar = barindex
endif
prevOscLo = osc[divRb]
prevPrcLo = low[divRb]
prevLoBar = barindex - divRb
hasLo = 1
endif
if oscPivHiOk and prcPivHiOk then
if hasHi = 1 and high[divRb] > prevPrcHi and osc[divRb] < prevOscHi then
drawsegment(prevHiBar, prevOscHi, barindex - divRb, osc[divRb]) coloured(255, 82, 82) style(line, 2)
drawtext("Bear Div", barindex - divRb, osc[divRb] + 1.1 * scaleAmf) coloured(255, 82, 82)
divState = 0 - 1
divBar = barindex
endif
prevOscHi = osc[divRb]
prevPrcHi = high[divRb]
prevHiBar = barindex - divRb
hasHi = 1
endif
endif
if barindex > divBar + 20 then
divState = 0
endif
//----------------------------------------------
// === PANEL RESUMEN ===
//----------------------------------------------
if showPanel = 1 and islastbarupdate then
drawtext("ADAPTIVE MOMENTUM FUSION", -185, -15) anchor(topright) coloured(200, 200, 200)
drawtext("Periodos: #fastLen# / #slowLen# / #signalLen#", -185, -34) anchor(topright) coloured(160, 160, 160)
if engineMode = 1 then
drawtext("Motor: Efficiency", -185, -53) anchor(topright) coloured(160, 160, 160)
elsif engineMode = 2 then
drawtext("Motor: Volatility", -185, -53) anchor(topright) coloured(160, 160, 160)
elsif engineMode = 3 then
drawtext("Motor: Fractal", -185, -53) anchor(topright) coloured(160, 160, 160)
elsif engineMode = 4 then
drawtext("Motor: Momentum", -185, -53) anchor(topright) coloured(160, 160, 160)
elsif engineMode = 5 then
drawtext("Motor: Volume", -185, -53) anchor(topright) coloured(160, 160, 160)
else
drawtext("Motor: Composite", -185, -53) anchor(topright) coloured(160, 160, 160)
endif
if osc > sigLine then
drawtext("Momentum: alcista", -185, -72) anchor(topright) coloured(0, 230, 118)
else
drawtext("Momentum: bajista", -185, -72) anchor(topright) coloured(255, 82, 82)
endif
drawtext("Fuerza: #strRound#%", -185, -91) anchor(topright) coloured(160, 160, 160)
if divState = 1 then
drawtext("Divergencia: alcista", -185, -110) anchor(topright) coloured(0, 230, 118)
elsif divState = 0 - 1 then
drawtext("Divergencia: bajista", -185, -110) anchor(topright) coloured(255, 82, 82)
else
drawtext("Divergencia: ninguna", -185, -110) anchor(topright) coloured(160, 160, 160)
endif
endif
//----------------------------------------------
// === SALIDA ===
//----------------------------------------------
if showHisto = 1 then
histPlot = histVal
else
histPlot = undefined
endif
return histPlot coloured(rh, gh, bh) style(histogram) as "Histograma AMF", osc coloured(rc, gc, bc) style(line, 2) as "AMF", sigLine coloured(rs, gs, bs) style(line, 1) as "Senal", 0 as "Cero"
Muchas gracias Iván.
Describe what this topic is trying to build, in plain English, and ProRealAI writes the ProRealTime™ indicator, screener or system for you.
Programación del MACD Adaptative Momentun fusion.
This topic contains 4 replies,
has 3 voices, and was last updated by Trader18
1 month, 3 weeks ago.
| Forum: | ProBuilder: Indicadores y Herramientas |
| Language: | Spanish |
| Started: | 07/24/2026 |
| Status: | Active |
| Attachments: | No files |
The information collected on this form is stored in a computer file by ProRealCode to create and access your ProRealCode profile. This data is kept in a secure database for the duration of the member's membership. They will be kept as long as you use our services and will be automatically deleted after 3 years of inactivity. Your personal data is used to create your private profile on ProRealCode. This data is maintained by SAS ProRealCode, 407 rue Freycinet, 59151 Arleux, France. If you subscribe to our newsletters, your email address is provided to our service provider "MailChimp" located in the United States, with whom we have signed a confidentiality agreement. This company is also compliant with the EU/Swiss Privacy Shield, and the GDPR. For any request for correction or deletion concerning your data, you can directly contact the ProRealCode team by email at privacy@prorealcode.com If you would like to lodge a complaint regarding the use of your personal data, you can contact your data protection supervisory authority.