← Zurück

Тип свечи RangeUS, с дополнительным параметром для разворота

RangeUS.png

Пока изучаю систему, буду писать полезные статьи, вроде этой. Если мешают, то напишите в коммент, Перестану)))) Что требуется: S#.API + понимание платформы.

И так. В основе классический рендж бар, но с дополнительным параметром ReverseSize (разворотный размер). Размеры указываются в шагах цены. На картинке сбербанк с параметрами 10/30 шагов(PriceStep)

Как добавить на график.


....
                _series = new CandleSeries(typeof(RangeUSCandle), sec, new RangeUSArgs { RangeSize = (decimal)sec.PriceStep * 10, ReverseSize= (decimal)sec.PriceStep * 30 });
....
                _candleManager = new CandleManager(client);
                _candleManager.Sources.Add(new RangeUSCandleBuilder { Sources = { new TradeCandleBuilderSource(client) } });
....
                _candleManager.Start(_series);

Сам код свечи и билдера Создайте новый класс в проекте, назовите его RangeUSCandle.cs например


using Ecng.Collections;
using Ecng.Common;
using Ecng.ComponentModel;

using System;
using System.Collections.Generic;
using System.Linq;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Candles.Compression;
using StockSharp.Localization;

namespace НазваниеВашегоПроекта
{
    public class RangeUSArgs
    {
        public decimal RangeSize;
        public decimal ReverseSize;
    }
    public enum RangeUSTrend
    {
         None = 0,
         UpTrend = 1,
         DownTrend = 2
    }

    /// <summary>
    /// Описание свечи
    /// </summary>
    public class RangeUSCandle : Candle
    {
        public override object Arg
        {
            get
            {
                return this.PriceRange;
            }
            set
            {
                this.PriceRange = (RangeUSArgs)value;
            }
        }

        /// <summary>
        /// Параметры свечи
        /// </summary>
        public RangeUSArgs PriceRange { get; set; }
        /// <summary>
        /// Текущий тренд. Значения: 1 восходящий, 2 нисходящий, 0 при инициации.
        /// </summary>
        public RangeUSTrend Trend;  
        public override Candle Clone()
        {
            return CopyTo(new RangeUSCandle());
        }
    }

    /// <summary>
    /// Построитель RangeUS свечей
    /// </summary>
    public class RangeUSCandleBuilder : CandleBuilder<RangeUSCandle>
    {
        public RangeUSCandleBuilder()
        {
        }

        public RangeUSCandleBuilder(ICandleBuilderContainer container)
            : base(container)
        {
        }

        public override IEnumerable<Range<DateTimeOffset>> GetSupportedRanges(CandleSeries series)
        {
            var ranges = base.GetSupportedRanges(series).ToArray();

            if (!ranges.IsEmpty())
            {
                if (!(series.Arg is RangeUSArgs))
                    throw new ArgumentException(LocalizedStrings.WrongCandleArg.Put(series.Arg), nameof(series));

                if (((RangeUSArgs)series.Arg).RangeSize <= 0)
                    throw new ArgumentOutOfRangeException(nameof(series), series.Arg, LocalizedStrings.PriceRangeMustBeGreaterThanZero);
            }

            return ranges;
        }

        protected override RangeUSCandle CreateCandle(CandleSeries series, ICandleBuilderSourceValue value)
        {
            // требуется перенести в новую свечу, понимание текущего направления.
            RangeUSTrend trend_value;
            if (CandleManager.GetCandleCount(series) > 0)
            {
                trend_value = CandleManager.GetCurrentCandle<RangeUSCandle>(series).Trend;
            } else {
                trend_value = RangeUSTrend.None;
            }
            return FirstInitCandle(series, new RangeUSCandle
            {
                PriceRange = (RangeUSArgs)series.Arg,
                OpenTime = value.Time,
                CloseTime = value.Time,
                HighTime = value.Time,
                LowTime = value.Time,
                Trend = trend_value,
            }, value);
        }

        protected override bool IsCandleFinishedBeforeChange(CandleSeries series, RangeUSCandle candle, ICandleBuilderSourceValue value)
        {
            var cm = CandleManager;
            var prev_candle = CandleHelper.GetCandle<RangeUSCandle>(cm,series,cm.GetCandleCount(series)-1);
            if(cm.GetCandleCount(series) <= 1)
            {
                // первая свеча. пытаемся понять направление
                candle.Trend = (candle.OpenPrice > value.Price) ? RangeUSTrend.DownTrend : RangeUSTrend.UpTrend;
                return candle.LowPrice + candle.PriceRange.RangeSize <= candle.HighPrice; //
            }
            if (candle.Trend == RangeUSTrend.UpTrend && value.Price > candle.OpenPrice)
            {
                return candle.OpenPrice + candle.PriceRange.RangeSize <= candle.HighPrice; //
            }
            if (candle.Trend == RangeUSTrend.DownTrend && value.Price < candle.OpenPrice)
            {
                return candle.OpenPrice - candle.PriceRange.RangeSize >= candle.LowPrice; //
            }
            var needReverse = candle.GetBody() > candle.PriceRange.ReverseSize; // 
            if (needReverse)
            {
                candle.Trend = (candle.Trend != RangeUSTrend.None & candle.Trend == RangeUSTrend.UpTrend) ? candle.Trend = RangeUSTrend.DownTrend : candle.Trend = RangeUSTrend.UpTrend;
            }
            return needReverse;
        }
    }
}

War dieses Thema hilfreich?

Thema teilen

Kommentare (0)

Anmelden oder Konto erstellen, Melden Sie sich an oder registrieren Sie sich, um einen Kommentar zu hinterlassen

Noch keine Kommentare. Seien Sie der Erste!