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


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


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

Теги:


Спасибо:




12 Ответов
esper

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


А значения вычисляются?
Спасибо:

kapustin-vladimir

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


выводил для проверки
"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

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


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

kapustin-vladimir

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


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

esper

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


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

Kefir

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


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

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


Спасибо:

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 13.02.2013
Ответить


Здравствуйте. Проверил 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. В коде я написал как привести индикатор в рабочее состояния, по крайней мере у меня он работает.Blushing

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

p.s. Когда проверять будете длину индикатора RSI поставте. Значение по умолчанию 100 и 0 выдает. Хотя бы так
Код
private RelativeStrengthIndex RSI = new RelativeStrengthIndex() { Length=10};
Спасибо: Kefir

esper

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


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

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 13.02.2013
Ответить


создал индикатор
Код
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

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


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

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

Иван З.

Фотография
Курсы Автор статей Благотворитель
Дата: 13.02.2013
Ответить


я на 4.1.7 сижу.
Не за что.
Спасибо:

esper

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


Исправлено в последней версии на кодепдексе.
Спасибо: VassilSanych


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

loading
clippy