Проблема в работе с отложенным ордерами.

 

Добрый день, коллеги! :)

Начну с того, что я далеко не гуру в написании советников, в связи с чем у меня возникла серьезная продлема, при работе с отложенными ордерами.

Принцип работы советника: В 1.10 советник спрашивает индикатор о его показаниях и выставляет по нему отложенный ордер. Как сделать так, что бы ордеры не мнодились я сообразил, а вот как сделать так, что бы в незвависимости от судьбы ордера сегодня - завтра в 1.10 снова выставились ордеры. Помогите, пожалуйста разобраться, вот код:

#define MAGIC 916883
 
extern color clOpenBuy =  Blue;
extern color clCloseBuy = Aqua;
extern color clOpenSell =  Red;
extern color clCloseSell = Violet;
extern color clModiBuy =  Blue;
extern color clModiSell =  Red;
 
extern double lTrailingStop  = 20;
extern double sTrailingStop  = 20;
 
 
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
  
   // EurUsd
   double BuyStop=iCustom(NULL,NULL, "Signals",0,0);
   double SellStop=iCustom(NULL,NULL, "Signals",1,0);
   double BuyProfit=iCustom(NULL,NULL, "Signals",2,0);
   double SellProfit=iCustom(NULL,NULL, "Signals",3,0);
   double BuyLoss=iCustom(NULL,NULL, "Signals",4,0);
   double SellLoss=iCustom(NULL,NULL, "Signals",5,0);
    
    
  if (!ExistPositions()){     
   if(Hour()==1){
   double ldLot; 
   ldLot = 0.5; 
   string lsComm; 
   lsComm = "2D-FX.com Signals 2.0"; 
   int last;
   OrderSend(Symbol(),OP_BUYSTOP,ldLot,BuyStop,0,BuyLoss,BuyProfit,lsComm,MAGIC,0,clOpenBuy);
   OrderSend(Symbol(),OP_SELLSTOP,ldLot,SellStop,0,SellLoss,SellProfit,lsComm,MAGIC,0,clOpenSell);   
   } // Hours check
  }  // If position exist
   return(0);
}
 
 
bool ExistPositions() {
  for (int i=0; i<OrdersTotal(); i++) {
     if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
    if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC) {
              if(TimeCurrent()<iTime(Symbol(),PERIOD_D1,1)){
          return(1);
          } else {
          // Вот тут надо че-та написать. :(
          }
   } 
return(True);
 }
} 
return(false);
}
 
Можно сделать проверку времени открытия ордера OrderOpenTime( ), если прошло больше 24 часов, то значит можно открывать новый.
Т.е. надо не так как ты хочешь пихать чего-то в элсе, а в ходе одного перебора проверить:
- совпадает ли символ
- совпадает ли магик
- время открытия.
Если все совпало и время больше 24 часов от настоящего момента, то можно ставить новый ордер. Если обнаружен ордер свежее 24 часов, то сразу выходить из проверки с кодом "облом".
Т.е. надо не плодить дополнительные проверки, а решать проблему комплексно.

Плюс в самом начале эксперта надо вставить проверку на время - если время не 1, то просто завершить работу, а не проверять все сигналы, ордера, и только потом обнаружив, что время ушло - обламываться. Тестироваться будет гораздо быстрее.
 
Вообще непонятно, как он у тебя ордера открывает.
Условие TimeCurrent()<iTime(Symbol(),PERIOD_D1,1)
всегда ложно, не может текущее время быть меньше открытого вчера бара.
Несмотря на это, выход из функции всегда истинный - return(True);
т.е. до установки ордеров программа не должна доходить.
И еще, почему 1.10? По твоим выкладкам проверка происходит ровно в час.
Последнее, timbo правильно посоветовал, сначала проверяй время, типа:

if(Hour()==1&&Minute()==10){
if (!ExistPositions()){
потом условия открытия ордеров.
Удачи.
 

Ага, спасибо, это понял!

Только подскажите, пожалуйста еще, как мне получить значение 1.10 следующего дня в секунах?

 

Всем спасибо - сам отвечаю на свой вопрос.

  • StrToTime
  • TimeToStr
  •  

    Нет. Так и не смог разобраться. Все гладко до момента, пока не наступает день, и предыдущий ордер какой-то не закрыт. Вот:

    :(((

    bool ExistPositions() {
        for (int i=0; i<OrdersTotal(); i++) {
            if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
            
               int NewDay=StrToTime(TimeToStr(OrderOpenTime(), TIME_DATE))+86400;
               int StopTime=NewDay+3700;
                if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC && TimeCurrent()<NewDay){
                return(1);
              }
              
              if (OrderSymbol()==Symbol() && OrderMagicNumber()==MAGIC && TimeCurrent()>NewDay && TimeCurrent()<StopTime){
                return(0);
              } else {
              return(1);
              }
     
       }
     
            } 
        return(false);
    }
    Файлы:
    strategy.zip  13 kb
     
    Это ты перемудрил.
    Должно быть как-то так:
    bool ExistPositions(int magic) {
       for (int i=0; i<OrdersTotal(); i++) 
       {
          if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) 
          {
             if (OrderSymbol()==Symbol())
             { 
                if(OrderMagicNumber()==magic) 
                {
                   if(OrderOpenTime() + 24*60*60 > TimeCurrent())
                   {
                      return(1);
                   }
                }
             }
          }
       }
    }
    Тебе надо только проконтролировать, что эксперт может открываться (а лучше вообще что-либо делать) только с 1 часа до 2, например. И всё.
    Добавь в самом начале что-то типа:
       if(TimeHour(TimeCurrent())!=1) 
       {
          return(0);
       }
    Если хочешь с точностью до минут, то добавь аналогичное условие для TimeMinute() , но не зажимай его сильно, т.е. не делай равно 10, а сделай больше 5, но меньше 15.

    PS Код в зипе я не смотрел.
     
    Кстати, сдается мне, что ты все переменные передаюшь в подпрограмму через глобальные переменные. Это не лучший вариант. Посмотри что я сделал с твоей ExistPositions, теперь чтобы обратиться к ней надо будет писать
    if(ExistPositions(magic) == 0) { ... }
    т.е. я передаю значение маджика внутрь подпрограммы. Аналогично можно запихать туда много разных переменных.
     

    Точно, спасибо. Разобрался.

    Причина обращения: