Как закрыть половину открытой позиции?

 

Привет Всем!

Может кто-нибудь подскажет команду(ы) для Эксперта (желателен Пример),

позволяющие закрыть половину позиции при исполнении определенного условия - Например: x > y

Спасибо!

 

bool OrderClose( int ticket, double lots, double price, int slippage, color Color=CLR_NONE)

lots - Количество лотов для закрытия.

 

Торговая функция OrderClose

 

Пример (взят в документации):

  if(iRSI(NULL,0,14,PRICE_CLOSE,0)>75)
{
OrderClose(order_id,1,Ask,3,Red);
return(0);
}

 
Спасибо, zxc!
 

Похоже возникла некоторая проблема - каждый ордер пронумерован при открытии уникальным номером

(в моем случае одновременно может быть открытым лишь один ордер). Если мы закрываем половину позиции, то МТ похоже

удаляет номер этого ордера и в дальнейшем не может закрыть позицию:

=====================================

Alert: Закрыт ордер 1/2 LOTs of Sell 23
Alert: Попытка закрыть Sell 23. Ожидание ответа..
unknown ticket 23 for OrderClose function
OrderClose error 4108
=====================================

- Может кто-нибудь сталкивался с подобным?

Спасибо!

//### #################################################################################

. . .

if (Lots >= 0.2) {
double LotsToClose = Lots / 2;

while(true) // Цикл закрытия орд.
{

RefreshRates(); // Обновление данных
if(Bid-OrderOpenPrice() > (Point*CloseHalfLevel))
{
if (Tip==0 && Cls_B==true) // Открыт ордер Buy..
{ //и есть критерий закр
Alert("Попытка закрыть 1/2 LOTs of Buy ",Ticket,". Ожидание ответа..");
RefreshRates(); // Обновление данных
AnsHalf = OrderClose(Ticket,LotsToClose,Bid,2, Aqua); // Закрытие Buy
if (AnsHalf == true) // Получилось :)
{
Alert ("Закрыт ордер 1/2 LOTs of Buy ",Ticket);
break; // Выход из цикла закр
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
} // if(Bid-OrderOpenPrice() > Point*CloseHalfLevel)

RefreshRates(); // Обновление данных
if((OrderOpenPrice()-Ask) > (Point*CloseHalfLevel))
{
if (Tip==1 && Cls_S==true) // Открыт ордер Sell..
{ // и есть критерий закр
Alert("Попытка закрыть 1/2 LOTs of Sell ",Ticket,". Ожидание ответа..");
RefreshRates(); // Обновление данных
AnsHalf = OrderClose(Ticket,LotsToClose,Ask,2, Aqua); // Закрытие Sell
if (AnsHalf == true) // Получилось :)
{
Alert ("Закрыт ордер 1/2 LOTs of Sell ",Ticket);
break; // Выход из цикла закр
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
} // if((OrderOpenPrice()-Ask)>(Point*TrailingStop))

break; // Выход из while
} // while

} // if (Lots >= 0.2)

. . .

//### #################################################################################

 

.)Для вставки кода на этом форуме есть специальная кнопка.

..)Закрытие ордеров у Вас организовано принципиально неправильно. После закрытие половины позы, оставшаяся часть будет иметь новый тикет. Возьмите любой эксперт например MACD_sample и посмотрите как это организовано там (цикл перебора всех ордеров-> выбор нужных-> закрытие). + см. справку по OrderSelect

 

Я использовал следующий скрипт как Пример:

https://c.mql5.com/mql4/book/mq4/experts/tradingexpert.mq4

.

В нем я поместил упомянутую выше часть перед "while" раздела "// Закрытие ордеров".

Можно чуть более подробно обьяснить что именно необходимо изменить?

.

Спасибо!

 

Для лучшего восприятия помещаю код, упомянутый выше, в формате кода:

if (Lots >= 0.2) {
double LotsToClose = Lots / 2;

while(true) // Цикл закрытия орд.
{

RefreshRates(); // Обновление данных
if(Bid-OrderOpenPrice() > (Point*CloseHalfLevel))
{
if (Tip==0 && Cls_B==true) // Открыт ордер Buy..
{ //и есть критерий закр
Alert("Попытка закрыть 1/2 LOTs of Buy ",Ticket,". Ожидание ответа..");
RefreshRates(); // Обновление данных
AnsHalf = OrderClose(Ticket,LotsToClose,Bid,2, Aqua); // Закрытие Buy
if (AnsHalf == true) // Получилось :)
{
Alert ("Закрыт ордер 1/2 LOTs of Buy ",Ticket);
break; // Выход из цикла закр
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
} // if(Bid-OrderOpenPrice() > Point*CloseHalfLevel)

RefreshRates(); // Обновление данных
if((OrderOpenPrice()-Ask) > (Point*CloseHalfLevel))
{
if (Tip==1 && Cls_S==true) // Открыт ордер Sell..
{ // и есть критерий закр
Alert("Попытка закрыть 1/2 LOTs of Sell ",Ticket,". Ожидание ответа..");
RefreshRates(); // Обновление данных
AnsHalf = OrderClose(Ticket,LotsToClose,Ask,2, Aqua); // Закрытие Sell
if (AnsHalf == true) // Получилось :)
{
Alert ("Закрыт ордер 1/2 LOTs of Sell ",Ticket);
break; // Выход из цикла закр
}
if (Fun_Error(GetLastError())==1) // Обработка ошибок
continue; // Повторная попытка
return; // Выход из start()
}
} // if((OrderOpenPrice()-Ask)>(Point*TrailingStop))

break; // Выход из while
} // while

} // if (Lots >= 0.2)


 

Вот так примерно должен выглядеть типовой блок закрытия ордеров.

int total=OrdersTotal();
for(int cnt=total-1;cnt>=0;cnt--)
{
   OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
   if( OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
   {
     int openticket = OrderTicket();
     if(OrderType()==OP_BUY && Close_BUY)
     {
       ticket=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slippage,Blue);
       if(ticket<0)
       {
         Print("OrderClose of BuyOrder failed with error #",GetLastError());
         Comment("OrderClose of BuyOrder failed with error #",GetLastError());                                                               
       }         
     }          
     if(OrderType()==OP_SELL && Close_SELL)
     {          
       ticket = OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slippage,Red);
       if(ticket<0)
       {     
         Print("OrderClose of SellOrder failed with error #",GetLastError());
         Comment("OrderClose of BuyOrder failed with error #",GetLastError());                        
       }                             
     }     
   }  
   }       
 

И посмотрите всеже справку по OrderSelect как и зачем оно нужно.

 
Правильно ли я понял - после закрытия половины лота, его идентификационный номер удаляется и оставшийся открытый ордер со второй половиной лота приобретает новый номер? Если это так, то надо перезапустить OrderSelect, чтобы начать работать с оставшимся ордером?
 
chief2000 писал(а) >>
Правильно ли я понял - после закрытия половины лота, его идентификационный номер удаляется и оставшийся открытый ордер со второй половиной лота приобретает новый номер? Если это так, то надо перезапустить OrderSelect, чтобы начать работать с оставшимся ордером?

О, да. Вы на правильном пути.

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