← Atrás

orders delay

Возможно ли при тестировании на истории тестеру EmulationTrader принудительно задать задержку например в 1000 милисекунд (по тестируемой шкале времени) для выставления ордеров (пропуск тиков перед размещением ордеров)? Ведь реальная задержка при выставлении ордеров 100 - 250 ms, а тестер их выставляет мгновенно.

¿Le resultó útil este tema?

Compartir tema

Comentarios (19)

Iniciar sesión o Crear cuenta, Inicie sesión o regístrese para dejar un comentario

Garic
Garic

Я это делаю вручную. Ордер сохраняю в список с желаемым временем. Подписываюсь на marketTimeChanged - и регистрирую.

Mikhail Sukhov
Mikhail Sukhov

Garic: Я это делаю вручную. Ордер сохраняю в список с желаемым временем. Подписываюсь на marketTimeChanged - и регистрирую.

Переопределите свой IMarketEmulator.

foRs
foRs

а можно поподробнее по задержке с куском кода для примера добавить в справку. это же актуально для всех, кто тести на истории

Garic
Garic

foRs: а можно поподробнее по задержке с куском кода для примера добавить в справку. это же актуально для всех, кто тести на истории

Ну я не думаю что мой код претендует на добавление в справку :) Исполнение у меня сделано примерно так (наследник Strategy)


        public decimal CurrentPos;
        private Object _lockObjCurrentPos = new Object();
        private SynchronizedDictionary<Order, OrderInfo> _ordersInfo = new SynchronizedDictionary<Order, OrderInfo>();
        public OrderInfo OrderInfo(Order order)
        {
            return _ordersInfo.SyncGet(o => o.FirstOrDefault(t => t.Key == order)).Value;
        }

        // Ордера которые отправляются с задержкой.
        protected SortedList<Order, DateTime> _delayedOrders = new SortedList<Order, DateTime>();
        private Object _lockObjDelayedOrders = new Object();

        public void OnMarketTimeChanged()
        {
            List<Order> orders = new List<Order>();

            var processOrders = _delayedOrders.Where(p => p.Value <= TraderManager.MarketTime);

            if (processOrders.Count() == 0)
                return;

            lock (_lockObjDelayedOrders)
            {
                foreach (var pair in processOrders)                
                    orders.Add(pair.Key);

                foreach (var order in orders)
                    _delayedOrders.RemoveWhere(p => p.Key.Id == order.Id);
            }

            foreach (var order in orders)
            {
                lock (_lockObjCurrentPos)
                {
                    CurrentPos += order.Volume * (order.Direction == OrderDirections.Buy ? 1 : -1);
                }
                                
                base.RegisterOrder(order);
            }
        }

        public virtual void MyCreateOrder(OrderDirections direction, string comment = "", decimal price = 0, decimal volume = 0, TimeSpan _delay = new TimeSpan())
        {   
            var priceLocal = price;

            if (volume == 0)
                volume = base.Volume;
            if (priceLocal == 0)
            {               
                priceLocal = Security.LastTrade.Price + 1000 * (direction == OrderDirections.Buy ? 1 : -1);              
            }

            var order = this.CreateOrder(direction, priceLocal, volume);

            var timePlan = MarketTime;            
                        
            _ordersInfo.SyncDo(o => o.Add(order, new OrderInfo
                               {
                                   Comment = comment,
                                   PricePlan = price == 0 ? candleList.Last().ClosePrice : price,
                                   TimePlan = timePlan
                               }));
            
            try
            {   
                if (_delay == new TimeSpan())
                {
                    lock (_lockObjCurrentPos)
                    {
                        CurrentPos += order.Volume * (order.Direction == OrderDirections.Buy ? 1 : -1);
                    }                    

                    base.RegisterOrder(order);
                }
                else
                {
                    _delayedOrders.Add(order, TraderManager.MarketTime + _delay);
                }                
            }
            catch (Exception e)
            {
                LoggingHelper.AddErrorLog(this, e);
            }            
        }

foRs
foRs

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

OvcharenkoVI
OvcharenkoVI

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

Если пользоваться предыдущим методом, то, наверное, вообще геморрой )))

pyhta4og
pyhta4og

MarketEmulator.Settings.Latency

  • задержка при RegisterOrder

давным давно было сделано

ra81
ra81

foRs: А в тесте с использованием котирования задержку на выставление при перерегистрации заявок как сделать? Вот если именно таймаут между перевыставлениями заявок - то кажется никак. Только сделать свое котирование с таймаутом :). Если же речь про латенси о которой говорилось выше, то ответ дан :)

OvcharenkoVI
OvcharenkoVI

Так в котировании же также используется RegisterOrder, значит задержка будет, зачем свое котирование писать

ra81
ra81

OvcharenkoVI: Так в котировании же также используется RegisterOrder, значит задержка будет, зачем свое котирование писать Я так понял вопрос, что нужно перед новой регистрацией заявки, выждать паузу. А не внести латенси регистрации заявки. Отсюда в котировании такой паузы нет.

в котировании используется вроде ReRegisterOrder Все зависит от Свойства IsSupportAtomicReRegister - если у эмулятора оно будет false, тада котирование будет юзать отмену и затем регистрацию заявки.

OvcharenkoVI
OvcharenkoVI

OvcharenkoVI: Так в котировании же также используется RegisterOrder, значит задержка будет, зачем свое котирование писать Я так понял вопрос, что нужно перед новой регистрацией заявки, выждать паузу. А не внести латенси регистрации заявки. Отсюда в котировании такой паузы нет.

в котировании используется вроде ReRegisterOrder Все зависит от Свойства IsSupportAtomicReRegister - если у эмулятора оно будет false, тада котирование будет юзать отмену и затем регистрацию заявки.

об этом и говорю

hurricane
hurricane

Так в котировании же также используется RegisterOrder, значит задержка будет, зачем свое котирование писать

в котировании используется вроде ReRegisterOrder

foRs
foRs

Вообще 2 варианта рассматривал выждать паузу и латенси при регистрации. Делал тест с латенси 0 мс. получилось к примеру 400 лосов, при латенси 1000 мс. 667 лосов. Ну значит пашет вроде при котировании.

А по умолчанию в котировании используется RegisterOrder или ReRegister ?

OvcharenkoVI
OvcharenkoVI

foRs: Вообще 2 варианта рассматривал выждать паузу и латенси при регистрации. Делал тест с латенси 0 мс. получилось к примеру 400 лосов, при латенси 1000 мс. 667 лосов. Ну значит пашет вроде при котировании.

А по умолчанию в котировании используется RegisterOrder или ReRegister ?

Если IsSupportAtomicReRegister = false, то Register. Если true, то reregister

Кот Матроскин
Кот Матроскин

OvcharenkoVI: Если IsSupportAtomicReRegister = false, то Register. Если true, то reregister Что-то не получается установить IsSupportAtomicReRegister = false Пишет, что метод доступа protected set, для записи не доступно...

hobo
hobo

В тестировании задержки при исполнении ордеров так же(а имхо даже более) важны, чем Latency при регистрации. Кидаем лимитку на уровень с большим числом заявок, ну пусть она зарегистрировалась даже через секунду, выполнение всех ордеров, которые были выставлены раньше, может занять гораздо больше чем секунду

pyhta4og
pyhta4og

hobo: В тестировании задержки при исполнении ордеров так же(а имхо даже более) важны, чем Latency при регистрации. Кидаем лимитку на уровень с большим числом заявок, ну пусть она зарегистрировалась даже через секунду, выполнение всех ордеров, которые были выставлены раньше, может занять гораздо больше чем секунду

Исполнение лимитки сделано только после того как исполнятся весь объем в стакане на уровне цены лимитки. Пример. цена 100 стоит 10 контрактов на покупку. кидаем заявку на покупку 1 контракта. Приходят сделки. 1,2,3 контракта по цене 100. Это кто-то продает в бид. Так вот, пока весь объем 10 контрактов на уровне 100 не кончится тестер не будет исполнять нашу заявку.

hobo
hobo

pyhta4og: Исполнение лимитки сделано только после того как исполнятся весь объем в стакане на уровне цены лимитки. Пример. цена 100 стоит 10 контрактов на покупку. кидаем заявку на покупку 1 контракта. Приходят сделки. 1,2,3 контракта по цене 100. Это кто-то продает в бид. Так вот, пока весь объем 10 контрактов на уровне 100 не кончится тестер не будет исполнять нашу заявку. Супер. А если стакан новый пришел, а мою заявку еще не исполнили? Ну допустим, на момент выставления моей заявки на уровне было 10 лотов, стакан появился новый, там стало 25 лотов, ясно что все 15(ну 15 минус мой объем, если быть точным) встали после меня, исполнение какого объема будет ждать тестер, когда дойдет до исполнения моего ордера?

Кот Матроскин: Пишет, что метод доступа protected set, для записи не доступно... Security.Exchange.IsSupportAtomicReRegister

Кот Матроскин
Кот Матроскин

hobo:

Кот Матроскин: Пишет, что метод доступа protected set, для записи не доступно... Security.Exchange.IsSupportAtomicReRegister А я пытался не через Security.Exchange, а через Trader 😊