public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            if (_timer == null)
            {
                _timer = NSTimer.CreateRepeatingScheduledTimer(0.01, (timer) =>
                {
                    for (var i = 0; i < 500; i++)
                    {
                        _lineDataSeries.UpdateYAt(i, Math.Sin(i * 0.1 + _phase));
                        _scatterDataSeries.UpdateYAt(i, Math.Cos(i * 0.1 + _phase));
                    }
                    _phase += 0.01;

                    _surface.InvalidateElement();
                });
            }
        }
        private void OnNewPrice(PriceBar price)
        {
            // Update the last price, or append?
            double smaLastValue;

            if (_lastPrice.DateTime == price.DateTime)
            {
                _ohlcDataSeries.Update(_ohlcDataSeries.Count - 1, price.Open, price.High, price.Low, price.Close);

                smaLastValue = _sma50.Update(price.Close).Current;
                _xyDataSeries.UpdateYAt(_xyDataSeries.Count - 1, smaLastValue);
            }
            else
            {
                _ohlcDataSeries.Append(price.DateTime, price.Open, price.High, price.Low, price.Close);

                smaLastValue = _sma50.Push(price.Close).Current;
                _xyDataSeries.Append(price.DateTime, smaLastValue);

                // If the latest appending point is inside the viewport (i.e. not off the edge of the screen)
                // then scroll the viewport 1 bar, to keep the latest bar at the same place
                var visibleRange = MainSurface.XAxes[0].VisibleRange;
                if (visibleRange.MaxAsDouble > _ohlcDataSeries.Count)
                {
                    visibleRange.SetMinMaxDouble(visibleRange.MinAsDouble + 1, visibleRange.MaxAsDouble + 1);
                }
            }

            Activity.RunOnUiThread(() =>
            {
                _ohlcAxisMarker.SetBackgroundColor((price.Close >= price.Open ? StrokeUpColor : StrokeDownColor).ToColor());
            });

            _ohlcAxisMarker.Y1Value = price.Close;
            _smaAxisMarker.Y1Value  = smaLastValue;

            _lastPrice = price;
        }
        private void OnNewPrice(PriceBar price)
        {
            InvokeOnMainThread(() =>
            {
                // Update the last price, or append?
                double smaLastValue;
                if (_lastPrice.DateTime == price.DateTime)
                {
                    _ohlcDataSeries.Update(_ohlcDataSeries.Count - 1, price.Open, price.High, price.Low, price.Close);

                    smaLastValue = _sma50.Update(price.Close).Current;
                    _xyDataSeries.UpdateYAt(_xyDataSeries.Count - 1, smaLastValue);
                }
                else
                {
                    _ohlcDataSeries.Append(price.DateTime, price.Open, price.High, price.Low, price.Close);

                    smaLastValue = _sma50.Push(price.Close).Current;
                    _xyDataSeries.Append(price.DateTime, smaLastValue);

                    // If the latest appending point is inside the viewport (i.e. not off the edge of the screen)
                    // then scroll the viewport 1 bar, to keep the latest bar at the same place
                    var xaxis        = Runtime.GetNSObject <SCICategoryDateTimeAxis>(MainSurface.XAxes[0].Handle);
                    var visibleRange = Runtime.GetNSObject <SCIDoubleRange>(xaxis.VisibleRange.Handle);
                    if (visibleRange.Max > _ohlcDataSeries.Count)
                    {
                        MainSurface.XAxes[0].VisibleRange = new SCIDoubleRange(visibleRange.Min + 1, visibleRange.Max + 1);
                    }
                }

                _ohlcAxisMarker.Style.BackgroundColor = (price.Close >= price.Open ? StrokeUpColor : StrokeDownColor).ToColor();

                _ohlcAxisMarker.Position = price.Close;
                _smaAxisMarker.Position  = smaLastValue;

                _lastPrice = price;
            });
        }