private void OnTimerTick(object sender, EventArgs e)
        {
            _yNext = _yNext + ((float)_random.NextDouble() - 0.5f);

            using (_xyDataSeries.SuspendUpdates())
            {
                if (_index == 999)
                {
                    // wrap around. Break the line with nan
                    _xyDataSeries.Append(_index + 1, float.NaN);
                    _index = 0;
                }

                _xyDataSeries.Update(_index++, _yNext);
            }
        }
        // The First method of updating a real-time chart: Updating Data Values
        private void Method1_UpdatingDataValues()
        {
            var scatterData = new XyDataSeries <double, double>();
            var lineData    = new XyDataSeries <double, double>();

            // Ensure that DataSeries are named for the legend
            scatterData.SeriesName = "Cos(x)";
            lineData.SeriesName    = "Sin(x)";
            for (int i = 0; i < 1000; i++)
            {
                lineData.Append(i, Math.Sin(i * 0.1));
                scatterData.Append(i, Math.Cos(i * 0.1));
            }
            LineSeries.DataSeries    = lineData;
            ScatterSeries.DataSeries = scatterData;
            // Start a timer to update our data
            double phase = 0.0;
            var    timer = new DispatcherTimer(DispatcherPriority.Render);

            timer.Interval = TimeSpan.FromMilliseconds(10);
            timer.Tick    += (s, e) =>
            {
                // SuspendUpdates() ensures the chart is frozen
                // while you do updates. This ensures best performance
                using (lineData.SuspendUpdates())
                    using (scatterData.SuspendUpdates())
                    {
                        for (int i = 0; i < 1000; i++)
                        {
                            // Updates the Y value at index i
                            lineData.Update(i, Math.Sin(i * 0.1 + phase));
                            scatterData.Update(i, Math.Cos(i * 0.1 + phase));
                        }
                    }
                phase += 0.01;
            };
            timer.Start();
        }
		/// <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();
		}
        private void UsePointMarkers_OnLoaded(object sender, RoutedEventArgs e)
        {
            var dataSeries1 = new XyDataSeries <double, double>()
            {
                SeriesName = "Ellipse Marker"
            };
            var dataSeries2 = new XyDataSeries <double, double>()
            {
                SeriesName = "Square Marker"
            };
            var dataSeries3 = new XyDataSeries <double, double>()
            {
                SeriesName = "Triangle Marker"
            };
            var dataSeries4 = new XyDataSeries <double, double>()
            {
                SeriesName = "Cross Marker"
            };
            var dataSeries5 = new XyDataSeries <double, double>()
            {
                SeriesName = "Sprite Marker"
            };

            const int dataSize = 30;
            var       rnd      = new Random();

            for (int i = 0; i < dataSize; i++)
            {
                dataSeries1.Append(i, rnd.NextDouble());
            }
            for (int i = 0; i < dataSize; i++)
            {
                dataSeries2.Append(i, 1 + rnd.NextDouble());
            }
            for (int i = 0; i < dataSize; i++)
            {
                dataSeries3.Append(i, 1.8 + rnd.NextDouble());
            }
            for (int i = 0; i < dataSize; i++)
            {
                dataSeries4.Append(i, 2.5 + rnd.NextDouble());
            }
            for (int i = 0; i < dataSize; i++)
            {
                dataSeries5.Append(i, 3.5 + rnd.NextDouble());
            }

            // insert a break into the line - we do this to test double.NaN for the point marker types
            dataSeries1.Update(dataSeries1.XValues[15], double.NaN);
            dataSeries2.Update(dataSeries1.XValues[15], double.NaN);
            dataSeries3.Update(dataSeries1.XValues[15], double.NaN);
            dataSeries4.Update(dataSeries1.XValues[15], double.NaN);
            dataSeries5.Update(dataSeries1.XValues[15], double.NaN);

            using (this.sciChart.SuspendUpdates())
            {
                this.lineSeries1.DataSeries = dataSeries1;
                this.lineSeries2.DataSeries = dataSeries2;
                this.lineSeries3.DataSeries = dataSeries3;
                this.lineSeries4.DataSeries = dataSeries4;
                this.lineSeries5.DataSeries = dataSeries5;
            }

            this.sciChart.ZoomExtents();
        }
        /// <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 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();
        }
		/// <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(() =>
			{
				// очищаем данные с предыдущего запуска скрипта
				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);
			});

			// получаем хранилище свечек
			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();
		}
        private void HandleTicks(List <Tick> list)
        {
            List <Tick> ticks = new List <Tick>();

            try
            {
                ticks = list.FindAll(i => i.Board == Board && i.Seccode == Seccode &&
                                     DateTime.Parse(i.Tradetime) > _lastCandle.TradeTime);
            }
            catch
            {
                if (_lastCandle == null)
                {
                    return;
                }
            }

            if (ticks.Count == 0)
            {
                return;
            }

            foreach (var tick in ticks)
            {
                var tickTime = DateTime.Parse(tick.Tradetime);
                try
                {
                    if ((tickTime - _lastCandle.TradeTime).TotalMinutes >= _timeframe)
                    {
                        if (OhlcDataSeries == null)
                        {
                            OhlcDataSeries = new OhlcDataSeries <DateTime, double>();
                        }
                        if (XyDataSeries == null)
                        {
                            XyDataSeries = new XyDataSeries <DateTime, int>();
                        }
                        OhlcDataSeries.Append(tickTime, tick.Price, tick.Price, tick.Price, tick.Price);
                        XyDataSeries.Append(tickTime, (int)tick.Price);
                        _lastCandle = new Candle //init last candle
                        {
                            Time  = tick.Tradetime,
                            Open  = tick.Price,
                            High  = tick.Price,
                            Low   = tick.Price,
                            Close = tick.Price
                        };
                    }
                    else //else we update the last one
                    {
                        //if (_lastCandle.Close == tick.Price)
                        //{
                        //    continue;
                        //}
                        _lastCandle.Close = tick.Price;
                        _lastCandle.High  = _lastCandle.High < tick.Price ? tick.Price : _lastCandle.High;
                        _lastCandle.Low   = _lastCandle.Low > tick.Price ? tick.Price : _lastCandle.Low;
                        if (Board == "FUT")
                        {
                            _lastCandle.Volume++;
                        }
                        else
                        {
                            _lastCandle.Volume += (int)tick.Price;
                        }
                        OhlcDataSeries?.Update(OhlcDataSeries.Count - 1, _lastCandle.Open, _lastCandle.High,
                                               _lastCandle.Low,
                                               _lastCandle.Close);
                        XyDataSeries?.Update(XyDataSeries.Count - 1, _lastCandle.Volume);
                    }
                }
                catch (Exception)
                {
                    if (_lastCandle == null)
                    {
                        return;
                    }
                    throw;
                }
            }
        }