← 返回

Метод Chart.Draw(StockSharp.Xaml.Charting.ChartDrawData data)

При запуске этого метода выдается исключение: InvalidOperationException. Если же использовать старый метод (закомментированные строки), то все работает правильно. StockSharp rev. 4.3.19.5; 4.3.21 Draw_invalidOperationException.png

Как это лечится?

本主题对您有帮助吗?

分享主题

评论 (46)

登录创建账户, 登录或注册以发表评论

Support
Support

Свечи из коннектора идут или исторические свечи?

swnike
swnike 作者

Свечи идут из коннектора.

Support
Support

Ошибка эта постоянно повторяется или иногда бывает?

swnike
swnike 作者

Ошибка присутствует постоянно.

Support
Support

У меня эта ошибка не воспроизводится... От Вас нужно 1) полный код программы, 2) для каких инструментов строить график... 3) от какого брокера данные?

swnike
swnike 作者

Проект взят из набора "StockSharp.Edu_4.3.19.5\04_lesson (Candles, Charts, Historical data)\CandlesChartProject". При запуске из урока ошибка та же самая, что описана выше. Модифицированный вариант: 1)Проект копируется в отдельную папку. ("CandlesChartProject"). Корректируется пространство имен. 2) Visual Studio 2015 -> Сборка -> Очистить Решение. 3) Ссылки заменены на новые из папки Reference библиотеки StockSharp rev 4.3.21 4) Visual Studio 2015 -> Сборка -> Пересобрать Решение. 5) в основном файле добавлено логирование и выполнена корректировка кода. 6) файл стратегии и индикатора не менялся 7) Брокер - Финам; Инструмент - SiH7@FORTS, SBER@TQBR 8) Программа запускалась на машине с win7 и win10. Исключения разные:

Exception_win7_20170306.png

exception_win10_20170306.png

Если необходимо, могу выслать папку проекта.


using System;
using MoreLinq;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using Ecng.Xaml;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Indicators;
using StockSharp.Quik;
using StockSharp.TraderConnection;
using StockSharp.Messages;
using StockSharp.Algo;
using StockSharp.Xaml.Charting;
using StockSharp.Logging;
using StockSharp.Xaml;
using Ecng.Serialization;


namespace CandlesChartProject
{

    // Изменения в коде относительно видеоурока
    // ------------------------------------------------------------------------------------------
    // Теперь отрисовка элементов графика выполняется
    // при помощи метода Chart.Draw. Методы Chart.ProcessValues и Chart.ProcessCandles - устарели.   
    // Метод TimeFrame.GetCandleBounds(Security) больше не используется, нужно использовать одну из новых перегрузок
    // TimeFrame.GetCandleBounds(DateTime), TimeFrame.GetCandleBounds(DateTime, ExchangeBoard), TimeFrame.GetCandleBounds(DateTime, WorkingTime)

    public partial class MainWindow : Window
    {
        private CandleManager _candleManager;
        private CandleSeries _candleSeries;

        private ChartArea _chartArea1;
        private ChartArea _chartArea2;

        private ChartCandleElement _chartCandleElement;
        private ChartIndicatorElement _chartIndicatorSmaElement;
        private ChartIndicatorElement _chartIndicatorMyElement;
        private ChartTradeElement _chartTradeElement;
        private ChartOrderElement _chartOrderElement;

        private SimpleMovingAverage _indicatorSma;
        private MyIndicator _indicatorMy;

        private SmaStrategy _smaStrategy;

        private ChartDrawData _data;

        public MainWindow()
        {
            InitializeComponent();

            ConnectionInterFace.SafeConnection = new SafeConnection(new QuikTrader(QuikTerminal.GetDefaultPath()));

            _logmanager.Listeners.Add(new GuiLogListener(_monitor));
            _logmanager.Listeners.Add(new FileLogListener("log.txt"));
            _logmanager.Sources.Add(ConnectionInterFace.SafeConnection.Trader);
            _monitor.Show();
        }

        MonitorWindow _monitor = new MonitorWindow();
        LogManager _logmanager = new LogManager();


        private void GetCandlesClick(object sender, RoutedEventArgs e)
        {
            _chartCandleElement = new ChartCandleElement();
            _chartArea1.Elements.Add(_chartCandleElement);

            _chartTradeElement = new ChartTradeElement();
            _chartArea1.Elements.Add(_chartTradeElement);

            _chartOrderElement = new ChartOrderElement();
            _chartArea1.Elements.Add(_chartOrderElement);

            InitIndicators();

            RunProcessGetCandles();

            InitStrategy();
        }

        private void RunProcessGetCandles()
        {
            _candleManager = new CandleManager(ConnectionInterFace.SafeConnection.Trader);

            var security = ConnectionInterFace.SelectedSecurity;

            var timeFrame = TimeSpan.FromMinutes(1);

            _candleSeries = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

            _candleManager.Processing += Draw;

            _logmanager.Sources.Add(_candleManager);

            _candleManager.Start(_candleSeries);
        }

        private void Draw(CandleSeries series, Candle candle)
        {
            
            //--------------
            var timeFrame = (TimeSpan) candle.Arg;
			var candleBounds = timeFrame.GetCandleBounds(DateTimeOffset.Now);
            //--------------

            var valueSma = _indicatorSma.Process(candle);
            //var chartValueSma = new ChartIndicatorValue(_indicatorSma, valueSma);

            var valueMy = _indicatorMy.Process(candle);
            //var chartValueMy = new ChartIndicatorValue(_indicatorMy, valueMy);

            //lastCandleTime = candle.CloseTime;

 

            if (candle.State == CandleStates.Finished || candle.OpenTime >= candleBounds.Min)
             {
                Debug.Print("Candle: {0}", candle);
                //var data = new 
                var dataItem = _data.Group(candle.OpenTime);
                dataItem.Add(_chartCandleElement, candle);
                dataItem.Add(_chartIndicatorSmaElement, valueSma);
                dataItem.Add(_chartIndicatorMyElement, valueMy);

                this.GuiAsync(() => Chart.Draw(_data));

                //this.GuiAsync(() => Chart.Draw(candle.OpenTime, new Dictionary<IChartElement, object>
                //    {
                //        {_chartCandleElement, candle},
                //        {_chartIndicatorSmaElement, valueSma},
                //        {_chartIndicatorMyElement, valueMy}
                //    }));



            }
        }
        
        private void InitChart()
        {
            _data = new ChartDrawData();

            Chart.IsAutoScroll = true;

            _chartArea1 = new ChartArea();
            Chart.Areas.Add(_chartArea1);

            _chartArea2 = new ChartArea();
            Chart.Areas.Add(_chartArea2);
        }

        private void WindowLoaded(object sender, RoutedEventArgs e)
        {
            InitChart();
        }

        private void InitIndicators()
        {
            _indicatorSma = new SimpleMovingAverage
                {
                    Length = 10
                };

            _chartIndicatorSmaElement = new ChartIndicatorElement
                {
                    Title = "SMA",
                    Color = Colors.BlueViolet,
                    //Indicator = _indicatorSma
                };

            _chartArea1.Elements.Add(_chartIndicatorSmaElement);


            _indicatorMy = new MyIndicator();

            _chartIndicatorMyElement = new ChartIndicatorElement
                {
                    Title = "My Indicator",
                    Color = Colors.Blue,
                    //Indicator = _indicatorMy
                };

            _chartArea2.Elements.Add(_chartIndicatorMyElement);
        }

        private void InitStrategy()
        {
            _smaStrategy = new SmaStrategy(_indicatorSma, _candleSeries)
                {
                    Connector = ConnectionInterFace.SafeConnection.Trader,
                    Security = ConnectionInterFace.SelectedSecurity,
                    Portfolio = ConnectionInterFace.SelectedPortfolio,
                    Volume = 1
                };

            _smaStrategy.SetCandleManager(_candleManager);

            var timeFrame = TimeSpan.FromMinutes(1);

            _smaStrategy.WhenNewMyTrade()                       //WhenNewMyTrades()
                        .Do(mytrade => this.GuiAsync(() =>
                        {
                            var dataItem = _data.Group(timeFrame.GetCandleBounds(mytrade.Trade.Time.DateTime).Min);
                            dataItem.Add(_chartTradeElement, mytrade);
                            //mytrades.ForEach(t => 
                            //{
                            //    var dataItem = _data.Group(timeFrame.GetCandleBounds(t.Trade.Time.DateTime).Min);
                            //    dataItem.Add(_chartTradeElement, t);
                            //});
                            Chart.Draw(_data);
                        }
                        )).Apply();

            _smaStrategy.WhenOrderRegistered()
                        .Do(order => this.GuiAsync(() =>
                            {
                                var dataItem = _data.Group(order.Time);
                                dataItem.Add(_chartOrderElement, order);
                                Chart.Draw(_data);
                            }))
                        .Apply();

            _logmanager.Sources.Add(_smaStrategy);

            _smaStrategy.Start();
        }
    }
}


Support
Support

Прежде чем дальше будем разбираться, вот эту часть candle.OpenTime >= candleBounds.Min из кода уберите и проверьте

swnike
swnike 作者

Проверил сегодня на SiH7@FORTS. Результат тот же - возникает исключение. MainWindow.xaml.cs Exception_20170307.png

Support
Support

У Вам местное время московское?

swnike
swnike 作者

Нет. Опережает на 2 часа Москву.

Support
Support

У Вас эта ошибка из-за разницы во времени.. Ищите места где локальное время с биржевым может быть перепутано...

Матильда
Матильда

У меня тот же вопрос. Время от московского не отличается, но появляются те же исключения, причем как на 4.3.19.5, так и на 4.3.21. Что-то решилось?

Support
Support

Т.е. вы на компе поставили московское время?

Матильда
Матильда

Ну да, как на компьютере операционку установил, так и стоит московское время.

Support
Support

Посмотрите, ваш комп автоматически на летнее время не перешел..

Матильда
Матильда

Нет, сейчас, скажем, 14:30.

Support
Support

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

Матильда
Матильда

Высылаю данные по минутным свечам и появляющиеся исключения: Log.rtf. Интересно, но исключение, как выяснилось, появляется не на всех таймфреймах.

Support
Support

На минутках только?

Матильда
Матильда

Я не исследовал подробно, но исключение возникало далеко не только на минутках. Я пробовал таймфреймы от 10 секунд до часа, ошибок не было вроде бы только в диапазоне 10-40 секунд.

Support
Support

Я в логе ошибку не нашел.. Чем Вы этот лог пишете?

Матильда
Матильда

А вы до конца файл промотайте, там и ошибки. И их много.

Support
Support

16:35:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.17, H:34.2, L:34.17, C:34.2, V:4) 16:36:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.19, H:34.19, L:34.18, C:34.18, V:2) Невозможно изменить значение для свечи для даты 06.04.2017 2:56:00 +03:00 последнее добавленное значение для даты 06.04.2017 19:24:00.

Выведите в лог время свечи... (OpenTime)

Матильда
Матильда

Вывод устроен таким образом, что вызывающая исключение свеча находится в предшествующей строке. В указанном вами случае такой свечой является свеча 16:36:00.

Support
Support

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

Матильда
Матильда

Уточните, пожалуйста, какие данные кроме этих: 16:36:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.19, H:34.19, L:34.18, C:34.18, V:2) вам могут понадобиться?

Support
Support

22:47:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.29, H:34.29, L:34.29, C:34.29, V:1) 22:51:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.28, H:34.28, L:34.27, C:34.27, V:2) 22:56:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.28, H:34.28, L:34.28, C:34.28, V:1) 02:56:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.28, H:34.28, L:34.28, C:34.28, V:1) 15:50:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.32, H:34.32, L:34.32, C:34.32, V:1) 15:55:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.38, H:34.38, L:34.38, C:34.38, V:1) 16:20:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.5, H:34.5, L:34.5, C:34.5, V:1) 16:30:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.52, H:34.58, L:34.52, C:34.58, V:2) 16:32:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.57, H:34.57, L:34.57, C:34.57, V:1) 16:33:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.56, H:34.56, L:34.55, C:34.55, V:2) 16:35:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.54, H:34.54, L:34.5, C:34.5, V:5) 16:37:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.49, H:34.49, L:34.47, C:34.47, V:3) 16:39:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.46, H:34.46, L:34.46, C:34.46, V:1)

Вот смотрите... Фактически начинают приходить свечи, которые уже были раньше... Например, 02:56:00. Просто проставьте время, я хочу проанализировать весь поток свечей, которые приходят...

Матильда
Матильда

02:56:00 - не была раньше, в вашем примере она находится на своем месте между 22:56:00 и 15:50:00, хотя и нельзя отрицать, что это какая-то техническая непонятная свеча. Однако конкретно она и не вызывает ошибки. Хотелось бы понять, что именно приводит к исключению "Невозможно изменить значение для свечи для даты..." Перезапись новой свечи на место старой или что-то другое?

Support
Support

Как же нет, посмотрите время в первой ошибке...

Матильда
Матильда

Первая свеча, вызывающая ошибку, это свеча 16:32:00, во время которой, похоже, зачем-то происходит попытка перезаписать первую в сутках свечу 02:56:00. Вторая ошибка - свеча 16:35:00, которая пытается перезаписать вторую в сутках свечу - 15:22:00. Третья ошибка пытается переписать третью в сутках свечу и т.д. То есть дело не в конкретной свече, а в системе записи, когда новые свечи по какой-то причине стремятся записаться не в конец, а поверх старых. В чем тут может быть сбой?

Support
Support

Еще раз... 1. Если Вы хотите. чтобы решили Вашу проблему сделайте то, что я сказал... Более того выведите в лог время открытия и время закрытия свечи... 2. Вы говорили, что это свечи реалтайм из коннектора, тогда откуда у Вас данные за предыдущие дни и пропуски в данных?

Матильда
Матильда

Ладно, спасибо, видимо, мы не понимаем друг друга. Вероятно, позже я переформулирую проблему.

Support
Support

Ок.

Prival
Prival

Подтверждаю первый пост в этой теме. версия 4.3.19.5 Квик 7.9.1.1 Пример CandlesChartProject (находится в 4-ом уроке) ничего не меняю, просто запускаю выбивает ошибку вот на этой строке this.GuiAsync(() => Chart.Draw(_data));

Если снять коментарии

                //this.GuiAsync(() => Chart.Draw(_data));

                this.GuiAsync(() => Chart.Draw(candle.OpenTime, new Dictionary<IChartElement, object>
                    {
                        {_chartCandleElement, candle},
                        {_chartIndicatorSmaElement, valueSma},
                        {_chartIndicatorMyElement, valueMy}
                    }));

То начинает рисовать. Это единственный пример рабочий который смог найти, задача нужен вывод реалтайм свечек.

Пример из 4.3.23 SampleQuikCandles не ищет инструменты, не понимаю почему. Буду конечно сам дальше разбираться, но может кто то поделится примером как правильно выводить реал тайм свечки на график, нужен вывод RIM7 и Индекса MICEX

VassilSanych
VassilSanych

В представленном тексте трейса на скриншоте видно, что время перепутано в Charting.dll (добавленное значение логируется без коррекции, а значение времени на свече - с коррекцией)

Support
Support

Ок,понятно.. Проверю и передам эту проблему разработчикам...

Support
Support

Не могу воспроизвести ошибку... Посылаю Вам пример... Попробуйте получить Вашу ошибку при его помощи...

Prival
Prival

Мне не удалось запустить ваш пример FirstChart.7z, использовал 4.3.23

Support
Support

Такая Xceed.Wpf.Toolkit.dll библиотека в референсах есть?

Support
Support

Если exeed есть? то в проектном файле
Эти строки:

<Reference Include="Xceed.Wpf.Toolkit, Version=2.6.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\..\StockSharp\StockSharp_4.3.19.5_ru\References\Xceed.Wpf.Toolkit.dll</HintPath>
</Reference>

надо поменять на эти

<Reference Include="Xceed.Wpf.Toolkit" >
  <SpecificVersion>False</SpecificVersion>
  <HintPath>..\..\StockSharp\StockSharp_4.3.19.5_ru\References\Xceed.Wpf.Toolkit.dll</HintPath>
</Reference>
Prival
Prival
  1. Попробовал заменить на <Reference Include="Xceed.Wpf.Toolkit" >.....непомогло, таже ошибка выскакивала
  2. закрыл студию, удалил папки bin и obj....открыл проект, запустил, все собралось без ошибок и запустилось. Но график не строится...(((

Если нужно готов предоставить удалённый доступ к компу. Может так будет быстрее ? Я все время есть в скайпе privalov-sv

Support
Support

В CandleSeries вот так сделайте: var series = new CandleSeries(typeof (TimeFrameCandle), security, timeFrame) ;

Prival
Prival

Support: В CandleSeries вот так сделайте: var series = new CandleSeries(typeof (TimeFrameCandle), security, timeFrame) ;

Спасибо. Для TimeFrameCandle работает, для TickCandle тоже работает. Для RangeCandle не получается (((

_series = new CandleSeries(typeof(RangeCandle), SecurityEditor.SelectedSecurity, 100) ;

как для этого типа свечек поступать ? Они не строятся ((

Матильда
Матильда

К сожалению, для версии 4.3.19.5 это неприменимо.

Support
Support

BuildCandlesMode = BuildCandlesModes.Build нужно делать только для последней версии, для 4.3.19.5 не нужно...

Support
Support

Проверим.