StopLimit - page 7

 
Sergey Chalyshev:

Apparently no one uses it,

the order is opened at non-existent prices:

a simple example to check:

//+------------------------------------------------------------------+
//|                                               StopLimit_Test.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
CTrade trade;

input int Deviation = 100;
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   trade.SetTypeFilling(ORDER_FILLING_RETURN);
   double ticksise=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);

   if(OrdersTotal()==0)
      trade.OrderOpen(
         _Symbol,                      // символ
         ORDER_TYPE_BUY_STOP_LIMIT,    // тип ордера
         1.0,                          // объем ордера
         tick.ask+Deviation*ticksise,  // цена исполнения
         tick.ask+10*ticksise,         // цена стоплимита
         0,                            // цена stop loss
         0                             // цена take profit
      );
  }
//+------------------------------------------------------------------+

Is this correct? First comes the stop limit price, and then the strike price. SeeDocumentation:

bool  OrderOpen(
   const string          symbol,          // символ
   ENUM_ORDER_TYPE       order_type,      // тип ордера
   double                volume,          // объем ордера
   double                limit_price,     // цена стоплимита
   double                price,           // цена исполнения
   double                sl,              // цена stop loss
   double                tp,              // цена take profit
   ENUM_ORDER_TYPE_TIME  type_time,       // тип по истечению
   datetime              expiration,      // истечение
   const string          comment=""       // комментарий
   )
 

Modified the code of the topicstarter a bit.

//+------------------------------------------------------------------+
//|                                               StopLimit_Test.mq5 |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
CTrade trade;

input int Deviation = 5;
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlTick tick;
   SymbolInfoTick(_Symbol,tick);
   trade.SetTypeFilling(ORDER_FILLING_RETURN);
   double ticksise=SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   if(OrdersTotal()==0)
     {
      ENUM_ORDER_TYPE ord_type=ORDER_TYPE_BUY_STOP_LIMIT;
      double ord_vol=0.1;
      double ask_pr=NormalizeDouble(tick.ask,_Digits);
      double ord_pr=NormalizeDouble(tick.ask+Deviation*ticksise,_Digits);
      double limit_pr=NormalizeDouble(tick.ask+10*ticksise,_Digits);
      string ord_comment=StringFormat("%0."+IntegerToString(_Digits)+"f;%0."+
                                      IntegerToString(_Digits)+"f;%0."+
                                      IntegerToString(_Digits)+"f",ask_pr,limit_pr,ord_pr);
      trade.OrderOpen(
         _Symbol,                     // символ
         ord_type,                    // тип ордера
         ord_vol,                     // объем ордера
         limit_pr,                    // цена стоплимита
         ord_pr,                      // цена исполнения
         0.,                          // цена stop loss
         0.,                          // цена take profit
         0,                           // тип по истечению
         0,                           // истечение
         ord_comment                  // комментарий
      );
     }
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
   PrintFormat(" %s",EnumToString(trans.type));
//---
   /*if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
     {
      DebugBreak();
     }
   else
      if(trans.type==TRADE_TRANSACTION_ORDER_UPDATE)
        {
         ENUM_ORDER_TYPE curr_ord_type=trans.order_type;
         if(curr_ord_type!=ORDER_TYPE_BUY_STOP_LIMIT)
            DebugBreak();
        }*/
  }
//+------------------------------------------------------------------+

Here is an example on the EURUSD forex instrument.

Important:The stoplimit price is set worse. This is for exchange execution.

A buy stop limit was set which was activated and opened as a limit order.




You can see in the screenshot that there are prices in the comment. The first price (1.10258) is the ask price when the order was placed, the second (1.10268) is the activation price of the limit part of the order and the third (1.10263) is the activation price of the stop part of the order.

 

The logic is as follows: if the market ask price reaches 1.10263, then the stop part of the order (the strike price) is activated. And the limit part of the order should trigger immediately, since its strike price is worse than the market price (1.10268).

We look at the log files:

2019.12.12 21:08:10.306 2019.12.02 00:00:11   buy stop limit 0.10 EURUSD at 1.10263 (1.10268) (1.10239 / 1.10258)
2019.12.12 21:08:10.310 2019.12.02 00:00:11   CTrade::OrderSend: buy stop limit 0.10 EURUSD at 1.10263 (1.10268) [done]
2019.12.12 21:08:10.310 2019.12.02 00:00:11    TRADE_TRANSACTION_ORDER_ADD
2019.12.12 21:08:10.310 2019.12.02 00:00:11    TRADE_TRANSACTION_REQUEST
2019.12.12 21:08:10.312 2019.12.02 00:02:15   order [#2  buy stop limit 0.10 EURUSD at 1.10263 (1.10268)] triggered
2019.12.12 21:08:10.312 2019.12.02 00:02:15    TRADE_TRANSACTION_ORDER_UPDATE
2019.12.12 21:09:18.333 2019.12.02 00:02:15   order [#2  buy limit 0.10 EURUSD at 1.10268] triggered
2019.12.12 21:09:18.333 2019.12.02 00:02:15   deal #2  buy 0.10 EURUSD at 1.10265 done (based on order #2)
2019.12.12 21:09:18.333 2019.12.02 00:02:15   deal performed [#2  buy 0.10 EURUSD at 1.10265]
2019.12.12 21:09:18.333 2019.12.02 00:02:15   order performed buy 0.10 at 1.10265 [#2  buy limit 0.10 EURUSD at 1.10268]

We see that at00:02:15 the order has turned into a limit order (the stop part has triggered). And it immediately turned into a market position. And what's interesting is that the logs don't give a bid-ask price as in the first line (1.10239 / 1.10258). And that's inconvenient. Yes, the position is open at 1.10265. It was expected to be open at 1.10263. Here I think there was a slippage of 2pts.

Looking at the tick base. Yes, testing was on real ticks from December 2, 2019.

We see that there is our tick (1.10265). Highlighted it in the screenshot. And since00:02:15 this was the third tick. The previous ask = 1.10271 (from00:02:15.428) was even higher. Although, at the same time as our tick. I.e., entered at a better price. Conclusion: As expected, we got a slippage of 2 points for the stop part of the order.

 
Denis Kirichenko:

Is this the right thing to do? First comes the stoplist price and then the strike price. Look at the documentation:

This is intentionally done so that when the stoplimit goes to the limit, the limit is triggered immediately. When it is triggered, it appears to be somewhere out there, at the price that is specified in the order and not at the price that activated the stoplimit (which actually was).

 
Denis Kirichenko:

The logic is as follows: if the market ask price reaches 1.10263, then the stop part of the order (the strike price) is activated. And the limit part of the order should trigger immediately, since its strike price is worse than the market price (1.10268).

There is a price of 123. The BUY_STOP_LIMIT. The stop price is 133. The limit price is 111.

If the price has passed the stop price, the limit price is activated. If the price returns to 111, the position is opened.

If the price has not passed the stop price and returned to the limit price, the position will not be opened.

Isn't it like that?

 
Denis Kirichenko:

A stop limit order can be checked in the tester for Forex as well. It is enough to set "Execution" = Exchange.



I checked the buy stop limit as follows: I set the price of the limit order worse than the activation price. The order opened at market price (ask price) on activation. So, it seems that the functionality in the Tester works.

Yes, on forex instruments, with exchange execution, it works correctly.

And now also change "Settlement Method"=FORTS Futures, and see how it works on exchange-traded instruments.

BSL_Forex-FORTS

If you put Calculation method = Forex on exchange-traded instrument, it works correctly, but the margin is not counted correctly.

 
Sergey Chalyshev:

Are you usingStopLimit in real trading?

It is clear thatStopLimit does not work adequately in the tester.

Does it make sense to use it in real trading? What are the advantages and disadvantages?

This type of orders does not make sense to use.

It is much easier to place a pending order right away, because we can specify any term of the order lifetime.

If we are on the exchange, rather than on the MQ server, this order is guaranteed to work at the price specified in it.

And the server can "glitch".