Experts: Diff_TF_MA_EA

 

Diff_TF_MA_EA:

An Expert Advisor based on the Diff_TF_MA indicator.


Author: Scriptor

 

In places, it cut into the code.

//+------------------------------------------------------------------+
//| Returns the name timeframe|
//+------------------------------------------------------------------+
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();
     }
  }
Try this
string NameTimeframe( const ENUM_TIMEFRAMES timeframe = PERIOD_CURRENT )
{
  return(StringSubstr(EnumToString(timeframe == PERIOD_CURRENT ? Period() : timeframe), 7));
}
 
//+------------------------------------------------------------------+
//|| Fills position ticket arrays|
//+------------------------------------------------------------------+
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 PositionGetTicket check.

"else if" can be just "else".

type is not taken after continue.

 

There are no pending orders in the Expert Advisor, that's why this condition is correct only for POSITION_TYPE_BUY.

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

This condition is correct only for POSITION_TYPE_BUY.

 
fxsaber:

There are no pending orders in the Expert Advisor, so such a

This condition is correct only for POSITION_TYPE_BUY.

Why?

The call of this function is present in two places in the code:

   //--- Opening positions by signals
      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();
              }
           }
        }

Accordingly, if only the programmer who wrote this code foolishly sends the wrong order type to the function, then yes, there will be an error. In the case of this code, there will be no error.

 
Artyom Trishkin:

Why?

The call to this function is present in two places in the code:

Accordingly, if only the programmer who wrote this code foolishly sends the wrong order type to the function, then yes, there will be an error. In the case of this code, there will be no error.

Because there can be a different view on the KB

Forum on trading, automated trading systems and testing trading strategies

MT4 or MT5. What are the advantages and disadvantages?

Renat Fatkhullin, 2018.01.31 14:28

  1. 4300 programmes and 870 experts inclusive, in the source code, knowingly enough to learn and develop your own ideas

It is not claimed that there will be an error in this particular case. But functions migrate from one code to another. A potential error in a migrating function is like a hanging gun on the wall.

You can, of course, let it pass through your fingers. But I see here that it is better to warn you.

 
fxsaber:

Because there can be a different perspective on the QB


It is not claimed that there will be a bug in this particular case. But functions migrate from one code to another. A potential error in a migrating function is like a hanging gun on the wall.

You can, of course, let it pass through your fingers. But I see here that it is better to warn.

You are right, warning is correct.
The author probably meant to remove unnecessary unnecessary checks - in some cases, versatility is unnecessary. You must have been confused by the enumeration of ENUM_ORDER_TYPE. If there was ENUM_POSITION_TYPE there would be no questions.

Neither would your suggestion to cut text. Isn't switch faster?

 
Artyom Trishkin:

The author probably meant to remove unnecessary unnecessary checks - in some cases universality is unnecessary. Here you must have been confused by the ENUM_ORDER_TYPE enumeration. If there were ENUM_POSITION_TYPE there would be no questions.

Here you should have corrected the function itself and its calls. The author has not fully realised this since MT4.

Just like your suggestion to cut the text. Isn't switch faster?

Such switch constructions are exactly what you should not do. As for speed, you don't need it at all for this function. But the example is really quite illustrative. It will be interesting at least.

 
fxsaber:

The function itself and its calls should have been corrected here. The author has not realised this to the end since MT4.

But such switch-constructions are exactly what should not be done. As for speed, this function does not need it at all. But the example is really quite illustrative. It will be interesting at least.

Interesting. And in your opinion, what is wrong with the approach to the standard calculation of the minimum distance for setting stop orders?

//+------------------------------------------------------------------+
//| Returns the correct StopLoss relative to 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)
    );
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Returns the calculated StopLevel|
//+------------------------------------------------------------------+
int StopLevel(void)
  {
   int sp=symbol_info.Spread();
   int lv=symbol_info.StopsLevel();
   return(lv==0 ? sp*size_spread : lv);
  }
//+------------------------------------------------------------------+

I don't see any errors here. Explain. And what is the difference between the minimum distance calculation for MT4 and MT5?

 

There are actually more errors in the code. For example, it is well shown that using CSymbolInfo only for the sake of SB-style is evil.

Closing positions via a previously collected list of tickets is evil. This is a very common error.

Forum on trading, automated trading systems and testing trading strategies

Errors, bugs, questions

fxsaber, 2018.01.23 09:39 pm.

This is the wrong logic. After a failed and successful OrderSend, the current trading environment should be completely read again. This rule should always apply.

About return codes. I do not analyse them in my Expert Advisors in any way. In my opinion, the trading logic should not depend on them.

 
Artyom Trishkin:

Interesting. What do you think is wrong with the approach to the standard calculation of the minimum distance of stop orders?

I don't see any errors here. Explain. And what is the difference between the minimum distance calculation for MT4 and MT5?

The error is in the enum input and call, not in the minimum distance. But it is also calculated incorrectly, because

Forum on trading, automated trading systems and testing trading strategies.

Expert Advisors: Diff_TF_MA_EA

fxsaber, 2018.02.01 21:38

It is well shown that using CSymbolInfo just for the sake of SB-style is evil.