Возможная ошибка S#
Atom
21.06.2013
ttt


Добрый день.

Пишу робота на S#.
Подписан на событие формирования новой свечи. Timeframe 1 минута.
В момент прихода новой свечи цена close последней свечи отличается от close той же свечи,
полученной с Finam'a на 1-7 пунктов (контракт Si-9.13). Если отключаюсь и
заново подключаюсь, то цены закрытия тех же самых свечей в точности совпадают с ценами
закрытия по данным с Finam'а.
Цены open, high, low также идут с ошибками:
[Количество несовпадений (на примере одного дня)]:
open: 0
high: 17 несовпадений
low: 23 несовпадения
close: 188 несовпадений
Всего 532 бара.
Во время вечерней сессии данные по свечам приходят корректные.

Общение с техподдержкой SmartCOM позволило выделить 2 возможные причины данной проблемы:
1. Либо происходят потери при получении тиковых данных от сервера, на основе которых S# формирует свечи.
2. Либо платформа S# неверно формирует свечи по тем данным, по которым получает данные от серверов.

Учитывая, что после перезапуска приложения, приходят корректные данные о свечах, можно предположить, что более вероятен второй вариант. Чтобы проверить, выполняю подписку на исторические свечи каждый раз после прихода события формирования новой свечи. В обработчике события NewHistoryCandles отслеживаю повторно полученную информацию о серии. Результат: данные не меняются.

Вопросы:
1) Правильно ли я понимаю, что внутри метода, реализующего формирование новой свечи, вызов GetBars осуществляется всего один раз при самом первом запуске приложения, а затем, S# не запрашивает каждый раз сервер о параметрах сформировавшейся свечи, а сам каким-то образом формирует свечи?
2) Как можно вызвать GetBars (или метод, который запросит информацию от сервера посредством GetBars)?
3) В каком событии и как отлавливать пришедшую информацию?

Теги:


Спасибо:


1 2  >
andy_baka

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


Наверное событие NewHistoricalCandles?
А как вы получаете исторические свечки в событии о приходе новой свечи? Нативными средствами SmartCom или же через CandleManager?
Спасибо:

Mikhail Sukhov

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


andy_baka
Наверное событие NewHistoricalCandles?
А как вы получаете исторические свечки в событии о приходе новой свечи? Нативными средствами SmartCom или же через CandleManager?


Присоединяюсь к вопросу. Хотя бы схематический код нужен, что откуда и куда.
Спасибо:

ttt

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


Наверное событие NewHistoricalCandles?
Да.

А как вы получаете исторические свечки в событии о приходе новой свечи? Нативными средствами SmartCom или же через CandleManager?

Через CandleManager. Напишите, pls, если возможно, как в моем случае можно использовать нативные средства SmartCOM (явно выполнить GetBars и затем обработать полученную серию).

Схема работы:

Запускаю получение свечей:
Код
 private void btnGetHistory_Click(object sender, EventArgs e)
        {
            DateTime date1 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 10, 0, 0);
            _lkSeries = new CandleSeries(typeof(TimeFrameCandle), _lkoh, TimeSpan.FromMinutes(1));
            _candleManager.Start(_lkSeries, date1, DateTime.Now);
        }


Отлавливаю данные в обработчике события NewHistoricalCandles:
Схема:
ЕСЛИ пришла 1 свеча,
ТО вывожу на экран только ее
ИНАЧЕ вывожу все свечи, начиная с последней загруженной

Код
_trader.NewHistoricalCandles  += (seri, candy) =>
                {
                    int cou = seri.GetCandleCount();
                    if (seri.Security.Code == _lkoh.Code)
                    {
//                            ÷ñÒ799988810êÖ0õæ÷http://stocksharp.com/fo...hi--ghrafiki--istoriia/
÷ñÒ799988810êÖ1õæ÷
                             
                            TimeSpan ts = seri.GetCandle<Candle>(0).OpenTime - GlobalParameters.lkohTimeLoad;
                            if (ts.TotalMinutes == 1)  // получена одна свеча: все как положено, без сбоев   
                            {
                                GlobalParameters.lkohTimeLoad = seri.GetCandle<Candle>(0).OpenTime;
                                _lkCandle = seri.GetCandle<Candle>(0);

                                SafeAddToTxb(txtSmartInfo, DateTime.Now.ToString() + " | " + _lkCandle.OpenTime.ToString() + " | " + _lkCandle.CloseTime.ToString() + " | " + _lkCandle.OpenPrice.ToString() + " | " + _lkCandle.HighPrice.ToString() + " | " + _lkCandle.LowPrice.ToString() + " | " + _lkCandle.ClosePrice.ToString());

// далее выполняется повторный запрос последних 10 свечей (для выявления ошибки)
                                DateTime date1 = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 10, 0, 0);
                                _trader.RegisterHistoryCandles(_lkoh, SmartTimeFrames.Minute1, DateTime.Now, 10, SmartHistoryDirections.Backward);
                            }
                            else if (ts.TotalMinutes > 1)  // был разрыв связи или еще какой-то сбой или самое начало работы
                            {
                                int i = 1;
                                try
                                {
                                    while (seri.GetCandle<Candle>(i).OpenTime > GlobalParameters.lkohTimeLoad)
                                    {
                                        i = i + 1;
                                    }
                                }
                                catch { }
                                GlobalParameters.lkohTimeLoad = seri.GetCandle<Candle>(0).OpenTime;

                                i = i - 1;
                                while (i >= 0)
                                {
                                    _lkCandle = seri.GetCandle<Candle>(i);

                                    SafeAddToTxb(txtSmartInfo, DateTime.Now.ToString() + " | " + _lkCandle.OpenTime.ToString() + " | " + _lkCandle.CloseTime.ToString() + " | " + _lkCandle.OpenPrice.ToString() + " | " + _lkCandle.HighPrice.ToString() + " | " + _lkCandle.LowPrice.ToString() + " | " + _lkCandle.ClosePrice.ToString());

                                    i = i - 1;
                                }
                            }
                            else  // вывод на экран данных, полученных в результате выполнения _trader.RegisterHistoryCandles выше
                            {
                                _lkCandle = seri.GetCandle<Candle>(0);

                                SafeAddToTxb(txtSmartInfo, "Пришел повтор: " + DateTime.Now.ToString() + " | " + _lkCandle.OpenTime.ToString() + " | " + _lkCandle.CloseTime.ToString() + " | " + _lkCandle.OpenPrice.ToString() + " | " + _lkCandle.HighPrice.ToString() + " | " + _lkCandle.LowPrice.ToString() + " | " + _lkCandle.ClosePrice.ToString());
                            }
                    }


Спасибо:

andy_baka

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


Под нативными я имел ввиду вызов именно RegisterHistoryCandles. Совсем до вызовов SmartCom пока не дошло.
Не много не по стартовому вопросу, но это именно та ситуация с которой я столкнулся -
я пока не понял как сделать такую вещь:
1. Получить сигнал об окончании свечи от CandleSeries, например по событию

_candleSeries.WhenCandlesFinished()
.Do(OnCandlesFinished)
.Apply();
2. Далее, в обработчике OnCandlesFinished уже вызвать RegisterHistoryCandles, заказать сколько надо исторических свечек от SmartCom и спокойно их обработать в
в обработчике на который подписываются например так: _trader.NewHistoricalCandles += OnNewHistoricalCandles;

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

Спасибо:

andy_baka

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


Проверил. Получается, что теперь (с какой версии не скажу, не знаю, но в 4.0.9 эти события еще работали отдельно)
обработка вызова RegisterHistoryCandles проходит через обработчик событий формирования новой свечи CandleSeries,
а потом, если была подписка, вызывается уже NewHistoricalCandles.
Михаил, это как раз то что я с Иваном Бухариным несколько дней обсуждал.
Реализовать не получилось и теперь не понятно как разделять потоки свечей в этом обработчике.
Спасибо:

Mikhail Sukhov

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


Переписка выдалась запутанной, судя по всему каждый пишет о своем.

Давайте поступим следующим образом - пойдем от простого к сложному. Запустите SampleCandles и проверьте, пожалуйста, работу.
Спасибо:

ttt

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


Михаил,

Сегодня с утра (24.06.2013) и SampleCandles, и моя программа показывают правильные(!!!) свечи.
Свою программу программу поставил на весь день - собирать статистику: вечером сообщу о результатах.

Складывается впечатление, что S# строит "правильные" (совпадают с Finam'ом) свечи на "неинтенсивном" рынке (в понедельник с утра, на вечерней сессии,...)

Все же не понял:
1) Могу ли я при приходе события появления новой свечи выполнить какой-нибудь метод, который внутри себя вызовет GetBars?
2) Если это сделать можно, то в обработчике какого события надо отлавливать пришедшую в ответ на GetBars информацию?


Спасибо:

Mikhail Sukhov

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


ttt

Складывается впечатление, что S# строит "правильные" (совпадают с Finam'ом) свечи на "неинтенсивном" рынке (в понедельник с утра, на вечерней сессии,...)


В SampleCandles S# свечки не строит.
Спасибо:

ttt

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


За день 24.06.2013 по контракту Si-9.13:
Всего свечей = 578.
Ошибок (в сравнении с Finam'ом):
open = 0
high = 0
low = 1 ошибка: отличие на 1 пункт (рубль), свеча сформировалась в 15:46:00
close = 2 ошибки:
1-я: отличие на 2 пункта (рубля), свеча сформировалась в 11:23:00
2-я: отличие на 1 пункт (рубль), свеча сформировалась в 18:26:00
Спасибо:

ttt

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


Михаил,
сегодня (25.06.2013) SampleCandles в режиме Real-time строит на графике свечки с ошибками.
В моей программе также идут сплошные ошибки (сравниваю с Finam'ом).
После перезапуска программы свечки, которые в Real-time были с ошибками, становятся правильными (в точности совпадают с Finam'овскими данными).
Вот отчет с утра:
Всего 288 свечей.
Ошибки:
open = 0
high = 70 ошибок (от 1 до 21 пункта)
low = 63 ошибки (от -1 до -15 пунктов)
close = 234 ошибки (от -20 до 12 пунктов)

На прошлой неделе была такая же ситуация: один день свечи идут почти без ошибок, другой - почти в каждой свече ошибка.

Похоже, что когда где-то внутри S# делает запрос с помощью GetBars, то свечи получаются корректные. А вот когда свечи получаются как-то иначе, то свечи могут построиться как правильно, так и неправильно.

Предложение: возможно стоит в момент, когда приходит событие появления новой свечи, явно запросить с сервера свечи за требуемый промежуток времени. И далее работать уже с этими (точно корректными) свечами.
Спасибо:
1 2  >

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

loading
clippy