Лишние моиТейды в EmulationTrader
Atom Ответить
01.01.2014


Заметил посчитаный мною PL, не совпадает с тем что считает ПЛМанагер при тестировании на истории, вот нашел почему.

версия 4.2.1.7

Прошу посмотреть рисунок:

67666290/8 - Обьем 2 по ней же прошел обем 4 контракта, так же 67666294/8 - Обьем 2 куплено по ней тоже - 4 контракта.

Нехорошо получается Cursing
MyTrades.jpg 115 KB (0)



Спасибо:




17 Ответов
Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 02.01.2014
Ответить


Не уверен что понял написанное.
Спасибо:

longtrades

Фотография
Дата: 02.01.2014
Ответить


На рисунке все видно посмотрите внимательно , это MyTrades в EmulationTrader , видно что я выставил один ордер на покупку с номером 67666290/8 и обьемом 2 контракта, то есть максимум что я могу купить по этому ордеру 2 контракта , но получаю три MyTrade , с общим обьемом 4 контракта , то есть на ордер на покупку 2 контрактов мне наливают 4 контракта, что невозможно в реале, и происходит навено потому что EmulationTrader неуспевает изменить статус заявки на уже исполненую.

Не знаю как считает PnL PnLManager но возникают большие сомнения в верности тестирования алгоритмов на истории.
Автор топика
Спасибо:

Sam

Фотография
Программист
Дата: 02.01.2014
Ответить


Аналогичная проблема после миграции на 4.2.1.7. Воспроизводится часто
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 02.01.2014
Ответить


Sam Перейти
Аналогичная проблема после миграции на 4.2.1.7. Воспроизводится часто


Добавил в список активных багов. На SampleHistory воспроизводится?
Спасибо:

longtrades

Фотография
Дата: 03.01.2014
Ответить


Спасибо , Михаил.

Если можно у меня есть вопрос о тестере ответ на который я нигде не нашел.

Если происзодится тестирование с использованием стаканов :
например я ставлю заявку на покупку одного контракта скажем на бид в то время на этом биде стоит скажем обьем 15 контрактов , потом обьем на этом биде возрастает до скажем 40, будет ли мой ордер исполнен когда по биде пройдет 16 контрактов , так как он был 16-тым в очереди на покупку по даной цене , или все будет зависеть от настройки параметра FillOnTouch в трейдере , тоесть ордер будет считаться исполненным или после касания или после прохождения ценой уровня .

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

Спасибо.
Автор топика
Спасибо:

esper

Фотография
Программист
Дата: 03.01.2014
Ответить


longtrades Перейти
На рисунке все видно посмотрите внимательно , это MyTrades в EmulationTrader , видно что я выставил один ордер на покупку с номером 67666290/8 и обьемом 2 контракта, то есть максимум что я могу купить по этому ордеру 2 контракта , но получаю три MyTrade , с общим обьемом 4 контракта , то есть на ордер на покупку 2 контрактов мне наливают 4 контракта, что невозможно в реале, и происходит навено потому что EmulationTrader неуспевает изменить статус заявки на уже исполненую.

На каких данных и с какими параметрами производится тестирование? Ошибка воспроизводится на SampleHistoryTesting?

Спасибо:

longtrades

Фотография
Дата: 03.01.2014
Ответить


Данные конвертировал с QScalp, на SampleHistoryTesting не пробовал но думаю что для того что бы воспроизвести на SampleHistoryTesting нужно не бить по маркету, а ставить заявку по определенной цене , думаю такое может быть еще и из-за того что один раз ордер исполняется изза изменения цены инструмента, а другой из-за накладания уровней в стакане , но это нужно проверять .
Автор топика
Спасибо:

esper

Фотография
Программист
Дата: 03.01.2014
Ответить


Еще раз, на каких данных тестируете (тики, стаканы, свечки, генераторы стаканов и т.д.), какие настройки у эмулятора?
Спасибо:

longtrades

Фотография
Дата: 03.01.2014
Ответить


Тестирую на тиках и стаканах
Настройки эмулятора:
Код

            var trader = new EmulationTrader(
                new[] { security },
                new[] { portfolio })
            {
                MarketTimeChangedInterval = TimeSpan.FromMilliseconds(10),
                StorageRegistry = storageRegistry,

                MarketEmulator =
                {
                    Settings =
                    {
                        // использовать стаканы
                        UseMarketDepth = true,

                        // использовать свечки
                        //UseCandlesTimeFrame = emulationInfo.UseCandleTimeFrame,

                        // проверка что стаканы соответствуют сделкам. Улучшает реалистичность тестирования.
                        SyncDepthToTrades = false,

                        // сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки. 
                        // Если выключено - требуется "прохождение цены сквозь уровень"
                        // (более "суровый" режим тестирования.)
                        FillOnTouch = false,                     
                    }
                }
            };
Автор топика
Спасибо:

esper

Фотография
Программист
Дата: 03.01.2014
Ответить


На похожей конфигурации в SampleHistoryTesting проблему воспроизвети не удается. Можете попробовать на нем? Я использовал стаканы и соответственно котировние, которое ставит лимитки в стакан.

По возможности, было бы хорошо увидеть небольшое приложение, которое воспроизводит проблему.
Спасибо:

longtrades

Фотография
Дата: 03.01.2014
Ответить


Котирование ставит по лучшему биду/аску или выше/ниже их ? если выше/ниже то не будет перекрытия уровней в стакане , заявка будет исполнятся только по попаданию цены. Думаю нужно ставить на лучшие бид или аск, чтобы воспроизвести проблему. Если у вас не получится то немного познее попробую на SampleHistoryTesting .
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 03.01.2014
Ответить


longtrades Перейти
Котирование ставит по лучшему биду/аску или выше/ниже их ? если выше/ниже то не будет перекрытия уровней в стакане , заявка будет исполнятся только по попаданию цены. Думаю нужно ставить на лучшие бид или аск, чтобы воспроизвести проблему. Если у вас не получится то немного познее попробую на SampleHistoryTesting .


Вы можете по первоначальной проблеме отписаться? Мы рассматриваем сейчас только ее, так как она подтверждена косвенно. Другие проблемы или ошибки просьба не писать в этом топике.
Спасибо:

longtrades

Фотография
Дата: 03.01.2014
Ответить


Я по первой и отписался. Что думаю что лишние трейды могут появлятся потому что цена прошла уровень , и стакан наложился на ордер.
Автор топика
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 03.01.2014
Ответить


longtrades Перейти
Я по первой и отписался. Что думаю что лишние трейды могут появлятся потому что цена прошла уровень , и стакан наложился на ордер.


Как воспроизвести данную ситуацию?
Спасибо:

longtrades

Фотография
Дата: 03.01.2014
Ответить


Вот переделал пример , будет ставить заявки на лучший бид/аск.

Ставим точку отановки на строку 54 в SmaStrategy.cs и получаем остановку когда нужно.

Код

namespace SampleHistoryTesting
{
	using Ecng.Common;
    using System.Collections.Generic;
    using System.Linq;
	using StockSharp.Algo;
	using StockSharp.Algo.Candles;
	using StockSharp.Algo.Indicators;
	using StockSharp.Algo.Indicators.Trend;
	using StockSharp.Algo.Strategies;
	using StockSharp.Algo.Testing;
	using StockSharp.Logging;
	using StockSharp.BusinessEntities;
    using StockSharp.Messages;

	class SmaStrategy : Strategy
	{
		private readonly CandleSeries _series;
		private bool _isShortLessThenLong;

		public SmaStrategy(CandleSeries series, SimpleMovingAverage longSma, SimpleMovingAverage shortSma)
		{
			_series = series;

			LongSma = longSma;
			ShortSma = shortSma;
		}

		public SimpleMovingAverage LongSma { get; private set; }
		public SimpleMovingAverage ShortSma { get; private set; }

		protected override void OnStarted()
		{

            this.Security.Trader.NewMyTrades += trades => NewMyTrades(trades);

            this.Trader.MarketTimeChanged += t => ProcessDepth();

			// запоминаем текущее положение относительно друг друга
			_isShortLessThenLong = ShortSma.GetCurrentValue() < LongSma.GetCurrentValue();

			base.OnStarted();
		}

        private void NewMyTrades(IEnumerable<MyTrade> trades)           
        {


            foreach (var tr in trades)
            {
                if (tr.Order.GetTrades().Sum(x => x.Trade.Volume) > tr.Order.Volume)
                {
                    var Trtrades = this.Trader.MyTrades;
                    var stp = 0;
                }
            }
        }

        Order buy_order = null;
        Order sell_order = null;

        private void ProcessDepth()
        {
            var Volume = 2;
            if (buy_order != null)
            {
                if (buy_order.State == OrderStates.Done || buy_order.State == OrderStates.Failed)
                {
                    buy_order = this.CreateOrder(OrderDirections.Buy, Security.BestBid.Price, Volume);
                    RegisterOrder(buy_order);
                }
                else
                    if (buy_order.Price != Security.BestBid.Price)
                    {
                        this.CancelOrder(buy_order);
                        buy_order = this.CreateOrder(OrderDirections.Buy, Security.BestBid.Price, Volume);
                        RegisterOrder(buy_order);
                    }
            }
            else 
            {
                buy_order = this.CreateOrder(OrderDirections.Buy, Security.BestBid.Price, Volume);
                RegisterOrder(buy_order);
            }

            if (sell_order != null)
            {
                if (sell_order.State == OrderStates.Done || sell_order.State == OrderStates.Failed)
                {
                    sell_order = this.CreateOrder(OrderDirections.Sell, Security.BestAsk.Price, Volume);
                    RegisterOrder(sell_order);
                }
                else
                    if (sell_order.Price != Security.BestAsk.Price)
                    {
                        this.CancelOrder(sell_order);
                        sell_order = this.CreateOrder(OrderDirections.Sell, Security.BestAsk.Price, Volume);
                        RegisterOrder(sell_order);
                    }
            }
            else
            {
                sell_order = this.CreateOrder(OrderDirections.Sell, Security.BestAsk.Price, Volume);
                RegisterOrder(sell_order);
            }




        }

	
	}
}
Автор топика
Спасибо: Mikhail Sukhov

longtrades

Фотография
Дата: 03.01.2014
Ответить


Если обьем заявки поставить равным одному контракту , лишние трейды не проходят.
Автор топика
Спасибо:

esper

Фотография
Программист
Дата: 04.01.2014
Ответить


Спасибо за код, ошибку подтверждаю, в следующей версии будет фикс.
Спасибо:


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

loading
clippy