Пожалуйста, помогите новичку разобраться с установкой ЛИМИТНОГО ордера при срабатывании ДРУГОГО лимитного ордера (ФОРТС-ОТКРЫТИЕ)

 

Всем привет! Буду очень признателен всем, кто поможет нубу разобраться, как правильно реализовать такую фишку: при срабатывании (заполнении) лимитной заявки устанавливается другая лимитная заявка по заданной цене. Причем нужно, чтобы другой лимитник устанавливался при срабатывании именно этой заявки. Как я понял, делать нужно, используя OntradeTransaction()

Я попытался сделать, используя уникальные параметры заявки (магик или коммент) во время прохождения исполненной заявки через OnTradeTransaction(), но видимо, эта мысль была ошибочной: 

Подскажите, пожалуйста, в каком направлении искать.

С Уважением.

void OnTick()
  {
   MqlTradeRequest mrequest;
   MqlTradeResult mresult;

   mrequest.action=TRADE_ACTION_PENDING;
   mrequest.symbol = _Symbol;
   mrequest.volume = Lot;
   mrequest.price=last_tick.bid;
   mrequest.stoplimit=last_tick.bid;
   mrequest.sl=0;                                       //Отправляем некую заявку
   mrequest.tp= 0;
   mrequest.type=ORDER_TYPE_BUY_LIMIT;
   mrequest.type_filling=ORDER_FILLING_RETURN;
   mrequest.type_time=ORDER_TIME_DAY;
   mrequest.magic=11;
   mrequest.expiration=0;
   mrequest.comment="B";
   OrderSend(mrequest,mresult);
  }
  
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
   if(trans.order_state==ORDER_STATE_FILLED)
     {
      if(trans.order_type==ORDER_TYPE_BUY_LIMIT)
        {
         if(request.magic==11)     // request.comment тоже "не взлетел" :(
           {
            MqlTradeRequest mrequest;
            MqlTradeResult mresult;
            mrequest.action=TRADE_ACTION_PENDING;
            mrequest.symbol = _Symbol;
            mrequest.volume = Lot;                            //При её исполнении хотелось бы отправить некий лимитный ордер
            mrequest.price=some_price;
            mrequest.stoplimit=some_price;
            mrequest.sl = 0;
            mrequest.tp = 0;
            mrequest.type=ORDER_TYPE_SELL_LIMIT;
            mrequest.type_filling=ORDER_FILLING_RETURN;
            mrequest.type_time=ORDER_TIME_DAY;
            mrequest.expiration=0;
            OrderSend(mrequest,mresult);
           }
        }
     }
  }
 
Adept:

Всем привет! Буду очень признателен всем, кто поможет нубу разобраться, как правильно реализовать такую фишку: при срабатывании (заполнении) лимитной заявки устанавливается другая лимитная заявка по заданной цене. Причем нужно, чтобы другой лимитник устанавливался при срабатывании именно этой заявки. Как я понял, делать нужно, используя OntradeTransaction(). 

Я попытался сделать, используя уникальные параметры заявки (магик или коммент) во время прохождения исполненной заявки через OnTradeTransaction(), но видимо, эта мысль была ошибочной: 

Подскажите, пожалуйста, в каком направлении искать.

С Уважением.

Добрый день!

1. Вы должны в OnTick() проверять установлен ли ордер (иначе , на каждом тике Вы будете устанавливать новый) 

if ( !OrderSelect(order_ticket) )
{
  //Устанавливаем отложенный ордер
}

 2. Отправляя ордер командой OrderSend(), мы должны получить билет ордера:

if ( OrderSend( mrequest, mresult ) )
{
  if ( mresult.retcode == TRADE_RETCODE_PLACED )
     { 
        order_ticket = mresult.order;
     }
  {
  }
}

3. Отложенный ордер может исполнится не полностью, значит нужно проверять

if ( PositionSelect( _Symbol ) )
{
  //позиция открыта, можно посмотреть объём позиции
}
 
Михаил:

Добрый день!

1. Вы должны в OnTick() проверять установлен ли ордер (иначе , на каждом тике Вы будете устанавливать новый) 

 2. Отправляя ордер командой OrderSend(), мы должны получить билет ордера:

3. Отложенный ордер может исполнится не полностью, значит нужно проверять

Здравствуйте Михаил, спасибо за ответ! Я понимаю, что код в примере будет исполняться на каждом тике, я просто вырезал стоящую перед ним логику принятия решений советника, чтобы не грузить лишней инфой. Проверки нужные, согласен, добавлю. 

Я наверное неправильно сформулировал, трудность вот в чем:

Предположим, висит ордер BUY_LIMIT, ждущий исполнения, и установленный с помощью кода, показанного в OnTick() выше.

Мне бы хотелось, чтобы при его исполнении именно этого ордера, сразу выставлялся ордер SELL_LIMIT на определенном расстоянии выше цены исполнения. (что-то вроде тейкпрофита, специфика штаного ТП не устраивает). 

Не подскажете, как примерно можно реализовать? Какие уникальные идентификаторы использовать (магик, комент,тикет)? И где, в каком обработчике и откуда их извлечь?  Хотел получить магик в OnTradeTransaction, и на основании него поставить ордер, но это видимо ошибочно.  Даже если просто скажете, в каком направлении копать - будет очень хорошо :).

 
Adept:

Здравствуйте Михаил, спасибо за ответ! Я понимаю, что код в примере будет исполняться на каждом тике, я просто вырезал стоящую перед ним логику принятия решений советника, чтобы не грузить лишней инфой. Проверки нужные, согласен, добавлю. 

Я наверное неправильно сформулировал, трудность вот в чем:

Предположим, висит ордер BUY_LIMIT, ждущий исполнения, и установленный с помощью кода, показанного в OnTick() выше.

Мне бы хотелось, чтобы при его исполнении именно этого ордера, сразу выставлялся ордер SELL_LIMIT на определенном расстоянии выше цены исполнения. (что-то вроде тейкпрофита, специфика штаного ТП не устраивает). 

Не подскажете, как примерно можно реализовать? Какие уникальные идентификаторы использовать (магик, комент,тикет)? И где, в каком обработчике и откуда их извлечь?  Хотел получить магик в OnTradeTransaction, и на основании него поставить ордер, но это видимо ошибочно.  Даже если просто скажете, в каком направлении копать - будет очень хорошо :).

Конечно билет ордера - уникальное число!

Событие TradeTransaction - не гарантировано и обычно используется для команды OrderSendAsync()

Используйте OnTrade(), не забывая, что ордер может исполнится частично. 

 

P/S поле mrequest.stoplimit=last_tick.bid; структуры  MqlTradeRequest 

не нужно заполнять! 

Установка отложенного ордера:

//+------------------------------------------------------------------+
//| Place order                                                      |
//+------------------------------------------------------------------+
void Place( ulong &ticket, const double price, const double volume, const bool buy_sell )
{
  MqlTradeRequest request = {0};
  MqlTradeResult  result  = {0};
  ticket = 0;
     
//--- Fill structure
  request.action = TRADE_ACTION_PENDING;
  request.magic  = 987654321;
  request.symbol = a_symbol;
  request.volume = volume;
  request.price  = price;
    
  if ( buy_sell )
  {
    request.type = ORDER_TYPE_BUY_LIMIT;
  }
  else
  {
    request.type = ORDER_TYPE_SELL_LIMIT;
  } 
  request.comment = "Отложенный ордер...";      
  request.type_filling = ORDER_FILLING_RETURN;
  request.type_time = ORDER_TIME_DAY;
  
//--- Send order
  if ( OrderSend( request, result ) )
  {
    if ( result.retcode == TRADE_RETCODE_PLACED ) 
    {
      ticket = result.order;
    }
  }
  else
  {
    Print( "Ордер не установлен! ", a_symbol );
  }
}
 
Михаил:

Конечно билет ордера - уникальное число!

Событие TradeTransaction - не гарантировано и обычно используется для команды OrderSendAsync()

Используйте OnTrade(), не забывая, что ордер может исполнится частично. 

 

P/S поле mrequest.stoplimit=last_tick.bid; структуры  MqlTradeRequest 

не нужно заполнять! 

Установка отложенного ордера:

Совет сделать через Ontrade() - то что нужно! Проблема решена. Большое Вам спасибо за код и за уделенное время! 

 

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