Для изменения размера нажмите или перетащите
Собственный тип свечей

S# позволяет расширить возможности CandleManager, давая возможность работать с произвольными типами свечей. Это полезно в тех случаях, когда требуется работать со свечами, не поддерживаемые в данный момент S#. Ниже описан план действия по добавлению тиковых свечей (свечи, которые формируются по количеству сделок).

Реализация тиковых свечей

  1. В начале необходимо создать свой тип свечи. Тип должен наследоваться от класса Candle:

    Внимание Внимание
    Тиковые свечи поддерживаются S# стандартно и данный шаг представлен лишь в качестве примера.
    C#
    /// <summary>
    /// Свеча, группируемая по количеству сделок.
    /// </summary>
    public class TickCandle : Candle
    {
        /// <summary>
        /// Параметр свечи.
        /// </summary>
        public override object Arg
        {
            get
            {
                return this.TradeCount;
            }
            set
            {
                this.TradeCount = (int) value;
            }
        }
    
        /// <summary>
        /// Максимальное количество сделок, которое может содержать свеча.
        /// </summary>
        public int TradeCount { get; set; }
    }
  2. Далее требуется создать построителя свечей, для нового типа свечей. Для этого необходимо создать реализацию CandleBuilderTCandle. В метод ProcessValue будут поступать данные типа ICandleBuilderSourceValue. В зависимости от источников Sources, ICandleBuilderSourceValue может содержать данные как о тиковой сделке Trade, так и о стакане MarketDepth.

    Метод ProcessValue должен возвратить или новую свечу (если новые данные привели к формированию свечи), или обновить переданную(если данных пока недостаточно для создания новой свечи). Если метод ProcessValue возвращает новую свечу, то CandleBuilderTCandle вызывает его еще раз, передав в метод то же самое значение ICandleBuilderSourceValue. Метод будет вызываться до тех пор, пока ProcessValue не вернет переданную свечу. Это сделано для тех случаев, когда по одному входящему значению ICandleBuilderSourceValue может быть сформированно несколько свечей:

    C#
    /// <summary>
    /// Построитель свечей типа <see cref="T:StockSharp.Algo.Candles.TickCandle" />.
    /// </summary>
    public class TickCandleBuilder : CandleBuilder<TickCandle>
    {
        /// <summary>
        /// Создать <see cref="T:StockSharp.Algo.Candles.Compression.TickCandleBuilder" />.
        /// </summary>
        public TickCandleBuilder()
        {
        }
    
        /// <summary>
        /// Создать <see cref="T:StockSharp.Algo.Candles.Compression.TickCandleBuilder" />.
        /// </summary>
        /// <param name="container">Контейнер данных.</param>
        public TickCandleBuilder(ICandleBuilderContainer container) : base(container)
        {
        }
    
        /// <summary>
        /// Создать новую свечу.
        /// </summary>
        /// <param name="series">Серия свечей.</param>
        /// <param name="value">Данные, с помощью которых необходимо создать новую свечу.</param>
        /// <returns>Созданная свеча.</returns>
        protected override TickCandle CreateCandle(CandleSeries series, ICandleBuilderSourceValue value)
        {
            TickCandle candle = new TickCandle {
                TradeCount = (int) series.Arg,
                OpenTime = value.Time,
                CloseTime = value.Time
            };
            return this.FirstInitCandle(series, candle, value);
        }
    
        /// <summary>
        /// Получить временные диапазоны, для которых у данного источника для передаваемой серии свечей есть данные.
        /// </summary>
        /// <param name="series">Серия свечей.</param>
        /// <returns>Временные диапазоны.</returns>
        public override IEnumerable<Range<DateTime>> GetSupportedRanges(CandleSeries series)
        {
            IEnumerable<Range<DateTime>> supportedRanges = base.GetSupportedRanges(series);
            if (!supportedRanges.IsEmpty<Range<DateTime>>())
            {
                if (!(series.Arg is int))
                {
                    throw new ArgumentException();
                }
                if (((int) series.Arg) <= 0)
                {
                    throw new ArgumentOutOfRangeException();
                }
            }
            return supportedRanges;
        }
    
        /// <summary>
        /// Сформирована ли свеча до добавления данных.
        /// </summary>
        /// <param name="series">Серия свечей.</param>
        /// <param name="candle">Свеча.</param>
        /// <param name="value">Данные, с помощью которых принимается решение о необходимости окончания формирования текущей свечи.</param>
        /// <returns>True, если свечу необходимо закончить. Иначе, false.</returns>
        protected override bool IsCandleFinishedBeforeChange(CandleSeries series, TickCandle candle, ICandleBuilderSourceValue value)
        {
            return (base.Container.GetValues(series, candle).Count<ICandleBuilderSourceValue>() >= candle.TradeCount);
        }
    
        /// <summary>
        /// Обновить свечу данными.
        /// </summary>
        /// <param name="series">Серия свечей.</param>
        /// <param name="candle">Свеча.</param>
        /// <param name="value">Данные.</param>
        protected override void UpdateCandle(CandleSeries series, TickCandle candle, ICandleBuilderSourceValue value)
        {
            base.UpdateCandle(series, candle, value);
            candle.CloseTime = value.Time;
        }
    }
  3. Затем, при создании CandleManager, нужно добавить TickCandleBuilder в источники. Этот построитель будет брать тики из IConnector:

    Внимание Внимание
    TickCandleBuilder, как источник свечей, стандартно присутствует в CandleManager. Данный шаг представлен лишь в качестве примера.
    C#
    private QuikTrader _trader;
    private CandleManager _candleManager;
    
    ...
    
    _candleManager = new CandleManager(_trader);
    _candleManager.Sources.Add(new TickCandleBuilder { Sources = { new TradeCandleBuilderSource(_trader) } });
  4. Создать CandleSeries и запросить по ней данные:

    C#
    private QuikTrader _trader;
    private Security _security;
    
    private CandleSeries _series;
    private CandleManager _candleManager;
    
    
    _series = new CandleSeries(typeof(TickCandle), _security, 1000);
    
    ...
    
    _candleManager.Start(_series);