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

Тестирование 4.2.2.16. Вывод свечей на график.
Atom
3/10/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)

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




Thanks:


1 2  >
Bond

Avatar
Date: 3/11/2014
Reply


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

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

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

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

Thanks:

romany4

Avatar
Date: 3/14/2014
Reply


Добрый день.

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

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 не намного изменяются, и изменяются они не везде, но в большинстве случаев.

Thanks:

Bond

Avatar
Date: 3/14/2014
Reply


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

Thanks:

romany4

Avatar
Date: 3/14/2014
Reply


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


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));
}

Thanks:

Bond

Avatar
Date: 3/14/2014
Reply


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

Thanks:

romany4

Avatar
Date: 3/14/2014
Reply


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


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 Закомментил пока этот код у себя. Но результат тот же.

Thanks:

romany4

Avatar
Date: 3/15/2014
Reply


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

  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 цены.

Thanks:

Bond

Avatar
Date: 3/15/2014
Reply


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

Thanks:

devruss

Avatar
Date: 3/15/2014
Reply


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

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

Thanks:

devruss

Avatar
Date: 3/15/2014
Reply


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

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

Thanks:
1 2  >

Attach files by dragging & dropping, , or pasting from the clipboard.

loading
clippy