Ayuda con indicador personalizado

Para añadir comentario, por favor Autorícese o regístrese
Juan David Rendon
11
Juan David Rendon  

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.

Miguel Antonio Rojas Martinez
2443
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:
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!!!

Juan David Rendon
11
Juan David Rendon  
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;

Para añadir comentario, por favor Autorícese o regístrese