Необходим простой код для советника (модифицировать два открытых ордера) - страница 3

 

В основном я устанавливаю два отложенных ордера в определенное время, а именно 23:00 GMT+2, я думаю. Один из отложенных ордеров является стопом на продажу, а другой - стопом на покупку, оба ордера находятся на одинаковом расстоянии от открытия свечи 23:00, в данном случае 14 пунктов. Оба имеют TakeProfit в 28 пунктов (в данном случае) и StopLoss в 55 пунктов.

Теперь, когда оба ордера будут исполнены (по сути, пройдя и вверх, и вниз 14 пунктов от цены открытия на свече 23:00 до истечения срока действия ордеров), я хочу, чтобы у обоих ордеров тейк-профит увеличился, например, на 20 пунктов. Таким образом, их новый тейк-профит в этом случае составит 58 пунктов. Стоп-лосс при этом должен остаться неизменным. По сути, я пытаюсь сделать что-то вроде хеджирования.

Если открыты две сделки, то вполне вероятно, что цена пойдет в одном направлении достаточно сильно, чтобы свести на нет любые потери, если увеличить тейк-профиты обеих сделок. Для получения прибыли нужно открыть только одну сделку и достичь тейк-профита или открыть обе сделки и достичь тейк-профита, не уходя далеко в одном направлении.

Надеюсь, это понятно, если нет, я предоставлю картинку, которая должна быть более понятной.

 
WHRoeder:

Я имел в виду ваш непосредственно предыдущий пост

madmax3 2012.03.09 14:52
Вот пересмотренный код для всего советника:
Который все еще показывает проблемы, которые я указал.
Эта часть кода относится к другой части советника, я полагаю, к той, которая открывает отложенные ордера, будет ли это иметь какое-либо влияние на ту часть, которую я пытаюсь исправить? Извините, я думаю, что я перепутал части кода, особенно в первоначальном сообщении. Однако я сделал то, что вы указали, с той частью кода, которая мне конкретно нужна.
 
madmax3:

Я надеюсь, что это понятно, если нет, я предоставлю картинку, которая должна быть более понятной.

Все ясно, спасибо.

Итак, вы просто хотите изменить эти ордера один раз ... тогда ответ прост. Вам нужно проверить бар 23:00 и определить TP, на которых должны были быть открыты ордера ... если ордера находятся на том же TP, то их нужно модифицировать, если они не находятся на том же TP, то они уже были модифицированы и их не нужно модифицировать снова ... просто.

 
RaptorUK:

Все ясно, спасибо.

Итак, вы просто хотите модифицировать эти ордера один раз ... тогда ответ прост. Вам нужно проверить бар 23:00 и определить TP, на которых должны были быть открыты ордера ... если ордера находятся на том же TP, то их нужно модифицировать, если они не находятся на том же TP, то они уже были модифицированы и их не нужно модифицировать снова ... просто.

Модификация и проверка должны происходить только тогда, когда открыты две сделки, но как мне это сделать? Должен ли я добавить к уже имеющемуся коду или начать заново?

То есть, по сути, если есть две сделки (один и тот же символ и магический номер), советник должен проверить тейк-профиты открытых сделок по сравнению с ранее существующими отложенными ордерами (которые сейчас исполнены), и если они одинаковы, то их нужно изменить, а после того, как он зациклится, он снова проверит и обнаружит, что они не одинаковы, и таким образом не будет дальше изменять сделки?
 
madmax3:
1. Модификация и проверка должны происходить только тогда, когда открыты две сделки, но как мне это сделать? Должен ли я добавить к уже имеющемуся коду или начать заново?

2. То есть, по сути, если есть две сделки (один и тот же символ и магический номер), советник должен проверить тейк-профиты открытых сделок по сравнению с ранее существующими отложенными ордерами (которые сейчас исполнены), и если они одинаковы, то их следует изменить, а после цикла он снова проверит и обнаружит, что они не одинаковы, и таким образом не будет дальше модифицировать сделки?

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

2. Нет, вы не можете увидеть TP отложенных ордеров, если они были активированы и теперь больше не отложены. Советник должен проверить бар 23:00 и определить, какими были бы первоначальные TP... затем сравнить их с TP двух открытых ордеров... на основе этой информации можно принять решение о модификации или не модификации.

 
RaptorUK:

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

2. Нет, вы не можете увидеть TP отложенных ордеров, если они были активированы и теперь больше не отложены. Советник должен проверить бар 23:00 и определить, какими были бы первоначальные TP... затем сравнить их с TP двух открытых ордеров... на основе этой информации можно принять решение о модификации или отказе от модификации.

Понятно, я полагаю, это то, что я пытался сделать все это время. Пока что один из ордеров модифицирован (в частности, ордер на покупку, который является ордером 2 в моем тестировании), но он продолжает модифицироваться, могу ли я использовать 'break', чтобы остановить его от повторения? Также как мне подсчитать и модифицировать только открытые ордера, если их всего два? Я пытался использовать для этого OrdersTotal(), но не получается, я не думаю, что мне нужно делать два отдельных куска кода для каждого ордера, верно?
Модифицируются только четные открытые ордера, и, как я уже сказал, они неоднократно модифицируются, я пробовал различные комбинации для OrderSelect(), но все еще не могу разобраться, как я уже сказал, я полный профан в MQL, и этот советник уже почти готов, поэтому я хотел бы просто закончить его. Я читал здесьhttps://book.mql4.com/trading/ordermodify, может ли это иметь какое-то отношение к моей ситуации? Это для стоп-лосса, но мне нужно для тейк-профита.

Что я делаю не так?

     for(int iPos = OrdersTotal()-1; iPos >= 1 ; iPos--) if (
        OrderSelect(iPos, SELECT_BY_POS)                    // Only my orders w/
    &&  OrderMagicNumber()  == MagicNumber                 // my magic number
    &&  OrderSymbol()       == "EURUSD"                // and my pair.
    && (OrderType() == OP_BUY)
    ){OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),Ask+((TakeProfit+20)*Point),0,Blue);}
    return(0);
    
  if (
        OrderSelect(iPos-1, SELECT_BY_POS-1)                    
    &&  OrderMagicNumber()  == MagicNumber                
    &&  OrderSymbol()       == "EURUSD"                
    && (OrderType() == OP_SELL)
    ){OrderModify(OrderTicket(),OrderOpenPrice(),OrderStopLoss(),Ask+((TakeProfit-20)*Point),0,Blue);}
return(0);
  }

Как мне проверить, совпадает ли ТП со свечой 23:00? Нужно ли это как таковое, ведь пока открытые ордера модифицируются, когда их 2, это достигает того же эффекта? Или это просто для того, чтобы ордер не модифицировался постоянно, и да, я проверил документацию.

Спасибо,

madmax3

 

Ваш return(0) выводит вас из start() до того, как 2-й ордер будет модифицирован.

Все, что вы делаете, это выбираете ордер по позиции, проверяете, что он имеет правильный номер Magic, проверяете, что это правильный символ и проверяете, что это OP_BUY ... затем вы изменяете его, где вы определяете, был ли он уже изменен или нет?

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

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

"Я установил два отложенных ордера на определенное время, а именно 23:00 GMT+2, я думаю. Один из отложенных ордеров является стопом на продажу, а другой стопом на покупку, оба ордера находятся на одинаковом расстоянии от открытия свечи 23:00, в данном случае 14 пунктов. Оба имеют TakeProfit в 28 пунктов (в данном случае) и StopLoss в 55 пунктов."

Вы можете вычислить, где находился первоначальный TP, сославшись на свечу 23:00, проверить ордер и посмотреть, установлен ли он все еще на первоначальный TP, если да, то его можно модифицировать... если нет, то он уже был модифицирован, поэтому не модифицируйте его снова.

Есть и другие способы регистрации того, что ордер был изменен, отслеживайте номер тикета, записывайте информацию в файл, когда он был изменен, когда вы собираетесь изменить его снова, откройте файл и проверьте номер тикета, и т.д. ... Я думаю, что проверка по сравнению с оригинальным TP намного проще.

 

На данный момент я имею следующее,

//+------------------------------------------------------------------+
//|                                                  TimeBasedEA.mq4 |
//|                      Copyright © 2008, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
//changed by:       "forex4capital@yahoo.ca"
//changed again by: madmax3

// Time frame: M5 and higher

extern int     MagicNumber = 20080122;
extern double DistancefromAsk;
extern double DistancefromBid;
extern double  TakeProfit  = 28;
extern double  StopLoss    = 55;
extern double  Lots        = 0.1;
extern int     StartHour   = 2300;      // Open Trade time
extern bool    OpenBuy     = true;
extern bool    OpenSell    = true;
extern int     NumBuys     = 1;
extern int     NumSells    = 1;
extern int     Slippage    = 2;

//+------------------------------------------------------------------+
//|                        S T A R T                                 |
//+------------------------------------------------------------------+
int start()
  {
   int cnt, ticket, total;
      if (TimeDayOfWeek(TimeCurrent())==5 && TimeCurrent()>=StrToTime("22:59")) { CloseAll(); return(0); }
   int ct;
//-------------------------------------+
   if(Bars<100)
     {
      Print("bars less than 100");
      return(0);  
     }
//-------------------------------------+

//-------------------------------------+
   if(TakeProfit<10)
     {
      Print("TakeProfit less than 10");
      return(0);  // check TakeProfit
     }
//-------------------------------------+

   ct = Hour() * 100 + Minute();
   total=OrdersTotal();
   if(total<1) 
     {
      // no opened orders identified
      if(AccountFreeMargin()<(1000*Lots))
        {
         Print("We have no money. Free Margin = ", AccountFreeMargin());
         return(0);  
        }
      // check for long position (BUY) possibility
      if(ct == StartHour && Close[1]>Open[1] && OpenBuy)
      //if(ct == StartHour && High[1]<Open[0] && OpenBuy)
        {
         for ( cnt = 0; cnt < NumBuys; cnt++)
         {
           ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+(DistancefromAsk*Point),Slippage,Bid-(StopLoss*Point),Ask+(TakeProfit*Point),"",MagicNumber,TimeCurrent()+39600,CLR_NONE);
           ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-(DistancefromBid*Point),Slippage,Ask+(StopLoss*Point),Bid-(TakeProfit*Point),"",MagicNumber,TimeCurrent()+39600,CLR_NONE); 
           if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
           }

          
           else Print("Error opening BUY order : ",GetLastError()); 
           

         }
         return; 
        }
      // check for short position (SELL) possibility
      if(ct == StartHour && Close[1]<Open[1] && OpenSell)
      //if(ct == StartHour && Low[1]>Open[0] && OpenSell)
        {
         for ( cnt = 0; cnt < NumSells; cnt++)
         {
           ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Bid-(DistancefromAsk*Point),Slippage,Ask+(StopLoss*Point),Bid-(TakeProfit*Point),"",MagicNumber,TimeCurrent()+39600,CLR_NONE);
           ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ask+(DistancefromBid*Point),Slippage,Bid-(StopLoss*Point),Ask+(TakeProfit*Point),"",MagicNumber,TimeCurrent()+39600,CLR_NONE);
           if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
           }
           else Print("Error opening SELL order : ",GetLastError());
         } 
         return; 
        
    
}
//---------------------------------------------------------------

 int Handle,                         // File descriptor
   Qnt_Symb;                           // Number of recorded symbols
   string File_Name="check.csv";        // File name
   
    Handle=FileOpen(File_Name,FILE_CSV|FILE_WRITE|FILE_READ,";");//File opening
   

         FileWrite(Handle,"Ticket","Magic","OTime","Type","Lots","Symbol","OPrice","S/L","T/P"); 
         
          for(int iPos = OrdersTotal()-1; iPos >= 1 ; iPos--)
      {       
       OrderSelect(iPos,SELECT_BY_POS) ;
       FileWrite(
         Handle,
         OrderTicket(),                //int
         OrderMagicNumber(),           //int
         TimeToStr(OrderOpenTime()),   //datetime
         
         OrderLots(),                  //double
         OrderSymbol(),                //string
         OrderOpenPrice(),             //double
         OrderStopLoss(),              //double
         OrderTakeProfit(),            //double
         TimeToStr(OrderCloseTime())  //int
       
        ) ; //end file write
           }   }
           
}
//---------------------------------------------------------------   
 
     
     
  void CloseAll()
{
   for(int cnt=OrdersTotal()-1;cnt>=0;cnt--)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if (OrderMagicNumber()!=MagicNumber) continue;
         
      //
      //
      //
      //
      //
         
      if (OrderType()==OP_BUY || OrderType()==OP_SELL)
      {
         for(int c=0; c<3; c++)
         {
            RefreshRates();
            if (OrderType()==OP_BUY)
                  { double cp = Bid;}  
            else  {        cp = Ask;}
               
            OrderClose(OrderTicket(),OrderLots(),cp,0,Yellow);
               int err=GetLastError();
               if(err==4 || err==136 || err==137 || err==138 || err==146)
               {
                  Sleep(5000); continue;
               }  
               break;                     
         }
         break;
      }
      }
      }
   
// the end.

Код записи файла, как указано выше, есть,

//---------------------------------------------------------------

 int Handle,                         // File descriptor
   Qnt_Symb;                           // Number of recorded symbols
   string File_Name="check.csv";        // File name
   
    Handle=FileOpen(File_Name,FILE_CSV|FILE_WRITE|FILE_READ,";");//File opening
   

         FileWrite(Handle,"Ticket","Magic","OTime","Type","Lots","Symbol","OPrice","S/L","T/P"); 
         
          for(int iPos = OrdersTotal()-1; iPos >= 1 ; iPos--)
      {       
       OrderSelect(iPos,SELECT_BY_POS) ;
       FileWrite(
         Handle,
         OrderTicket(),                //int
         OrderMagicNumber(),           //int
         TimeToStr(OrderOpenTime()),   //datetime
         
         OrderLots(),                  //double
         OrderSymbol(),                //string
         OrderOpenPrice(),             //double
         OrderStopLoss(),              //double
         OrderTakeProfit(),            //double
         TimeToStr(OrderCloseTime())  //int
       
        ) ; //end file write
          	 FileClose(Handle); }   }
           
}
//---------------------------------------------------------------   

Но я получаю эти ошибки,

2012.04.04 15:30:06 2012.01.16 06:25 TimeBasedEA Version 2: FileOpen - слишком много открытых файлов

2012.04.04 15:30:06 2012.01.16 06:25 TimeBasedEA Version 2: invalid handle -1 in FileWrite

В чем дело?

 

Почему вы выбрали самый сложный из двух вариантов?

Когда вы закончили запись в файл, вам нужно закрыть его ... если он уже открыт, вам не нужно открывать его снова.

//---------------------------------------------------------------

int Handle,                         // File descriptor
    Qnt_Symb;                           // Number of recorded symbols
string File_Name="check.csv";        // File name
   
Handle=FileOpen(File_Name,FILE_CSV|FILE_WRITE|FILE_READ,";");//File opening    File opened here, outside the loop
   

FileWrite(Handle,"Ticket","Magic","OTime","Type","Lots","Symbol","OPrice","S/L","T/P"); 
         
for(int iPos = OrdersTotal()-1; iPos >= 1 ; iPos--)
   {       
   OrderSelect(iPos,SELECT_BY_POS);
   FileWrite(
         Handle,
         OrderTicket(),                //int
         OrderMagicNumber(),           //int
         TimeToStr(OrderOpenTime()),   //datetime   //  this is a string - Time  to  String
         
         OrderLots(),                  //double
         OrderSymbol(),                //string
         OrderOpenPrice(),             //double
         OrderStopLoss(),              //double
         OrderTakeProfit(),            //double
         TimeToStr(OrderCloseTime() )  //int     //  this is a string - Time  to  String
       
        ) ; //end file write

   FileClose(Handle);      //  why close the file inside the loop when it was opened outside the loop ?
   }   
}    //  what is this code inside of ?
           
}  // end of start
//--------------------------------------------------------------- 

Ваш цикл for неправильный ... ... позиция последнего порядка 0, а не 1.

 
RaptorUK:

Почему вы выбрали самый сложный из двух вариантов?

Разве это не способ сделать модификацию и проверку с помощью файла? Или мне нужно объединить оба кода, модификацию (мое сообщение перед последним) и код файла (который нужен только для того, чтобы убедиться в отсутствии дальнейших модификаций)?