При запуске этого метода выдается исключение: InvalidOperationException.
Если же использовать старый метод (закомментированные строки), то все работает правильно.
StockSharp rev. 4.3.19.5; 4.3.21
Проект взят из набора "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. Исключения разные:
Если необходимо, могу выслать папку проекта.
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();
}
}
}
Я не исследовал подробно, но исключение возникало далеко не только на минутках. Я пробовал таймфреймы от 10 секунд до часа, ошибок не было вроде бы только в диапазоне 10-40 секунд.
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.
Вывод устроен таким образом, что вызывающая исключение свеча находится в предшествующей строке. В указанном вами случае такой свечой является свеча 16:36:00.
Вот смотрите... Фактически начинают приходить свечи, которые уже были раньше... Например, 02:56:00.
Просто проставьте время, я хочу проанализировать весь поток свечей, которые приходят...
02:56:00 - не была раньше, в вашем примере она находится на своем месте между 22:56:00 и 15:50:00, хотя и нельзя отрицать, что это какая-то техническая непонятная свеча. Однако конкретно она и не вызывает ошибки. Хотелось бы понять, что именно приводит к исключению "Невозможно изменить значение для свечи для даты..." Перезапись новой свечи на место старой или что-то другое?
Первая свеча, вызывающая ошибку, это свеча 16:32:00, во время которой, похоже, зачем-то происходит попытка перезаписать первую в сутках свечу 02:56:00. Вторая ошибка - свеча 16:35:00, которая пытается перезаписать вторую в сутках свечу - 15:22:00. Третья ошибка пытается переписать третью в сутках свечу и т.д. То есть дело не в конкретной свече, а в системе записи, когда новые свечи по какой-то причине стремятся записаться не в конец, а поверх старых. В чем тут может быть сбой?
Еще раз... 1. Если Вы хотите. чтобы решили Вашу проблему сделайте то, что я сказал... Более того выведите в лог время открытия и время закрытия свечи... 2. Вы говорили, что это свечи реалтайм из коннектора, тогда откуда у Вас данные за предыдущие дни и пропуски в данных?
Подтверждаю первый пост в этой теме. версия 4.3.19.5 Квик 7.9.1.1
Пример CandlesChartProject (находится в 4-ом уроке) ничего не меняю, просто запускаю
выбивает ошибку вот на этой строке
this.GuiAsync(() => Chart.Draw(_data));
То начинает рисовать. Это единственный пример рабочий который смог найти, задача нужен вывод реалтайм свечек.
Пример из 4.3.23
SampleQuikCandles не ищет инструменты, не понимаю почему. Буду конечно сам дальше разбираться, но может кто то поделится примером как правильно выводить реал тайм свечки на график, нужен вывод RIM7 и Индекса MICEX
В представленном тексте трейса на скриншоте видно, что время перепутано в Charting.dll (добавленное значение логируется без коррекции, а значение времени на свече - с коррекцией)
コメント (46)
ログイン または アカウントを作成, コメントを残すにはログインまたは新規登録してください
Свечи из коннектора идут или исторические свечи?
Свечи идут из коннектора.
Ошибка эта постоянно повторяется или иногда бывает?
Ошибка присутствует постоянно.
У меня эта ошибка не воспроизводится... От Вас нужно 1) полный код программы, 2) для каких инструментов строить график... 3) от какого брокера данные?
Проект взят из набора "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. Исключения разные:
Если необходимо, могу выслать папку проекта.
Прежде чем дальше будем разбираться, вот эту часть candle.OpenTime >= candleBounds.Min из кода уберите и проверьте
Проверил сегодня на SiH7@FORTS. Результат тот же - возникает исключение. MainWindow.xaml.cs
У Вам местное время московское?
Нет. Опережает на 2 часа Москву.
У Вас эта ошибка из-за разницы во времени.. Ищите места где локальное время с биржевым может быть перепутано...
У меня тот же вопрос. Время от московского не отличается, но появляются те же исключения, причем как на 4.3.19.5, так и на 4.3.21. Что-то решилось?
Т.е. вы на компе поставили московское время?
Ну да, как на компьютере операционку установил, так и стоит московское время.
Посмотрите, ваш комп автоматически на летнее время не перешел..
Нет, сейчас, скажем, 14:30.
Тогда нужен лог, в котором показаны данные каждой свечи, и момент ошибки..
Высылаю данные по минутным свечам и появляющиеся исключения: Log.rtf. Интересно, но исключение, как выяснилось, появляется не на всех таймфреймах.
На минутках только?
Я не исследовал подробно, но исключение возникало далеко не только на минутках. Я пробовал таймфреймы от 10 секунд до часа, ошибок не было вроде бы только в диапазоне 10-40 секунд.
Я в логе ошибку не нашел.. Чем Вы этот лог пишете?
А вы до конца файл промотайте, там и ошибки. И их много.
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.
Я хочу полностью увидеть данные свечи со временем, чтобы понять откуда она берется..
Уточните, пожалуйста, какие данные кроме этих: 16:36:00 TimeFrameCandle_GM@SPFEQ_00:01:00 (O:34.19, H:34.19, L:34.18, C:34.18, V:2) вам могут понадобиться?
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, хотя и нельзя отрицать, что это какая-то техническая непонятная свеча. Однако конкретно она и не вызывает ошибки. Хотелось бы понять, что именно приводит к исключению "Невозможно изменить значение для свечи для даты..." Перезапись новой свечи на место старой или что-то другое?
Как же нет, посмотрите время в первой ошибке...
Первая свеча, вызывающая ошибку, это свеча 16:32:00, во время которой, похоже, зачем-то происходит попытка перезаписать первую в сутках свечу 02:56:00. Вторая ошибка - свеча 16:35:00, которая пытается перезаписать вторую в сутках свечу - 15:22:00. Третья ошибка пытается переписать третью в сутках свечу и т.д. То есть дело не в конкретной свече, а в системе записи, когда новые свечи по какой-то причине стремятся записаться не в конец, а поверх старых. В чем тут может быть сбой?
Еще раз... 1. Если Вы хотите. чтобы решили Вашу проблему сделайте то, что я сказал... Более того выведите в лог время открытия и время закрытия свечи... 2. Вы говорили, что это свечи реалтайм из коннектора, тогда откуда у Вас данные за предыдущие дни и пропуски в данных?
Ладно, спасибо, видимо, мы не понимаем друг друга. Вероятно, позже я переформулирую проблему.
Ок.
Подтверждаю первый пост в этой теме. версия 4.3.19.5 Квик 7.9.1.1 Пример CandlesChartProject (находится в 4-ом уроке) ничего не меняю, просто запускаю выбивает ошибку вот на этой строке this.GuiAsync(() => Chart.Draw(_data));
Если снять коментарии
То начинает рисовать. Это единственный пример рабочий который смог найти, задача нужен вывод реалтайм свечек.
Пример из 4.3.23 SampleQuikCandles не ищет инструменты, не понимаю почему. Буду конечно сам дальше разбираться, но может кто то поделится примером как правильно выводить реал тайм свечки на график, нужен вывод RIM7 и Индекса MICEX
В представленном тексте трейса на скриншоте видно, что время перепутано в Charting.dll (добавленное значение логируется без коррекции, а значение времени на свече - с коррекцией)
Ок,понятно.. Проверю и передам эту проблему разработчикам...
Не могу воспроизвести ошибку... Посылаю Вам пример... Попробуйте получить Вашу ошибку при его помощи...
Мне не удалось запустить ваш пример FirstChart.7z, использовал 4.3.23
Такая Xceed.Wpf.Toolkit.dll библиотека в референсах есть?
Если exeed есть? то в проектном файле
Эти строки:
надо поменять на эти
Если нужно готов предоставить удалённый доступ к компу. Может так будет быстрее ? Я все время есть в скайпе privalov-sv
В CandleSeries вот так сделайте: var series = new CandleSeries(typeof (TimeFrameCandle), security, timeFrame) ;
Спасибо. Для TimeFrameCandle работает, для TickCandle тоже работает. Для RangeCandle не получается (((
_series = new CandleSeries(typeof(RangeCandle), SecurityEditor.SelectedSecurity, 100) ;
как для этого типа свечек поступать ? Они не строятся ((
К сожалению, для версии 4.3.19.5 это неприменимо.
BuildCandlesMode = BuildCandlesModes.Build нужно делать только для последней версии, для 4.3.19.5 не нужно...
Проверим.