Pequeño indicador de gestión del dinero arruinado por el nuevo MQL4

 

Hola codificadores,

Hice un pequeño indicador de Moneymanagement que me funcionaba bien. Pero desde el nuevo MQL4 causa problemas que no puedo manejar.

Cuando se arrastra este indicador a su gráfico algunos números se imprimen en el lado derecho. El primer número significa el Stoploss en pips y el segundo es el tamaño del lote. En las opciones puedes elegir el riesgo. El otro número son los niveles de Stoploss. Pero cuando cambio el par de divisas los números desaparecen. En su lugar veo varias veces la palabra "Etiqueta". Y cuando miro a la lista de indicadores, mi indicador también ha desaparecido. Así que, en resumen, después de cambiar el par de divisas, el indicador se ha ido y ha dejado etiquetas en lugar de números.

Estoy totalmente confundido. Este indicador solía funcionar sin ningún problema. La ayuda es muy apreciada.

Aquí está el código:

#property indicator_chart_window
//--- input parameters
extern int  Risk=2;
extern int SL_Levels=20;
int multi, exp, SL, i, k;
double MoneyRisk, Spread, _modifySpread, lots;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      if (ObjectFind("SL"+i) == -1)
      {
         ObjectCreate("SL"+i, OBJ_LABEL, 0, 0, 0);
         ObjectSet("SL"+i, OBJPROP_CORNER, 1);
         ObjectSet("SL"+i, OBJPROP_XDISTANCE, 3);
         ObjectSet("SL"+i, OBJPROP_YDISTANCE, k);
         k=k+15;    
      }
   }
   if (ObjectFind("Spread") == -1)
   {
      ObjectCreate("Spread", OBJ_LABEL, 0, 0, 0);
      ObjectSet("Spread", OBJPROP_CORNER, 3);
      ObjectSet("Spread", OBJPROP_XDISTANCE, 3);
      ObjectSet("Spread", OBJPROP_YDISTANCE, 1);
   }
   
//-- 4 / 5 Digit Settings --
   multi   = 1;
   exp     = 0;
   if (Digits==5 || Digits==3)
   {
      _modifySpread = 0.1;
      multi=10;
      exp=1;
   }
//----
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   for(i=1; i<=SL_Levels; i++)
   {
      ObjectDelete("SL"+i);
   }
   ObjectDelete("Spread");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
   Spread     = MarketInfo(Symbol(), MODE_SPREAD)*_modifySpread;
   MoneyRisk  = AccountBalance()*Risk*0.01;
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
      ObjectSetText("SL"+i, SL+ " : "+DoubleToStr(lots, 2), 10, "Calibri", Red);
      k=k+15;
      SL = SL+MathFloor(((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1)/2);     
   }
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
   ObjectSetText("Spread", DoubleToStr(Spread,1), 10, "Calibri", Red);
   WindowRedraw();
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

primero no puedes usar "exp" para un int, está reservado

segundo expresas el "SL"

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);

en la sección init, mala idea

porque si obtienes el error 4066 el "SL" = 0

entonces usted consigue cero dividir en "lotes"

lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);

y el indicador se detiene y tienes que recargar el indicador

 
Lo entiendo. Acabo de cambiar la variable exp, pero ¿puede decirme cómo comprobar o evitar el error 4066? He leído que tiene que ver con el hecho de que MetaTrader actualiza sólo las cotizaciones del gráfico y marco de tiempo actual. Pero, ¿qué sugieres hacer para evitar el 4066?
 

obviamente no puedes evitar la actualización ;-) pero tienes que evitar una situación de "división por cero"

así que tienes que comprobar si una de las variables es igual a 0.... en caso de evitar la división por cero

y como no puedes parar un indicador tienes que averiguar algo

ejemplo:

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
if (SL == 0) // because error 4066 (for example)
   {
   SL = Someting;
   }
lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
 

Tienes razón... No puedo evitarlo. :-)

Lo que quería decir es que si puedo esperar a que se complete la actualización antes de seguir con el cálculo del SL. El problema es que no puedo darle a SL un valor aleatorio porque entonces todo el indicador es inútil. Así que me gustaría comprobar el error 4066 y si se produce, me gustaría esperar de alguna manera y comprobar de nuevo antes de continuar.

 

Por cierto, tengo el mismo problema con este indicador. ¿Pero por qué no era un problema en el "viejo" MetaTrader? Aquí siempre recibo un cero para el ATR(5). ¿¡POR QUÉ!? Eso nunca sucedió antes .. ¡Odio este nuevo MetaTrader...!

int start()
//----
  {
   double Spread = MarketInfo(Symbol(), MODE_SPREAD);
   double ATR = iATR(NULL, PERIOD_D1, 5, 0);
   int exp1 = 0;
   if (Digits==5 || Digits==3)
   {
      Spread=Spread*0.1;
      exp1 = 1;
   }
   Comment  (
            "ADR(5): ",DoubleToStr(ATR*MathPow(10,Digits-exp1),1),
            " || TODAY: ",(iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1),
            " || ", DoubleToStr(((iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1)/(ATR*MathPow(10,Digits-exp1))*100), 2), "%",
            "\n" +
            "SPREAD: ", Spread,
            " || RATIO: ",DoubleToStr((Spread/ATR)*MathPow(10,-(Digits-exp1-2)), 2),"%"
            );
//----
   return(0);
  }
 
¿Qué quiere decir cero? Imprimo todo el comentario y ATR(5) muestra la salida mayor que cero ... por encima de 50, de hecho ...
 

Creo que he encontrado el problema. Definitivamente es un problema de actualización. Cuando ahora cambio de divisas, el indicador funciona. Pero entonces abrí un par de divisas que aún no había abierto hoy. Entonces recibí este mensaje:


Abra un par que aún no ha abierto hoy. Cambie a cualquier marco de tiempo que desee, excepto D1. Luego arrastra el indicador a tu gráfico. El resultado será un error como el de arriba. Me parece que el ATR(5) del gráfico diario no es correcto porque faltan DATOS DIARIOS. Abrir un gráfico "fresco" en el marco temporal D1 no causa ningún problema. Y cuando se cambia a otro marco temporal también está bien porque el ATR(5) es correcto. Me he dado cuenta de que puedo cambiar a cualquier par siempre que me quede en el gráfico D1. Pero el cambio a otros pares en otros marcos de tiempo que D1 causa problemas, siempre y cuando MetaTrader no ha recibido los datos diarios. Así, mi pregunta es ahora, ¿cómo puedo obtener los datos diarios que mi ATR-cálculo es correcto cuando abro un nuevo gráfico en un marco de tiempo que no es D1?
 

Tienes que poner algo como

if(number==0)dothis; else dothis; 

en ShowSpread.mq4


Busca la línea en la que se produce esta división de cero.

 
mar:

Creo que he encontrado el problema. Definitivamente es un problema de actualización. Cuando ahora cambio de divisas, el indicador funciona. Pero entonces abrí un par de divisas que aún no había abierto hoy. Entonces recibí este mensaje:


Abra un par que aún no ha abierto hoy. Cambia a cualquier marco de tiempo que quieras, excepto D1. Luego arrastra el indicador a tu gráfico. El resultado será un error como el de arriba. Me parece que el ATR(5) del gráfico diario no es correcto porque faltan DATOS DIARIOS. Abrir un gráfico "fresco" en el marco temporal D1 no causa ningún problema. Y cuando se cambia a otro marco temporal también está bien porque el ATR(5) es correcto. Me he dado cuenta de que puedo cambiar a cualquier par siempre que me quede en el gráfico D1. Pero cambiar a otros pares en otros marcos de tiempo que D1 causa problemas mientras MetaTrader no haya recibido los datos diarios. Así que mi pregunta es ahora, ¿cómo puedo obtener los datos diarios que mi ATR-cálculo es correcto cuando abro un nuevo gráfico en un marco de tiempo que no es D1?
qjol ya te dijo donde está el problema. ¿Por qué no sigues o al menos compruebas lo que te han aconsejado si estás pidiendo ayuda?
 

angevoyageur, creo que no has visto este post mío:

mar 2014.04.02 08:16 #

Tienes razón... No puedo evitarlo :-)

"Lo que quería decir es que si puedo esperar a que se complete la actualización para seguir con el cálculo del SL. El problema es que no puedo darle a SL un valor aleatorio porque entonces todo el indicador es inútil. Así que me gustaría comprobar el error 4066 y si se produce, me gustaría esperar de alguna manera y comprobar de nuevo antes de continuar."

Ahí puedes ver que describió que no puedo seguir el consejo y como llegué a esa solución también puedes ver que definitivamente comprobé lo que me aconsejó qjol.

Razón de la queja: