CandleSeries и WeightedIndexSecurity


CandleSeries и WeightedIndexSecurity
Atom
12/17/2012


Умеет ли CandleSeries работать с BasketSecurity и его производными (например, WeightedIndexSecurity)? Теста ради написал простой обработчик свечек (см. ниже). Если в этом коде в строке
Code
_series = new CandleSeries(typeof(TimeFrameCandle), Security, TimeFrame)
в качестве Security использовать WeightedIndexSecurity, то _series всегда будет пустым. При этом новые свечки в обработчик приходят исправно, и строка _message заполняется данными, которые выводятся в лог. SMA также рассчиывается (под отладчиком видно некоторые осмысленные значения), однако корректность расчета пока не проверял - для начала хочется уяснить про CandleSeries.

Если в качестве Security указать обыкновенный инструмент (т.е. StockSharp.BusinessEntities.Security) - _candles заполняется отлично.

Вопрос: умеет ли CandleSeries работать с WeightedIndexSecurity? Для чего это надо - например, к арбитражной стратегии прикрутить скользящую среднюю. Удобнее всего это делать через свечки, да и унификации хочется с кодом, который работает с единичными инструментами.

Собственно, код:

Code
class WeightedSmaCandleStrategy : BasePortfolioStrategy
    {
        public TimeSpan TimeFrame { get; set; }
        public int Length;

        private CandleSeries _series;
        DateTime strategyStartTime;
        private SimpleMovingAverage Sma;

        protected override void OnStarted()
        {
            if (TimeFrame == null)
                throw new ApplicationException("Не задан таймфрейм!");
            if (Length <= 0)
                throw new ApplicationException("Не задан период скользящей средней!");

            strategyStartTime = DateTime.Now;

            base.OnStarted();

            Sma = new SimpleMovingAverage() { Length = Length };

            _series = new CandleSeries(typeof(TimeFrameCandle), Security, TimeFrame);  // Если Security - это WeightedIndexSecurity, то _series не заполняется
            _series.WorkingTime = WorkingTime;

            _series
                .WhenCandlesFinished()
                .Do(ProcessCandle)
                .Apply(this);

            TraderBuilder.CandleManager.Start(_series);
        }

        private void ProcessCandle(Candle candle)
        {
            // если наша стратегия в процессе остановки
            if (ProcessState == ProcessStates.Stopping)
            {
                // отменяем активные заявки
                CancelActiveOrders();

                return;
            }

            bool _canTrade = true;

            Sma.Process(candle);

            string _message;
            // Исторические свечки просто запоминаем
            if (candle.CloseTime < StartedTime)
            {
               _message = string.Format("Историческая свечка: Time: {0} O:{1} H:{1} L:{2} C:{3}", candle.OpenTime, candle.OpenPrice, candle.HighPrice, candle.LowPrice, candle.ClosePrice);
                _canTrade = false;
                //return;
            }
            else
                _message = string.Format("Реальная свечка: Time: {0} O:{1} H:{1} L:{2} C:{3}", candle.OpenTime, candle.OpenPrice, candle.HighPrice, candle.LowPrice, candle.ClosePrice);

            var _seriesCount = _series.GetCandleCount();  // В случае с WeightedIndexSecurity здесь всегда возвращается 0
            var _smaValue = Sma.GetCurrentValue();
            if (_seriesCount < Length)
            {
                //this.AddInfoLog(string.Format("GetCandleCount < Length. GetCandleCount = {0} Length = {1}", _seriesCount, Length));
                //return;
                _canTrade = false;
            }
            else
            {
                _message = string.Concat(_message, string.Format(" SMA={0}", _smaValue));
            }

            this.AddInfoLog(_message);

            var _previousCandle = _series.GetCandle<TimeFrameCandle>(1);
            if (_previousCandle != null)
            {
                if (candle.ClosePrice > _smaValue && _previousCandle.ClosePrice < _smaValue)
                {
                    this.AddInfoLog("Пересечение снизу! CC={0} PC={1} SMA={2}", candle.ClosePrice, _previousCandle.ClosePrice, _smaValue);
                    if (_canTrade)
                    {
                        var _buyOrder = new Order()
                        {
                            Type = OrderTypes.Market,
                            Direction = OrderDirections.Buy,
                            Volume = Position != 0 ? 2 : 1
                        };
                  
                        RegisterOrder(_buyOrder);
                    }
                }

                if (candle.ClosePrice < _smaValue && _previousCandle.ClosePrice > _smaValue)
                {
                    this.AddInfoLog("Пересечение сверху! CC={0} PC={1} SMA={2}", candle.ClosePrice, _previousCandle.ClosePrice, _smaValue);
                    if (_canTrade)
                    {
                        var _sellOrder = new Order()
                        {
                            Type = OrderTypes.Market,
                            Direction = OrderDirections.Sell,
                            Volume = Position != 0 ? 2 : 1
                        };

                        RegisterOrder(_sellOrder);
                    }
                }
            }
}

Tags:


Thanks:


esper

Avatar
Date: 12/17/2012
Reply


Проверяете, так понимаю, на исторических данных?
Thanks:

Algonavt

Avatar
Date: 12/17/2012
Reply


Данные - накопленная в Квике информация по сделкам в текущей сессии, которые поступают сразу после старта стратегии + все новые данные (по мере формирования свечей). Обрабатываются ли новые данные (т.е. по свечам, сфирмированным после старта стратегии) проверю сегодня вечером.
Thanks:

Algonavt

Avatar
Date: 12/17/2012
Reply


Проверил. Новые данные поступают, но
Code
var _seriesCount = _series.GetCandleCount();
всё равно получает 0.
Thanks:


Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy