Полезные функции от KimIV - страница 26

 
aceventura:

Функция количества ордеров не подойдет, т.к. для каждой пары тотже советник настроен по своему. И ставит ордера бывает по разным парам одновременно. Тогда получится если по двум парам поставлено четыре ордера, и один сработал, три удалятся. а надо чтоб удалялся противоположный для каждой

Все функции от KimIV "фильтруют" ордера по типу+паре+магику. Т.е. (чтобы мне! :) не бегать и не искать - с этой страницы "SecondsAfterCloseLastPos(string sy="", int op=-1, int mn=-1)" ) вызвав "Коунт там какой-то" с указанием интересующей тебы пары (просто Symbol() в первом поле), маджики наверное у тебя одинаковые, хотя я даже на разных парах запускаю одинаковые советники с разными маджиками, ты получишь реальное количество открытых ордеров на этой паре, а то и этим советником (маджик).

ЗЫ.Я имел ввиду функцию

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

с 12ой страницы.

 
SergNF:

Все функции от KimIV "фильтруют" ордера по типу+паре+магику. Т.е. (чтобы мне! :) не бегать и не искать - с этой страницы "SecondsAfterCloseLastPos(string sy="", int op=-1, int mn=-1)" ) вызвав "Коунт там какой-то" с указанием интересующей тебы пары (просто Symbol() в первом поле), маджики наверное у тебя одинаковые, хотя я даже на разных парах запускаю одинаковые советники с разными маджиками, ты получишь реальное количество открытых ордеров на этой паре, а то и этим советником (маджик).

ЗЫ.Я имел ввиду функцию

с 12ой страницы.

Спасибо! Очень помог! Буду разбиратся

 
Извеняюсь за вторжение Помогите чайнику Как в МТ4 строить паралельные линии быстро и удобно ?
 
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);
  }
Помогите пожалуйста. Скомпоновал простой советник с использованием трейлинг-стопом.

Как сделать так, чтобы трейлинг стоп ставился один раз +5 пунктов и далее не переносился, закрытие происходило

заложенным индикаторам? Если можно на примере!!!
 
KimIV писал (а) >>

Наверно, нет... у мну токо два: указательный и хватательный... гы

Игорь я в тебя просто влюбился, хотя и не гей. Ведь ты и Задорновым можешь работать.

 

Функция SecondsAfterOpenLastPos().

Эта функция возвращает количество секунд после открытия последней позиций. Отбор учитываемых позиций задаётся внешними параметрами:

  • sy - Наименование рыночного инструмента. Если задать этот параметр, то функция учтёт позиции только заданного инструмента. Значение по умолчанию - "" означает любой рыночный инструмент. Значение NULL означает текущий инструмент.
  • op - Торговая операция, тип позиции. Допустимые значения: OP_BUY, OP_SELL или -1. Значение по умолчанию -1 означает любую позицию.
  • mn - Идентификатор позиции, MagicNumber. Значение по умолчанию -1 означает любой идентификатор.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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. Во вложении скрипт для тестирования функции SecondsAfterOpenLastPos().
 

Я конечно дико извиняюсь, то что Вы делаете, это, конечно, хорошо.

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

1. То что Вы описываете названия переменных это классно, но каждый раз лезть в шапку чтобы посмотреть что обозначает очередное дикое сокращение -- это жесть, пока будешь выяснять для чего переменная, забудешь, что хотел выяснить в коде. Неужели нельзя писать КАЧЕСТВЕННЫЙ самодокументированный код, который даже без комментариев будет понятен человеку знающему английский язык, тем более, что делаете Вы это для других, а ведь эти другие с таким качеством в жизни не найдут ошибки в коде, если она там будет.



2. Перегруженность функций. Универсальность это ЗЛО, 6 параметров для функции это очень много.



3. Простота кода

Пример.

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);
}

Это Ваш код. Посмотрим, что с ним можно сделать:

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);
}

Сравним код? Он делает то же самое.

1. Да, мой код больше по размеру, но в конце концов, мы живем не в век дискеток, места мало что ли???

2. Мой код внутри на порядок понятней. Даже без комментариев, которые вставлены по месту.

3. У Вашей функции вложенность 7, у меня 2, есть разница?

4. Это одна из немногих функций, которая не перегружена, но открытие, модификация и иже с ними -- это жесть.



ЗЫЖ: Уважайте тех, для кого Вы это пишете.

 

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

-1. Не согласен. Абсолютно все устраивает, как по форме, так и по содержанию. Прошу продолжать ровно в том же формате.

Да, мой код больше по размеру

Именно. А чем меньше код - тем он проще для восприятия. Терпеть не могу ф-ий "размазанных" на 2-3 экрана. Ф-ия должна быть вся на экране, без перелистывания. Поэтому я - за компактность.

У Вашей функции вложенность 7, у меня 2, есть разница?

А ничего, что у Вас полно необязательных континуев которые, к слову, снова оттягивают на себя внимание читающего?

 
Андрей (TheXpert), благодарю за Ваши замечания и предложения! Все они совершенно справедливы, и Вы абсолютно правЫ в Ваших высказываниях!
 

Функция DeleteOppositeOrders().

Эта функция удаляет один или несколько ордеров, противоположных позиции, тип которой указывается в параметре op. Например, позиции Buy противоположными будут ордера SellLimit и SellStop. Удаление противоположного ордера становится необходимым, например, при установке двух противоположных ордеров и при сработке одного из них.

  • sy - Наименование рыночного инструмента. Если задать этот параметр, то функция учтёт позиции только заданного инструмента. Значение по умолчанию - "" означает любой рыночный инструмент. Значение NULL означает текущий инструмент.
  • op - Торговая операция, тип позиции. Допустимые значения: OP_BUY, OP_SELL или -1. Значение по умолчанию -1 означает любую позицию.
  • mn - Идентификатор позиции, MagicNumber. Значение по умолчанию -1 означает любой идентификатор.
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. 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);
  }
}
ЗЫ. Во вложении скрипт для тестирования функции DeleteOppositeOrders()
Файлы: