Asesores Expertos: Diff_TF_MA_EA

 

Diff_TF_MA_EA:

Asesor Experto a base del indicador Diff_TF_MA.


Autor: Scriptor

 

En algunos lugares, cortaba el código.

//+------------------------------------------------------------------+
//| Devuelve el nombre del plazo|
//+------------------------------------------------------------------+
string NameTimeframe(int timeframe=PERIOD_CURRENT)
  {
   if(timeframe==PERIOD_CURRENT) timeframe=Period();
   switch(timeframe)
     {
      case 1      : return "M1";
      case 2      : return "M2";
      case 3      : return "M3";
      case 4      : return "M4";
      case 5      : return "M5";
      case 6      : return "M6";
      case 10     : return "M10";
      case 12     : return "M12";
      case 15     : return "M15";
      case 20     : return "M20";
      case 30     : return "M30";
      case 16385  : return "H1";
      case 16386  : return "H2";
      case 16387  : return "H3";
      case 16388  : return "H4";
      case 16390  : return "H6";
      case 16392  : return "H8";
      case 16396  : return "H12";
      case 16408  : return "D1";
      case 32769  : return "W1";
      case 49153  : return "MN1";
      default     : return (string)(int)Period();
     }
  }
Prueba esto
string NameTimeframe( const ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT )
{
  return(StringSubstr(EnumToString(timeframe == PERIOD_CURRENT ? Period() : timeframe), 7));
}
 
//+------------------------------------------------------------------+
//|| Rellena las matrices de entradas de posición|
//+------------------------------------------------------------------+
void FillingListTickets(void)
  {
   list_tickets_buy.Clear();
   list_tickets_sell.Clear();
   total_volume_buy=0;
   total_volume_sell=0;
//---
   int total=PositionsTotal();
   for(int i=total-1; i>=0; i--)
     {
      ulong ticket=PositionGetTicket(i);
      ENUM_POSITION_TYPE type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      if(PositionGetInteger(POSITION_MAGIC)!=InpMagic)   continue;
      if(PositionGetString(POSITION_SYMBOL)!=symb)       continue;
      double volume=PositionGetDouble(POSITION_VOLUME);
      if(type==POSITION_TYPE_BUY)
        {
         list_tickets_buy.Add(ticket);
         total_volume_buy+=volume;
        }
      else if(type==POSITION_TYPE_SELL)
        {
         list_tickets_sell.Add(ticket);
         total_volume_sell+=volume;
        }
     }
  }

No hay comprobación de PositionGetTicket.

"else if" puede ser simplemente "else".

tipo no se toma después de continuar.

 

No hay órdenes pendientes en el Asesor Experto, por eso esta condición es correcta sólo para POSITION_TYPE_BUY.

double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());

Esta condición es correcta sólo para POSITION_TYPE_BUY.

 
fxsaber:

No hay órdenes pendientes en el Asesor Experto, por lo que tal

Esta condición es correcta sólo para POSITION_TYPE_BUY.

¿Por qué?

La llamada de esta función está presente en dos lugares en el código:

   //--- Apertura de posiciones por señales
      if(open_long)
        {
         if(num_s>0) CloseSell();
         if(num_b==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_BUY,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_BUY,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_BUY);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_BUY,ll))
              {
               if(trade.Buy(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }
      if(open_short)
        {
         if(num_b>0) CloseBuy();
         if(num_s==0)
           {
            double sl=(InpStopLoss==0   ? 0 : CorrectStopLoss(ORDER_TYPE_SELL,InpStopLoss));
            double tp=(InpTakeProfit==0 ? 0 : CorrectTakeProfit(ORDER_TYPE_SELL,InpTakeProfit));
            double ll=trade.CheckVolume(symb,lot,symbol_info.Ask(),ORDER_TYPE_SELL);
            if(ll>0 && CheckLotForLimitAccount(POSITION_TYPE_SELL,ll))
              {
               if(trade.Sell(ll,symb,0,sl,tp))
                  FillingListTickets();
              }
           }
        }

En consecuencia, si sólo el programador que escribió este código tontamente envía el tipo de orden equivocado a la función, entonces sí, habrá un error. En el caso de este código, no habrá error.

 
Artyom Trishkin:

¿Por qué?

La llamada a esta función está presente en dos lugares del código:

En consecuencia, si sólo el programador que escribió este código envía tontamente el tipo de orden incorrecto a la función, entonces sí, habrá un error. En el caso de este código, no habrá error.

Debido a que puede haber un punto de vista diferente sobre el KB

Foro sobre el comercio, los sistemas automatizados de comercio y probar estrategias de negociación

MT4 o MT5. Cuáles son las ventajas y desventajas?

Renat Fatkhullin, 2018.01.31 14:28

  1. 4300 programas y 870 expertos incluidos, en el código fuente, con conocimiento suficiente para aprender y desarrollar sus propias ideas.

No se afirma que habrá un error en este caso particular. Pero las funciones migran de un código a otro. Un error potencial en una función que migra es como una pistola colgada en la pared.

Por supuesto, se puede dejar pasar. Pero aquí veo que es mejor advertirlo.

 
fxsaber:

Porque puede haber una perspectiva diferente sobre el QB


No se afirma que habrá un error en este caso particular. Pero las funciones migran de un código a otro. Un error potencial en una función que migra es como un arma colgada en la pared.

Por supuesto, se puede dejar pasar. Pero aquí veo que es mejor advertir.

Tiene razón, advertir es correcto.
El autor probablemente pretendía eliminar las comprobaciones innecesarias - en algunos casos, la versatilidad es innecesaria. Usted debe haber sido confundido por la enumeración de ENUM_ORDER_TYPE. Si existiera ENUM_POSITION_TYPE no habría dudas.

Tampoco lo haría tu sugerencia de cortar texto. ¿No es más rápido cambiar?

 
Artyom Trishkin:

Probablemente, el autor pretendía eliminar comprobaciones innecesarias: en algunos casos, la universalidad es innecesaria. Aquí debe haberse confundido por la enumeración ENUM_ORDER_TYPE. Si estuviera ENUM_POSITION_TYPE, no habría dudas.

Aquí debería haber corregido la propia función y sus llamadas. El autor no se ha dado cuenta del todo desde MT4.

Igual que tu sugerencia de cortar texto. ¿No es switch más rápido?

Tales construcciones switch son exactamente lo que no debe hacer. En cuanto a la velocidad, no la necesita en absoluto para esta función. Pero el ejemplo es realmente muy ilustrativo. Será interesante por lo menos.

 
fxsaber:

Aquí se debería haber corregido la función en sí y sus llamadas. El autor no se ha dado cuenta por completo desde MT4.

Pero tal interruptor-construcciones son exactamente lo que no se debe hacer. En cuanto a la velocidad, esta función no la necesita en absoluto. Pero el ejemplo es realmente muy ilustrativo. Será interesante por lo menos.

Interesante. Y en su opinión, ¿qué hay de malo en el enfoque del cálculo estándar de la distancia mínima para establecer órdenes stop?

//+------------------------------------------------------------------+
//| Devuelve el StopLoss correcto relativo al StopLevel ||
//+------------------------------------------------------------------+
double CorrectStopLoss(const ENUM_ORDER_TYPE order_type,const int stop_loss)
  {
   if(stop_loss==0) return 0;
   double pt=symbol_info.Point();
   double price=(order_type==ORDER_TYPE_BUY ? symbol_info.Ask() : symbol_info.Bid());
   int lv=StopLevel(),dg=symbol_info.Digits();
   return
   (order_type==ORDER_TYPE_BUY ?
    NormalizeDouble(fmin(price-lv*pt,price-stop_loss*pt),dg) :
    NormalizeDouble(fmax(price+lv*pt,price+stop_loss*pt),dg)
    );
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Devuelve el StopLevel calculado|
//+------------------------------------------------------------------+
int StopLevel(void)
  {
   int sp=symbol_info.Spread();
   int lv=symbol_info.StopsLevel();
   return(lv==0 ? sp*size_spread : lv);
  }
//+------------------------------------------------------------------+

Yo aquí no veo ningún error. Explíquese. ¿Y cuál es la diferencia entre el cálculo de la distancia mínima para MT4 y MT5?

 

En realidad hay más errores en el código. Por ejemplo, está bien demostrado que usar CSymbolInfo sólo para el estilo SB es malvado.

Cerrar posiciones mediante una lista de entradas previamente recopilada es malvado. Este es un error muy común.

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading

Errores, fallos, preguntas

fxsaber, 2018.01.23 09:39 pm.

Esta es la lógica incorrecta. Después de un OrderSend fallido y exitoso, el entorno de negociación actual debe ser completamente leído de nuevo. Esta regla debería aplicarse siempre.

Sobre los códigos de retorno. Yo no los analizo en mis Asesores Expertos de ninguna manera. En mi opinión, la lógica de negociación no debería depender de ellos.

 
Artyom Trishkin:

Interesante. ¿Qué crees que falla en el planteamiento del cálculo estándar de la distancia mínima de las órdenes stop?

Yo no veo ningún error aquí. Explíquese. ¿Y cuál es la diferencia entre el cálculo de la distancia mínima para MT4 y MT5?

El error está en el enum input y call, no en la distancia mínima. Pero incluso se calcula incorrectamente, porque

Foro sobre trading, sistemas automatizados de trading y testeo de estrategias de trading.

Asesores Expertos: Diff_TF_MA_EA

fxsaber, 2018.02.01 21:38

Está bien demostrado que usar CSymbolInfo solo por el estilo SB es maligno.