Ayuda con indicador personalizado

 

Buenas tardes compañeros,

Resulta que estoy tratando de programar un indicador con cruce de Emas, pero una de las emas corresponde a un indicador personalizado, una ema trend, que al cambiar de tendencia cambia de color y de valor; fijándome en la ventana de datos, he visto que el indicador tiene dos valores, al estar en una tendencia alcista el valor 0 marca la ema y el valor 1 queda en blanco,cuando la tendencia es lateral ambos valores marcan la Ema y cuando cambia la tendencia a bajista el valor 0 queda en blanco y el valor 1 pasa a ser quien dibuje la ema).
La idea es que una SMA al cruzar con el indicador personalizado me lance una alerta, ya tengo todo listo, el fallo está cuando llamo al indicador personalizado con la función iCustom, no logro crear un solo valor para dicho indicador, o sea, al tener dos valores diferentes que cambian, el cruce con la SMA se me ha hecho difícil programarlo.

Algunas partes del código:

//Emat  es el valor unificado del indicador que quiero

//fastema es la SMA

//CrossDown dibujar arrow 

//llamado del indicador personalizado en vela actual y anterior en ambos valores

EmatrendNow = iCustom(NULL, 0, "..\\Indicators\\trend.ex4", 30, 2, 1, 0, i);

      EmatrendPrev = iCustom(NULL, 0, "..\\Indicators\\trend.ex4", 30, 2, 1, 0, i+1);

      EmatrendNow2 = iCustom(NULL, 0, "..\\Indicators\\trend.ex4", 30, 2, 1, 1, i);

      EmatrendPrev2 = iCustom(NULL, 0, "..\\Indicators\\trend.ex4", 30, 2, 1, 1, i+1);

por ahora hasta acá todo bien, pero al unificar ambos valores es donde no he podido.
He intentado con la siguiente fórmula sin tener éxito:

if (EmatrendNow >= EmaTrendNow2)

{

Emat = EmatrendNow;

}

else if (EmatrendNow < EmatrendNow2)

{

Emat = EmatrendNow2;

}

if fastema > Emat

{

CrossDown[i] = High[i] + Range*0.55;

}


Al hacer esto, me dibuja señales sobre todo el gráfico, sin importar si la SMA esté por encima o debajo de la ematrend.

 
Amigo, tienes un par de cosas por corregir.
Lo primero es que no es necesario poner la ruta del indicador (en caso de estar en la carpeta por default), por lo que puedes usarlo asi:
EmatrendPrev2 = iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 1, i+1);


Lo segundo es que no estas leyendo bien los buffers del indicador personalizado, o al menos asi lo veo yo.
El indicador, como bien lo dices, tiene dos buffers, por lo que puedes usar algo asi: (solo leer el buffer actual del indicador personalizado y comparar esa posicion con la posicion actual y previa de la Media Simple tradicional para chequear el cruce)

en pocas palabras, la lectura del indicador TREND seria asi:

EmatrendNowBuff0= iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 0, i);   // estas leyendo el buffer 0 actual 

EmatrendNowBuff1 = iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 1 , i);// estas leyendo el buffer 1 actual

if(EmatrendNowBuff0 != EMPTY_VALUE && EmatrendNowBuff1 == EMPTY_VALUE) // ALCISTA
if( EmatrendNowBuff0 != EMPTY_VALUE && EmatrendNowBuff1 == EMPTY_VALUE ) //LATERAL
if(EmatrendNowBuff0 == EMPTY_VALUE && EmatrendNowBuff1 != EMPTY_VALUE) //BAJISTA

Y esa data la integras a la lectura de  la media tradicional, que repito, si deberás considerar los valores de la actual y previa, 

Espero con esto encuentres un poco de ayuda

Saludos!!!

 
Miguel Antonio Rojas Martinez:
Amigo, tienes un par de cosas por corregir.
Lo primero es que no es necesario poner la ruta del indicador (en caso de estar en la carpeta por default), por lo que puedes usarlo asi:


Lo segundo es que no estas leyendo bien los buffers del indicador personalizado, o al menos asi lo veo yo.
El indicador, como bien lo dices, tiene dos buffers, por lo que puedes usar algo asi: (solo leer el buffer actual del indicador personalizado y comparar esa posicion con la posicion actual y previa de la Media Simple tradicional para chequear el cruce)

en pocas palabras, la lectura del indicador TREND seria asi:

Y esa data la integras a la lectura de  la media tradicional, que repito, si deberás considerar los valores de la actual y previa, 

Espero con esto encuentres un poco de ayuda

Saludos!!!

Miguel buenas tardes,

Maravilloso tu comentario, he logrado unificar ambos valores del indicador trend en uno solo y de esa forma identificar el cruce de la EMA con este indicador. Pero, ahora me ha resultado otro inconveniente. Después de que se cumple la condición de cruce, la función de dibujar una señal (arrow) se ejecuta de manera de correcta, me coloca una flecha en la dirección a la que empieza a ir la tendencia justo en ese cruce y no en toda la gráfica como antes, pero la función de alerta se queda ejecutando por cada segundo que pasa, es decir, si habilito la opción de alerta y que me envíe una notificación o mensaje dentro del MT4, este mensaje me sale de forma recurrente, prácticamente por segundo me envía un mensaje.

Te mostraré algunas partes para ver si me puedes ayudar con ello por favor...


EmatrendN = iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 0, i);

      EmatrendP = iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 0, i+1);

      EmatrendN2 = iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 1, i);

      EmatrendP2 = iCustom(NULL, 0, "trend.ex4", 30, 2, 1, 1, i+1);


slowMAnow = iMA(NULL, 0, 12, 0, MODE_EMA, PRICE_MEDIAN, i);

      slowMAprevious = iMA(NULL, 0, 12, 0, MODE_EMA, PRICE_MEDIAN, i+1);


if(EmatrendN != EMPTY_VALUE && EmatrendN2 == EMPTY_VALUE)

{

EmaT = EmatrendN;

}

else 

{

EmaT = EmatrendN2;

}


if (EmatrendP != EMPTY_VALUE && EmatrendP2 == EMPTY_VALUE)

{

EmaTP = EmatrendP;

else 

{

EmaTP = EmatrendP2;

}


if ((slowMAnow < EmaT) && (slowMAprevious > EmaTP))

      {

         CrossDown2[i] = High[i] + Range*0.55;

           if (AlertsON)

      {

           if (SoundON) PlaySound("tick.wav");

           if (MessON) Alert("BUY signal at Ask=",Ask,"\n Bid=",Bid,"\n Time=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()),"\n Symbol=",Symbol()," Period=",Period());

           if (EmailON) SendMail("BUY signal alert","BUY signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());

           if (NotifiON) SendNotification ("BUY signal alert");

         }

      }

      else if ((slowMAnow > EmaT) && (slowMAprevious < EmaTP))

      {

         CrossUp2[i] = Low[i] - Range*0.55;

           if (AlertsON)

      {

           if (SoundON) PlaySound("tick.wav");

           if (MessON) Alert("BUY signal at Ask=",Ask,"\n Bid=",Bid,"\n Time=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime()),"\n Symbol=",Symbol()," Period=",Period());

           if (EmailON) SendMail("BUY signal alert","BUY signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());

           if (NotifiON) SendNotification("BUY signal alert");

         }

      }


Estoy casi seguro que el problema está en la definición de "i", yo lo he definido de la siguiente forma, copiándolo de otro indicador:

int start() {

   int limit, i, counter;

   double tmp=0;

   double EmaT, EmaTP, EmaS33, EmaSP33, Ema200, Ema200P, Ema11, EmaP11, Ema33, EmaP33, EmaS50, EmaSP50, EmatrendN, EmatrendP,EmatrendN2,EmatrendP2, fastMAnow, slowMAnow, fastMAprevious, slowMAprevious, EmaUpnow, EmaUpprevious, EmaN1now, EmaN1previous, Ema0now, Ema0previous, EmaDwnow, EmaDwprevious, EmaN01now, EmaN01previous;

   double Range, AvgRange;

   int counted_bars=IndicatorCounted();

//---- check for possible errors

   if(counted_bars<0) return(-1);

//---- last counted bar will be recounted

   if(counted_bars>0) counted_bars--;


   limit=Bars-counted_bars;

   

   for(i = 1; i <= limit; i++) {

   

      counter=i;

      Range=0;

      AvgRange=0;

      for (counter=i ;counter<=i+9;counter++)

      {

         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);

      }

      Range=AvgRange/10;

 

Te sugiero que la próxima vez copies el código con Alt+S para preguntar en el foro

Por otra parte no sé si lo has solucionado. Yo uso normalmente este código antes de  "Custom indicator initialization function ":

void myAlert(string type, string message)
  {
   if(type == "print")
      Print(message);
   else if(type == "error")
     {
      Print(type+" | alarms @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }
   else if(type == "order")
     {
     }
   else if(type == "modify")
     {
     }
   else if(type == "indicator")
     {
      Print(type+" | alarms @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Audible_Alerts) Alert(type+" | alarms @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Send_Email) SendMail("alarms", type+" | alarms @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
      if(Push_Notifications) SendNotification(type+" | alarms @ "+Symbol()+","+IntegerToString(Period())+" | "+message);
     }

Y más tarde lo defino en el cuerpo del código, por ejemplo:

//Indicator Buffer 1
      if(iMA(NULL, PERIOD_CURRENT, Period1, 0, MODE_SMA, PRICE_CLOSE, i) > iMA(NULL, PERIOD_CURRENT, Period2, 0, MODE_SMA, PRICE_CLOSE, i)
      && iMA(NULL, PERIOD_CURRENT, Period1, 0, MODE_SMA, PRICE_CLOSE, i+1) < iMA(NULL, PERIOD_CURRENT, Period2, 0, MODE_SMA, PRICE_CLOSE, i+1) //Moving Average crosses above Moving Average
      )
        {
         Buffer1[i] = Low[i]; //Set indicator value at Candlestick Low
         if(i == 0 && Time[0] != time_alert) { myAlert("indicator", "Buy"); time_alert = Time[0]; } //Instant alert, only once per bar
        }
      else
        {
         Buffer1[i] = EMPTY_VALUE;
        }
 

No entiendo muy bien la definición que haces de i,

te muestro un ejemplo de como y lo hago de manera "standard"

//--- main loop
   for(int i = limit-1; i >= 0; i--)
     {
      if (i >= MathMin(5000-1, rates_total-1-50)) continue; //omit some old rates to prevent "Array out of range" or slow calculation   

Claro, depende de qué quieras hacer, solo es una idea, por si eso te puede ayudar de alguna manera

 
Disculpen la pregunta, quien podría hacerme un indicador básico para mt5 y cuánto me costaría???
 
PabloEsteban25:
Disculpen la pregunta, quien podría hacerme un indicador básico para mt5 y cuánto me costaría???
En la sección Freelance te pueden ayudar. El precio variará en función del desarrollador y de la complejidad del proyecto
 
Enrique Enguix Vino:

Te sugiero que la próxima vez copies el código con Alt+S para preguntar en el foro

Por otra parte no sé si lo has solucionado. Yo uso normalmente este código antes de  "Custom indicator initialization function ":

Y más tarde lo defino en el cuerpo del código, por ejemplo:

Hola Enrique, gracias por tus anotaciones, lo he resuelto.
Razón de la queja: