Почему свеча отрисовывается многократно?
Atom Ответить
14.11.2013


Пытаюсь работать со свечками. Рисовать на графике я их не хочу,
просто хочу например выводить время закрытия законченной свечи тайм-фрейма 1 мин в ListBox,
то есть например чтобы раз в минуту появлялась запись о сформировавшейся свече.
Для этого я делаю _candleManager.Processing += PrintCandle;

И в процедуре PrintCandle у меня только это:

if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() => MyList.Items.Add(candle.CloseTime + " " + candle.ClosePrice));
}

При этом в ListBox валятся свечки, во первых исторические (так как они подпадают под условие
законченности), а также текущая свеча выводится многократно с предыдущей, типа такого:

14.11.2013 18:31:00 143520
14.11.2013 18:32:00 143460
14.11.2013 18:31:00 143520
14.11.2013 18:32:00 143460
14.11.2013 18:31:00 143520
14.11.2013 18:32:00 143460
14.11.2013 18:31:00 143520
14.11.2013 18:32:00 143460


Подскажите, что я делаю не так, как сделать, чтобы видеть только одну запись раз в минуту по окончанию свечи и не грузить исторические, ну или грузить заданное их количество.

Спасибо.

Теги:


Спасибо:




10 Ответов
alexan3010

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


Ok, спрошу по другому.
PrintCandle как я понял вызывается несколько раз в секунду конструкцией _candleManager.Processing += PrintCandle;

Соответственно туда передаются все полученные свечки, как я понял и новые и исторические.

Мне нужно как то в MyList выводить только уникальную новую свечку после ее формирования, то есть один раз в TimeFrame.


Коннектор SmartCom если что.
Автор топика
Спасибо:

Дюшес

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


alexan3010 Перейти

нужно как то в MyList выводить только уникальную новую свечку после ее формирования, то есть один раз в TimeFrame.

Правило WhenCandlesFinished не подходит?
Код

            _series
                .WhenCandlesFinished()
                .Do(candle =>
                {
                })
                .Sync(syncToken)
                .Apply(this);



Спасибо:

alexan3010

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


Как то сложно, а syncToken откуда берется?

А если вам не сложно, можете пояснить физику процесса, что происходит при вызове
_candleManager.Processing += PrintCandle; ?

Из мануалов - это подписывание на событие появления нового элемента для обработки, который мы передаем в процедуру PrintCandle,
где и обрабатываем.
А что туда фактически передается и когда во времени?
Правильно ли я понимаю, что любое изменение состояния свечи (по сути любая сделка) вызывает это событие?
Если так, то как мне в процедуре обработку написать так, чтобы я видел скажем Close последних N полных завершенных свечей, а текущую - не видел, чтобы она появлялась только в момент своего завершения.
Автор топика
Спасибо:

Дюшес

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


alexan3010 Перейти

Как то сложно, а syncToken откуда берется?

Это пример правила, для получения законченных свечек, если вы пользуетесь стратегиями.
https://stocksharp.ru/doc/html/...a1-a158-9a258e0a62e1.htm
synctoken - это new SyncObject(), примерно то же, что и new object(), т.е. объект синхронизации.

alexan3010 Перейти

А если вам не сложно, можете пояснить физику процесса, что происходит при вызове
_candleManager.Processing += PrintCandle; ?

Из мануалов - это подписывание на событие появления нового элемента для обработки, который мы передаем в процедуру PrintCandle,
где и обрабатываем.
А что туда фактически передается и когда во времени?
Правильно ли я понимаю, что любое изменение состояния свечи (по сути любая сделка) вызывает это событие?
Если так, то как мне в процедуре обработку написать так, чтобы я видел скажем Close последних N полных завершенных свечей, а текущую - не видел, чтобы она появлялась только в момент своего завершения.

CandleManager формирует из тиков свечки заданного таймфрейма, с каждым тиком вызывается событие processing и передает вашему обработчику объект candle, т.е. текущую свечу. Если нужно ловить окончание свечи, то проверяете на candle.State == CandleStates.Finished. Получить n-последних свечек можно через метод _series.GetCandles, например так:
Код

var candles = _series.GetCandles<TimeFrameCandle>(3).Where(c => c.State == CandleStates.Finished);
Спасибо:

Mikhail Sukhov

Фотография
Автор статей Программист Трейдер
Дата: 20.11.2013
Ответить


Дюшес Перейти
alexan3010 Перейти

Как то сложно, а syncToken откуда берется?

Это пример правила, для получения законченных свечек, если вы пользуетесь стратегиями.
https://stocksharp.ru/doc/html/...a1-a158-9a258e0a62e1.htm
synctoken - это new SyncObject(), примерно то же, что и new object(), т.е. объект синхронизации.


На 100% не уверен, но с 4.2 скорее всего этот метод более не нужен. Причина - события ITrader вызываются из одного потока по умолчанию. Если это не менять, то и синхронизация не нужна.
Спасибо:

alexan3010

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


Дюшес, спасибо за разъяснения!

Но тогда, как понимать то, что я описал в начале этой темы?
Почему, когда с каждым тиком, когда вызывается processing и передает моему обработчику candle, т.е. текущую свечу, я по конструкции
if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() => MyList.Items.Add(candle.CloseTime + " " + candle.ClosePrice));
}

вижу чередование текущей и предыдущей?
Автор топика
Спасибо:

Дюшес

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


alexan3010 Перейти

Почему, когда с каждым тиком, когда вызывается processing и передает моему обработчику candle, т.е. текущую свечу, я по конструкции
if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() => MyList.Items.Add(candle.CloseTime + " " + candle.ClosePrice));
}

вижу чередование текущей и предыдущей?

Ну тогда надо поглядеть весь код, угадать сложно.
Спасибо:

alexan3010

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


Вот, код тестовый минимальный, коннект, подписка и вывод. Для версии API 4.1.19, в последней что то пока не разобрался в изменениях, свечки вообще не появляются.
Код внутри обработки события OnClick кнопки. На форме только одна эта кнопка и лист-бокс MyList в который все выводится.

Код

 var account = "BP****";

            _trader = new SmartTrader { Login = "BP****", Password = "*****"}; //Создаем шлюз
            this.GuiAsync(() => MyList.Items.Add("Производим подключение к SmartCom v3.0..."));
            _trader.ApplyWrapper(SmartComVersions.V3);   //тут указываем что именно третья версия.
            _trader.NewSecurities += securities =>
            {

                _ri = securities.FirstOrDefault(sec => sec.Code == "RIZ3");
                if (_ri != null)
                {
                    this.GuiAsync(() => MyList.Items.Add("RIZ3 появился."));
                    _trader.RegisterSecurity(_ri);
                      _trader.RegisterTrades(_ri);    
                    _candleManager = new CandleManager(_trader);  //Заводим менеджер свечей
                    _series = new CandleSeries(typeof(TimeFrameCandle), _ri, _timeFrame);
                    _candleManager.Start(_series);
                    _trader.RegisterTrades(_ri);
                    _candleManager.Processing += (s, candle) =>
                    {
                        if (candle.State == CandleStates.Finished) this.GuiAsync(() => MyList.Items.Add(candle.CloseTime + "  " + candle.ClosePrice));
                    };

                }

            };   //NewSecurities

          _trader.NewPortfolios += portfolios =>
            {
                portfolios.ForEach(_trader.RegisterPortfolio);
               if (_portfolio == null)
                {
                    // находим нужный портфель и присваиваем его переменной _portfolio
                    _portfolio = portfolios.FirstOrDefault(p => p.Name == account);
                   if (_portfolio != null)
                    {
                        this.GuiAsync(() => MyList.Items.Add("Портфель появился. "+_portfolio));
                   }
                } //конец if _portfolio
            };//конец NewPortFolios
            _trader.Connected += () =>
            {
                this.GuiAsync(() => MyList.Items.Add("Подключение было произведено успешно, запускаем экспорт."));
                 _trader.StartExport();   
             };
            _trader.Connect();

Автор топика
Спасибо:

Дюшес

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


alexan3010 Перейти

Вот, код тестовый минимальный

Лучше полный проект, чтобы на своем терминале проверить.
На каких-то версиях S# работает или не работает вообще?
Спасибо: alexan3010

alexan3010

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


Спасибо, я вроде более менее подразобрался.
У меня не то чтобы не работало, более теоретический был вопрос, что валится после вызова обработчика _candleManager.Processing += PrintCandle.
Просто если не указывать в _candleManager.Start(_series) временные рамки, то валится кроме текущих свечей еще ряд исторических свечей заданного таймфрема в обработчик. Вот это меня и смущало - валилось куча свечек разных.
Но во-первых можно указать временные рамки, во вторых я научился их запихивать в List и уже там анализировать и выводить когда мне нужно.



Автор топика
Спасибо:


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

loading
clippy