585 lines
No EOL
54 KiB
MQL5
585 lines
No EOL
54 KiB
MQL5
//╔════════════════════════════════════════════════════════════════════════╗
|
|
//║ ██████╗██╗ ██╗ █████╗ ██████╗ ██████╗ █████╗ █████╗ █████╗ ███╗ ██╗ ║
|
|
//║ ██╔═══╝╚██╗██╔╝██╔══██╗██╔══██╗██╔═══╝██╔══██╗██╔═══╝██╔══██╗████╗ ██║ ║
|
|
//║ █████╗ ╚███╔╝ ██║ ██║██████╔╝█████╗ ███████║██║ ██║ ██║██╔██╗██║ ║
|
|
//║ ██╔══╝ ██╔██╗ ██║ ██║██╔══██╗██╔══╝ ██╔══██║██║ ██║ ██║██║╚████║ ║
|
|
//║ ██████╗██╔╝ ██╗╚█████╔╝██████╔╝██████╗██║ ██║╚█████╗╚█████╔╝██║ ╚███║ ║
|
|
//║ ╚═════╝╚═╝ ╚═╝ ╚════╝ ╚═════╝ ╚═════╝╚═╝ ╚═╝ ╚════╝ ╚════╝ ╚═╝ ╚══╝ ║
|
|
//╚═══════ Algorithms that observe ════ Signals that speak ════════════════╝
|
|
//
|
|
//+------------------------------------------------------------------+
|
|
//| Archivo : CoralTrendIndicator.mq5 |
|
|
//| Origen : Coral Trend Indicator [LazyBear] - TradingView |
|
|
//| URL ref. : tradingview.com/script/qyUwc2Al |
|
|
//| |
|
|
//| El Coral Trend Indicator es matematicamente identico al |
|
|
//| T3 Moving Average de Tim Tillson (TASC, Enero 1998). |
|
|
//| Consiste en 6 EMAs en cascada combinadas via coeficientes |
|
|
//| de expansion binomial de tercer grado: |
|
|
//| bfr = -cd^3 * e6 + c3*e5 + c4*e4 + c5*e3 |
|
|
//| donde c3 = 3(cd^2 + cd^3), c4 = -3(2cd^2 + cd + cd^3), |
|
|
//| c5 = 1 + 3cd + 3cd^2 + cd^3. |
|
|
//| |
|
|
//| Herencia: Sistema THV (Traders Harmonic Volatility) de |
|
|
//| JanusTrader/CobraForex en ForexFactory. LazyBear porto |
|
|
//| el indicador MT4 a Pine Script en Enero 2015. |
|
|
//| |
|
|
//| Modos de visualizacion: |
|
|
//| - Trend Line: linea coloreada sobre el grafico (defecto) |
|
|
//| - Color Bars: velas del precio coloreadas por tendencia |
|
|
//| - Ambos simultaneamente si se desea |
|
|
//| |
|
|
//| Direccion de tendencia por pendiente: |
|
|
//| bfr[n] > bfr[n-1] => Alcista (Verde) |
|
|
//| bfr[n] < bfr[n-1] => Bajista (Rojo) |
|
|
//| bfr[n] == bfr[n-1] => Neutral (Azul/Gris) |
|
|
//+------------------------------------------------------------------+
|
|
|
|
#property copyright "Exobeacon Labs"
|
|
#property link "https://www.exobeacon.com/"
|
|
#property version "1.0"
|
|
#property description "Coral Trend Indicator [LazyBear] v1.0"
|
|
#property description "T3 Moving Average (Tillson, 1998) with trend coloring."
|
|
#property description "6 cascaded EMAs + binomial polynomial combination."
|
|
#property description "Ported from TradingView Pine Script (LazyBear)."
|
|
#property description " "
|
|
#property description "〰〰〰〰〰((👽))〰〰〰〰〰"
|
|
#property description "🛸 mql5.com/en/users/ulisescalb"
|
|
#property description "🛸 github.com/Exobeacon-Labs"
|
|
#property strict
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Propiedades del indicador |
|
|
//+------------------------------------------------------------------+
|
|
// --- Ventana: sobre el grafico de precios ---
|
|
#property indicator_chart_window
|
|
|
|
// --- Buffers totales: 2 (linea + color) + 6 internos + 5 (OHLC candles + color) = 13 ---
|
|
#property indicator_buffers 13
|
|
#property indicator_plots 2
|
|
|
|
// --- Plot 0: Linea Coral Trend (DRAW_COLOR_LINE) ---
|
|
#property indicator_label1 "Coral Trend"
|
|
#property indicator_type1 DRAW_COLOR_LINE
|
|
#property indicator_color1 clrLime, clrRed, clrDodgerBlue
|
|
#property indicator_style1 STYLE_SOLID
|
|
#property indicator_width1 3
|
|
|
|
// --- Plot 1: Color Bars (DRAW_COLOR_CANDLES) ---
|
|
#property indicator_label2 "Open;High;Low;Close"
|
|
#property indicator_type2 DRAW_COLOR_CANDLES
|
|
#property indicator_color2 clrLime, clrRed, clrDodgerBlue
|
|
#property indicator_style2 STYLE_SOLID
|
|
#property indicator_width2 1
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Parametros de entrada |
|
|
//+------------------------------------------------------------------+
|
|
|
|
// === Parametros del algoritmo Coral/T3 ===
|
|
input group "====== Coral Algorithm ======"
|
|
input int InpSmoothPeriod = 21; // Smoothing Period
|
|
input double InpConstantD = 0.4; // Constant D (Volume Factor)
|
|
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // Applied Price
|
|
|
|
// === Modo de visualizacion ===
|
|
input group "====== Display Mode ======"
|
|
input bool InpShowTrendLine = true; // Show Trend Line
|
|
input bool InpColorBars = false; // Color Bars by Trend
|
|
input int InpLineWidth = 3; // Trend Line Width (1-5)
|
|
input color InpColorUp = clrLime; // Uptrend Color
|
|
input color InpColorDown = clrRed; // Downtrend Color
|
|
input color InpColorNeutral = clrDodgerBlue; // Neutral Color
|
|
|
|
// === Sistema de alertas ===
|
|
input group "====== Alerts ======"
|
|
input bool InpEnableAlerts = false; // Enable Alert System
|
|
input bool InpAlertPopup = true; // Alert: Popup
|
|
input bool InpAlertSound = false; // Alert: Sound
|
|
input bool InpAlertPush = false; // Alert: Push Notification
|
|
input bool InpAlertEmail = false; // Alert: Email
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Buffers de indicador |
|
|
//+------------------------------------------------------------------+
|
|
|
|
// --- Plot 0: Linea Coral ---
|
|
double g_coralBuffer[]; // Buffer de datos de la linea Coral
|
|
double g_coralColor[]; // Buffer de indice de color de la linea
|
|
|
|
// --- Plot 1: Color Candles (OHLC + color) ---
|
|
double g_candleOpen[]; // Buffer Open para velas coloreadas
|
|
double g_candleHigh[]; // Buffer High para velas coloreadas
|
|
double g_candleLow[]; // Buffer Low para velas coloreadas
|
|
double g_candleClose[]; // Buffer Close para velas coloreadas
|
|
double g_candleColor[]; // Buffer de indice de color de velas
|
|
|
|
// --- Buffers internos: 6 EMAs en cascada ---
|
|
double g_i1[]; // EMA cascada nivel 1 (sobre precio)
|
|
double g_i2[]; // EMA cascada nivel 2 (sobre i1)
|
|
double g_i3[]; // EMA cascada nivel 3 (sobre i2)
|
|
double g_i4[]; // EMA cascada nivel 4 (sobre i3)
|
|
double g_i5[]; // EMA cascada nivel 5 (sobre i4)
|
|
double g_i6[]; // EMA cascada nivel 6 (sobre i5)
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Variables globales |
|
|
//+------------------------------------------------------------------+
|
|
|
|
// --- Coeficientes del filtro (calculados una vez en OnInit) ---
|
|
double g_c1 = 0.0; // Factor de suavizado alpha = 2/(di+1)
|
|
double g_c2 = 0.0; // Complemento (1 - alpha)
|
|
double g_c3 = 0.0; // Coeficiente para i5: 3*(cd^2 + cd^3)
|
|
double g_c4 = 0.0; // Coeficiente para i4: -3*(2*cd^2 + cd + cd^3)
|
|
double g_c5 = 0.0; // Coeficiente para i3: 1 + 3*cd + 3*cd^2 + cd^3
|
|
double g_cd3 = 0.0; // Coeficiente para i6: cd^3
|
|
|
|
// --- Control de alertas ---
|
|
datetime g_lastAlertTime = 0; // Tiempo de la ultima alerta enviada
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| OnInit - Inicializacion del indicador |
|
|
//+------------------------------------------------------------------+
|
|
int OnInit()
|
|
{
|
|
// --- Validacion de parametros de entrada ---
|
|
if(InpSmoothPeriod < 1)
|
|
{
|
|
Print("ERROR: Smoothing Period must be >= 1. Current: ", InpSmoothPeriod);
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
|
|
if(InpConstantD < 0.0 || InpConstantD > 2.0)
|
|
{
|
|
Print("ERROR: Constant D must be between 0.0 and 2.0. Current: ", InpConstantD);
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
|
|
if(InpLineWidth < 1 || InpLineWidth > 5)
|
|
{
|
|
Print("ERROR: Line Width must be between 1 and 5. Current: ", InpLineWidth);
|
|
return(INIT_PARAMETERS_INCORRECT);
|
|
}
|
|
|
|
// --- Asignacion de buffers ---
|
|
// Plot 0: Linea Coral (2 buffers: datos + color)
|
|
SetIndexBuffer(0, g_coralBuffer, INDICATOR_DATA);
|
|
SetIndexBuffer(1, g_coralColor, INDICATOR_COLOR_INDEX);
|
|
|
|
// Plot 1: Color Candles (5 buffers: OHLC + color)
|
|
SetIndexBuffer(2, g_candleOpen, INDICATOR_DATA);
|
|
SetIndexBuffer(3, g_candleHigh, INDICATOR_DATA);
|
|
SetIndexBuffer(4, g_candleLow, INDICATOR_DATA);
|
|
SetIndexBuffer(5, g_candleClose, INDICATOR_DATA);
|
|
SetIndexBuffer(6, g_candleColor, INDICATOR_COLOR_INDEX);
|
|
|
|
// Buffers internos: 6 EMAs en cascada (no visibles)
|
|
SetIndexBuffer(7, g_i1, INDICATOR_CALCULATIONS);
|
|
SetIndexBuffer(8, g_i2, INDICATOR_CALCULATIONS);
|
|
SetIndexBuffer(9, g_i3, INDICATOR_CALCULATIONS);
|
|
SetIndexBuffer(10, g_i4, INDICATOR_CALCULATIONS);
|
|
SetIndexBuffer(11, g_i5, INDICATOR_CALCULATIONS);
|
|
SetIndexBuffer(12, g_i6, INDICATOR_CALCULATIONS);
|
|
|
|
// --- Configuracion de colores del Plot 0 (Linea Coral) ---
|
|
PlotIndexSetInteger(0, PLOT_COLOR_INDEXES, 3);
|
|
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 0, InpColorUp);
|
|
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 1, InpColorDown);
|
|
PlotIndexSetInteger(0, PLOT_LINE_COLOR, 2, InpColorNeutral);
|
|
PlotIndexSetInteger(0, PLOT_LINE_WIDTH, InpLineWidth);
|
|
|
|
// --- Configuracion de colores del Plot 1 (Color Candles) ---
|
|
PlotIndexSetInteger(1, PLOT_COLOR_INDEXES, 3);
|
|
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 0, InpColorUp);
|
|
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 1, InpColorDown);
|
|
PlotIndexSetInteger(1, PLOT_LINE_COLOR, 2, InpColorNeutral);
|
|
|
|
// --- Visibilidad de plots segun configuracion ---
|
|
// Si no se muestra la linea, ocultar Plot 0
|
|
if(!InpShowTrendLine)
|
|
{
|
|
PlotIndexSetInteger(0, PLOT_DRAW_TYPE, DRAW_NONE);
|
|
}
|
|
|
|
// Si no se colorean velas, ocultar Plot 1
|
|
if(!InpColorBars)
|
|
{
|
|
PlotIndexSetInteger(1, PLOT_DRAW_TYPE, DRAW_NONE);
|
|
}
|
|
|
|
// --- PLOT_DRAW_BEGIN: evitar basura visual en las primeras barras ---
|
|
// El filtro necesita varias barras para estabilizarse.
|
|
// Usamos 3x el periodo de suavizado como margen conservador.
|
|
const int drawBegin = InpSmoothPeriod * 3;
|
|
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, drawBegin);
|
|
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, drawBegin);
|
|
|
|
// --- Etiquetas ---
|
|
PlotIndexSetString(0, PLOT_LABEL, "Coral Trend");
|
|
PlotIndexSetString(1, PLOT_LABEL, "Open;High;Low;Close");
|
|
|
|
// --- Nombre corto del indicador ---
|
|
const string shortName = StringFormat("Coral Trend(%d, %.2f)", InpSmoothPeriod, InpConstantD);
|
|
IndicatorSetString(INDICATOR_SHORTNAME, shortName);
|
|
|
|
// --- Pre-calculo de coeficientes del filtro Coral/T3 ---
|
|
// Paso 1: Factor de suavizado alpha derivado del periodo
|
|
// di = (sm - 1) / 2 + 1 => Para sm=21: di=11
|
|
// alpha = 2 / (di + 1) => Para sm=21: alpha = 2/12 = 0.16667
|
|
const double di = (InpSmoothPeriod - 1.0) / 2.0 + 1.0;
|
|
g_c1 = 2.0 / (di + 1.0);
|
|
g_c2 = 1.0 - g_c1;
|
|
|
|
// Paso 2: Coeficientes polinomiales derivados de Constant D
|
|
// Estos son los coeficientes de la expansion binomial de T3:
|
|
// T3 = (1+v)^3 * e3 - 3v(1+v)^2 * e4 + 3v^2(1+v) * e5 - v^3 * e6
|
|
// donde v = cd (Constant D)
|
|
const double cd = InpConstantD;
|
|
const double cd2 = cd * cd;
|
|
g_cd3 = cd * cd2; // cd^3
|
|
g_c3 = 3.0 * (cd2 + g_cd3); // 3*(cd^2 + cd^3) = 3*v^2*(1+v)
|
|
g_c4 = -3.0 * (2.0 * cd2 + cd + g_cd3); // -3*(2cd^2 + cd + cd^3) = -3*v*(1+v)^2
|
|
g_c5 = 3.0 * cd + 1.0 + g_cd3 + 3.0 * cd2; // 1 + 3cd + 3cd^2 + cd^3 = (1+v)^3
|
|
|
|
// --- Verificacion: la suma de coeficientes debe ser 1.0 (ganancia unitaria) ---
|
|
const double coeffSum = -g_cd3 + g_c3 + g_c4 + g_c5;
|
|
if(MathAbs(coeffSum - 1.0) > 1e-10)
|
|
{
|
|
PrintFormat("WARNING: Coefficient sum = %.15f (expected 1.0)", coeffSum);
|
|
}
|
|
|
|
// --- Inicializacion de variable de control de alertas ---
|
|
g_lastAlertTime = 0;
|
|
|
|
return(INIT_SUCCEEDED);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| OnDeinit - Limpieza al remover el indicador |
|
|
//+------------------------------------------------------------------+
|
|
void OnDeinit(const int reason)
|
|
{
|
|
// --- Limpiar comentario del chart si hubiera ---
|
|
Comment("");
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| GetAppliedPrice - Obtener el precio segun ENUM_APPLIED_PRICE |
|
|
//| Pine Script original usa close; aqui exponemos la opcion |
|
|
//+------------------------------------------------------------------+
|
|
double GetAppliedPrice(const int bar,
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[])
|
|
{
|
|
switch(InpAppliedPrice)
|
|
{
|
|
case PRICE_OPEN:
|
|
return(open[bar]);
|
|
case PRICE_HIGH:
|
|
return(high[bar]);
|
|
case PRICE_LOW:
|
|
return(low[bar]);
|
|
case PRICE_CLOSE:
|
|
return(close[bar]);
|
|
case PRICE_MEDIAN:
|
|
return((high[bar] + low[bar]) / 2.0);
|
|
case PRICE_TYPICAL:
|
|
return((high[bar] + low[bar] + close[bar]) / 3.0);
|
|
case PRICE_WEIGHTED:
|
|
return((high[bar] + low[bar] + close[bar] + close[bar]) / 4.0);
|
|
default:
|
|
return(close[bar]);
|
|
}
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| OnCalculate - Calculo principal del indicador |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total,
|
|
const int prev_calculated,
|
|
const datetime &time[],
|
|
const double &open[],
|
|
const double &high[],
|
|
const double &low[],
|
|
const double &close[],
|
|
const long &tick_volume[],
|
|
const long &volume[],
|
|
const int &spread[])
|
|
{
|
|
// --- Verificar minimo de barras disponibles ---
|
|
if(rates_total < 2)
|
|
return(0);
|
|
|
|
// --- Configurar indexacion: indice 0 = barra mas antigua (como Pine Script) ---
|
|
ArraySetAsSeries(open, false);
|
|
ArraySetAsSeries(high, false);
|
|
ArraySetAsSeries(low, false);
|
|
ArraySetAsSeries(close, false);
|
|
ArraySetAsSeries(time, false);
|
|
|
|
ArraySetAsSeries(g_coralBuffer, false);
|
|
ArraySetAsSeries(g_coralColor, false);
|
|
ArraySetAsSeries(g_candleOpen, false);
|
|
ArraySetAsSeries(g_candleHigh, false);
|
|
ArraySetAsSeries(g_candleLow, false);
|
|
ArraySetAsSeries(g_candleClose, false);
|
|
ArraySetAsSeries(g_candleColor, false);
|
|
ArraySetAsSeries(g_i1, false);
|
|
ArraySetAsSeries(g_i2, false);
|
|
ArraySetAsSeries(g_i3, false);
|
|
ArraySetAsSeries(g_i4, false);
|
|
ArraySetAsSeries(g_i5, false);
|
|
ArraySetAsSeries(g_i6, false);
|
|
|
|
// --- Determinar barra de inicio del calculo ---
|
|
// En la primera ejecucion, empezar desde barra 0.
|
|
// En ejecuciones subsiguientes, recalcular solo desde la penultima barra
|
|
// (porque la ultima podria haber sido una vela incompleta que se actualizo).
|
|
int start = 0;
|
|
if(prev_calculated > 0)
|
|
start = prev_calculated - 1;
|
|
|
|
// --- Bucle principal: calcular barra por barra ---
|
|
for(int bar = start; bar < rates_total; bar++)
|
|
{
|
|
// --- Obtener el precio de entrada para esta barra ---
|
|
const double src = GetAppliedPrice(bar, open, high, low, close);
|
|
|
|
// --- Barra 0: inicializacion ---
|
|
// Pine Script usa nz() que retorna 0 para valores nulos.
|
|
// Inicializamos todos los buffers internos a 0.0 en la primera barra.
|
|
if(bar == 0)
|
|
{
|
|
g_i1[0] = 0.0;
|
|
g_i2[0] = 0.0;
|
|
g_i3[0] = 0.0;
|
|
g_i4[0] = 0.0;
|
|
g_i5[0] = 0.0;
|
|
g_i6[0] = 0.0;
|
|
g_coralBuffer[0] = 0.0;
|
|
g_coralColor[0] = 2; // Neutral
|
|
|
|
// Velas coloreadas: barra 0
|
|
if(InpColorBars)
|
|
{
|
|
g_candleOpen[0] = open[0];
|
|
g_candleHigh[0] = high[0];
|
|
g_candleLow[0] = low[0];
|
|
g_candleClose[0] = close[0];
|
|
g_candleColor[0] = 2; // Neutral
|
|
}
|
|
else
|
|
{
|
|
g_candleOpen[0] = EMPTY_VALUE;
|
|
g_candleHigh[0] = EMPTY_VALUE;
|
|
g_candleLow[0] = EMPTY_VALUE;
|
|
g_candleClose[0] = EMPTY_VALUE;
|
|
g_candleColor[0] = 0;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// === ETAPA 1: Seis EMAs en cascada ===
|
|
// Cada nivel suaviza la salida del nivel anterior.
|
|
// Formula EMA recursiva: ema[n] = alpha * input[n] + (1-alpha) * ema[n-1]
|
|
g_i1[bar] = g_c1 * src + g_c2 * g_i1[bar - 1];
|
|
g_i2[bar] = g_c1 * g_i1[bar] + g_c2 * g_i2[bar - 1];
|
|
g_i3[bar] = g_c1 * g_i2[bar] + g_c2 * g_i3[bar - 1];
|
|
g_i4[bar] = g_c1 * g_i3[bar] + g_c2 * g_i4[bar - 1];
|
|
g_i5[bar] = g_c1 * g_i4[bar] + g_c2 * g_i5[bar - 1];
|
|
g_i6[bar] = g_c1 * g_i5[bar] + g_c2 * g_i6[bar - 1];
|
|
|
|
// === ETAPA 2: Combinacion polinomial Coral/T3 ===
|
|
// bfr = -cd^3 * i6 + c3 * i5 + c4 * i4 + c5 * i3
|
|
// Esto implementa T3 = (1+v)^3*e3 - 3v(1+v)^2*e4 + 3v^2(1+v)*e5 - v^3*e6
|
|
g_coralBuffer[bar] = -g_cd3 * g_i6[bar]
|
|
+ g_c3 * g_i5[bar]
|
|
+ g_c4 * g_i4[bar]
|
|
+ g_c5 * g_i3[bar];
|
|
|
|
// === ETAPA 3: Determinar direccion de tendencia por pendiente ===
|
|
// Comparar valor actual con valor anterior (identico al original Pine)
|
|
if(g_coralBuffer[bar] > g_coralBuffer[bar - 1])
|
|
g_coralColor[bar] = 0; // Color index 0 = Alcista (Verde)
|
|
else if(g_coralBuffer[bar] < g_coralBuffer[bar - 1])
|
|
g_coralColor[bar] = 1; // Color index 1 = Bajista (Rojo)
|
|
else
|
|
g_coralColor[bar] = 2; // Color index 2 = Neutral (Azul)
|
|
|
|
// === ETAPA 4: Velas coloreadas (si esta activado) ===
|
|
if(InpColorBars)
|
|
{
|
|
g_candleOpen[bar] = open[bar];
|
|
g_candleHigh[bar] = high[bar];
|
|
g_candleLow[bar] = low[bar];
|
|
g_candleClose[bar] = close[bar];
|
|
g_candleColor[bar] = g_coralColor[bar]; // Mismo indice de color que la linea
|
|
}
|
|
else
|
|
{
|
|
// Si Color Bars esta desactivado, llenar con EMPTY_VALUE
|
|
g_candleOpen[bar] = EMPTY_VALUE;
|
|
g_candleHigh[bar] = EMPTY_VALUE;
|
|
g_candleLow[bar] = EMPTY_VALUE;
|
|
g_candleClose[bar] = EMPTY_VALUE;
|
|
g_candleColor[bar] = 0;
|
|
}
|
|
}
|
|
|
|
// --- Sistema de alertas: procesar solo en la ultima vela cerrada ---
|
|
if(InpEnableAlerts && rates_total >= 3)
|
|
{
|
|
ProcessAlerts(rates_total, time);
|
|
}
|
|
|
|
return(rates_total);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| ProcessAlerts - Evaluar y enviar alertas de cambio de tendencia |
|
|
//| Se evalua sobre la vela cerrada (rates_total - 2) comparada con |
|
|
//| la vela anterior (rates_total - 3) para evitar repintado. |
|
|
//+------------------------------------------------------------------+
|
|
void ProcessAlerts(const int rates_total, const datetime &time[])
|
|
{
|
|
// --- Indices de las dos ultimas velas cerradas ---
|
|
const int barCurr = rates_total - 2; // Ultima vela cerrada
|
|
const int barPrev = rates_total - 3; // Vela anterior a la cerrada
|
|
|
|
// --- Verificar rango valido ---
|
|
if(barCurr < 1 || barPrev < 0)
|
|
return;
|
|
|
|
// --- Evitar alertas duplicadas: una alerta por vela ---
|
|
if(time[barCurr] <= g_lastAlertTime)
|
|
return;
|
|
|
|
// --- Obtener estados de tendencia ---
|
|
const int trendCurr = (int)g_coralColor[barCurr];
|
|
const int trendPrev = (int)g_coralColor[barPrev];
|
|
|
|
// --- Detectar cambio de tendencia ---
|
|
if(trendCurr == trendPrev)
|
|
return; // Sin cambio, no alertar
|
|
|
|
// --- Construir mensaje de alerta ---
|
|
string direction = "";
|
|
if(trendCurr == 0)
|
|
direction = "BULLISH"; // Cambio a tendencia alcista
|
|
else if(trendCurr == 1)
|
|
direction = "BEARISH"; // Cambio a tendencia bajista
|
|
else
|
|
direction = "NEUTRAL"; // Cambio a neutral
|
|
|
|
// Prefijo con nombre del indicador, simbolo y timeframe
|
|
const string prefix = StringFormat("Coral Trend | %s %s | ",
|
|
_Symbol,
|
|
EnumToString(Period()));
|
|
const string message = prefix + "Trend changed to " + direction;
|
|
|
|
// --- Registrar tiempo de alerta para evitar duplicados ---
|
|
g_lastAlertTime = time[barCurr];
|
|
|
|
// --- Enviar por los canales configurados ---
|
|
if(InpAlertPopup)
|
|
Alert(message);
|
|
|
|
if(InpAlertSound)
|
|
PlaySound("alert.wav");
|
|
|
|
if(InpAlertPush)
|
|
SendNotification(message);
|
|
|
|
if(InpAlertEmail)
|
|
SendMail("Coral Trend Alert", message);
|
|
}
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//| ================================================================ |
|
|
//| REFERENCIA: CODIGO PINE SCRIPT ORIGINAL |
|
|
//| ================================================================ |
|
|
//| |
|
|
//| Autor : LazyBear |
|
|
//| Script : Coral Trend Indicator [LazyBear] |
|
|
//| URL : tradingview.com/script/qyUwc2Al |
|
|
//| Version : Pine Script v1/v2 (publicado Enero 14, 2015) |
|
|
//| Licencia : Codigo abierto en TradingView |
|
|
//| |
|
|
//| --- INICIO DEL CODIGO PINE SCRIPT --- |
|
|
//| |
|
|
//| study(title="Coral Trend Indicator [LazyBear]", |
|
|
//| shorttitle="CTI_LB", overlay=true) |
|
|
//| src=close |
|
|
//| sm =input(21, title="Smoothing Period") |
|
|
//| cd = input(0.4, title="Constant D") |
|
|
//| ebc=input(false, title="Color Bars") |
|
|
//| ribm=input(false, title="Ribbon Mode") |
|
|
//| |
|
|
//| di = (sm - 1.0) / 2.0 + 1.0 |
|
|
//| c1 = 2 / (di + 1.0) |
|
|
//| c2 = 1 - c1 |
|
|
//| c3 = 3.0 * (cd * cd + cd * cd * cd) |
|
|
//| c4 = -3.0 * (2.0 * cd * cd + cd + cd * cd * cd) |
|
|
//| c5 = 3.0 * cd + 1.0 + cd * cd * cd + 3.0 * cd * cd |
|
|
//| |
|
|
//| i1 = c1*src + c2*nz(i1[1]) |
|
|
//| i2 = c1*i1 + c2*nz(i2[1]) |
|
|
//| i3 = c1*i2 + c2*nz(i3[1]) |
|
|
//| i4 = c1*i3 + c2*nz(i4[1]) |
|
|
//| i5 = c1*i4 + c2*nz(i5[1]) |
|
|
//| i6 = c1*i5 + c2*nz(i6[1]) |
|
|
//| |
|
|
//| bfr = -cd*cd*cd*i6 + c3*(i5) + c4*(i4) + c5*(i3) |
|
|
//| |
|
|
//| bfrC = bfr > nz(bfr[1]) ? green : |
|
|
//| bfr < nz(bfr[1]) ? red : blue |
|
|
//| |
|
|
//| tc=ebc?gray:bfrC |
|
|
//| plot(ribm?na:bfr, title="Trend", linewidth=3, |
|
|
//| style=circles, color=tc) |
|
|
//| bgcolor(ribm?bfrC:na, transp=50) |
|
|
//| barcolor(ebc?bfrC:na) |
|
|
//| |
|
|
//| --- FIN DEL CODIGO PINE SCRIPT --- |
|
|
//| |
|
|
//| ================================================================ |
|
|
//| CORRESPONDENCIA PINE SCRIPT -> MQL5 |
|
|
//| ================================================================ |
|
|
//| |
|
|
//| Pine: src = close |
|
|
//| MQL5: GetAppliedPrice() con PRICE_CLOSE por defecto |
|
|
//| (expandido a ENUM_APPLIED_PRICE para flexibilidad) |
|
|
//| |
|
|
//| Pine: i1 = c1*src + c2*nz(i1[1]) |
|
|
//| MQL5: g_i1[bar] = g_c1 * src + g_c2 * g_i1[bar-1] |
|
|
//| nz() retorna 0 para null; MQL5 inicializa buffers a 0.0 |
|
|
//| |
|
|
//| Pine: bfr = -cd*cd*cd*i6 + c3*i5 + c4*i4 + c5*i3 |
|
|
//| MQL5: g_coralBuffer[bar] = -g_cd3*g_i6 + g_c3*g_i5 + ... |
|
|
//| Coeficientes pre-calculados en OnInit() para eficiencia |
|
|
//| |
|
|
//| Pine: bfrC = bfr > nz(bfr[1]) ? green : ... |
|
|
//| MQL5: g_coralColor[bar] = 0/1/2 con DRAW_COLOR_LINE |
|
|
//| |
|
|
//| Pine: barcolor(ebc?bfrC:na) |
|
|
//| MQL5: DRAW_COLOR_CANDLES con InpColorBars toggle |
|
|
//| |
|
|
//| Pine: plot(..., style=circles, ...) |
|
|
//| MQL5: DRAW_COLOR_LINE (linea continua en lugar de circulos; |
|
|
//| para circulos usar DRAW_COLOR_ARROW con codigo 159) |
|
|
//| |
|
|
//| DIFERENCIAS TECNICAS: |
|
|
//| - Pine inicializa series con nz()=0; MQL5 usa ArrayInitialize=0 |
|
|
//| - Pine procesa oldest->newest; MQL5 con ArraySetAsSeries(false) |
|
|
//| logra el mismo orden |
|
|
//| - El indicador NO repinta: solo usa datos cerrados para alertas |
|
|
//| - Se agrego ENUM_APPLIED_PRICE (no existe en el original) |
|
|
//| - Se agrego sistema de alertas multi-canal (no existe en el orig)|
|
|
//| - Ribbon Mode del original no se implemento como plot separado; |
|
|
//| se reemplazo con Color Bars que es mas util en chart window |
|
|
//| |
|
|
//+------------------------------------------------------------------+ |