← Atrás

Тестирование на истории 4.0.21 вход по рынку всегда по худшей цене.

Перешел на 4.0.21, запускаю тест на истории и наблюдаю радикальноотличающийся график эквити. Перебрал несколько прошлых сборок: 4.0.17, 4.0.18, 4.0.19, 4.0.20 график примерно одинаковый.

и текущая

😳 Ну все думаю, накрылся мой грааль.😀

Запускаю тестовые примеры 4.0.20 и 4.0.21 графики примерно одинаковые(для ускорения тестирования период взят 1месяц)

😳

Ковыряние в своем коде результатов не дало. Причина нашлась после изучения отчетов. При сравнении аналогичных входов на 4.0.20 и 4.0.21 вход всегдабыл примерно на 100п. хуже. Почему 100п, у меня стояло проскальзывание в 100п.

Меняю в тестовых примерах вход с помощью котирования

	
	// если произошло пересечение
	if (_isShortLessThenLong != isShortLessThenLong)
	{
		// если короткая меньше чем длинная, то продажа, иначе, покупка.
		var direction = isShortLessThenLong ? OrderDirections.Sell : OrderDirections.Buy;

 		// создаем заявку
                var order = this.CreateOrder(direction, Security.GetMarketPrice(direction), Volume);

		// регистрируем заявку (обычным способом - лимитированной заявкой)
		// RegisterOrder(order);

		// регистрируем заявку (через котирование)
		var strategy = new MarketQuotingStrategy(order, new Unit(), new Unit());
		ChildStrategies.Add(strategy);

		// запоминаем текущее положение относительно друг друга
		_isShortLessThenLong = isShortLessThenLong;
	}

на вход по рынку с проскальзыванием


	// если произошло пересечение
	if (_isShortLessThenLong != isShortLessThenLong)
	{
		// если короткая меньше чем длинная, то продажа, иначе, покупка.
		var direction = isShortLessThenLong ? OrderDirections.Sell : OrderDirections.Buy;

                
                var slip = Security.MinStepSize * 20;//проскальзование 100п.
                var price = isShortLessThenLong
	                    ? Security.GetMarketPrice(direction) - slip
		            : Security.GetMarketPrice(direction) + slip;
                

		// создаем заявку
                var order = this.CreateOrder(direction, price, Volume);

		// регистрируем заявку (обычным способом - лимитированной заявкой)
		RegisterOrder(order);

		// регистрируем заявку (через котирование)
		//var strategy = new MarketQuotingStrategy(order, new Unit(), new Unit());
		//ChildStrategies.Add(strategy);

		// запоминаем текущее положение относительно друг друга
		_isShortLessThenLong = isShortLessThenLong;
	}

Картинка примерно не изменилась.

Ок, ставлю проскальзывание в 10 000п.

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

¿Le resultó útil este tema?

Compartir tema

Comentarios (23)

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

pyhta4og
pyhta4og

Вопросы:

  1. Проскальзывание ставите MarketEmulator.Settings.Slippage=100?
  2. Используете в стратегии только маркет-ордера?
  3. Тестируете со генерируемыми стаканами ?
  4. Тестируете с настоящими стаканами ?
Moadip
Moadip Autor

pyhta4og: Вопросы:

  1. Проскальзывание ставите MarketEmulator.Settings.Slippage=100?
  2. Используете в стратегии только маркет-ордера?
  3. Тестируете со генерируемыми стаканами ?
  4. Тестируете с настоящими стаканами ?
  1. Нет, проскальзывание ставиться внутри стратегии. Про класс MarketEmulator вообще не знал. В примерах по тестированию использование данного класса не нашел. Можно небольшой пример как его применять?
  2. Да, только маркет ордера. 3.4. Тест на генерируемых стаканах.
pyhta4og
pyhta4og

Moadip:

pyhta4og: Вопросы:

  1. Проскальзывание ставите MarketEmulator.Settings.Slippage=100?
  2. Используете в стратегии только маркет-ордера?
  3. Тестируете со генерируемыми стаканами ?
  4. Тестируете с настоящими стаканами ?
  1. Нет, проскальзывание ставиться внутри стратегии.

это как? В моем понятии проскальзывание это то что происходит на бирже а не выставляется внутри стратегии. Например MarketEmulator.Settings.Slippage - это то, насколько по более худшей цене по сравнению с последняя сделка произойдет исполнение маркет-ордера

Про класс MarketEmulator вообще не знал. В примерах по тестированию использование данного класса не нашел. Можно небольшой пример как его применять?

см. EmulationTrader.MarketEmulator и документацию

  1. Да, только маркет ордера.

с 4.0.20->4.0.21 ничего с матчингом маркетордеров не менялось, для того чтобы выяснить есть ли ошибка в тестере надо по логам по ордерно разбитраться.

3.4. Тест на генерируемых стаканах.

Moadip
Moadip Autor

это как? В моем понятии проскальзывание это то что происходит на бирже а не выставляется внутри стратегии.

Естественно что проскальзывание происходит на бирже. Допустим есть лучший бид/оффер 900/910, я хочу продать по рынку. Посылаю лимитку на продажу по 800, т.е. устанавливаю для стратегии порог в 100п на проскальзывание. Моя заявка может исполнится как по 900, так и допустим по 850, т.е. по лучшему биду в текущий момент. Если же на момент когда моя заявка будет на бирже лучший бид будет меньше 800, скажем 790, то я встану в стакан лимиткой на продажу по 800. Это я и называю учитывать/выставлять проскальзывание внутри стратегии.

Например MarketEmulator.Settings.Slippage - это то, насколько по более худшей цене по сравнению с последняя сделка произойдет исполнение маркет-ордера

Это то как работает алгоритм данного свойства? Т.к. в моем понимании проскальзывание это не то, насколько по более худшей цене пройдет исполнение моей заявки по сравнению с последней. А то, по какой цене исполнится моя заявка, относительно той цены, которую я увидел в стакане на момент отправления заявки.

pyhta4og
pyhta4og

это как? В моем понятии проскальзывание это то что происходит на бирже а не выставляется внутри стратегии.

Естественно что проскальзывание происходит на бирже. Допустим есть лучший бид/оффер 900/910, я хочу продать по рынку. Посылаю лимитку на продажу по 800, т.е. устанавливаю для стратегии порог в 100п на проскальзывание. Моя заявка может исполнится как по 900, так и допустим по 850, т.е. по лучшему биду в текущий момент. Если же на момент когда моя заявка будет на бирже лучший бид будет меньше 800, скажем 790, то я встану в стакан лимиткой на продажу по 800. Это я и называю учитывать/выставлять проскальзывание внутри стратегии.

Понял вас. Но в таком случае вы пользуетесь лимитными заявками, а не маркетордерами. Поскольку ввсе-таки выставляете цену в 800.

В итоге, вы утверждаете что теперь кидаете селл-заявку ниже рынка на 100 пунктов и она всегда исполняется по этой самой худщей цене, даже если есть бид гораздо лучше?

Например MarketEmulator.Settings.Slippage - это то, насколько по более худшей цене по сравнению с последняя сделка произойдет исполнение маркет-ордера

Это то как работает алгоритм данного свойства? Т.к. в моем понимании проскальзывание это не то, насколько по более худшей цене пройдет исполнение моей заявки по сравнению с последней. А то, по какой цене исполнится моя заявка, относительно той цены, которую я увидел в стакане на момент отправления заявки.

Смотрите, есть режим эмуляции без стакана вообще. Это когда нет генераторов и нет данных о стакане. В этом конкретном случае заявки помеченные как маркетные (НЕ лимитные!) исполняются по LastTrade плюс Slippage если заявка на покупку или LastTrade минус Slippage если на продажу.

Если есть какие-то стаканы, генерированные или записанные то и маркетные ордера и лимитированные филяться о встречные заявки и свойство Slippage фактически не используется

risty
risty

pyhta4og: Смотрите, есть режим эмуляции без стакана вообще. Это когда нет генераторов и нет данных о стакане. В этом конкретном случае заявки помеченные как маркетные (НЕ лимитные!) исполняются по LastTrade плюс Slippage если заявка на покупку или LastTrade минус Slippage если на продажу.

Если есть какие-то стаканы, генерированные или записанные то и маркетные ордера и лимитированные филяться о встречные заявки и свойство Slippage фактически не используется Вопрос: "EmulationTrader.MarketEmulator.Settings.Slippage" ограничивает максимальное проскальзывание или устанавливает абсолютное значение проскальзывание при сделках по рынку?

И если это свойство ограничивает, то как ввести в тестирование на истории проскальзывание при сделках по рынку ?

Moadip
Moadip Autor

Но в таком случае вы пользуетесь лимитными заявками, а не маркетордерами.

Может я чего то не знаю, но насколько мне известно на фортс нет рыночных заявок. Если надо войти по рынку, то выставляется лимитка с заведомо большей/меньшей ценой, чтобы купить/продать. Касательно S# знаю только два способа как подать заявку.


        void GoLong(decimal vol)
        {
            var order = new Order
            {
                Portfolio = Portfolio,
                Price = Security.BestAsk.Price + Security.MinStepSize * _instrSlippage, ////////////// проскальзывание
                Security = Security,
                Volume = vol,
                Direction = OrderDirections.Buy,
            };
            RegisterOrder(order);
        }


        var order = StrategyHelper.CreateOrder(this, OrderDirections.Buy, Security.GetMarketPrice(OrderDirections.Buy), Volume);
        RegisterOrder(order);

Возможно Security.GetMarketPrice(OrderDirections.Buy) считается "рыночным" ордером?

В итоге, вы утверждаете что теперь кидаете селл-заявку ниже рынка на 100 пунктов и она всегда исполняется по этой самой худщей цене, даже если есть бид гораздо лучше? Именно! Это и показано на скриншотах выше.

Смотрите, есть режим эмуляции без стакана вообще. Это когда нет генераторов и нет данных о стакане. В этом конкретном случае заявки помеченные как маркетные (НЕ лимитные!) исполняются по LastTrade плюс Slippage если заявка на покупку или LastTrade минус Slippage если на продажу.

Если есть какие-то стаканы, генерированные или записанные то и маркетные ордера и лимитированные филяться о встречные заявки и свойство Slippage фактически не используется А вот за это спасибо. Такие нюансы в справке не написаны.

UPD: Отвечаю сам на свой вопрос "рыночные" это BuyAtMarket и SellAtMarket. Но с реализацией данных методов я не совсем согласен(посмотрел рефлектором) Т.к. с помощь их не всегда можно войти по "рынку".

Mikhail Sukhov
Mikhail Sukhov

Moadip: UPD: Отвечаю сам на свой вопрос "рыночные" это BuyAtMarket и SellAtMarket. Но с реализацией данных методов я не совсем согласен(посмотрел рефлектором) Т.к. с помощь их не всегда можно войти по "рынку".

На РТС нет маркетных заявок. Так что хоть как-то входить. Не по планкам же.

JackSparrow
JackSparrow

Mikhail Sukhov:

Moadip: UPD: Отвечаю сам на свой вопрос "рыночные" это BuyAtMarket и SellAtMarket. Но с реализацией данных методов я не совсем согласен(посмотрел рефлектором) Т.к. с помощь их не всегда можно войти по "рынку".

На РТС нет маркетных заявок. Так что хоть как-то входить. Не по планкам же.

Так вопрос утыкается в то что если есть цена более лучшая чем указанная то сделка закрывается по ней. Это, на фортсе, будет принцип входа по маркету. Тоже самое что по краю стакана ударить.

Mikhail Sukhov
Mikhail Sukhov

JackSparrow: Так вопрос утыкается в то что если есть цена более лучшая чем указанная то сделка закрывается по ней. Это, на фортсе, будет принцип входа по маркету. Тоже самое что по краю стакана ударить.

Сейчас речь о тестере? С тестером это не ко мне. Я ответил насчет того, почему XXXAtMarket так сделан.

Alexander
Alexander

В итоге, вы утверждаете что теперь кидаете селл-заявку ниже рынка на 100 пунктов и она всегда исполняется по этой самой худщей цене, даже если есть бид гораздо лучше? Именно! Это и показано на скриншотах выше.

Фикс залит на codeplex. Возьмите свежие библиотеки из ветки dev и протестируйте. Только учитывайте то, что архив с котировками (RIU9@RTS) был также обновлён.

Moadip
Moadip Autor

EmulationTrader.MarketEmulator.Settings.Slippage это максимальное проскальзование. Т.е. если Slippage = 100, то проскальзование будет браться случайным образом от 0 до 100.

Цитата из справки

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

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

_trader.DepthGenerators[security] = new TrendMarketDepthGenerator(security) { Interval = TimeSpan.FromMilliseconds(2000)};

Допустим появился сигнал на вход, входим в шорт по рынку, стакан последний раз генерировался по 1000, bid/offer 990/1010, но последний тик уже 1020, bid/offer 1010/1030 и мы должны войти по 1010, но т.к. стакан генерируется с каким то периодом, то мы войдем по худшей цене по 990.

Возможен и другой вариант, если последний тик 980, то получается мы войдем по лучшей цене. Т.е. может эмулируется как положительное так и отрицательное проскальзывание. Это то как я понимаю работу тестера, возможно и не правильно.

Опять же, все зависит от стратегии, если вход может быть только скажем по закрытию 1 мин. свечки, то это не подойдет. А если вход возможен на каждом тике, то да. Ну если только обновление стакана поставить раз в 2 минуты.🙂

Самое интересное что стакан не обновляется чаще чем 1 раз в секунду, установлено экспериментальным путем.

risty
risty

Moadip: Если же используются стаканы, то проскальзывание можно сэмулировать с помощью периода обновления стакана, я так делаю.

_trader.DepthGenerators[security] = new TrendMarketDepthGenerator(security) ;

> 
> Допустим появился сигнал на вход, входим в шорт по рынку, стакан последний раз генерировался по 1000, bid/offer 990/1010, но последний тик уже 1020, bid/offer 1010/1030 и мы должны войти по 1010, но т.к. стакан генерируется с каким то периодом, то мы войдем по худшей цене по 990.
> 
> Возможен и другой вариант, если последний тик 980, то получается мы войдем по лучшей цене.
> Т.е. может эмулируется как положительное так и отрицательное проскальзывание. Это то как я понимаю работу тестера, возможно и не правильно.
> 
> Опять же, все зависит от стратегии, если вход может быть только скажем по закрытию 1 мин. свечки, то это не подойдет. А если вход возможен на каждом тике, то да. Ну если только обновление стакана поставить раз в 2 минуты.🙂
> 
> Самое интересное что стакан не обновляется чаще чем 1 раз в секунду, установлено экспериментальным путем.
Супер, спасибо огромное!!!!

Может уважаемые авторы библиотеки подскажут ещё какие-то "документированные/рекомендуемые" свойства EmulationTrader, которые позволяют играться с проскальзыванием при генерируемом стакане?

И ещё вопрос:
```csharp
var order = this.CreateOrder(OrderDirections.Sell, Security.GetMarketPrice(OrderDirections.Sell), Volume);

и

var order = this.SellAtMarket(Volume);

это синонимы ?

InsiderHSE
InsiderHSE

Moadip: EmulationTrader.MarketEmulator.Settings.Slippage это максимальное проскальзование. Т.е. если Slippage = 100, то проскальзование будет браться случайным образом от 0 до 100.

А какой закон распределения этого проскальзывания? равномерно в интервале от 0 до 100? или от -100 до 100? или неравномерно? Есть ли способ установить фиксированное проскальзывание на каждую сделку?

Alexander
Alexander

Для тех рынков где нет рыночных заявок - синонимы. где есть - нет, т.к. второй вариант создаст именно рыночную заявку, а первый вариант - нет, будет по стакану смотреть.

InsiderHSE
InsiderHSE

Установил EmulationTrader.MarketEmulator.Settings.Slippage в 10 пипсов, стаканов нет и не генерирую. При этом сделки this.SellAtMarket(Volume) исполняются по LastPrice. Версия 0,22. Баг?

Moadip
Moadip Autor

InsiderHSE: Установил EmulationTrader.MarketEmulator.Settings.Slippage в 10 пипсов, стаканов нет и не генерирую. При этом сделки this.SellAtMarket(Volume) исполняются по LastPrice. Версия 0,22. Баг?

Проблема которая была в 4.0.21 никуда не делась в 4.0.22, также как и в 4.0.23. Из за этого похоже и не работает slippage.

Alexander
Alexander

InsiderHSE: Установил EmulationTrader.MarketEmulator.Settings.Slippage в 10 пипсов, стаканов нет и не генерирую. При этом сделки this.SellAtMarket(Volume) исполняются по LastPrice. Версия 0,22. Баг?

Смотрите на 4.1

InsiderHSE
InsiderHSE

Alexander Mukhanchikov:

InsiderHSE: Установил EmulationTrader.MarketEmulator.Settings.Slippage в 10 пипсов, стаканов нет и не генерирую. При этом сделки this.SellAtMarket(Volume) исполняются по LastPrice. Версия 0,22. Баг?

Смотрите на 4.1 Когда примерно можно ожидать хотя бы базовой справки по 4.1? Без хотя бы краткого объяснения, как изменилась логика формирования свечек, разобраться сложно...

Alexander
Alexander

InsiderHSE:

Alexander Mukhanchikov:

InsiderHSE: Установил EmulationTrader.MarketEmulator.Settings.Slippage в 10 пипсов, стаканов нет и не генерирую. При этом сделки this.SellAtMarket(Volume) исполняются по LastPrice. Версия 0,22. Баг?

Смотрите на 4.1 Когда примерно можно ожидать хотя бы базовой справки по 4.1? Без хотя бы краткого объяснения, как изменилась логика формирования свечек, разобраться сложно...

Попробуем в ближайшие пару недель. Есть ещё что хочется сделать для 4.1. Код первичнее документации

InsiderHSE
InsiderHSE

Версия 4.1.5 Тестирую стратегию в EmulationTrader при UseMarketDepth = false. При этом лимитные заявки по заведомо лучшей цене исполняются по цене заявки, а не по цене последней сделки. ТО есть если послать лимитку на покупку фьючерса ртс по 1000000, то сделка пройдет по цене 1000000. При этом параметр EmulationTrader.MarketEmulator.Settings.Slippage на результат не влияет. Задача состоит в том, чтобы совершать сделки по LastPrice с фиксированным проскальзыванием против меня, например, 10 пипсов. Раньше (версии 4.0.х) для этого я входил лимитником с ценой на 1000 пипсов хуже, что обеспечивало мгновенную сделку по LastPrice с проскальзыванием, указанным в EmulationTrader.MarketEmulator.Settings.Slippage. Можно ли получить такую же функциональность в 4.1.5?

Sergey Masyura
Sergey Masyura

InsiderHSE: Версия 4.1.5 Тестирую стратегию в EmulationTrader при UseMarketDepth = false. При этом лимитные заявки по заведомо лучшей цене исполняются по цене заявки, а не по цене последней сделки. ТО есть если послать лимитку на покупку фьючерса ртс по 1000000, то сделка пройдет по цене 1000000. При этом параметр EmulationTrader.MarketEmulator.Settings.Slippage на результат не влияет. Задача состоит в том, чтобы совершать сделки по LastPrice с фиксированным проскальзыванием против меня, например, 10 пипсов. Раньше (версии 4.0.х) для этого я входил лимитником с ценой на 1000 пипсов хуже, что обеспечивало мгновенную сделку по LastPrice с проскальзыванием, указанным в EmulationTrader.MarketEmulator.Settings.Slippage. Можно ли получить такую же функциональность в 4.1.5?

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

InsiderHSE
InsiderHSE

"Если исполняется по цене заявки, логичный workaround для тестирования выставлять заявку по LastPrice плюс проскальзывание - вероятно результат будет более ожидаем"

Обновился до версии 20971 из транка, все работает как надо! Спасибо =)