Тестирование 4.2.2.16. Вывод свечей на график.

Тестирование 4.2.2.16. Вывод свечей на график.
Atom
10.03.2014
romany4


Добрый вечер! Разъясните, пожалуйста, следующую ситуацию. Есть HistoryEmulationConnector. Есть свечи из бд (источник финам). Допустим такой набор

OPEN | HIGH | LOW | CLOSE | VOLUME | DATETIME_CANDLE 97.8000 | 98.2000 | 97.7500 | 98.0100 | 1505670 | 2013-10-01 10:00:00 98.0600 | 98.1100 | 97.8800 | 98.0000 | 1208190 | 2013-10-01 10:05:00 98.0000 | 98.1600 | 97.9500 | 98.0000 | 3890740 | 2013-10-01 10:10:00 98.0000 | 98.0500 | 98.0000 | 98.0400 | 99520 | 2013-10-01 10:15:00 ...

Свечи формируются следующим образом


var time = DateTime.ParseExact(candle.DatetimeCandle, "dd.MM.yyyy HH:mm:ss", null);
return new TimeFrameCandle()
{
    OpenPrice = candle.Open,
    HighPrice = candle.High,
    LowPrice = candle.Low,
    ClosePrice = candle.Close,
    TimeFrame = timeFrameCandle,
    OpenTime = time,
    CloseTime = time + timeFrameCandle,
    TotalVolume = candle.Volume,
    Security = security,
    State = CandleStates.Finished
};

Если смотреть через дебаггер - то значения соответствуют тем, что выше.

  1. Но вот при отрисовке свечей их OPEN и CLOSE значения изменяются. Изменяются они не намного, но все же мне пока не понятно по какому принципу это происходит.
  2. И еще - все первые свечи (10:00:00) каждого дня при отрисовке имеют OPEN = HIGH = LOW = CLOSE, что, например, не соответствует данным, указанным выше. (Для первого набора, например, эти значения равны 97,8)

Буду благодарен, если кто-то объяснит почему так происходит.




Спасибо:


1 2  >
Bond

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


Добрый день! К сведению, некоторые особенности формирования свечей из тиков:

  • Свечи закрываются первой сделкой из следующей свечи. Так может возникнуть запаздывание события закрытия свечи.
  • В первой свече может возникнуть неопределенность и, в принципе, по алгоритму может формироваться новая свеча только когда закроется первая. Но это нужно смотреть алгоритм.

Изменяются они не намного Уточните конкретнее о чем речь.

Вам лучше по шагам просмотреть как парсится текстовый файл. Тогда сразу будет все понятно.

Спасибо:

romany4

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


Добрый день.

Уточните конкретнее о чем речь. Есть уже готовые свечи в бд. Хранятся они в таком виде:

OPEN | HIGH | LOW | CLOSE | DATETIME_CANDLE 97.8000 | 98.2000 | 97.7500 | 98.0100 | 2013-10-01 10:00:00 98.0600 | 98.1100 | 97.8800 | 98.0000 | 2013-10-01 10:05:00 98.0000 | 98.1600 | 97.9500 | 98.0000 | 2013-10-01 10:10:00 98.0000 | 98.0500 | 98.0000 | 98.0400 | 2013-10-01 10:15:00

Данные из бд получаю и сохраняю в IEnumerable<Candle> candles Если смотреть candles через дебаггер - то все нормально - данные те же самые.
Далее я их сохраняю в StorageRegistry, который в свою очередь используется в HistoryEmulationConnector И вот если через дебаг смотреть уже метод DrawCandle то там будут такие значения

OPEN | HIGH | LOW | CLOSE | DATETIME_CANDLE 97.8000 | 98.8000 | 97.8000 | 98.8000 | 2013-10-01 10:00:00 97.7500 | 98.2000 | 97.7500 | 98.0600 | 2013-10-01 10:05:00 98.1100 | 98.1100 | 97.8800 | 98.0000| 2013-10-01 10:10:00 98.1600 | 98.1600 | 97.9500 | 98.0000 | 2013-10-01 10:15:00 98.0000 | 98.0500 | 98.0000 | 98.0400 | 2013-10-01 10:20:00

Т.е. получается так. Первая свеча формируется из OPEN. При этом OPEN = HIGH = LOW = CLOSE. Для остальных свечей HIGH и LOW соответствуют первоначальным значениям (что и в бд). А вот OPEN и CLOSE не намного изменяются, и изменяются они не везде, но в большинстве случаев.

Спасибо:

Bond

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


Приведите полный код преобразований. Здесь явно какая-то ошибка.

Спасибо:

romany4

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


Так получаю свечи


IEnumerable<Candle> candles = instanceCandle.GetHistoryCandle(_security, _fromDate.ToMysqlTimestampFormat(), _toDate.ToMysqlTimestampFormat(), timeFrameCandle);

если смотреть через дебаг - candles содержит тот же набор что и в бд.

теперь сохраняю в StorageRegistry, затем создаю HistoryEmulationConnector, и вывожу свечи


var registry = new StorageRegistry();
registry.GetCandleStorage(typeof(TimeFrameCandle), _security, timeFrameCandle).Save(candles);
// тестовый портфель
var portfolio = new Portfolio
{
    Name = "test account",
    BeginValue = 10000,
};

//шлюз для эмуляции
var trader = new HistoryEmulationConnector(
    new[] { _security },
    new[] { portfolio })
{
    StorageRegistry = registry,
    MarketEmulator =
    {
        Settings =
        {
            // использовать свечки
            UseCandlesTimeFrame = timeFrameCandle,
            MatchOnTouch = false,
        }
    }
};
trader.MarketDataAdapter.SessionHolder.MarketTimeChangedInterval = TimeSpan.FromSeconds(10);

trader.NewSecurities += securities =>
{
    if (securities.All(s => s != _security))
        return;

    trader.RegisterMarketDepth(new TrendMarketDepthGenerator(trader.GetSecurityId(_security))
    {
        // стакан для инструмента в истории обновляется раз в секунду
        Interval = TimeSpan.FromSeconds(1),
        MaxAsksDepth = 1,
        MaxBidsDepth = 1,
        UseTradeVolume = true,
        MaxVolume = 1,
        MinSpreadStepCount = 2,
        MaxSpreadStepCount = 5,
        MaxPriceStepCount = 3
    });
};
trader.Connect();
trader.StartExport();

_candleManager = new CandleManager(trader);

_series = new CandleSeries(typeof(TimeFrameCandle), _security, timeFrameCandle);
                                
_area = new ChartArea();
Chart.Areas.Add(_area);

//создание элемента графика представляющего свечки
_candlesElem = new ChartCandleElement();
_area.Elements.Add(_candlesElem);

_series.ProcessCandle += DrawCandle;

Вот собственно весь код.

И вот еще сам метод DrawCandle

private void DrawCandle(Candle candle)
{
    this.GuiAsync(() => Chart.ProcessCandle((ChartCandleElement)Chart.Areas[0].Elements[0], candle));
}

Спасибо:

Bond

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


Вы берете текстовый файл с данными свечи. Потом его парсите и сохраняете в хранилище. Потом берете из хранилища сохраненные свечи(!). При этом используете генератор стакана! Затем создаете свечи из приходящих сделок (скорее всего случайные из стакана. Здесь появляются отличия.) [laugh] Я даже не знаю как эту схему еще больше можно усложнить) Берете свечи - используйте свечи. Торгуете тики и стаканы - используйте тики и стаканы. От себя советую не использовать никакие генераторы - это бред. Торгуйте свечи или тики. Нужны стаканы - берите ордер лог. Данные качайте Гидрой и не забиыайте себе голову всякими ненужными преобразованиями.

Спасибо:

romany4

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


Спасибо за советы) Намудрил) Тогда подскажите, правильно ли я понимаю, что могу исключить этот блок кода


trader.NewSecurities += securities =>
                                {
                                    if (securities.All(s => s != _security))
                                        return;
                                    trader.RegisterMarketDepth(new TrendMarketDepthGenerator(trader.GetSecurityId(_security))
                                    {
                                        // стакан для инструмента в истории обновляется раз в секунду
                                        Interval = TimeSpan.FromSeconds(1),
                                        MaxAsksDepth = 1,
                                        MaxBidsDepth = 1,
                                        UseTradeVolume = true,
                                        MaxVolume = 1,
                                        MinSpreadStepCount = 2,
                                        MaxSpreadStepCount = 5,
                                        MaxPriceStepCount = 3
                                    });
                                };

скорее всего случайные из стакана. Здесь появляются отличия Почему тогда эта случайность одна и та же? или тут речь о псевдослучайности?

PS Закомментил пока этот код у себя. Но результат тот же.

Спасибо:

romany4

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


Собственно в продолжение темы решил данные выкачать гидрой и проверить.

  1. Для сравнения выкачиваем данные с финама вручную (тыц) (Сбербанк, с 01.10.2013 по 01.12.2013, 5мин. свечи) - это будет эталон, на который будем ориентироваться.
  2. С помощью гидры также выкачиваем Сбер за аналогичный период. (только пятиминутные свечи, без сделок)
  3. Протестируем данные гидры на SampleHistoryTesting (4.2.2.16)
  4. Проверим данные, записанные в лог и сравним их с тем, что прислал финам Вот что я вижу - финам
<TICKER>;<PER>;<DATE>;<TIME>;<OPEN>;<HIGH>;<LOW>;<CLOSE>;<VOL> SBER;5;20131001;100000;97.8000000;98.2000000;97.7500000;98.0100000;1505670 SBER;5;20131001;100500;98.0600000;98.1100000;97.8800000;98.0000000;1208190 SBER;5;20131001;101000;98.0000000;98.1600000;97.9500000;98.0000000;3890740 SBER;5;20131001;101500;98.0000000;98.0500000;98.0000000;98.0400000;99520 SBER;5;20131001;102000;98.0400000;98.3500000;98.0400000;98.2000000;1323520 SBER;5;20131001;102500;98.1900000;98.6400000;98.1600000;98.4100000;2353380 SBER;5;20131001;103000;98.4300000;98.6200000;98.3000000;98.3500000;1511960 SBER;5;20131001;103500;98.3900000;98.4000000;98.2500000;98.3000000;558720 SBER;5;20131001;104000;98.3500000;98.4400000;98.2600000;98.3000000;715980 SBER;5;20131001;104500;98.3100000;98.3900000;98.2000000;98.2100000;316160 SBER;5;20131001;105000;98.2200000;98.2800000;98.0700000;98.1100000;890210 SBER;5;20131001;105500;98.1200000;98.2800000;98.0300000;98.1700000;892270

лог с SampleHistoryTesting

2013/10/01 00:00:00.000| |SS_SBER@EQBR_test account|Стратегия запущена. [0,-1]. Позиция при старте 0. 2013/10/01 00:00:00.000| |HistoryEmulationConnector|Инструмент SBER@EQBR зарегистрирован на получение рыночных данных для Candles. 2014/03/15 12:44:13.945| |HistoryMessageAdapter|Loading 01.10.2013 0:00:00 Events: 0 2014/03/15 12:44:14.096| |HistoryMessageAdapter|Loading 02.10.2013 0:00:00 Events: 212 2014/03/15 12:44:14.102| |HistoryMessageAdapter|Loading 03.10.2013 0:00:00 Events: 424 2014/03/15 12:44:14.107| |HistoryMessageAdapter|Loading 04.10.2013 0:00:00 Events: 636 2013/10/01 10:05:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:00:00: 97.8000000;97.8000000;97.8000000;97.8000000; объем 376417 2014/03/15 12:44:14.421| |HistoryMessageAdapter|Loading 05.10.2013 0:00:00 Events: 848 2014/03/15 12:44:14.425| |HistoryMessageAdapter|Loading 06.10.2013 0:00:00 Events: 848 2014/03/15 12:44:14.427| |HistoryMessageAdapter|Loading 07.10.2013 0:00:00 Events: 848 2013/10/01 10:10:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:05:00: 97.7500000;98.2000000;97.7500000;98.0600000; объем 1431300 2013/10/01 10:15:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:10:00: 98.1100000;98.1100000;97.8800000;98.0000000; объем 1878828 2013/10/01 10:20:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:15:00: 98.1600000;98.1600000;97.9500000;98.0000000; объем 2942935 2013/10/01 10:25:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:20:00: 98.0000000;98.0500000;98.0000000;98.0400000; объем 405520 2013/10/01 10:30:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:25:00: 98.0400000;98.3500000;98.0400000;98.1900000; объем 1580985 2013/10/01 10:35:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:30:00: 98.1600000;98.6400000;98.1600000;98.4300000; объем 2143025 2013/10/01 10:40:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:35:00: 98.6200000;98.6200000;98.3000000;98.3900000; объем 1273650 2013/10/01 10:45:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:40:00: 98.4000000;98.4000000;98.2500000;98.3500000; объем 598035 2013/10/01 10:50:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:45:00: 98.4400000;98.4400000;98.2600000;98.3100000; объем 616025 2013/10/01 10:55:00.000| |SS_SBER@EQBR_test account|Новая свеча 10/01/2013 10:50:00: 98.3900000;98.3900000;98.2000000;98.2200000; объем 459672

Наблюдаются те же самые расхождения. Совпадают только HIGH и LOW цены.

Спасибо:

Bond

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


Сбросьте ВСЕ файлы, включая ваш пример и исторические данные в одном архиве на почту bond_algotrade@mail.ru Найдем, где собака зарыта.

Спасибо:

devruss

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


Bond: От себя советую не использовать никакие генераторы - это бред.

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

Спасибо:

devruss

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


romany4: Наблюдаются те же самые расхождения. Совпадают только HIGH и LOW цены.

У финама дырявые данные. НО бесплатные=))) Доверять можно только данным записанным вживую с рынка, и то, с определенным скептицизмом (latency, рассинхронизация на очень маленьких таймфреймах и т.д.)

Спасибо:
1 2  >

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

loading
clippy