Useful features from KimIV - page 26

 
aceventura:

The number of orders function will not work, because the EA is set differently for each pair. And orders are set for different pairs at the same time. Then if four orders are placed for two pairs and one triggered, three of them are deleted and the opposite one should be deleted for all pairs.

All functions of KimIV will "filter" orders by type+pair+magic. I.e. (for me! :) not to run and search - from this page "SecondsAfterCloseLastPos(string sy="", int op=-1, int mn=-1)" ) by calling "Count there some" For sure you will get the real opened orders for this currency pair or even with this EA.

ZS I meant the function

int NumberOfOrders(string sy="", int op=-1, int mn=-1)

from page 12.

 
SergNF:

All functions from KimIV 'filter' orders by type+pair+magic. I.e. (to me! :) not to run and search - from this page "SecondsAfterCloseLastPos(string sy="", int op=-1, int mn=-1)" ) by calling "Count there some" For sure you will get the real number of open orders on this pair or even with this EA.

ZS I meant the function

from page 12.

Thank you! Very helpful! I'll look into it.

 
Apologies for the intrusion Help for Dummies How to draw parallel lines in MT4 quickly and comfortably?
 
extern double Lots = 0.1;
extern double TrailingStop = 10;
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   double ADXg_1,ADXr_1,ao2,ao1,ac1,ac2;
   double P_up0,P_down0,P_up1,P_down1;
   int cnt,ticket,total;
 
   if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
   P_up0=iCustom(0,0,"Ценовой канал",5,0,0);
   P_down0=iCustom(0,0,"Ценовой канал",5,1,0);
   P_up1=iCustom(0,0,"Ценовой канал",5,0,1);
   P_down1=iCustom(0,0,"Ценовой канал",5,1,1);
   ADXg_1=iCustom(0,0,"ADX пересечение",14,10000,0,1);
   ADXr_1=iCustom(0,0,"ADX пересечение",14,10000,1,1);
   ao1=iAO(0,0,1);
   ao2=iAO(0,0,2);
   ac1=iAC(0,0,1);
   ac2=iAC(0,0,2);
//задали все данные 
 
   total=OrdersTotal();
   if(total<1) 
     {
      // Проверка свободной маржи
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
      // Условие открытие позиции BUY
      if(ADXg_1<ADXr_1&&ao2<ao1&&ac2<ac1)
        {
         ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,0,"",16384,0,Green);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
           }
         else Print("Error opening BUY order : ",GetLastError()); 
         return(0); 
        }
      // Условие открытие позиции SELL
      if(ADXg_1>ADXr_1&&ao2>ao1&&ac2>ac1)
        {
         ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,0,"",16384,0,Red);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
           }
         else Print("Error opening SELL order : ",GetLastError()); 
         return(0); 
        }
      return(0);
     }
    
   for(cnt=0;cnt<total;cnt++)
     {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()<=OP_SELL &&   
         OrderSymbol()==Symbol())  
        {
         if(OrderType()==OP_BUY)   // длинная позиция открыта
           {
            // условие закрытие длинной позиции
            if(P_down1>P_down0)
                {
                 OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); 
                 return(0); 
                }
            if(TrailingStop>0)  
              {                 
               if(Bid-OrderOpenPrice()>Point*TrailingStop)
                 {
                  if(OrderStopLoss()<Bid-Point*TrailingStop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
           }
         else 
           {
            // условие закрытия короткой позиции
            if(P_up1<P_up0)
              {
               OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); 
               return(0); 
              }
            if(TrailingStop>0)  
              {                 
               if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
                 {
                  if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
           }
        }
     }
   return(0);
  }
Please help. I made a simple Expert Advisor using trailing stop.

How to make trailing stop was put once +5 pips and not transferred further, closing was done by

How do I use trailing stop if it is already set by the indicators? If you can give an example!!!
 
KimIV писал (а) >>

Probably not... I only have two: index finger and grip... >> hee

Igor, I have a crush on you, even though I'm not gay. After all, you can work as Zadornov, too.

 

SecondsAfterOpenLastPos() function.

This function returns the number of seconds since the last position was opened. The selection of positions to be taken into account is set by external parameters:

  • sy - Name of market instrument. If this parameter is set, the function will only consider positions of the specified instrument. The default value - "" means any market instrument. NULL value means the current instrument.
  • op - Trade operation, position type. Valid values: OP_BUY, OP_SELL or -1. The default value -1 means any position.
  • mn - Position identifier, MagicNumber. The default value of -1 means any identifier.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 19.02.2008                                                     |
//|  Описание : Возвращает количество секунд после открытия последней позиций. |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
datetime SecondsAfterOpenLastPos(string sy="", int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersTotal();

  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderOpenTime()) t=OrderOpenTime();
            }
          }
        }
      }
    }
  }
  return(TimeCurrent()-t);
}
P.S. Attached is a script to test the SecondsAfterOpenLastPos() function.
 

I am of course wildly sorry, what you are doing is certainly a good thing.

But HOW you do it, I don't like it at all.

1. the fact that you describe the names of the variables is great, but every time you have to look in the header to see what the next wild abbreviation means, it's hard to understand what the variable stands for, you forget what you wanted to find out in the code. Can't you write a QUALITY self-documented code, which even without comments will be understandable to someone who knows English, especially as you are doing it for others and others with this quality will never find a mistake in code, if there is one.



2. Overloaded functions. Versatility is a BAD thing, 6 parameters for a function is too much.



3. Code simplicity

Example.

datetime SecondsAfterOpenLastPos(string sy="", int op=-1, int mn=-1) {
  datetime t;
  int      i, k=OrdersTotal();
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      if (OrderSymbol()==sy || sy=="") {
        if (OrderType()==OP_BUY || OrderType()==OP_SELL) {
          if (op<0 || OrderType()==op) {
            if (mn<0 || OrderMagicNumber()==mn) {
              if (t<OrderOpenTime()) t=OrderOpenTime();
            }
          }
        }
      }
    }
  }
  return(TimeCurrent()-t);
}

This is your code. Let's see what you can do with it:

datetime SecondsAfterOpenLastPos(string symbol = "", int type = -1, int magic = -1) 
{
  datetime nearestTime = 0; // Инициализировать не надо? Самые сложно находимые ошибки.
  int count = OrdersTotal();
 
  if (symbol == "0") 
     symbol = Symbol();
 
  for (int i = 0; i < count; i++) 
  {
     // invalid select    
     if (!OrderSelect(i, SELECT_BY_POS)) continue;
     
     // not needed symbol     
     if (OrderSymbol() != symbol && symbol != "") continue;
 
     int currentType = OrderType();
 
     // only active orders are checked     
     if (currentType != OP_BUY && currentType != OP_SELL) continue;
     
     // type doesn't pass     
     if (type > 0 && currentType != type) continue;
 
     // magic number doesn't pass     
     if (magic > 0 && OrderMagicNumber() != magic) continue;
 
     if (nearestTime < OrderOpenTime()) nearestTime = OrderOpenTime();
  }
 
  return (TimeCurrent() - nearestTime);
}

Shall we compare the code? It does the same thing.

1. Yes, my code is bigger, but after all, we don't live in the age of floppy disks, is there not enough space?

2. My code is much clearer inside. Even without the comments, which are pasted in place.

3. Your function has nesting 7, mine has 2, is there a difference?

4 It's one of the few functions that isn't overloaded, but opening, modifying and so on is a nightmare.



SZZH: Respect the people you're writing it for.

 

Но КАК вы это делаете, мне абсолютно не нравится.

-1. Disagree. Absolutely fine with everything, both in form and content. Please continue in exactly the same format.

Yes, my code is larger.

Exactly. And the smaller the code, the easier it is to read. I hate fonts "smeared" on 2-3 screens. A function should be all in one screen, without flipping through it. That is why I am for compactness.

Your function has nesting 7, I have 2, is there a difference?

Is it okay that you have a lot of optional continuums which, by the way, again pull the reader's attention away?

 
Andrei(TheXpert), thank you for your comments and suggestions! All of them are absolutely fair and you are absolutely right in your statements!
 

DeleteOppositeOrders() function.

This function deletes one or more orders opposite to the position, the type of which is specified in the op. For example, for a Buy position the opposite orders would be SellLimit and SellStop. The deletion of the opposite order becomes necessary if, for example, two opposite orders are set and one of them triggers.

  • sy - Name of market instrument. If you set this parameter, the function will only consider positions of the specified symbol. The default value "" means any market instrument. NULL value means the current instrument.
  • op - Trade operation, position type. Valid values: OP_BUY, OP_SELL or -1. The default value -1 means any position.
  • mn - Position identifier, MagicNumber. The default value of -1 means any identifier.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 16.06.2008                                                     |
//|  Описание : Удаление ордеров, противоположных позиции                      |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любая позиция)                  |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//+----------------------------------------------------------------------------+
void DeleteOppositeOrders(string sy="", int op=-1, int mn=-1) {
  bool eb, es;

  switch (op) {
    case OP_BUY : eb=ExistPositions(sy, OP_BUY , mn); break;
    case OP_SELL: es=ExistPositions(sy, OP_SELL, mn); break;
    default:      eb=ExistPositions(sy, OP_BUY , mn);
                  es=ExistPositions(sy, OP_SELL, mn); break;
  }

  if (eb) {
    DeleteOrders(sy, OP_SELLLIMIT, mn);
    DeleteOrders(sy, OP_SELLSTOP , mn);
  }
  if (es) {
    DeleteOrders(sy, OP_BUYLIMIT, mn);
    DeleteOrders(sy, OP_BUYSTOP , mn);
  }
}
SZZ. Attached is a script to test the DeleteOppositeOrders() function.