мол4

 

как закрыть все позиции сразу?

 
//+------------------------------------------------------------------+
//|                                                       _CLOSE.mq4 |
//|                      Copyright © 2009, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
   for(int i=OrdersTotal();i>=0;i--){
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
       //if(OrderSymbol()==Symbol()){
         if(OrderType()<2){
           OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(OrderClosePrice(),Digits),MarketInfo(Symbol(),MODE_DIGITS));
         }else{OrderDelete(OrderTicket());}
       //}
     }
   } 
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

Оно конечно и так сработает, но более корректно

for(int i=OrdersTotal()-1;i>=0;i--) 

 

а мне лень "-1" писать... если ордера с данным номером нет, то функция OrderSelect() и так не пропустит, а если уж быть совсем точным. то надо предварительно задать переменной значение OrdersTotal(), инваче постоянный вызов этой функции.

 

почему мы не используем

   while(OrdersTotal()>0){// работаем до тех пор, пока не будут закрыты ВСЕ открытые ордера
      RefreshRates();
ведь в некоторых случаях эта конструкция более предпочтительна...
 
В его случае OrderClosePrice() всегда новая.
 
DDFedor:

почему мы не используем

ведь в некоторых случаях эта конструкция более предпочтительна...


до сих пор не знаю ..... как то так сложилось, что пользуемся пересчетом, просто while и позависнуть может... а так один проход, что не закрылось - я не виноват.... ессно все это примитив, по идее надо еще и проверять а закрылся ли ордер, и прочие предосторожности...
 
DDFedor:

почему мы не используем

   while(OrdersTotal()>0){// работаем до тех пор, пока не будут закрыты ВСЕ открытые ордера
      RefreshRates();
ведь в некоторых случаях эта конструкция более предпочтительна... ведь в некоторых случаях эта конструкция более предпочтительна...

По ТЗ требовалось закрыть ПОЗИЦИИ, а

OrdersTotal()

вернёт общее кол-во ордеров в т.ч. и отложенных.

Тут для корректности надо писать функцию подсчёта открытых позиций и на каждом проходе проверять.

Мой вариант скрипта:

//+------------------------------------------------------------------+
//|                                        ClosePositionByMarket.mq4 |
//|                      Copyright © 2009, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void start() {
   while (PositionsTotal() > 0) {
      ClosePositions();
   }
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Закрывает с рынка все открытые позиции                           |
//+---------------------------------------------------- -------------+
void ClosePositions() {
  for(int i=OrdersTotal()-1;i>=0;i--) {
    OrderSelect(i, SELECT_BY_POS);
    RefreshRates();
    if (OrderType()==OP_BUY) {
       OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,0);
    }
    if (OrderType()==OP_SELL) {
       OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5,0);
    }
  }
} 
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//    Функция, возвращающая сумманое количество позиций, открытых    |
//    советником по всем инструментам                                |
//+------------------------------------------------------------------+
int PositionsTotal() {
   int total = OrdersTotal(), pos = 0;
   for (int i = 0; i < total; i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if (OrderType() == OP_BUY || OrderType() == OP_SELL)
         pos++;
   }
   return(pos);
}
//+------------------------------------------------------------------+
 
goldtrader:

По ТЗ требовалось закрыть ПОЗИЦИИ, а

вернёт общее кол-во ордеров в т.ч. и отложенных.

Тут для корректности надо писать функцию подсчёта открытых позиций и на каждом проходе проверять.

Мой вариант скрипта:

дык стоит же условие


if(OrderType()<2)

смысл писать отдельно функцию для проверки позиций ? :-)

 
Vladon:

дык стоит же условие


смысл писать отдельно функцию для проверки позиций ? :-)



Потому, что при наличии отложенных ордеров while в варианте дяди Федора попадет в бесконечный цикл.

2 DDFedor

почему мы не используем
   while(OrdersTotal()>0){// работаем до тех пор, пока не будут закрыты ВСЕ открытые ордера
      RefreshRates();
ведь в некоторых случаях эта конструкция более предпочтительна... ведь в некоторых случаях эта конструкция более предпочтительна...

Это самый медленный вариант: вызов функции на каждом проходе цикла, к тому же склонен к зацикливанию при наличии отложенных ордеров. while используют когда неизвестно максимальное количество проходов, а условие на выход формируется динамически. А так for и while полные аналоги.

2 xrust

xrust 21.06.2010 23:00
  

а мне лень "-1" писать... если ордера с данным номером нет, то функция OrderSelect() и так не пропустит, а если уж быть совсем точным. 
то надо предварительно задать переменной значение OrdersTotal(), инваче постоянный вызов этой функции.

В приведенном Вами варианте 

for(int i=OrdersTotal();i>=0;i--)
не будет: условие перед первой ";" выполняется один раз - перед началом цикла. Зато такая привычка (опускать -1) запросто может привести к выходу за пределы массива (в других случаях). Потому лучше как в армии : "Безобразно, но однообразно" - легче ошибки вылавливать. ИМХО, естественно.


2 goldtrader

 

for(int i=OrdersTotal()-1;i>=0;i--) {
    OrderSelect(i, SELECT_BY_POS);

в общем случае не совсем верно: если ордер выбран не будет этот цикл все равно пытается его обработать. Более правильно :

for(int i=OrdersTotal()-1;i>=0;i--) 
{
    if(!OrderSelect(i, SELECT_BY_POS)) break;
.............................................
}

или так

for(int i=OrdersTotal()-1;i>=0;i--) 
    if(OrderSelect(i, SELECT_BY_POS))
    {
    ...................................
    }

 

Удачи. 

 
VladislavVG:



2 goldtrader

в общем случае не совсем верно: если ордер выбран не будет этот цикл все равно пытается его обработать.

Согласен. Просто на практике не встречалось чтобы ордер не был выбран. С учётом Вашего замечания:

//+------------------------------------------------------------------+
//|                                        ClosePositionByMarket.mq4 |
//|                      Copyright © 2009, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void start() {
   while (PositionsTotal() > 0) {
      ClosePositions();
   }
}
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Закрывает с рынка все открытые позиции                           |
//+---------------------------------------------------- -------------+
void ClosePositions() {
   for(int i=OrdersTotal()-1;i>=0;i--) {
      if (OrderSelect(i, SELECT_BY_POS)) {
         RefreshRates();
         if (OrderType()==OP_BUY) {
            OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),5,0);
         }
         if (OrderType()==OP_SELL) {
            OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),5,0);
         }
      }
   }
} 
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//    Функция, возвращающая сумманое количество позиций, открытых    |
//    советником по всем инструментам                                |
//+------------------------------------------------------------------+
int PositionsTotal() {
   int total = OrdersTotal(), pos = 0;
   for (int i = 0; i < total; i++) {
      if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderType() == OP_BUY || OrderType() == OP_SELL) {
            pos++;
         }
      }
   }
   return(pos);
}
//+------------------------------------------------------------------+
Причина обращения: