Глюк платформы? Тестера? Или так и должно быть?

 
Столкнулся с интересной ситуацией в тестере, и на мой взгляд, тестер ведет себя не очень логично.

Имеем успешно выставленный отложенный ордер. Тралим стоп с каждым новым баром. Стоп намного дальше от цены открытия, чем положено по MODE_STOPLEVEL. Однако, когда текущая цена подходит к цене открытия на величину, меньшую MODE_STOPLEVEL, попытка передвинуть стоп приводит к ошибке 130 - ERR_INVALID_STOPS. При этом меняется только стоп, цена открытия ордера остается без изменения. Стоп находится намного дальше минимально допустимого расстояния.

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

Вот тестовый код, который воспроизводит такую ситуацию:

int start()
{
 
    static int ticket = -1;
 
    if( OrdersTotal() == 0 )
    {
        // Ставим отложку
        ticket = OrderSend( Symbol(), OP_BUYSTOP, 0.1, Ask + 30 * Point, 0, 0, 0 );
    }    
    else
    {
        OrderSelect( ticket, SELECT_BY_TICKET );
        
        double openPrice = OrderOpenPrice();
        
        // Если цена ушла далеко, подвигаем ордер поближе, чтобы почаще создавать нужную нам ситуацию
        if( openPrice - Ask > 30 * Point ) 
        {
            openPrice = Ask + 30 * Point;
            OrderModify( ticket, openPrice, OrderOpenPrice() - Point * ( 50 + MathRand() % 50 ), 
                OrderTakeProfit(), OrderExpiration() );
        }        
 
        // Цена подошла близко к цене открытия? Пытаемся поменять стоп-лосс, не меняя цену открытия            
        if( MathAbs( openPrice - Ask ) < Point * MarketInfo( Symbol(), MODE_STOPLEVEL ) )
        {
            double stopLoss = OrderOpenPrice() - Point * ( 50 + MathRand() % 50 );
            
            Print( "Bid=" + DoubleToStr( Bid, Digits ) + ", Ask=" + DoubleToStr( Ask, Digits ) + ", open=" + 
                DoubleToStr( OrderOpenPrice(), Digits ) + ", stop=" + DoubleToStr( stopLoss, Digits ) + 
                ", stopLevel=" + DoubleToStr( MarketInfo( Symbol(), MODE_STOPLEVEL ), 0 ) );
 
            bool ok = OrderModify( ticket, OrderOpenPrice(), stopLoss, OrderTakeProfit(), OrderExpiration() );
 
            Print( "ok=" + ok + ", err=" + GetLastError() );    
        }
    }    
   
    return(0);
}
А вот пример протокола работы этого эксперта:

EURUSD,H1: open #1 buy stop 0.10 EURUSD at 1.1605 ok
EURUSD,H1: Bid=1.1595, Ask=1.1598, open=1.1605, stop=1.1514, stopLevel=10
EURUSD,H1: ok=0, err=130
EURUSD,H1: Bid=1.1594, Ask=1.1597, open=1.1605, stop=1.1538, stopLevel=10
EURUSD,H1: ok=0, err=130


Из него хорошо видно, что эксперт получает ошибку, когда пытается изменить стоп. Стоп намного дальше минимального расстояния от цены открытия, а вот цена открытия ордера слишком близко. Но мы то ее не меняем!

Это глюк или ожидаемое поведение? Просто из документации оно вроде бы не следует.

Если это глюк, то на что он распространяется? Только на тестер? Или такое же поведение следует ждать и от терминала в процессе торговли?
 
Все верно, Вы пытались поставить стоп на 9 пунктов от цены открытия, что запрещено. У отложенных ордеров контролируется цена открытия ордера, а не рыночные цены.
 
Renat:
Все верно, Вы пытались поставить стоп на 9 пунктов от цены открытия, что запрещено. У отложенных ордеров контролируется цена открытия ордера, а не рыночные цены.

Не понял. Может вы не совсем уловили суть проблемы? Давайте посмотрим по логу:

EURUSD,H1: open #1 buy stop 0.10 EURUSD at 1.1605 ok

Т.е. нормально без ошибок выставился отложенный ордер на покупку 0.1 лота по цене 1.6505. Дальше эксперт пытается изменить значение stop-loss для этого ордера:

EURUSD,H1: Bid=1.1595, Ask=1.1598, open=1.1605, stop=1.1514, stopLevel=10

Стоп-лосс удален от цены открытия на на 91 пункт. Где вы увидели 9 пунктов? Не совсем понятно.

И еще смущает ваше утверждение: "У отложенных ордеров контролируется цена открытия ордера, а не рыночные цены". Я же не могу поставить отложенный ордер на текущую рыночную цену, а значит, у отложенных ордеров должна контролироваться не только цена открытия, но и текущая рыночная. Разве нет?
 
Да, ошибся на 100 пунктов, извините.
 
Так а как тогда охарактеризовать поведение тестера? Разве должна возникать ошибка? И будет ли она возникать только в тестере или терминал также будет на такие операции ругаться?
 
bstone:


EURUSD,H1: Bid=1.1595, Ask=1.1598, open=1.1605, stop=1.1514, stopLevel=10

Стоп-лосс удален от цены открытия на на 91 пункт.
Может быть у вашего брокера используется "заморозка" отложенных ордеров на расстоянии 10(?) пунктов (для того чтобы у брокера было время успеть захеджироваться)? То есть как только рыночная цена приблизилась к цене открытия ордера на расстояние 10 и менее пунктов, то ордер "замораживается", то  есть с ним невозможны какие-либо модификации до тех пор пока рыночная цена не отойдёт от ордера на 11 и более пунктов. Что-то подобное в своё время уже обсуждалось.
 
solandr:
bstone:


EURUSD,H1: Bid=1.1595, Ask=1.1598, open=1.1605, stop=1.1514, stopLevel=10

Стоп-лосс удален от цены открытия на на 91 пункт.
Может быть у вашего брокера используется "заморозка" отложенных ордеров на расстоянии 10(?) пунктов (для того чтобы у брокера было время успеть захеджироваться)? То есть как только рыночная цена приблизилась к цене открытия ордера на расстояние 10 и менее пунктов, то ордер "замораживается", то есть с ним невозможны какие-либо модификации до тех пор пока рыночная цена не отойдёт от ордера на 11 и более пунктов. Что-то подобное в своё время уже обсуждалось.
Похоже, что так и есть. Значение уровня заморозки можно выяснить по MarketInfo(Symbol(),MODE_FREEZELEVEL), добавлено в 204 билде.
 
Renat:
Похоже, что так и есть. Значение уровня заморозки можно выяснить по MarketInfo(Symbol(),MODE_FREEZELEVEL), добавлено в 204 билде.

Вставил такой код в функцию init():

    Print( "freeze=" + MarketInfo( Symbol(), MODE_FREEZELEVEL ) );
В логе получается:

2007.04.23 16:47:11 2000.01.01 00:00 MLs-2 EURUSD,H1: freeze=0.00000000


Так что думаю, проблема не в этом. Может все-таки проверите терминал/тестер на предмет глюка? :)
 

И к тому же, разве в этом случае код ошибки был бы 130? Я думал, что в случае заморозки я бы получал ошибку 139 (ERR_ORDER_LOCKED) или 145 (ERR_TRADE_MODIFY_DENIED). Это было бы куда логичнее в плане диагностики.

 
Спасибо, проверим.
 
Смоделировали ситуацию и нашли ошибку с излишним контролем стопов у отложенных ордеров в тестере торговых стратегий.
Уже исправили и сегодня выложим обновленный 204 билд.

Спасибо за найденную ошибку.
Причина обращения: