Открывается только первая позиция.

 

Подскажите пожалуйста как зафиксировать реальную цену открытия первой позиции, чтобы другие позиции тоже открывались . Цены остальных позиций расчитываются от первой. Выдается ошибка 138(цены изменились).

//+------------------------------------------------------------------+
//|                                                    Open7-lim.mq4 |
//|                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+

      
//--------------------------------------------------------------------
extern int    takeprofit1     =150;
extern int    takeprofit2     =120;
extern int    takeprofit3     =90;
extern int    takeprofit4     =60;
extern int    takeprofit5     =30;
extern int    takeprofit11     =150;
extern int    takeprofit12     =120;
extern int    takeprofit13     =90;
extern int    takeprofit14     =60;
extern int    takeprofit15     =30;
extern int    stoploss       =30;
extern bool   AllPositions   = False; // Управлять всеми позициями
extern bool   ProfitTrailing = False;  // Тралить только профит
extern int    TrailingStop   = 30;    // Фиксированный размер трала
extern int    TrailingStep   = 2;     // Шаг трала
extern bool   UseSound       = True;  // Использовать звуковой сигнал
extern string NameFileSound  = "expert.wav";  // Наименование звукового файла
                            
extern double LOT=0.1;


//--------------------------------------------------------------------
double SL1,SL2,SL3,SL4,SL5,SL11,SL12,SL13,SL14,SL15,TP1,TP2,TP3,TP4,TP5,TP11,TP12,TP13,TP14,TP15;
double OrderLevel=30;

double _OrderOpenPrice1,
       _OrderOpenPrice2,
       _OrderOpenPrice3,
       _OrderOpenPrice4,
       _OrderOpenPrice5,

      _OrderOpenPrice11,
      _OrderOpenPrice12,
      _OrderOpenPrice13,
      _OrderOpenPrice14,
      _OrderOpenPrice15;   
//-------------------------------------------------------------------+
//|  expert start function                                            |
//+------------------------------------------------------------------+

int TimeBar;
int start()
{
for (int i=OrdersTotal()-1; i>=0; i--)
   {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
     {
      if (AllPositions || OrderSymbol()==Symbol())
       {               
        TrailingPositions();
      }
    }
  }

  if (TimeBar==Time[0]) return(0);
   if (TimeBar==0) {TimeBar=Time[0];return(0);}//первый запуск программы 
   
   
   int k;
   for(k=1;k<=40;k++)
   if (k>=0 && k<=40&&(Open[0]-Open[0+k])>=0.0030 )//Buy
   {
      TimeBar=Time[0];
      _OrderOpenPrice1=NormalizeDouble(Ask,Digits);
      _OrderOpenPrice2=_OrderOpenPrice1+OrderLevel*Point;
      _OrderOpenPrice3=_OrderOpenPrice1+2*OrderLevel*Point;
      _OrderOpenPrice4=_OrderOpenPrice1+3*OrderLevel*Point;
      _OrderOpenPrice5=_OrderOpenPrice1+4*OrderLevel*Point;
                                   
      TP1  = _OrderOpenPrice1 + takeprofit1*Point;
      TP2  = _OrderOpenPrice2 + takeprofit2*Point;
      TP3  = _OrderOpenPrice3 + takeprofit3*Point;
      TP4  = _OrderOpenPrice4 + takeprofit4*Point;
      TP5  = _OrderOpenPrice5 + takeprofit5*Point;
      
      SL1  = _OrderOpenPrice1-stoploss*Point;
      SL2  = _OrderOpenPrice2-stoploss*Point;
      SL3  = _OrderOpenPrice3-stoploss*Point;     
      SL4  = _OrderOpenPrice4-stoploss*Point;
      SL5  = _OrderOpenPrice5-stoploss*Point;
      
     OPENORDER1("Buy");
     OPENORDER2("Buy");
     
     
     
     
     
   }
   for(k=1;k<=40;k++)
   if (k>=0 && k<=40&&(Open[0]-Open[0+k])>=-0.0030 ) //Sell
   {
      TimeBar=Time[0];
      _OrderOpenPrice11=NormalizeDouble(Bid,Digits);
      _OrderOpenPrice12=_OrderOpenPrice11-OrderLevel*Point;
      _OrderOpenPrice13=_OrderOpenPrice11-2*OrderLevel*Point;
      _OrderOpenPrice14=_OrderOpenPrice11-3*OrderLevel*Point;
      _OrderOpenPrice15=_OrderOpenPrice11-4*OrderLevel*Point;
       
      TP11  = _OrderOpenPrice11 - takeprofit11*Point;
      TP12  = _OrderOpenPrice12 - takeprofit12*Point;
      TP13  = _OrderOpenPrice13 - takeprofit13*Point;
      TP14  = _OrderOpenPrice14 - takeprofit14*Point;
      TP15  = _OrderOpenPrice15 - takeprofit15*Point;                           
      
      
      SL11  = _OrderOpenPrice11+stoploss*Point;
      SL12  = _OrderOpenPrice12+stoploss*Point;
      SL13  = _OrderOpenPrice13+stoploss*Point;     
      SL14  = _OrderOpenPrice14+stoploss*Point;
      SL15  = _OrderOpenPrice15+stoploss*Point;
                  
          
     
     OPENORDER1("Sell");
     OPENORDER2("Sell");
     
    
     
     
     
      }
return(0);

}
//--------------------------------------------------------------------
void OPENORDER1(string ord)
{
int total=OrdersTotal();
  Comment("total = "+total);
if (OrdersTotal()!=0) return;

   int error;
   if (ord=="Buy" ) error=OrderSend(Symbol(),OP_BUY,LOT,_OrderOpenPrice1,2,SL1,TP1,"",1,3);
   if (ord=="Sell") error=OrderSend(Symbol(),OP_SELL,LOT,_OrderOpenPrice1,2,SL11,TP11,"",-1,3);
   if (error==-1) //неудачная покупка OK
    
   {  
      ShowERROR(error,0,0);
   }
return;
}  

//--------------------------------------------------------------------
void OPENORDER2(string ord)
{
int total=OrdersTotal();
  Comment("total = "+total);
if (OrdersTotal()==0) return;

   int error;
   if (ord=="Buy") error=OrderSend(Symbol(),OP_BUY,LOT,_OrderOpenPrice2,2,SL2,TP1,"",1,3);
   if (ord=="Sell") error=OrderSend(Symbol(),OP_SELL,LOT,_OrderOpenPrice12,2,SL12,TP11,"",-1,3);
   if (ord=="Buy" ) error=OrderSend(Symbol(),OP_BUY,LOT,_OrderOpenPrice3,2,SL3,TP1,"",1,3);
   if (ord=="Sell") error=OrderSend(Symbol(),OP_SELL,LOT,_OrderOpenPrice13,2,SL13,TP11,"",-1,3);
   if (ord=="Buy" ) error=OrderSend(Symbol(),OP_BUY,LOT,_OrderOpenPrice4,2,SL4,TP1,"",1,3);
   if (ord=="Sell") error=OrderSend(Symbol(),OP_SELL,LOT,_OrderOpenPrice14,2,SL14,TP11,"",-1,3);
   if (ord=="Buy" ) error=OrderSend(Symbol(),OP_BUY,LOT,_OrderOpenPrice5,2,SL5,TP1,"",1,3);
   if (ord=="Sell") error=OrderSend(Symbol(),OP_SELL,LOT,_OrderOpenPrice15,2,SL15,TP11,"",-1,3);
   if (error==-1) //неудачная покупка OK
    
   {  
      ShowERROR(error,0,0);
   }
return;
}  



//+------------------------------------------------------------------+
//| Сопровождение позиции простым тралом                             |
//+------------------------------------------------------------------+
void TrailingPositions() {
  double pBid, pAsk, pp;

  pp = MarketInfo(OrderSymbol(), MODE_POINT);
  if (OrderType()==OP_BUY) {
    pBid = MarketInfo(OrderSymbol(), MODE_BID);
    if (!ProfitTrailing || (pBid-OrderOpenPrice())>TrailingStop*pp) {
      if (OrderStopLoss()<pBid-(TrailingStop+TrailingStep-1)*pp) {
        ModifyStopLoss(pBid-TrailingStop*pp);
        return;
      }
    }
  }
  if (OrderType()==OP_SELL) {
    pAsk = MarketInfo(OrderSymbol(), MODE_ASK);
    if (!ProfitTrailing || OrderOpenPrice()-pAsk>TrailingStop*pp) {
      if (OrderStopLoss()>pAsk+(TrailingStop+TrailingStep-1)*pp || OrderStopLoss()==0) {
        ModifyStopLoss(pAsk+TrailingStop*pp);
        return;
      }
    }
  }
}

//+------------------------------------------------------------------+
//| Перенос уровня StopLoss                                          |
//| Параметры:                                                       |
//|   ldStopLoss - уровень StopLoss                                  |
//+------------------------------------------------------------------+
void ModifyStopLoss(double ldStopLoss) {
  bool fm;

  fm=OrderModify(OrderTicket(),OrderOpenPrice(),ldStopLoss,OrderTakeProfit(),0,CLR_NONE);
  if (fm && UseSound) PlaySound(NameFileSound);
}

//--------------------------------------------------------------------
void ShowERROR(int Ticket,double SL,double TP)
{
   int err=GetLastError();
   switch ( err )
   {                  
      case 1:                                                                               return;
      case 2:   Alert("Нет связи с торговым сервером   "              ,Ticket," ",Symbol());return;
      case 3:   Alert("Error  неправильные параметры   Ticket ",       Ticket," ",Symbol());return;
      case 130: Alert("Error близкие стопы   Ticket ",                 Ticket," ",Symbol());return;
      case 134: Alert("Недостаточно денег   ",                         Ticket," ",Symbol());return;
      case 138: Alert("цены изменились   ",                            Ticket," ",Symbol());return;
      case 146: Alert("Error Подсистема торговли занята ",             Ticket," ",Symbol());return;
      case 129: Alert("Error Неправильная цена ",                      Ticket," ",Symbol());return;
      case 131: Alert("Error Неправильный объем ",                     Ticket," ",Symbol());return;
      case 4051:Alert("Error Недопустимое значение параметра функции ",Ticket," ",Symbol());return;
      case 4105:Alert("Error Ни один ордер не выбран ",                Ticket," ",Symbol());return;
      case 4063:Alert("Error Ожидается параметр типа integer ",        Ticket," ",Symbol());return;
      case 4200:Alert("Error Объект уже существует ",                  Ticket," ",Symbol());return;
      default:  Alert("Error  " ,err,"   Ticket ",                     Ticket," ",Symbol());return;
   }
}

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

Ух ё. Ну дык нельзя же открывать рыночные ордера не по текущим ценам. Уровни, которые у Вас просчитываются, на них можно только ставить отложенные ордера.

Поясняю. Пришёл очередной тик - это значит, что пришёл Бид и Аск - это текущая цена. Рыночный ордер типа Бай/Селл - его можно открыть только по текущей цене. Если уровень рассчитывается как Бид+отклонение*Point, то уровень будет отстоять от текущей цены на размер этого отклонения. Уроввень будет ВЫШЕ текущей цены. Туда можно ставить только БайСтоп или СеллЛимит ордер. Да и то только в том случае, если размер отклонения болше или равен минимально-допустимому расстоянию для установки отложенных ордеров и/или стоп-приказов. Не забывайте так же, что Бай-ордера ставятся по Аску, а закрываются по Биду. У Селл-ордеров всё наоборот. Это правило справедливо для Бай/Селл ордеров любого типа. Поэтоу минимально-допустимое отклонение нужно рассчитывать опираясь на цены Бид/Аск в зависимости от типа ордера.

 
drknn:

Ух ё. Ну дык нельзя же открывать рыночные ордера не по текущим ценам. Уровни, которые у Вас просчитываются, на них можно только ставить отложенные ордера.

Поясняю. Пришёл очередной тик - это значит, что пришёл Бид и Аск - это текущая цена. Рыночный ордер типа Бай/Селл - его можно открыть только по текущей цене. Если уровень рассчитывается как Бид+отклонение*Point, то уровень будет отстоять от текущей цены на размер этого отклонения. Уроввень будет ВЫШЕ текущей цены. Туда можно ставить только БайСтоп или СеллЛимит ордер. Да и то только в том случае, если размер отклонения болше или равен минимально-допустимому расстоянию для установки отложенных ордеров и/или стоп-приказов. Не забывайте так же, что Бай-ордера ставятся по Аску, а закрываются по Биду. У Селл-ордеров всё наоборот. Это правило справедливо для Бай/Селл ордеров любого типа. Поэтоу минимально-допустимое отклонение нужно рассчитывать опираясь на цены Бид/Аск в зависимости от типа ордера.


А если написать для каждого ордера свое условие открытия? Например:

if(_OrderOpenPrice1+OrderLevel*Point==Ask)

{

TimeBar=Time[0];
_OrderOpenPrice2=NormalizeDouble(Ask,Digits);
OPENORDER2("Buy")

}

Но все равно вместо расчетного значения _OrderOpenPrice1 надо вставить реальное. Как это сделать ? Может кто то подскажет или даст ссылку?

 
david2:


А если написать для каждого ордера свое условие открытия? Например:

if(_OrderOpenPrice1+OrderLevel*Point==Ask)

{

TimeBar=Time[0];
_OrderOpenPrice2=NormalizeDouble(Ask,Digits);
OPENORDER2("Buy")

}

Но все равно вместо расчетного значения _OrderOpenPrice1 надо вставить реальное. Как это сделать ? Может кто то подскажет или даст ссылку?


Установите рыночный ордер. Отыщите цену его открытия. Используйте эту цену как точку отсчёта (стартовый уровень). К этому уровню поприбавляйте отклонения - внесите полученные величины новых уровней в переменные. Расставьте по этим уровням BuyStop-ордера. Как только тренд достигнет очередного BuyStop-ордера, этот ордер сработает и станет обычным рыночным Бай-ордером, и именно на том уровне, который Вы так хотели. И не нужно ухищряться с описанием особых условий - Вы же хотели расставить ордера на разных уровнях - вот и расставьте - вычислите эти уровни и расставьте стоповые отложки.
 
drknn:

Установите рыночный ордер. Отыщите цену его открытия. Используйте эту цену как точку отсчёта (стартовый уровень). К этому уровню поприбавляйте отклонения - внесите полученные величины новых уровней в переменные. Расставьте по этим уровням BuyStop-ордера. Как только тренд достигнет очередного BuyStop-ордера, этот ордер сработает и станет обычным рыночным Бай-ордером, и именно на том уровне, который Вы так хотели. И не нужно ухищряться с описанием особых условий - Вы же хотели расставить ордера на разных уровнях - вот и расставьте - вычислите эти уровни и расставьте стоповые отложки.

Отложки уже пробывал. Или не полностю удоляются, или открываются новые когда не нужно. Чтобы задать правильные условия открытия и удаления все равно все сводится к фиксации событий, и построению каких то массивов для учета ордеров, но четкого примера исполнения пока не нашел, поэтому захотелось пойти легким путем, фиксировать только цену открытия первой позиции.
 
david2:

Отложки уже пробывал. Или не полностю удоляются, или открываются новые когда не нужно. Чтобы задать правильные условия открытия и удаления все равно все сводится к фиксации событий, и построению каких то массивов для учета ордеров, но четкого примера исполнения пока не нашел, поэтому захотелось пойти легким путем, фиксировать только цену открытия первой позиции.


Ну если рассчитать, что очередной ордер должен открываться от текущего с определённым шагом, то какая разница, отложка там, или код советника по достижении этого уровня ставит рыночный ордер - один чёрт ордер на этот уровень встанет.

Отложки не удаляются - значит не правильно что-то делаете.

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