← Atrás

RSI.IsFormed команда IsFormed не работает в индикаторе RSI== помогите

RSI.IsFormed команда IsFormed не работает в индикаторе RSI== помогите.. показывает все время false

Comentarios (12)

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

esper
esper

А значения вычисляются?

kapustin-vladimir
kapustin-vladimir Autor

выводил для проверки "LongSma.GetCurrentValue()", LongSma.GetCurrentValue(), "RSI", RSI.GetCurrentValue() LongSma.GetCurrentValue(), 10336.05, RSI, 100, SMAStrategy LongSma.GetCurrentValue(), 11491.05, RSI, 100, SMAStrategy LongSma.GetCurrentValue(), 12646.05, RSI, 100, SMAStrategy RSI выводи все время 100 без изменений

esper
esper

Что-то у вас не так. Rsi из последней версии на кодеплексе проходит тест.

kapustin-vladimir
kapustin-vladimir Autor

Что-то у вас не так. Rsi из последней версии на кодеплексе проходит тест. Было написано так в ответе и воз ныне там, скажите что происходит. больше ответов не было, закончились ли тесты???

esper
esper

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

Kefir
Kefir

esper: В проекте с индикаторами есть набор тестов для большинства индикаторов, в том числе для RSI. Т.к. индикатор RSI свой тест проходит без ошибок, то он должен рассчитывать свои значения верно и ошибка, скорее всего, где-то у вас, что и было написано в предыдущем сообщении. Т.к. вы не показали никакого кода, как вы работаете с индикатором, то и сказать что-то еще нет возможности.

То же столкнулся с той же проблемой значение RSI постоянно равно 100

в классе RelativeStrengthIndex

var gainValue = _gain.Process(input.SetValue(delta > 0 ? delta : 0m)).GetValue<decimal>(); var lossValue = _loss.Process(input.SetValue(delta > 0 ? 0m : -delta)).GetValue<decimal>();

gainValue и lossValue постоянно равны нулю и соответственно

if (lossValue == 0) { return 100m; }

всегда возвращает 100

не очень силен в программировании может что то не то подаю на вход?

Иван З.
Иван З.

Здравствуйте. Проверил RSI, действительно не работает. Стал разбираться в чем дело. RSI в себе использует индикатор SmoothedMovingAverage. Взял коды двух индикаторов. И получилось следующее.


using StockSharp.Algo.Indicators;


namespace WpfApplication1
{
    using System.ComponentModel;
    using System.Linq;
    /// <summary>
    /// Сглаженное скользящее среднее.
    /// </summary>
    [DisplayName("SMMA")]
    [Description("Сглаженное скользящее среднее.")]
    public class SmoothedMovingAverage : LengthIndicator<decimal>
    {
        /// <summary>
        /// Создать <see cref="SmoothedMovingAverage"/>.
        /// </summary>
        public SmoothedMovingAverage()
            : base(typeof(decimal))
        {
        }

        /// <summary>
        /// Обработать входное значение.
        /// </summary>
        /// <param name="input">Входное значение.</param>
        /// <returns>Результирующее значение.</returns>
        protected override decimal OnProcess(IIndicatorValue input)
        {
            var newValue = input.GetValue<decimal>();

            if (input.IsFinal)
                Buffer.Add(newValue);

            if (!IsFormed)
                return this.GetCurrentValue();

            if (Buffer.Count == Length)
            {
                return Buffer.Sum() / Length;
            }
            else
            {
                if (input.IsFinal)
                    Buffer.RemoveAt(0);
                return (this.GetCurrentValue() * (Length - 1) + newValue) / Length;
            }
        }
    }

    /// <summary>
    /// Индекс относительной силы.
    /// </summary>
    [DisplayName("RSI")]
    [Description("Индекс относительной силы.")]
    public class RelativeStrengthIndex : LengthIndicator<decimal>
    {
        private readonly SmoothedMovingAverage _gain;
        private readonly SmoothedMovingAverage _loss;
        private bool _isInitialized;
        private decimal _last;

        /// <summary>
        /// Создать <see cref="RelativeStrengthIndex"/>.
        /// </summary>
        public RelativeStrengthIndex()
            : base(typeof(decimal))
        {
            _gain = new SmoothedMovingAverage();
            _loss = new SmoothedMovingAverage();
        }

        /// <summary>
        /// Сформирован ли индикатор.
        /// </summary>
        public override bool IsFormed { get { return _gain.IsFormed; } }

        /// <summary>
        /// Длина периода.
        /// </summary>
        public override int Length
        {
            get
            {
                return _gain.Length;
            }
            set
            {
                _loss.Length = _gain.Length = value;
                Reset();
            }
        }

        /// <summary>
        /// Обработать входное значение.
        /// </summary>
        /// <param name="input">Входное значение.</param>
        /// <returns>Результирующее значение.</returns>
        protected override decimal OnProcess(IIndicatorValue input)
        {
            var value = input.GetValue<decimal>();

            if (!_isInitialized)
            {
                _last = value;
                _isInitialized = true;
                return this.GetCurrentValue();
            }

            var delta = value - _last; 
            

            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Для проверки ввел следующие 4 строки, на работу индикатора они ни как не влияют, их можно удалить
            var g = input.SetValue(delta > 0 ? delta : 0m); // После изменения входное значения индикатора, у g значения индикатора g свойство IsFinal=false
            var l = input.SetValue(delta > 0 ? 0m : -delta); // После изменения значения индикатора, у l значения индикатора g свойство IsFinal=false
            var gg = _gain.Process(g);//SmoothedMovingAverage проверяет свойство IsFinal и при false считается несформированным и выдает последнее значение которое = 100
            var ll = _loss.Process(l);//SmoothedMovingAverage проверяет свойство IsFinal и при false считается несформированным и выдает последнее значение которое = 100
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


            //Поможет следующее действие
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Это мы закоментируем до лучших времен
            //var gainValue = _gain.Process(input.SetValue(delta > 0 ? delta : 0m)).GetValue<decimal>();
            //var lossValue = _loss.Process(input.SetValue(delta > 0 ? 0m : -delta)).GetValue<decimal>();
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            // Честно говоря, не вижу смысла изменять входное значение индикатора(если я не прав прошу поправить и объяснить почему? Здесь так мало что-то кому-то объясняют, до всего самому доходить приходиться.), так как SmoothedMovingAverage принимает на вход decimal то
            // input.SetValue(delta > 0 ? delta : 0m) можно заменить на delta > 0 ? delta : 0m И все, код работает
            var gainValue = _gain.Process(delta > 0 ? delta : 0m).GetValue<decimal>();
            var lossValue = _loss.Process(delta > 0 ? 0m : -delta).GetValue<decimal>();

            _last = value;

            if (lossValue == 0)
            {
                return 100m;
            }
            else if (gainValue / lossValue == 1)
            {
                return 0m;
            }
            else
            {
                return 100m - 100m / (1m + gainValue / lossValue);
            }
        }
    }
}

Проблема возникает из-за того, что input.SetValue(delta > 0 ? 0m : -delta) выдает значение со свойством IsFinal=false, SmoothedMovingAverage проверяет свойство IsFinal и при false считается не сформированным и выдает последнее значение которое = 100. В коде я написал как привести индикатор в рабочее состояния, по крайней мере у меня он работает.😊

Остается вопрос input.SetValue() должно выдавать значение со свойством IsFinal=false?

p.s. Когда проверять будете длину индикатора RSI поставте. Значение по умолчанию 100 и 0 выдает. Хотя бы так

private RelativeStrengthIndex RSI = new RelativeStrengthIndex() { Length=10};
Kefir
esper
esper

Давайте пока не трогать код индикатора, просто покажите как вы его используете.

Иван З.
Иван З.

создал индикатор

private RelativeStrengthIndex RSI = new RelativeStrengthIndex() { Length=10};

подписываюсь на свечки

        private void Chart_Click(object sender, RoutedEventArgs e)
        {

            //добавляем источник информации трейдера
            _trader = new QuikTrader();
            InitChart();
            _candleManager = new CandleManager();
            var startTime = new DateTime(2012, 1, 1);
            var endTime = new DateTime(2012, 1, 5);

            // Добавление в источник свечек TimeFrameCandleBuilder источник данных в виде файлов гидры 
            var storageRegistry = new StorageRegistry();
            ((LocalMarketDataDrive)storageRegistry.DefaultDrive).Path = PathStorage;
            var stor = new StorageCandleSource { StorageRegistry = storageRegistry };
            _series = new CandleSeries(typeof(TimeFrameCandle), SelectedSecurity,
                                       TimeSpan.FromMinutes(SelectedTimeFrame));

            _candleManager.Sources.Add(stor);

            _candleManager.Container.CandlesKeepTime = TimeSpan.FromDays(2);

            _candleManager.Processing += Draw;

            _candleManager.Start(_series, startTime, endTime);
        }

через отладку смотрю значения

 private void Draw(CandleSeries series, Candle candle)
        {
           var ggg = RSI.Process(candle.ClosePrice);
           var fff = RSI.GetCurrentValue();
        }

И ggg и fff равны 100

esper
esper

Версия библиотеки какая?

Иван З., спасибо за пример, багу подтверждаю.

Иван З.
Иван З.

я на 4.1.7 сижу. Не за что.

esper
esper

Исправлено в последней версии на кодепдексе.

VassilSanych