/// <summary> /// To analyze. /// </summary> protected override void OnAnalyze() { var chart = Chart; var grid = Grid; var chartSeries = new XyzDataSeries <DateTime, double, double>(); ThreadSafeObservableCollection <GridRow> gridSeries = null; chart.GuiSync(() => { // clear prev values chart.RenderableSeries.Clear(); grid.Columns.Clear(); chart.RenderableSeries.Add(new FastBubbleRenderableSeries { ResamplingMode = ResamplingMode.Auto, BubbleColor = Colors.Chocolate, ZScaleFactor = 0.1, AutoZRange = true, DataSeries = chartSeries }); chart.XAxis = new DateTimeAxis { GrowBy = new DoubleRange(0.0, 0.1) }; chart.YAxis = new NumericAxis { GrowBy = new DoubleRange(0.1, 0.1) }; grid.AddTextColumn("Time", LocalizedStrings.Time).Width = 150; var volumeColumn = grid.AddTextColumn("Volume", LocalizedStrings.Volume); volumeColumn.Width = 100; var gridSource = new ObservableCollectionEx <GridRow>(); grid.ItemsSource = gridSource; gridSeries = new ThreadSafeObservableCollection <GridRow>(gridSource); grid.SetSort(volumeColumn, ListSortDirection.Descending); }); // get candle storage var storage = StorateRegistry.GetCandleStorage(typeof(TimeFrameCandle), Security, TimeFrame, format: StorageFormat); // get available dates for the specified period var dates = storage.GetDates(From, To).ToArray(); var rows = new Dictionary <TimeSpan, GridRow>(); foreach (var loadDate in dates) { // check if stopped if (ProcessState != ProcessStates.Started) { break; } // load candles var candles = storage.Load(loadDate); // groupping candles by open time var groupedCandles = candles.GroupBy(c => c.OpenTime.TimeOfDay.Truncate(TimeSpan.FromHours(1))); foreach (var group in groupedCandles.OrderBy(g => g.Key)) { // check if stopped if (ProcessState != ProcessStates.Started) { break; } var time = group.Key; // calc total volume for the specified time frame var sumVol = group.Sum(c => c.TotalVolume); var row = rows.TryGetValue(time); if (row == null) { // new volume level rows.Add(time, row = new GridRow { Time = time, Volume = sumVol }); // draw on chart chartSeries.Append(DateTime.Today + time, (double)sumVol, (double)sumVol / 1000); // draw on table gridSeries.Add(row); } else { // update existing volume level row.Volume += sumVol; // update chart chartSeries.Update(DateTime.Today + time, (double)row.Volume, (double)row.Volume / 1000); } } chart.GuiAsync(() => { // update grid sorting grid.RefreshSort(); // scale chart chart.ZoomExtents(); }); } // notify the script stopped Stop(); }
/// <summary> /// To analyze. /// </summary> protected override void OnAnalyze() { var chart = Chart; var grid = Grid; var chartSeries = new XyDataSeries <double, double>(); ThreadSafeObservableCollection <GridRow> gridSeries = null; chart.GuiSync(() => { // clear prev values chart.RenderableSeries.Clear(); grid.Columns.Clear(); chart.RenderableSeries.Add(new FastColumnRenderableSeries { ResamplingMode = ResamplingMode.None, DataPointWidth = 1, SeriesColor = Colors.Chocolate, DataSeries = chartSeries }); chart.XAxis = new NumericAxis { AxisTitle = LocalizedStrings.Price }; chart.YAxis = new NumericAxis { AxisTitle = LocalizedStrings.Volume, GrowBy = new DoubleRange(0, 0.1) }; grid.AddTextColumn("Price", LocalizedStrings.Price).Width = 150; var volumeColumn = grid.AddTextColumn("Volume", LocalizedStrings.Volume); volumeColumn.Width = 100; var gridSource = new ObservableCollectionEx <GridRow>(); grid.ItemsSource = gridSource; gridSeries = new ThreadSafeObservableCollection <GridRow>(gridSource); grid.SetSort(volumeColumn, ListSortDirection.Descending); }); // get candle storage var storage = StorateRegistry.GetCandleStorage(typeof(TimeFrameCandle), Security, TimeFrame, format: StorageFormat); // get available dates for the specified period var dates = storage.GetDates(From, To).ToArray(); var rows = new Dictionary <decimal, GridRow>(); foreach (var loadDate in dates) { // check if stopped if (ProcessState != ProcessStates.Started) { break; } // load candles var candles = storage.Load(loadDate); // groupping candles by candle's middle price var groupedCandles = candles.GroupBy(c => c.LowPrice + c.GetLength() / 2); foreach (var group in groupedCandles.OrderBy(g => g.Key)) { // check if stopped if (ProcessState != ProcessStates.Started) { break; } var price = group.Key; // calc total volume for the specified time frame var sumVol = group.Sum(c => c.TotalVolume); var row = rows.TryGetValue(price); if (row == null) { // new price level rows.Add(price, row = new GridRow { Price = price, Volume = sumVol }); // draw on chart chartSeries.Append((double)price, (double)sumVol); // draw on table gridSeries.Add(row); } else { // update existing price level row.Volume += sumVol; // update chart chartSeries.Update((double)price, (double)row.Volume); } } chart.GuiAsync(() => { // update grid sorting grid.RefreshSort(); // scale chart chart.ZoomExtents(); }); } // notify the script stopped Stop(); }
/// <summary> /// Анализировать. /// </summary> protected override void OnAnalyze() { var chart = Chart; var grid = Grid; var chartSeries = new XyzDataSeries <DateTime, double, double>(); ThreadSafeObservableCollection <GridRow> gridSeries = null; chart.GuiSync(() => { // очищаем данные с предыдущего запуска скрипта chart.RenderableSeries.Clear(); grid.Columns.Clear(); chart.RenderableSeries.Add(new FastBubbleRenderableSeries { ResamplingMode = ResamplingMode.Auto, BubbleColor = Colors.Chocolate, ZScaleFactor = 0.1, AutoZRange = true, DataSeries = chartSeries }); chart.XAxis = new DateTimeAxis { GrowBy = new DoubleRange(0.0, 0.1) }; chart.YAxis = new NumericAxis { GrowBy = new DoubleRange(0.1, 0.1) }; grid.AddTextColumn("Time", LocalizedStrings.Time).Width = 150; var volumeColumn = grid.AddTextColumn("Volume", LocalizedStrings.Volume); volumeColumn.Width = 100; var gridSource = new ObservableCollectionEx <GridRow>(); grid.ItemsSource = gridSource; gridSeries = new ThreadSafeObservableCollection <GridRow>(gridSource); grid.SetSort(volumeColumn, ListSortDirection.Descending); }); // получаем хранилище свечек var storage = StorateRegistry.GetCandleStorage(typeof(TimeFrameCandle), Security, TimeFrame, format: StorageFormat); // получаем набор доступных дат за указанный период var dates = storage.GetDates(From, To).ToArray(); var rows = new Dictionary <TimeSpan, GridRow>(); foreach (var loadDate in dates) { // проверяем флаг остановки if (ProcessState != ProcessStates.Started) { break; } // загружаем свечки var candles = storage.Load(loadDate); // группируем свечки по часовой отметке времени var groupedCandles = candles.GroupBy(c => c.OpenTime.TimeOfDay.Truncate(TimeSpan.FromHours(1))); foreach (var group in groupedCandles.OrderBy(g => g.Key)) { // проверяем флаг остановки if (ProcessState != ProcessStates.Started) { break; } var time = group.Key; // получаем суммарный объем в пределах часовой отметки var sumVol = group.Sum(c => c.TotalVolume); var row = rows.TryGetValue(time); if (row == null) { // пришел новый уровень - добавляем новую запись rows.Add(time, row = new GridRow { Time = time, Volume = sumVol }); // выводим на график chartSeries.Append(DateTime.Today + time, (double)sumVol, (double)sumVol / 1000); // выводит в таблицу gridSeries.Add(row); } else { // увеличиваем суммарный объем row.Volume += sumVol; // обновляем график chartSeries.Update(DateTime.Today + time, (double)row.Volume, (double)row.Volume / 1000); } } chart.GuiAsync(() => { // обновление сортировки в таблице grid.RefreshSort(); // автомасштабирование графика chart.ZoomExtents(); }); } // оповещаем программу об окончании выполнения скрипта base.Stop(); }
/// <summary> /// Анализировать. /// </summary> protected override void OnAnalyze() { var chart = Chart; var grid = Grid; var chartSeries = new XyDataSeries <double, double>(); ThreadSafeObservableCollection <GridRow> gridSeries = null; chart.GuiSync(() => { // очищаем данные с предыдущего запуска скрипта chart.RenderableSeries.Clear(); grid.Columns.Clear(); chart.RenderableSeries.Add(new FastColumnRenderableSeries { ResamplingMode = ResamplingMode.None, DataPointWidth = 1, SeriesColor = Colors.Chocolate, DataSeries = chartSeries }); chart.XAxis = new NumericAxis { AxisTitle = LocalizedStrings.Str123 }; chart.YAxis = new NumericAxis { AxisTitle = LocalizedStrings.Str87, GrowBy = new DoubleRange(0, 0.1) }; grid.AddTextColumn("Price", LocalizedStrings.Str123).Width = 150; var volumeColumn = grid.AddTextColumn("Volume", LocalizedStrings.Str87); volumeColumn.Width = 100; var gridSource = new ObservableCollectionEx <GridRow>(); grid.ItemsSource = gridSource; gridSeries = new ThreadSafeObservableCollection <GridRow>(gridSource); grid.SetSort(volumeColumn, ListSortDirection.Descending); }); // получаем хранилище свечек var storage = StorateRegistry.GetCandleStorage(typeof(TimeFrameCandle), Security, TimeFrame, format: StorageFormat); // получаем набор доступных дат за указанный период var dates = storage.GetDates(From, To).ToArray(); var rows = new Dictionary <decimal, GridRow>(); foreach (var loadDate in dates) { // проверяем флаг остановки if (ProcessState != ProcessStates.Started) { break; } // загружаем свечки var candles = storage.Load(loadDate); // группируем свечки по цене (середина свечи) var groupedCandles = candles.GroupBy(c => c.LowPrice + c.GetLength() / 2); foreach (var group in groupedCandles.OrderBy(g => g.Key)) { // проверяем флаг остановки if (ProcessState != ProcessStates.Started) { break; } var price = group.Key; // получаем суммарный объем в пределах ценового уровня за день var sumVol = group.Sum(c => c.TotalVolume); var row = rows.TryGetValue(price); if (row == null) { // пришел новый уровень - добавляем новую запись rows.Add(price, row = new GridRow { Price = price, Volume = sumVol }); // выводим на график chartSeries.Append((double)price, (double)sumVol); // выводит в таблицу gridSeries.Add(row); } else { // увеличиваем суммарный объем row.Volume += sumVol; // обновляем график chartSeries.Update((double)price, (double)row.Volume); } } chart.GuiAsync(() => { // обновление сортировки в таблице grid.RefreshSort(); // автомасштабирование графика chart.ZoomExtents(); }); } // оповещаем программу об окончании выполнения скрипта base.Stop(); }