ChartALGUIEN PUEDE HACER QUE TRABAJE EN TIEMPO REAL MUY BUENO PINTA 3 NIVELES DE TP Y DOS DE SL

1

Code: Select all

[[co//+-----------------------------------------------------------------+
//|                                              DarkPoint_MQL4.mq4  |
//|                                  VERSIÓN SIN REPAINTING CORREGIDA|
//+------------------------------------------------------------------+
#property copyright "Dark Point No-Repaint"
#property link      ""
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2

//--- Plot Buy Point
#property indicator_label1  "Buy Signal"
#property indicator_type1   DRAW_ARROW
#property indicator_color1  clrAqua
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3

//--- Plot Sell Point
#property indicator_label2  "Sell Signal"
#property indicator_type2   DRAW_ARROW
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  3

//--- Input Parameters
input string InpObjectsPrefix = "DP_";
input int    InpDarkPointPeriod = 50;
input int    InpVolatilityFactor = 3;
input double InpSensitivityMultiplier = 1.0;
input int    InpATRPeriods = 18;
input bool   InpEnableTP1 = true;
input double InpTP1Multiplier = 0.4;
input bool   InpEnableTP2 = true;
input double InpTP2Multiplier = 1.0;
input bool   InpEnableTP3 = true;
input double InpTP3Multiplier = 3.2;
input bool   InpEnableSL1 = true;
input double InpSL1Multiplier = 1.6;
input bool   InpEnableSL2 = true;
input double InpSL2Multiplier = 3.2;
input int    InpLinesLength = 10;

//--- Indicator Buffers
double BuySignalBuffer[];
double SellSignalBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, BuySignalBuffer);
   SetIndexBuffer(1, SellSignalBuffer);
   
   SetIndexArrow(0, 233);
   SetIndexArrow(1, 234);
   
   SetIndexEmptyValue(0, EMPTY_VALUE);
   SetIndexEmptyValue(1, EMPTY_VALUE);
   
   SetIndexLabel(0, "Buy Signal");
   SetIndexLabel(1, "Sell Signal");
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectsDeleteAll(0, InpObjectsPrefix);
}

//+------------------------------------------------------------------+
//| 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 < InpDarkPointPeriod + InpATRPeriods)
      return(0);
   
   //--- Calculate ATR manualmente
   double atrBuffer[];
   ArrayResize(atrBuffer, rates_total);
   ArraySetAsSeries(atrBuffer, true);
   
   for(int i = 0; i < rates_total; i++)
   {
      if(i < InpATRPeriods)
      {
         atrBuffer[i] = 0;
         continue;
      }
      
      double sum = 0;
      for(int j = 0; j < InpATRPeriods; j++)
      {
         double tr = high[i-j] - low[i-j];
         sum += tr;
      }
      atrBuffer[i] = sum / InpATRPeriods;
   }
   
   //--- Calculate base price (SMA of typical price)
   double basePrice[];
   ArrayResize(basePrice, rates_total);
   ArraySetAsSeries(basePrice, true);
   
   for(int i = 0; i < rates_total; i++)
   {
      if(i < InpDarkPointPeriod)
      {
         basePrice[i] = 0;
         continue;
      }
      
      double sum = 0;
      for(int j = 0; j < InpDarkPointPeriod; j++)
      {
         double typicalPrice = (high[i-j] + low[i-j] + close[i-j]) / 3.0;
         sum += typicalPrice;
      }
      basePrice[i] = sum / InpDarkPointPeriod;
   }
   
   //--- Calculate bands and detect signals
   // EMPEZAR desde prev_calculated-1 para no recalcular todo, pero SIN incluir la vela actual
   int start = MathMax(prev_calculated - 1, InpDarkPointPeriod);
   
   // IMPORTANTE: Solo procesar hasta rates_total-1 (excluir la vela actual i=0)
   for(int i = start; i < rates_total - 1; i++)  // <--- AQUÍ ESTÁ LA CLAVE: rates_total - 1
   {
      BuySignalBuffer[i] = EMPTY_VALUE;
      SellSignalBuffer[i] = EMPTY_VALUE;
      
      if(basePrice[i] == 0 || atrBuffer[i] == 0)
         continue;
      
      double range = InpVolatilityFactor * atrBuffer[i] * InpSensitivityMultiplier;
      double upperBand = basePrice[i] + range;
      double lowerBand = basePrice[i] - range;
      
      // Verificar cruce con la vela ANTERIOR (i+1) para evitar repainting
      if(i + 1 < rates_total)
      {
         double prevHigh = high[i + 1];
         double prevLow = low[i + 1];
         
         // Buy Signal: Price touches or crosses lower band
         if(prevLow >= lowerBand && low[i] <= lowerBand)
         {
            BuySignalBuffer[i] = low[i] - (atrBuffer[i] * 0.5);
            DrawTPLines(close[i], atrBuffer[i], "BUY", time[i], i, time, rates_total);
         }
         
         // Sell Signal: Price touches or crosses upper band
         if(prevHigh <= upperBand && high[i] >= upperBand)
         {
            SellSignalBuffer[i] = high[i] + (atrBuffer[i] * 0.5);
            DrawTPLines(close[i], atrBuffer[i], "SELL", time[i], i, time, rates_total);
         }
      }
   }
   
   // Limpiar la vela actual (i=0) para que nunca tenga señal
   BuySignalBuffer[0] = EMPTY_VALUE;
   SellSignalBuffer[0] = EMPTY_VALUE;
   
   return(rates_total);
}

//+------------------------------------------------------------------+
//| Draw TP/SL Lines (hacia atrás)                                   |
//+------------------------------------------------------------------+
void DrawTPLines(double price, double atrValue, string signalType, datetime signalTime, int signalIndex, const datetime &time[], int rates_total)
{
   string prefix = InpObjectsPrefix;
   color buyColor = clrLime;
   color sellColor = clrRed;
   string timeStr = TimeToString(signalTime, TIME_DATE|TIME_MINUTES);
   
   // Calcular tiempo de inicio (10 velas hacia atrás desde la señal)
   int startIndex = signalIndex + InpLinesLength;
   if(startIndex >= rates_total) startIndex = rates_total - 1;
   datetime startTime = time[startIndex];
   
   if(signalType == "BUY")
   {
      if(InpEnableTP1)
         DrawTrendLine(prefix + "TP1_" + timeStr, startTime, price + (atrValue * InpTP1Multiplier), signalTime, price + (atrValue * InpTP1Multiplier), buyColor, "TP 1");
      if(InpEnableTP2)
         DrawTrendLine(prefix + "TP2_" + timeStr, startTime, price + (atrValue * InpTP2Multiplier), signalTime, price + (atrValue * InpTP2Multiplier), buyColor, "TP 2");
      if(InpEnableTP3)
         DrawTrendLine(prefix + "TP3_" + timeStr, startTime, price + (atrValue * InpTP3Multiplier), signalTime, price + (atrValue * InpTP3Multiplier), buyColor, "TP 3");
      
      if(InpEnableSL1)
         DrawTrendLine(prefix + "SL1_" + timeStr, startTime, price - (atrValue * InpSL1Multiplier), signalTime, price - (atrValue * InpSL1Multiplier), sellColor, "SL 1");
      if(InpEnableSL2)
         DrawTrendLine(prefix + "SL2_" + timeStr, startTime, price - (atrValue * InpSL2Multiplier), signalTime, price - (atrValue * InpSL2Multiplier), sellColor, "SL 2");
   }
   else
   {
      if(InpEnableTP1)
         DrawTrendLine(prefix + "TP1_" + timeStr, startTime, price - (atrValue * InpTP1Multiplier), signalTime, price - (atrValue * InpTP1Multiplier), buyColor, "TP 1");
      if(InpEnableTP2)
         DrawTrendLine(prefix + "TP2_" + timeStr, startTime, price - (atrValue * InpTP2Multiplier), signalTime, price - (atrValue * InpTP2Multiplier), buyColor, "TP 2");
      if(InpEnableTP3)
         DrawTrendLine(prefix + "TP3_" + timeStr, startTime, price - (atrValue * InpTP3Multiplier), signalTime, price - (atrValue * InpTP3Multiplier), buyColor, "TP 3");
      
      if(InpEnableSL1)
         DrawTrendLine(prefix + "SL1_" + timeStr, startTime, price + (atrValue * InpSL1Multiplier), signalTime, price + (atrValue * InpSL1Multiplier), sellColor, "SL 1");
      if(InpEnableSL2)
         DrawTrendLine(prefix + "SL2_" + timeStr, startTime, price + (atrValue * InpSL2Multiplier), signalTime, price + (atrValue * InpSL2Multiplier), sellColor, "SL 2");
   }
}

//+------------------------------------------------------------------+
//| Draw Trend Line - MQL4                                           |
//+------------------------------------------------------------------+
void DrawTrendLine(string name, datetime time1, double price1, datetime time2, double price2, color clr, string label)
{
   if(ObjectFind(0, name) < 0)
   {
      ObjectCreate(0, name, OBJ_TREND, 0, time1, price1, time2, price2);
      ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
      ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_DOT);
      ObjectSetInteger(0, name, OBJPROP_WIDTH, 1);
      ObjectSetInteger(0, name, OBJPROP_RAY_RIGHT, false);
      ObjectSetInteger(0, name, OBJPROP_RAY_LEFT, false);
      ObjectSetString(0, name, OBJPROP_TEXT, label);
   }
   else
   {
      ObjectSetInteger(0, name, OBJPROP_TIME, 0, (long)time1);
      ObjectSetInteger(0, name, OBJPROP_TIME, 1, (long)time2);
      ObjectSetDouble(0, name, OBJPROP_PRICE, 0, price1);
      ObjectSetDouble(0, name, OBJPROP_PRICE, 1, price2);
   }
}
//+-----------------------------------------------------------------