SuperTrend/SuperTrend.mq5

297 satır
20 KiB
MQL5
Ham Kalıcı Bağlantı Normal Görünüm Geçmiş

<EFBFBD><EFBFBD>//T%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%P%W%
//Q% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%W% Q%
//Q% <EFBFBD>%<EFBFBD>%T%P%P%P%]%Z%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%T%]%<EFBFBD>%<EFBFBD>%T%P%P%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%T%P%P%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%T%P%P%P%]%<EFBFBD>%<EFBFBD>%T%P%P%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%T%P%P%P%]%<EFBFBD>%<EFBFBD>%T%P%P%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%Q% Q%
//Q% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% Z%<EFBFBD>%<EFBFBD>%<EFBFBD>%T%]% <EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%T%]%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%Q%<EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q%<EFBFBD>%<EFBFBD>%T%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%Q% Q%
//Q% <EFBFBD>%<EFBFBD>%T%P%P%]% <EFBFBD>%<EFBFBD>%T%<EFBFBD>%<EFBFBD>%W% <EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q%<EFBFBD>%<EFBFBD>%T%P%P%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%T%P%P%]% <EFBFBD>%<EFBFBD>%T%P%P%<EFBFBD>%<EFBFBD>%Q%<EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q%<EFBFBD>%<EFBFBD>%Q%Z%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%Q% Q%
//Q% <EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%T%]% <EFBFBD>%<EFBFBD>%W%Z%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%T%]%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%T%]%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W%<EFBFBD>%<EFBFBD>%Q% <EFBFBD>%<EFBFBD>%Q%Z%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%W%Z%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%<EFBFBD>%T%]%<EFBFBD>%<EFBFBD>%Q% Z%<EFBFBD>%<EFBFBD>%<EFBFBD>%Q% Q%
//Q% Z%P%P%P%P%P%]%Z%P%]% Z%P%]% Z%P%P%P%P%]% Z%P%P%P%P%P%]% Z%P%P%P%P%P%]%Z%P%]% Z%P%]% Z%P%P%P%P%]% Z%P%P%P%P%]% Z%P%]% Z%P%P%]% Q%
//Z%P%P%P%P%P%P%P% Algorithms that observe P%P%P%P%P%P% Signals that speak P%P%P%P%P%P%P%P%P%P%P%P%P%P%]%
// Indicador t<EFBFBD>cnico SuperTrend
// Basado en el concepto original de Olivier Seban.
// Inspirado en la visualizaci<EFBFBD>n popularizada por KivancOzbilgic.
// Implementaci<EFBFBD>n para MetaTrader por Ulises Calder<EFBFBD>n Bautista.
#property copyright "Exobeacon Labs"
#property link "https://www.exobeacon.com/"
#property version "1.3"
#property description "SuperTrend  Adaptive Trend-Following Indicator"
#property description "ATR-based dynamic support/resistance overlay that adapts to volatility in real time."
#property description " "
#property description "0000000000((=<3D>}<7D>))0000000000"
#property description "=<3D><><EFBFBD> mql5.com/en/users/ulisescalb"
#property description "=<3D><><EFBFBD> github.com/Exobeacon-Labs"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 2
// Propiedades de las l<EFBFBD>neas
#property indicator_label1 "SuperTrend Up"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrLime
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
#property indicator_label2 "SuperTrend Down"
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 2
// Par<EFBFBD>metros de entrada
input int InpAtrPeriod = 10; // ATR Length
input double InpFactor = 3.0; // Factor
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_MEDIAN; // Applied Price
// Buffers del indicador
double UpTrendBuffer[];
double DownTrendBuffer[];
double SuperTrendBuffer[];
double DirectionBuffer[];
// Handle del ATR
int atrHandle;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Validaci<EFBFBD>n de par<EFBFBD>metros
if(InpAtrPeriod <= 0)
{
Print("Error: ATR Period debe ser mayor que 0");
return(INIT_PARAMETERS_INCORRECT);
}
if(InpFactor <= 0)
{
Print("Error: Factor debe ser mayor que 0");
return(INIT_PARAMETERS_INCORRECT);
}
// Asignaci<EFBFBD>n de buffers
SetIndexBuffer(0, UpTrendBuffer, INDICATOR_DATA);
SetIndexBuffer(1, DownTrendBuffer, INDICATOR_DATA);
SetIndexBuffer(2, SuperTrendBuffer, INDICATOR_CALCULATIONS);
SetIndexBuffer(3, DirectionBuffer, INDICATOR_CALCULATIONS);
// Configuraci<EFBFBD>n de valores vac<EFBFBD>os
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
// Inicializar arrays como series
ArraySetAsSeries(UpTrendBuffer, true);
ArraySetAsSeries(DownTrendBuffer, true);
ArraySetAsSeries(SuperTrendBuffer, true);
ArraySetAsSeries(DirectionBuffer, true);
// Crear handle del ATR
atrHandle = iATR(_Symbol, _Period, InpAtrPeriod);
if(atrHandle == INVALID_HANDLE)
{
Print("Error al crear el indicador ATR");
return(INIT_FAILED);
}
// Nombre del indicador
string priceLabel = "";
switch(InpAppliedPrice)
{
case PRICE_CLOSE: priceLabel = "Close"; break;
case PRICE_OPEN: priceLabel = "Open"; break;
case PRICE_HIGH: priceLabel = "High"; break;
case PRICE_LOW: priceLabel = "Low"; break;
case PRICE_MEDIAN: priceLabel = "Median"; break;
case PRICE_TYPICAL: priceLabel = "Typical"; break;
case PRICE_WEIGHTED: priceLabel = "Weighted"; break;
}
IndicatorSetString(INDICATOR_SHORTNAME,
StringFormat("SuperTrend(%d,%.2f,%s)", InpAtrPeriod, InpFactor, priceLabel));
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(atrHandle != INVALID_HANDLE)
IndicatorRelease(atrHandle);
}
//+------------------------------------------------------------------+
//| Funci<EFBFBD>n auxiliar para obtener el precio aplicado |
//+------------------------------------------------------------------+
double GetAppliedPrice(const int pos,
const double &open[],
const double &high[],
const double &low[],
const double &close[])
{
switch(InpAppliedPrice)
{
case PRICE_CLOSE:
return close[pos];
case PRICE_OPEN:
return open[pos];
case PRICE_HIGH:
return high[pos];
case PRICE_LOW:
return low[pos];
case PRICE_MEDIAN:
return (high[pos] + low[pos]) / 2.0;
case PRICE_TYPICAL:
return (high[pos] + low[pos] + close[pos]) / 3.0;
case PRICE_WEIGHTED:
return (high[pos] + low[pos] + close[pos] + close[pos]) / 4.0;
default:
return (high[pos] + low[pos]) / 2.0; // Default a Median
}
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
if(rates_total < InpAtrPeriod)
return(0);
// Configurar arrays como series
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
// Obtener valores del ATR
double atr[];
ArraySetAsSeries(atr, true);
int to_copy = rates_total - prev_calculated + InpAtrPeriod + 1;
if(prev_calculated == 0)
to_copy = rates_total;
if(CopyBuffer(atrHandle, 0, 0, to_copy, atr) <= 0)
{
Print("Error al copiar datos del ATR");
return(0);
}
// Determinar desde d<EFBFBD>nde calcular
int start;
if(prev_calculated == 0)
start = InpAtrPeriod;
else
start = prev_calculated - 1;
// Calcular SuperTrend
for(int i = start; i < rates_total; i++)
{
int pos = rates_total - 1 - i;
// Calcular l<EFBFBD>nea central usando el precio aplicado seleccionado
double basePrice = GetAppliedPrice(pos, open, high, low, close);
// Calcular bandas b<EFBFBD>sicas
double upperBand = basePrice + InpFactor * atr[pos];
double lowerBand = basePrice - InpFactor * atr[pos];
// Ajustar bandas seg<EFBFBD>n la barra anterior
if(i > InpAtrPeriod)
{
int prevPos = pos + 1;
// Ajustar banda superior
if(upperBand < SuperTrendBuffer[prevPos] || close[prevPos] > SuperTrendBuffer[prevPos])
upperBand = upperBand;
else
upperBand = SuperTrendBuffer[prevPos];
// Ajustar banda inferior
if(lowerBand > SuperTrendBuffer[prevPos] || close[prevPos] < SuperTrendBuffer[prevPos])
lowerBand = lowerBand;
else
lowerBand = SuperTrendBuffer[prevPos];
}
// Determinar direcci<EFBFBD>n y valor del SuperTrend
if(i == InpAtrPeriod)
{
SuperTrendBuffer[pos] = upperBand;
DirectionBuffer[pos] = 1; // Tendencia bajista
}
else
{
int prevPos = pos + 1;
// Verificar cambio de tendencia
if(DirectionBuffer[prevPos] == 1) // Estaba en tendencia bajista
{
if(close[pos] > SuperTrendBuffer[prevPos])
{
// Cambio a tendencia alcista
DirectionBuffer[pos] = -1;
SuperTrendBuffer[pos] = lowerBand;
}
else
{
// Contin<EFBFBD>a bajista
DirectionBuffer[pos] = 1;
SuperTrendBuffer[pos] = upperBand;
}
}
else // Estaba en tendencia alcista
{
if(close[pos] < SuperTrendBuffer[prevPos])
{
// Cambio a tendencia bajista
DirectionBuffer[pos] = 1;
SuperTrendBuffer[pos] = upperBand;
}
else
{
// Contin<EFBFBD>a alcista
DirectionBuffer[pos] = -1;
SuperTrendBuffer[pos] = lowerBand;
}
}
}
// Asignar valores a los buffers de plot
if(DirectionBuffer[pos] < 0)
{
// Tendencia alcista
UpTrendBuffer[pos] = SuperTrendBuffer[pos];
DownTrendBuffer[pos] = 0.0;
}
else
{
// Tendencia bajista
UpTrendBuffer[pos] = 0.0;
DownTrendBuffer[pos] = SuperTrendBuffer[pos];
}
}
return(rates_total);
}
//+------------------------------------------------------------------+