Exemple #1
0
        internal void UpdateValues()
        {
            Debug.Assert(_values.Count == _items.Count);

            _values.Start();
            foreach (InfoPanelItem item in _items)
            {
                Label label = _values.GetPaintObject();
                label._textBlock.Text = item.ValueEx;
            }
            _values.Stop();
        }
Exemple #2
0
        internal void ShowSelection(bool bShow)
        {
            _selectionVisible = bShow;

            SetCursor();

            if (!_selectionVisible)
            {
                _selectionDots.RemoveAll();
                return;
            }

            _selectionDots.C = C;
            _selectionDots.Start();

            foreach (SelectionDotInfo point in GetSelectionPoints())
            {
                SelectionDot dot = _selectionDots.GetPaintObject(point.Corner, point.Clickable);
                dot.SetPos(point.Position);
                dot.Tag = this;
                //dot.SetClip(Clip);
                Shape shape = dot.Shape;
                shape.Clip = GetClip(Canvas.GetLeft(shape), Canvas.GetTop(shape), _paintableRect);

                dot.ZIndex = ZIndexConstants.SelectionPoint1;
            }

            _selectionDots.Stop();
        }
Exemple #3
0
        internal void ShowSelection()
        {
            if (!_selectable)
            {
                return;
            }

            _selected = true;

            double dx = 0;
            DataEntryCollection data = _chartPanel._chartX._dataManager[_seriesIndex].Data;

            _selectionDots.C = _chartPanel._rootCanvas;
            _selectionDots.Start();
            for (int i = _chartPanel._chartX._startIndex; i < _chartPanel._chartX._endIndex; i++)
            {
                if (!data[i].Value.HasValue)
                {
                    continue;
                }

                double x = _chartPanel._chartX.GetXPixel(i - _chartPanel._chartX._startIndex);
                if (x - dx <= 50)
                {
                    continue;
                }

                dx = x;
                SelectionDot dot = _selectionDots.GetPaintObject(Types.Corner.MoveAll);
                dot.SetPos(new Point(dx, GetY(data[i].Value.Value)));
                dot.Tag = this;
            }
            _selectionDots.Stop();
            _selectionDots.Do(dot => dot.ZIndex = ZIndexConstants.SelectionPoint1);
        }
        internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus)
        {
            rect.Normalize();

            _lines.C = C;
            _lines.Start();

            Utils.DrawLine(rect.Left, rect.Top, rect.Left, rect.Bottom, Stroke, StrokeType, StrokeThickness, _lines);
            Utils.DrawLine(rect.Right, rect.Top, rect.Right, rect.Bottom, Stroke, StrokeType, StrokeThickness, _lines);

            foreach (double d in _fib)
            {
                double x = rect.Left + rect.Width * d;
                Utils.DrawLine(x, rect.Top, x, rect.Bottom, Stroke, StrokeType, StrokeThickness, _lines);
            }

            _lines.Stop();

            _internalObjectCreated = true;

            if (_firstPaint)
            {
                _firstPaint = false;

                _lines.Do(l =>
                {
                    l._line.Tag = this;
                    l.ZIndex    = ZIndexConstants.LineStudies1;
                });

                _contextLine = new ContextLine(this);
                _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this));
            }
        }
Exemple #5
0
        public override bool Paint()
        {
            if (_series.OHLCType != SeriesTypeOHLC.High && _series.OHLCType != SeriesTypeOHLC.Low)
            {
                return(false);
            }
            StockChartX chartX = _series._chartPanel._chartX;
            Series      high   = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (high == null || high.Painted || high.RecordCount == 0)
            {
                return(false);
            }
            Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (low == null || low.Painted || low.RecordCount == 0)
            {
                return(false);
            }

            high.Painted = low.Painted = true;

            Brush upBrush   = new SolidColorBrush(_series._upColor.HasValue ? _series.UpColor.Value : chartX.UpColor);
            Brush downBrush = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor);

            double width = chartX.PaintableWidth;

            double max = chartX.GetMax(high, true);
            double min = chartX.GetMin(low, true);

            double boxSize = chartX._priceStyleParams[0];

            if (boxSize > 50 || boxSize < 0.00000000000000000000001)
            {
                boxSize = (max - min) / 25;
            }
            double reversalSize = chartX._priceStyleParams[1];

            if (reversalSize > 50 || reversalSize < 1)
            {
                reversalSize = 3;
            }

            chartX._priceStyleParams[0] = boxSize;
            chartX._priceStyleParams[1] = reversalSize;

            double    nHigh, nLow, nLastHigh = 0, nLastLow = 0;
            int       column       = 0; // X=1 O=2
            int       columnHeight = 0;
            int       totalColumns = 0;
            int       boxes;
            const int Xs = 1;
            const int Os = 2;

            chartX._psValues1.Clear();
            chartX._psValues2.Clear();
            chartX._psValues3.Clear();

            chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1];
            int cnt = 0;
            // Count columns
            int n;

            for (n = chartX._startIndex; n < chartX._endIndex; n++)
            {
                if (!high[n].Value.HasValue || !low[n].Value.HasValue)
                {
                    continue;
                }
                // Calculate Point and Figure
                nHigh = high[n].Value.Value;
                nLow  = low[n].Value.Value;

                switch (column)
                {
                case Xs:
                    boxes = (int)((nHigh - nLastHigh) / boxSize);
                    if (boxes >= boxSize)
                    {
                        // Add one X box
                        columnHeight += 1;
                        nLastHigh    += boxSize;
                        if (nLastHigh > max)
                        {
                            max = nLastHigh;
                        }
                    }
                    else
                    {
                        // Check for O's reversal
                        boxes = (int)((nLastHigh - nLow) / boxSize);
                        if (boxes >= reversalSize)
                        {
                            column       = Os;
                            columnHeight = boxes;
                            totalColumns++;
                            nLastLow = nLastHigh - (boxes * boxSize);
                            if (nLastLow < min && min != 0)
                            {
                                min = nLastLow;
                            }
                        }
                    }
                    break;

                case Os:
                    boxes = (int)((nLastLow - nLow) / boxSize);
                    if (boxes >= boxSize)
                    {
                        // Add one O box
                        columnHeight += 1;
                        nLastLow     -= boxSize;
                        if (nLastLow < min && min != 0)
                        {
                            min = nLastLow;
                        }
                    }
                    else
                    {
                        // Check for X's reversal
                        boxes = (int)((nHigh - nLastLow) / boxSize);
                        if (boxes >= reversalSize)
                        {
                            column       = Xs;
                            columnHeight = boxes;
                            totalColumns++;
                            nLastHigh = nLastLow + (boxes * boxSize);
                            if (nLastHigh > max)
                            {
                                max = nLastHigh;
                            }
                        }
                    }
                    break;
                }

                if (column != 0)
                {
                    continue;              // Prime first column
                }
                column       = Xs;
                boxes        = (int)Math.Floor(((nHigh - (nLow + (boxSize * reversalSize))) / boxSize) + 0.5);
                columnHeight = boxes;
                nLastHigh    = nHigh;
                nLastLow     = nHigh - (boxes * boxSize);
                totalColumns = 1;
            }

            chartX._xCount = totalColumns;

            column = 0;
            double x = chartX.LeftChartSpace;

            if (totalColumns == 0)
            {
                return(false);
            }
            double space = width / totalColumns;

            totalColumns = 0;

            _lines.C = _ellipses.C = _series._chartPanel._rootCanvas;
            _lines.Start();
            _ellipses.Start();

            // Calculate from beginning, but only show between startIndex and endIndex
            for (n = 0; n < chartX._endIndex; n++)
            {
                if (high[n].Value.HasValue && low[n].Value.HasValue)
                {
                    // Calculate Point and Figure
                    nHigh = high[n].Value.Value;
                    nLow  = low[n].Value.Value;

                    double y1;
                    double y2;
                    switch (column)
                    {
                    case Xs:
                        boxes = (int)((nHigh - nLastHigh) / boxSize);
                        if (boxes >= boxSize)
                        {
                            // Add one X box
                            columnHeight += 1;
                            nLastHigh    += boxSize;
                        }
                        else
                        {
                            // Check for O's reversal
                            boxes = (int)((nLastHigh - nLow) / boxSize);
                            if (boxes >= reversalSize)
                            {
                                // Paint the previous X column
                                if (n >= chartX._startIndex && n <= chartX._endIndex)
                                {
                                    double y = nLastHigh;
                                    if (columnHeight > 0)
                                    {
                                        for (int col = 0; col < columnHeight; ++col)
                                        {
                                            y1 = _series._chartPanel.GetY(y);
                                            y -= boxSize;
                                            y2 = _series._chartPanel.GetY(y);
                                            double x1 = x;
                                            double x2 = x + space;
                                            Utils.DrawLine(x1, y1, x2, y2, upBrush, _series._strokePattern, _series._strokeThickness, _series._opacity, _lines);
                                            Utils.DrawLine(x2, y1, x1, y2, upBrush, _series._strokePattern, _series._strokeThickness, _series._opacity, _lines);
                                        }
                                    }
                                }

                                // Create new O column
                                column       = Os;
                                columnHeight = boxes;

                                if (n >= chartX._startIndex && n <= chartX._endIndex)
                                {
                                    totalColumns++;
                                    x += space;
                                }

                                nLastLow = nLastHigh - (boxes * boxSize);
                            }
                        }
                        break;

                    case Os:
                        boxes = (int)((nLastLow - nLow) / boxSize);
                        if (boxes >= boxSize)
                        {
                            // Add one O box
                            columnHeight += 1;
                            nLastLow     -= boxSize;
                        }
                        else
                        {
                            // Check for X's reversal
                            boxes = (int)((nHigh - nLastLow) / boxSize);
                            if (boxes >= reversalSize)
                            {
                                // Paint the previous O's column
                                if (n >= chartX._startIndex && n <= chartX._endIndex)
                                {
                                    double y = nLastLow - boxSize;
                                    if (columnHeight > 0)
                                    {
                                        for (int col = 0; col < columnHeight; ++col)
                                        {
                                            y2 = _series._chartPanel.GetY(y);
                                            y += boxSize;
                                            y1 = _series._chartPanel.GetY(y);
                                            System.Windows.Shapes.Ellipse ellipse = _ellipses.GetPaintObject()._ellipse;
                                            Types.RectEx bounds = new Types.RectEx(x, y1, x + space, y2);
                                            Canvas.SetLeft(ellipse, bounds.Left);
                                            Canvas.SetTop(ellipse, bounds.Top);
                                            ellipse.Width           = bounds.Width;
                                            ellipse.Height          = bounds.Height;
                                            ellipse.Stroke          = downBrush;
                                            ellipse.StrokeThickness = _series._strokeThickness;
                                            ellipse.Fill            = _series._chartPanel.Background;
                                        }
                                    }
                                }

                                // Create new X column
                                column       = Xs;
                                columnHeight = boxes;

                                if (n >= chartX._startIndex && n <= chartX._endIndex)
                                {
                                    totalColumns++;
                                    x += space;
                                }

                                nLastHigh = nLastLow + (boxes * boxSize);
                            }
                        }
                        break;
                    }

                    if (column == 0)
                    { // Prime first column
                        column       = Xs;
                        boxes        = (int)Math.Floor(((nHigh - (nLow + (boxSize * reversalSize))) / boxSize) + 0.5);
                        columnHeight = boxes;
                        nLastHigh    = nHigh;
                        nLastLow     = nHigh - (boxes * boxSize);

                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalColumns = 1;
                        }

                        x = chartX.LeftChartSpace;
                    }

                    // Record the x value
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        chartX._xMap[cnt] = x + (space / 2);
                        cnt++;
                    }
                }

                chartX._psValues3.Add(new PriceStyleValue(high[n].TimeStamp, column == 1 ? 1 : -1));
                chartX._psValues1.Add(new PriceStyleValue(high[n].TimeStamp, columnHeight));

                // Once the direction changes, we need to
                // go backwards until the previous change
                // and fill in the values.
                if (chartX._psValues3.Count <= 1)
                {
                    continue;
                }
                for (int prev = chartX._psValues3.Count - 1; prev >= 0; --prev)
                {
                    if (chartX._psValues3[prev].Value != column)
                    {
                        break;
                    }
                    chartX._psValues1[prev].Value = columnHeight;
                }
            }

            _lines.Stop();
            _ellipses.Stop();

            _lines.Do(l => l.ZIndex    = ZIndexConstants.PriceStyles1);
            _ellipses.Do(e => e.ZIndex = ZIndexConstants.PriceStyles1);

            return(true);
        }
        private void PaintSideVolumeDepthBars()
        {
            if (_sideVolumeDepthBars == 0) //remove
            {
                _rectsSideVolumeDepth.RemoveAll();
                return;
            }
            if (_chartX._endIndex == 0)
            {
                return;
            }
            if (_series.Count < 3)
            {
                return;
            }
            Series open = null;

            foreach (Series series in _series)
            {
                if (series.OHLCType != SeriesTypeOHLC.Open)
                {
                    continue;
                }
                open = series;
                break;
            }
            if (open == null)
            {
                return;
            }
            Series close = GetSeriesOHLCV(open, SeriesTypeOHLC.Close);

            if (close == null)
            {
                return;
            }
            Series volume = _chartX.GetSeriesOHLCV(open, SeriesTypeOHLC.Volume);

            if (volume == null)
            {
                return;
            }

            double maxVolume = double.MinValue, minVolume = double.MaxValue;
            int    i;

            for (i = _chartX._startIndex; i < _chartX._endIndex; i++)
            {
                if (!volume[i].Value.HasValue)
                {
                    continue;
                }
                if (volume[i].Value.Value > maxVolume)
                {
                    maxVolume = volume[i].Value.Value;
                }
                else if (volume[i].Value.Value < minVolume)
                {
                    minVolume = volume[i].Value.Value;
                }
            }

            double range              = maxVolume - minVolume;
            double barVolumeIncrement = range / _sideVolumeDepthBars;
            double barHeight          = _rootCanvas.ActualHeight / _sideVolumeDepthBars;

            double volBar = minVolume;

            int[] volBarsPos = new int[_sideVolumeDepthBars];
            int[] volBarsNeg = new int[_sideVolumeDepthBars];

            for (int n = 0; n < _sideVolumeDepthBars; n++)
            {
                for (int j = _chartX._startIndex; j < _chartX._endIndex; j++)
                {
                    if (!volume[j].Value.HasValue)
                    {
                        continue;
                    }
                    double v = volume[j].Value.Value;
                    if (v < volBar || v > volBar + barVolumeIncrement)
                    {
                        continue;
                    }

                    if (close[j].Value > open[j].Value)
                    {
                        volBarsPos[n]++;
                    }
                    else if (close[j].Value < open[j].Value)
                    {
                        volBarsNeg[n]++;
                    }
                }
                volBar += barVolumeIncrement;
            }

            double[] volBarsWidthPos = new double[_sideVolumeDepthBars];
            double[] volBarsWidthNeg = new double[_sideVolumeDepthBars];

            double maxVolBars = Math.Max(Algorithms.Maximum(volBarsPos), Algorithms.Maximum(volBarsNeg));
            double minVolBars = Math.Min(Algorithms.Minimum(volBarsPos), Algorithms.Minimum(volBarsNeg));


            double volumeBarScaleWidth = _rootCanvas.ActualWidth * 0.15; //15% for positive values and 15% for negative values

            _rectsSideVolumeDepth.C = _rootCanvas;
            _rectsSideVolumeDepth.Start();

            for (int n = 0; n < _sideVolumeDepthBars; n++)
            {
                volBarsWidthPos[n] = (volBarsPos[n] - minVolBars) / (maxVolBars - minVolBars);
                volBarsWidthNeg[n] = (volBarsNeg[n] - minVolBars) / (maxVolBars - minVolBars);

                volBarsWidthPos[n] *= volumeBarScaleWidth;
                volBarsWidthNeg[n] *= volumeBarScaleWidth;

                double x1 = _chartX.LeftChartSpace;
                double y1 = n * barHeight;
                double x2 = _chartX.LeftChartSpace + volBarsWidthPos[n];
                double y2 = (n + 1) * barHeight;
                Utils.DrawRectangle(x1, y1, x2, y2, Brushes.Blue, _rectsSideVolumeDepth);

                x1 = x2;
                x2 = x1 + volBarsWidthNeg[n];
                Utils.DrawRectangle(x1, y1, x2, y2, Brushes.Red, _rectsSideVolumeDepth);
            }

            _rectsSideVolumeDepth.Stop();
            _rectsSideVolumeDepth.Do(r =>
            {
                r.ZIndex                      = ZIndexConstants.VolumeDepthBars;
                r._rectangle.Opacity          = 0.5;
                r._rectangle.IsHitTestVisible = false;
            });
        }
Exemple #7
0
        internal override void Paint()
        {
            if (Painted || !_visible || RecordCount < 0 || RecordCount < _chartPanel._chartX._startIndex)
            {
                return;
            }
            Painted = true;

            InitPainting();

            if (_chartPanel._chartX.OptimizePainting)
            {
                PaintOptimized();
                return;
            }

            Brush strokeUpBrush = new SolidColorBrush(UpColor == null ? _chartPanel._chartX.UpColor : UpColor.Value);

            strokeUpBrush.Freeze();
            Brush strokeDownBrush = new SolidColorBrush(DownColor == null ? _chartPanel._chartX.DownColor : DownColor.Value);

            strokeDownBrush.Freeze();
            Brush strokeNormalBrush = new SolidColorBrush(_strokeColor);

            strokeNormalBrush.Freeze();
            Brush currentBrush = strokeNormalBrush;

            _lines.C = _chartPanel._rootCanvas;
            _lines.Start();

            double x2 = _chartPanel._chartX.GetXPixel(0);
            double?y1;
            double?y2 = null;

            int cnt = 0;

            for (int i = _chartPanel._chartX._startIndex; i < _chartPanel._chartX._endIndex; i++, cnt++)
            {
                //cnt++;
                double x1 = _chartPanel._chartX.GetXPixel(cnt);
                y1 = this[i].Value;
                if (!y1.HasValue)
                {
                    continue;
                }
                y1 = GetY(y1.Value);
                if (i == _chartPanel._chartX._startIndex)
                {
                    y2 = y1.Value;
                }

                if (_volumeUpDown)
                {
                    if (i > 0)
                    {
                        if (_seriesClose[i].Value > _seriesClose[i - 1].Value)
                        {
                            currentBrush = _seriesTypeOHLC == SeriesTypeOHLC.Volume ? strokeUpBrush : strokeDownBrush;  //up
                        }
                        else if (_seriesClose[i].Value < _seriesClose[i - 1].Value)
                        {
                            currentBrush = _seriesTypeOHLC == SeriesTypeOHLC.Volume ? strokeDownBrush : strokeUpBrush; //down
                        }
                        else
                        {
                            currentBrush = strokeNormalBrush;
                        }
                    }
                    else
                    {
                        currentBrush = strokeNormalBrush;
                    }
                }
                else if ((_chartPanel._chartX._useLineSeriesColors || _upColor.HasValue)) // +/- change colors
                {
                    if (!_isOscillator)
                    {
                        if (i > 0)
                        {
                            if (this[i].Value > this[i - 1].Value)
                            {
                                currentBrush = strokeUpBrush;
                            }
                            else
                            {
                                currentBrush = this[i].Value < this[i - 1].Value ? strokeDownBrush : strokeNormalBrush;
                            }
                        }
                        else
                        {
                            currentBrush = strokeNormalBrush;
                        }
                    }
                    else
                    {
                        if (this[i].Value > 0)
                        {
                            currentBrush = strokeUpBrush;
                        }
                        else
                        {
                            currentBrush = this[i].Value < 0 ? strokeDownBrush : strokeNormalBrush;
                        }
                    }
                }

                if (_seriesType == SeriesTypeEnum.stVolumeChart || ForceOscilatorPaint)
                {
                    if (this[i].Value.HasValue && y2.HasValue)
                    {
                        // Make sure at least 2 or 3 pixels show
                        // if the value is the same as the min Y.
                        double minY = GetY(SeriesEntry._min);
                        double nY1  = y1.Value;
                        if (minY - 3 < nY1)
                        {
                            nY1 -= 3;
                        }
                        DrawLine(x1, nY1, x1, _isOscillator ? GetY(0) : minY, _chartPanel._chartX.GetBarBrush(FullName, i, currentBrush));
                    }
                }
                else if ((_seriesType == SeriesTypeEnum.stLineChart || _seriesType == SeriesTypeEnum.stIndicator) &&
                         i > _chartPanel._chartX._startIndex)
                {
                    if (this[i].Value.HasValue && y2.HasValue)
                    {
                        DrawLine(x1, y1.Value, x2, y2.Value, currentBrush);
                    }
                }

                y2 = y1;
                x2 = x1;
            }

            _lines.Stop();

            _lines.Do(l =>
            {
                l.ZIndex = ZIndexConstants.PriceStyles1;
                if (l._line.Tag == null)
                {
                    l._line.Tag = this;
                }
            });

            if (Selected)
            {
                ShowSelection();
            }
        }
Exemple #8
0
        public override bool Paint()
        {
            /*
             * pCtrl->priceStyleParams[0] = lines
             * 7 columns
             * width = 300
             * 300 / 7 = 42.85 pixels per column
             */
            if (_series.OHLCType != SeriesTypeOHLC.Close)
            {
                return(false);
            }
            Series close = _series;

            StockChartX chartX = _series._chartPanel._chartX;
            double      width  = chartX.PaintableWidth;

            double boxSize = chartX._priceStyleParams[0];

            if (boxSize > 50 || boxSize < 0.0001)
            {
                boxSize = 1;
            }

            chartX._priceStyleParams[0] = boxSize;

            double    nClose, nHH = 0, nLL = 0;
            const int white       = 1;
            const int black       = 2;
            int       brick       = 0; // black or white
            int       totalBricks = 0;


            chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1];
            int cnt = 0;

            chartX._psValues1.Clear();
            chartX._psValues2.Clear();
            chartX._psValues3.Clear();

            int n;

            // Calculate from beginning, but only show between startIndex and endIndex
            for (n = 0; n < chartX._endIndex; n++)
            {
                if (!close[n].Value.HasValue)
                {
                    continue;
                }
                nClose = close[n].Value.Value;


                if (brick == 0)
                { // Prime first brick
                    double nClose2 = close[n + 1].Value.Value;
                    if (nClose2 > nClose)
                    {
                        brick = white; nHH = nClose + boxSize; nLL = nClose;
                    }
                    else
                    {
                        brick = black; nHH = nClose2; nLL = nClose2 - boxSize;
                    }
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        totalBricks = 1;
                    }
                }


                if (nClose < nLL - boxSize)
                {
                    brick = black;
                    nHH   = nLL;
                    nLL   = nHH - boxSize;
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        totalBricks++;
                    }
                }
                else if (nClose > nHH + boxSize)
                {
                    brick = white;
                    nLL   = nHH;
                    nHH   = nLL + boxSize;
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        totalBricks++;
                    }
                }
            }

            chartX._xCount = totalBricks;

            // Paint columns
            brick = 0;
            double x = chartX.LeftChartSpace;

            if (totalBricks == 0)
            {
                return(false);
            }
            double space = width / totalBricks;

            Color upColor       = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor;
            Color downColor     = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor;
            Brush upBrush       = new SolidColorBrush(upColor);
            Brush downBrush     = new SolidColorBrush(downColor);
            Brush upGradBrush   = Utils.CreateFadeVertBrush(upColor, Colors.Black);
            Brush downGradBrush = Utils.CreateFadeVertBrush(downColor, Colors.Black);

            _rects.C = _series._chartPanel._rootCanvas;
            _rects.Start();

            totalBricks = 0;

            for (n = 0; n < chartX._endIndex; n++)
            {
                if (close[n].Value.HasValue)
                {
                    // Calculate Renko
                    nClose = (double)close[n].Value;


                    if (brick == 0)
                    { // Prime first brick
                        double nClose2 = (double)close[n + 1].Value;
                        if (nClose2 > nClose)
                        {
                            brick = white; nHH = nClose + boxSize; nLL = nClose;
                        }
                        else
                        {
                            brick = black; nHH = nClose2; nLL = nClose2 - boxSize;
                        }
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBricks = 1;
                        }
                        x = chartX.LeftChartSpace;
                    }

                    if (nClose < nLL - boxSize)
                    {
                        // Paint last white brick
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, brick);
                            totalBricks++;
                            x += space;
                        }

                        brick = black;
                        nHH   = nLL;
                        nLL   = nHH - boxSize;
                    }
                    else if (nClose > nHH + boxSize)
                    {
                        // Paint last black brick
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, brick);
                            totalBricks++;
                            x += space;
                        }
                        brick = white;
                        nLL   = nHH;
                        nHH   = nLL + boxSize;
                    }

                    // Record the x value
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        chartX._xMap[cnt] = x + (space / 2);
                        cnt++;
                    }
                }

                chartX._psValues1.Add(new PriceStyleValue(close[n].TimeStamp, nHH));
                chartX._psValues2.Add(new PriceStyleValue(close[n].TimeStamp, nLL));
                chartX._psValues3.Add(new PriceStyleValue(close[n].TimeStamp, brick == white ? 1 : -1));
            }

            _rects.Stop();

            _rects.Do(r => r.ZIndex = r.ZIndex = ZIndexConstants.PriceStyles1);

            return(true);
        }
Exemple #9
0
        public override bool Paint()
        {
            StockChartX chartX = _series._chartPanel._chartX;

            chartX._psValues1.Clear();
            chartX._psValues2.Clear();
            chartX._psValues3.Clear();

            if (_series.OHLCType != SeriesTypeOHLC.Close)
            {
                return(false);
            }

            Series close = _series;
            Series low   = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (low == null)
            {
                return(false);
            }

            Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (high == null)
            {
                return(false);
            }

            /*
             * Initial box top is the high of day 1.
             *
             * The first step is to find a new high that is higher than the high of day 1.
             * The high can be found anytime - even after 5 days.
             * But once the bottom has been found, the box is complete.
             *
             * To find the bottom, the low must be after day 2 of the day the last box
             * top was found and must be lower than the low of original day 1 low.
             *
             * The bottom is always found last and a new high may not be found once
             * the bottom is locked in - the Darvas box is complete then.
             *
             * A new box is started when the price breaks out of top or bottom,
             *
             * The bottom stop loss box is drawn as a percentage of the last price.
             */

            Brush brDarvas            = new SolidColorBrush(Color.FromArgb(0xFF, 0, 0, 255));
            Brush brDarvaseIncomplete = new SolidColorBrush(Color.FromArgb(0xFF, 100, 115, 255));
            Brush topLeft             = new SolidColorBrush(Color.FromArgb(0xFF, 240, 240, 240));
            Brush bottomRight         = new SolidColorBrush(Color.FromArgb(0xFF, 150, 150, 150));
            Brush brGradStopLoss      = Utils.CreateFadeVertBrush(Color.FromArgb(0xFF, 255, 255, 255), Colors.Red);

            double boxTop      = 0;
            double boxBottom   = 0;
            int    bottomFound = 0;
            int    cnt         = 0;
            int    start       = 0;
            int    state       = 0;

            _rects.C = _rects3D.C = _series._chartPanel._rootCanvas;
            _rects3D.Start();
            _rects.Start();

            for (int n = chartX._startIndex; n < chartX._endIndex; n++, cnt++)
            {
                if (!close[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue)
                {
                    continue;
                }

                double x1;
                double x2;
                double y1;
                double y2;
                if (n == chartX._endIndex - 1)
                {
                    x1 = chartX.GetXPixel(start);
                    x2 = chartX.GetXPixel(cnt);
                    y1 = _series._chartPanel.GetY(boxTop);
                    y2 = _series._chartPanel.GetY(boxBottom);

                    if (state == 5) // draw the last COMPLETED box
                    {
                        Rectangle rect = Utils.DrawRectangle(x1, y1, x2 + 2, y2, brDarvas, _rects);
                        rect._rectangle.Opacity = 0.5;

                        Utils.Draw3DRectangle(x1, y1, x2 + 2, y2, topLeft, bottomRight, _rects3D);
                    }
                    else if (bottomFound > 0)
                    {
                        Rectangle rect = Utils.DrawRectangle(x1, y1, x2 + 2, y2, brDarvaseIncomplete, _rects);
                        rect._rectangle.Opacity = 0.5;

                        Utils.Draw3DRectangle(x1, y1, x2 + 2, y2, topLeft, bottomRight, _rects3D);
                    }

                    // Gradient stop loss box
                    double y3 = _series._chartPanel.GetY(boxBottom - (boxBottom * chartX._darvasPct));
                    if (y3 < y2)
                    {
                        y3 = y2;
                    }

                    Utils.DrawRectangle(x1, y2, x2 + 2, y3, brGradStopLoss, _rects);

                    break;
                }

                if (state == 0)
                { // Start of a new box
                  // Save new box top and bottom
                    start       = cnt;
                    bottomFound = 0;
                    boxTop      = high[n].Value.Value;
                    boxBottom   = -1;
                    state       = 1;
                }

                switch (state)
                {
                case 1:
                    if (high[n].Value.Value > boxTop)
                    {
                        boxTop = high[n].Value.Value;
                        state  = 1;
                    }
                    else
                    {
                        state = 2;
                    }
                    break;

                case 2:
                    if (high[n].Value.Value > boxTop)
                    {
                        boxTop = high[n].Value.Value;
                        state  = 1;
                    }
                    else
                    {
                        bottomFound = n;
                        boxBottom   = low[n].Value.Value;
                        state       = 3;
                    }
                    break;

                case 3:
                    if (high[n].Value.Value > boxTop)
                    {
                        boxTop = high[n].Value.Value;
                        state  = 1;
                    }
                    else
                    {
                        if (low[n].Value.Value < boxBottom)
                        {
                            boxBottom   = low[n].Value.Value;
                            bottomFound = n;
                            state       = 3;
                        }
                        else
                        {
                            state = 4;
                        }
                    }
                    break;

                case 4:
                    if (high[n].Value.Value > boxTop)
                    {
                        boxTop = high[n].Value.Value;
                        state  = 1;
                    }
                    else
                    {
                        if (low[n].Value.Value < boxBottom)
                        {
                            boxBottom   = low[n].Value.Value;
                            bottomFound = n;
                            state       = 3;
                        }
                        else
                        {
                            state = 5; // Darvas box is complete
                        }
                    }
                    break;
                }

                if (state != 5)
                {
                    continue;
                }

                if (low[n].Value.Value >= boxBottom && high[n].Value.Value <= boxTop)
                {
                    continue;
                }

                x1 = chartX.GetXPixel(start);
                x2 = chartX.GetXPixel(cnt);
                y1 = _series._chartPanel.GetY(boxTop);
                y2 = _series._chartPanel.GetY(boxBottom);

                Rectangle rectangle = Utils.DrawRectangle(x1, y1, x2, y2, brDarvas, _rects);
                rectangle._rectangle.Opacity = 0.5;

                Utils.Draw3DRectangle(x1, y1, x2, y2, topLeft, bottomRight, _rects3D);

                Utils.DrawRectangle(x1, y2, x2, _series._chartPanel.GetY(boxBottom - (boxBottom * chartX._darvasPct)),
                                    brGradStopLoss, _rects);

                state = 0;
                cnt--;
                n--;
            }

            _rects3D.Stop();
            _rects.Stop();

            _rects.Do(r => r.ZIndex   = ZIndexConstants.DarvasBoxes1);
            _rects3D.Do(r => r.ZIndex = ZIndexConstants.DarvasBoxes2);

            return(true);
        }
Exemple #10
0
        internal void RecalculateLayout()
        {
            Debug.Assert(_chartX != null);

            _values.Start();
            _labels.Start();
            _values.C = this;
            _labels.C = this;

            double labelsMaxWidth          = double.MinValue;
            double valuesMaxWidth          = double.MinValue;
            double valuesNoCaptionMaxWidth = double.MinValue;
            int    valueIndex;

            _entries.Clear();

            foreach (InfoPanelItem item in _items)
            {
                _entries.Add(new Tuple <string, string>(item.Caption, item.ValueEx));

                if (!item._noCaption)
                {
                    Label labelCaption = _labels.GetPaintObject();
                    labelCaption._textBlock.Text       = item.Caption;
                    labelCaption._textBlock.FontFamily = _chartX.InfoPanelFontFamily;
                    labelCaption._textBlock.FontSize   = _chartX.InfoPanelFontSize;
                    labelCaption._textBlock.Foreground = _chartX.InfoPanelLabelsForeground;
                    SetZIndex(labelCaption._textBlock, 5);
                }

                Label labelValue = _values.GetPaintObject();
                labelValue._textBlock.Text       = item.ValueEx;
                labelValue._textBlock.FontFamily = _chartX.InfoPanelFontFamily;
                labelValue._textBlock.FontSize   = _chartX.InfoPanelFontSize;
                labelValue._textBlock.Foreground = _chartX.InfoPanelValuesForeground;
                SetZIndex(labelValue._textBlock, 5);
            }
            _values.Stop();
            _labels.Stop();

            int    labelIndex = valueIndex = 0;
            double top        = 1;

            foreach (InfoPanelItem item in _items)
            {
                Label labelValue = _values[valueIndex++];

                if (!item._noCaption)
                {
                    Label labelCaption = _labels[labelIndex++];
                    if (labelCaption._textBlock.ActualWidth > labelsMaxWidth)
                    {
                        labelsMaxWidth = labelCaption._textBlock.ActualWidth;
                    }
                    SetLeft(labelCaption._textBlock, 1);
                    SetTop(labelCaption._textBlock, top - 1);
                }

                top += labelValue._textBlock.ActualHeight + 2;
            }

            top        = 1;
            valueIndex = 0;
            foreach (InfoPanelItem item in _items)
            {
                Label labelValue = _values[valueIndex++];

                if (item._noCaption)
                {
                    SetLeft(labelValue._textBlock, 2);
                    if (labelValue._textBlock.ActualWidth > valuesNoCaptionMaxWidth)
                    {
                        valuesNoCaptionMaxWidth = labelValue._textBlock.ActualWidth;
                    }
                }
                else
                {
                    SetLeft(labelValue._textBlock, labelsMaxWidth + 3);
                    if (labelValue._textBlock.ActualWidth > valuesMaxWidth)
                    {
                        valuesMaxWidth = labelValue._textBlock.ActualWidth;
                    }
                }
                SetTop(labelValue._textBlock, top - 1);

                top += labelValue._textBlock.ActualHeight + 2;
            }

            double maxWidth = labelsMaxWidth + valuesMaxWidth + 4;

            Width = Math.Max(maxWidth, valuesNoCaptionMaxWidth);

            if (_rectLabels == null)
            {
                _rectLabels = new Rectangle {
                    Stroke = null, StrokeThickness = 0
                };
                Children.Add(_rectLabels);
                _rectValues = new Rectangle {
                    Stroke = null, StrokeThickness = 0
                };
                Children.Add(_rectValues);
            }

            SetLeft(_rectLabels, 0);
            SetTop(_rectLabels, 0);
            _rectLabels.Width  = labelsMaxWidth + 2;
            _rectLabels.Height = top;
            _rectLabels.Fill   = _chartX.InfoPanelLabelsBackground;

            SetLeft(_rectValues, GetLeft(_rectLabels) + _rectLabels.Width);
            SetTop(_rectValues, 0);
            _rectValues.Width  = Math.Max(maxWidth, valuesNoCaptionMaxWidth) - labelsMaxWidth + 2;
            _rectValues.Height = top;
            _rectValues.Fill   = _chartX.InfoPanelValuesBackground;

            Height = top;
        }
        internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus)
        {
            if (lineStatus == LineStatus.StartPaint)
            {
                return;
            }

            rect.Normalize();

            if (rect.Width == 0 || rect.Left < 0)
            {
                return;
            }

            int revX1 = (int)(_chartX.GetReverseXInternal(rect.Left) + _chartX._startIndex);
            int revX2 = (int)(_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex);

            if (revX1 < 0)
            {
                revX1 = 0;
            }
            if (revX2 < 0)
            {
                revX2 = 0;
            }

            if (revX1 == revX2)
            {
                return;
            }

            // Note: this code makes the vague assumption
            // that only one symbol exists on this panel.
            // Get the close series
            Series sClose = GetSeriesOHLC(SeriesTypeOHLC.Close);

            if (sClose == null)
            {
                return;
            }
            //Debug.Assert(sClose.RecordCount == _chartX.RecordCount);
            if (revX1 >= _chartX.RecordCount)
            {
                revX1 = _chartX.RecordCount - 1;
            }
            if (revX2 >= _chartX.RecordCount)
            {
                revX2 = _chartX.RecordCount - 1;
            }

            // Get the highest high of the high series.
            double highestHigh = 0;
            Series sHigh       = GetSeriesOHLC(SeriesTypeOHLC.High);

            if (sHigh == null)
            {
                return;
            }
            //Debug.Assert(revX1 <= revX2);
            for (int i = revX1; i <= revX2; i++)
            {
                if (sHigh[i].Value > highestHigh)
                {
                    highestHigh = sHigh[i].Value.Value;
                }
            }

            //Get the lowest low of the low series.
            double lowestLow = highestHigh;
            Series sLow      = GetSeriesOHLC(SeriesTypeOHLC.Low);

            if (sLow == null)
            {
                return;
            }
            for (int i = revX1; i <= revX2; i++)
            {
                if (sLow[i].Value < lowestLow)
                {
                    lowestLow = sLow[i].Value.Value;
                }
            }

            double range = (highestHigh - lowestLow) * 0.5;

            if (_rangeScale.HasValue)
            {
                range = (highestHigh - lowestLow) * _rangeScale.Value;
            }

            // Perform linear regression on the data
            double xSum = 0, ySum = 0, xSquaredSum = 0, xYSum = 0;
            int    x = revX2 - revX1;
            int    j, n;

            for (n = 1; n != x + 1; ++n)
            {
                j            = revX1 + n - 1;
                xSum        += n;
                ySum        += sClose[j].Value.Value;
                xSquaredSum += (n * n);
                xYSum       += (sClose[j].Value.Value * n);
            }
            n = x;
            double q1         = n != 0 ? (xYSum - ((xSum * ySum) / n)) : 0;
            double q2         = n != 0 ? (xSquaredSum - ((xSum * xSum) / n)) : 0;
            double slope      = q2 != 0 ? (q1 / q2) : 0;
            double leftValue  = slope != 0 ? (((1 / (double)n) * ySum) - (((int)((double)n / 2)) * slope)) : 0.0;
            double rightValue = ((n * slope) + leftValue);
            double inc        = (x - 1) != 0 ? (rightValue - leftValue) / (x - 1) : 0;

            j = 0;
            double prevVal = 0;
            double lX1     = rect.Left;  //_chartX.GetX(revX1 - _chartX._startIndex);
            double lX2     = rect.Right; // _chartX.GetX((revX2 - 1) - _chartX._startIndex + 1);

            if (_linesError.Count == 0)
            {
                for (int i = 0; i < 3; i++)
                {
                    System.Windows.Shapes.Line line = new System.Windows.Shapes.Line {
                        Tag = this
                    };
                    Canvas.SetZIndex(line, ZIndexConstants.LineStudies1);
                    C.Children.Add(line);

                    _linesError.Add(line);
                }

                _contextLine = new ContextLine(this);

                _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this));
            }

            _internalObjectCreated = true;

            _lines.C = C;
            _lines.Start();
            for (n = revX1; n <= revX2; n++, j++)
            {
                double val = leftValue + inc * (j - 1);
                //double lX1 = _chartX.GetX(n - _chartX._startIndex);
                //double lX2 = _chartX.GetX(n - _chartX._startIndex + 1);
                double lY1 = _chartPanel.GetY(prevVal + range);
                double lY2 = _chartPanel.GetY(val + range);
                if (prevVal != 0.0)
                {
                    _errorLines[2].Y1 = lY1;
                    _errorLines[2].Y2 = lY2;
                    Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _linesError[0]);
                }

                lY1 = _chartPanel.GetY(prevVal - range);
                lY2 = _chartPanel.GetY(val - range);
                if (prevVal != 0.0)
                {
                    _errorLines[0].Y1 = lY1;
                    _errorLines[0].Y2 = lY2;
                    Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _linesError[1]);
                }

                lY1 = _chartPanel.GetY(prevVal);
                lY2 = _chartPanel.GetY(val);
                if (prevVal != 0.0)
                {
                    _errorLines[1].Y1 = lY1;
                    _errorLines[1].Y2 = lY2;
                    Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _linesError[2]);
                }

                prevVal = val;
            }
            if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting)
            {
                Utils.DrawLine(rect.Left, 0, rect.Left, _chartPanel.Height, Stroke, StrokeType, StrokeThickness, _lines);
                Utils.DrawLine(rect.Right, 0, rect.Right, _chartPanel.Height, Stroke, StrokeType, StrokeThickness, _lines);
            }

            _lines.Stop();

            _lines.Do(l => l.ZIndex = ZIndexConstants.LineStudies1);

            _errorLines[0].X1 = rect.Left;
            _errorLines[0].X2 = rect.Right;
            _errorLines[1].X1 = rect.Left;
            _errorLines[1].X2 = rect.Right;
            _errorLines[2].X1 = rect.Left;
            _errorLines[2].X2 = rect.Right;

            if (_contextLine == null && _linesError.Count > 0)
            {
                _contextLine = new ContextLine(this);
            }
        }
Exemple #12
0
        public override bool Paint()
        {
            /*
             * highestVolume = highest volume up to current record (not after)
             *
             * x = volume / highestVolume
             * if x = 0 then x = 1
             *
             * 1,0.25,0.5,0.75,0.25,0.5,1
             * total=4.25
             *
             * /4.25 total
             * 0.235,0.058,0.117,0.176,0.058,0.117,0.235=1
             *
             * 300* pixels
             * 70.5,17.4,35.1,52.8,17.4,35.1,70.5=300
             *
             */
            if (_series.OHLCType == SeriesTypeOHLC.Volume)
            {
                return(false);
            }
            StockChartX chartX = _series._chartPanel._chartX;

            Series open = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open);

            if (open == null || open.Painted || open.RecordCount == 0)
            {
                return(false);
            }
            Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (high == null || high.Painted || high.RecordCount == 0)
            {
                return(false);
            }
            Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (low == null || low.Painted || low.RecordCount == 0)
            {
                return(false);
            }
            Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close);

            if (close == null || close.Painted || close.RecordCount == 0)
            {
                return(false);
            }
            Series volume = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Volume);

            if (volume == null || volume.RecordCount == 0)
            {
                return(false);
            }

            open.Painted = high.Painted = low.Painted = close.Painted = true;

            double width = chartX.PaintableWidth;

            const int up   = 1;
            const int down = 2;
            double    highestVolume;
            double    x;
            double    equiVol;
            double    total = 0;

            Types.RectEx box;

            Brush customBrush = new SolidColorBrush(_series._strokeColor);
            Brush upBrush     = new SolidColorBrush(_series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor);
            Brush downBrush   = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor);
            Brush upGradBrush = Utils.CreateFadeVertBrush(_series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor,
                                                          Colors.Black);
            Brush downGradBrush = Utils.CreateFadeVertBrush(Colors.Black,
                                                            _series._downColor.HasValue
                                                        ? _series._downColor.Value
                                                        : chartX.DownColor);

            chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1];
            int cnt = 0;

            _lines.C = _rects.C = _rects3D.C = _series._chartPanel._rootCanvas;
            _lines.Start();
            _rects.Start();
            _rects3D.Start();

            // Count total Equi-Volume
            int n;

            for (n = chartX._startIndex; n < chartX._endIndex; n++)
            {
                if (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue ||
                    !volume[n].Value.HasValue)
                {
                    continue;
                }

                // Calculate Equi-Volume
                highestVolume = HighestVolumeToRecord(n, volume);
                x             = highestVolume != 0.0 ? volume[n].Value.Value / highestVolume : 0;
                total        += x;

                if (!chartX._darwasBoxes)
                {
                    continue;
                }

                equiVol = volume[n].Value.Value / highestVolume;
                equiVol = equiVol / total;
                equiVol = width * equiVol;
                x      += equiVol;
                // Record the x value
                chartX._xMap[cnt] = x;
                cnt++;
            }

            cnt = 0;
            x   = chartX.LeftChartSpace;
            double px = x;

            for (n = chartX._startIndex; n < chartX._endIndex; n++)
            {
                if (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue ||
                    !volume[n].Value.HasValue)
                {
                    continue;
                }

                // Calculate Equi-Volume
                highestVolume = HighestVolumeToRecord(n, volume);
                equiVol       = highestVolume != 0 ? volume[n].Value.Value / highestVolume : 0.0;
                equiVol       = equiVol / total;
                equiVol       = width * equiVol;
                x            += equiVol;

                // Record the x value
                chartX._xMap[cnt] = x;
                cnt++;

                double x1 = px;
                double x2 = x;
                double y1 = _series._chartPanel.GetY(high[n].Value.Value);
                double y2 = _series._chartPanel.GetY(low[n].Value.Value);
                if (y2 == y1)
                {
                    y1 = y2 - 2;
                }

                box = new Types.RectEx(x1, y1, x2, y2);
                Types.RectEx frame = box;

                if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow)
                {
                    if (close[n].Value > open[n].Value)
                    {
                        box.Top = _series._chartPanel.GetY(close[n].Value.Value);
                    }
                    else
                    {
                        box.Bottom = _series._chartPanel.GetY(close[n].Value.Value);
                    }
                }

                double wx = x1 + (x2 - x1) / 2;
                if (chartX._priceStyle == PriceStyleEnum.psCandleVolume)
                {
                    if (close[n].Value > open[n].Value)
                    {
                        box.Top    = _series._chartPanel.GetY(close[n].Value.Value);
                        box.Bottom = _series._chartPanel.GetY(open[n].Value.Value);
                    }
                    else
                    {
                        box.Top    = _series._chartPanel.GetY(open[n].Value.Value);
                        box.Bottom = _series._chartPanel.GetY(close[n].Value.Value);
                    }
                    if (box.Bottom == box.Top)
                    {
                        box.Top = box.Bottom - 2;
                    }

                    Utils.DrawLine(wx, y1, wx, y2, customBrush, _series.StrokePattern, _series._strokeThickness, _lines);

                    frame = box;
                }

                // Is the bar up or down?
                int direction;
                if (n == 0)
                {
                    direction = close[n].Value > open[n].Value ? up : down;
                }
                else
                {
                    direction = close[n].Value > close[n - 1].Value ? up : down;
                }

                if (chartX.ThreeDStyle)
                {
                    if (direction == up)
                    {
                        Utils.DrawRectangle(box, upGradBrush, _rects);
                        if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow)
                        {
                            Utils.Draw3DRectangle(frame, upBrush, downBrush, _rects3D);
                        }
                    }
                    else
                    {
                        Utils.DrawRectangle(box, downGradBrush, _rects);
                        if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow)
                        {
                            Utils.Draw3DRectangle(frame, upBrush, downBrush, _rects3D);
                        }
                    }
                }
                else
                {
                    if (direction == up)
                    {
                        Utils.DrawRectangle(box, upBrush, _rects);
                        if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow)
                        {
                            Utils.Draw3DRectangle(frame, upBrush, upBrush, _rects3D);
                        }
                    }
                    else
                    {
                        Utils.DrawRectangle(box, downBrush, _rects);
                        if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow)
                        {
                            Utils.Draw3DRectangle(frame, downBrush, downBrush, _rects3D);
                        }
                    }
                }

                px = x;
            }

            _lines.Stop();
            _rects.Stop();
            _rects3D.Stop();

            _lines.Do(l => l.ZIndex   = ZIndexConstants.PriceStyles1);
            _rects.Do(r => r.ZIndex   = ZIndexConstants.PriceStyles2);
            _rects3D.Do(r => r.ZIndex = ZIndexConstants.PriceStyles3);

            return(true);
        }
        public override bool Paint()
        {
            if (_series.OHLCType == SeriesTypeOHLC.Volume)
            {
                return(false);
            }
            //Find Series
            Series open = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open);

            if (open == null || open.RecordCount == 0 || open.Painted)
            {
                return(false);
            }
            Series high = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (high == null || high.RecordCount == 0 || high.Painted)
            {
                return(false);
            }
            Series low = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (low == null || low.RecordCount == 0 || low.Painted)
            {
                return(false);
            }
            Series close = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close);

            if (close == null || close.RecordCount == 0 || close.Painted)
            {
                return(false);
            }

            _series = close;

            open.Painted = high.Painted = low.Painted = close.Painted = true;

            CalculateCandleSpacing();
            if (ChartX._barSpacing < 0)
            {
                return(false);
            }

            _upColor   = _series._upColor.HasValue ? _series._upColor.Value : ChartX.UpColor;
            _downColor = _series._downColor.HasValue ? _series._downColor.Value : ChartX.DownColor;

            if (_oldOptimizePainting.HasValue && _oldOptimizePainting.Value != ChartX.OptimizePainting)
            {
                if (!ChartX.OptimizePainting)
                {
                    Canvas c = _series._chartPanel._rootCanvas;
                    c.Children.Remove(_pathCandlesDown);
                    c.Children.Remove(_pathCandlesUp);
                    c.Children.Remove(_pathWicksUp);
                    c.Children.Remove(_pathWicksDown);

                    _pathCandlesDown = null;
                    _pathCandlesUp   = null;
                    _pathWicksUp     = null;
                    _pathWicksDown   = null;
                }
                else
                {
                    _candles.RemoveAll();
                }
            }
            _oldOptimizePainting = ChartX.OptimizePainting;

            if (ChartX.OptimizePainting)
            {
                return(PaintOptimized(new[] { open, high, low, close }, _series));
            }

            if (!_subscribedToCustomBrush)
            {
                _subscribedToCustomBrush    = true;
                ChartX.OnCandleCustomBrush += ChartX_OnCandleCustomBrush;
            }


            //bool setBrushes = false;
            if (!_old3DStyle.HasValue || _old3DStyle.Value != ChartX.ThreeDStyle ||
                !_oldUpColor.HasValue || _oldUpColor.Value != _upColor ||
                !_oldDownColor.HasValue || _oldDownColor.Value != _downColor ||
                (ChartX._candleDownOutlineColor.HasValue && ChartX._candleDownOutlineColor.Value != _oldCandleDownOutline) ||
                ChartX._candleUpOutlineColor.HasValue && ChartX._candleUpOutlineColor.Value != _oldCandleUpOutline)
            {
                //setBrushes = true;
                _old3DStyle   = ChartX.ThreeDStyle;
                _oldUpColor   = _upColor;
                _oldDownColor = _downColor;

                _upBrush = !ChartX.ThreeDStyle
                     ? (Brush) new SolidColorBrush(_upColor)
                     : new LinearGradientBrush
                {
                    StartPoint    = new Point(0, 0.5),
                    EndPoint      = new Point(1, 0.5),
                    GradientStops =
                    {
                        new GradientStop
                        {
                            Color  = _upColor,
                            Offset = 0
                        },
                        new GradientStop
                        {
                            Color  = Constants.FadeColor,
                            Offset = 1.25
                        }
                    }
                };
#if WPF
                _upBrush.Freeze();
#endif

                _downBrush = !ChartX.ThreeDStyle
                       ? (Brush) new SolidColorBrush(_downColor)
                       : new LinearGradientBrush
                {
                    StartPoint    = new Point(0, 0.5),
                    EndPoint      = new Point(1, 0.5),
                    GradientStops =
                    {
                        new GradientStop
                        {
                            Color  = _downColor,
                            Offset = 0
                        },
                        new GradientStop
                        {
                            Color  = Constants.FadeColor,
                            Offset = 1.25
                        }
                    }
                };
#if WPF
                _downBrush.Freeze();
#endif

                if (ChartX._candleDownOutlineColor.HasValue)
                {
                    _oldCandleDownOutline   = ChartX._candleDownOutlineColor.Value;
                    _candleDownOutlineBrush = new SolidColorBrush(ChartX._candleDownOutlineColor.Value);
#if WPF
                    _candleDownOutlineBrush.Freeze();
#endif
                }
                if (ChartX._candleUpOutlineColor.HasValue)
                {
                    _oldCandleUpOutline   = ChartX._candleUpOutlineColor.Value;
                    _candleUpOutlineBrush = new SolidColorBrush(ChartX._candleUpOutlineColor.Value);
#if WPF
                    _candleUpOutlineBrush.Freeze();
#endif
                }
            }

            int n;

            _candles.C = _series._chartPanel._rootCanvas;
            _candles.Start();

            for (n = ChartX._startIndex; n < ChartX._endIndex; n++)
            {
                if (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue)
                {
                    continue;
                }

                Candle candle = _candles.GetPaintObject(_upBrush, _downBrush);
                candle.Init(_series);
                //if (setBrushes)   //because if we have a small number of bars, then enlarge the new brushes won't be propagated to new candles.
                candle.SetBrushes(_upBrush, _downBrush, _candleUpOutlineBrush, _candleDownOutlineBrush);
                candle.SetValues(open[n].Value.Value, high[n].Value.Value, low[n].Value.Value, close[n].Value.Value, ChartX._barSpacing,
                                 _halfwick, n - ChartX._startIndex);
            }
            _candles.Stop();

            _candles.Do(c => c.ZIndex = ZIndexConstants.PriceStyles1);

            return(true);
        }
Exemple #14
0
        public override bool Paint()
        {
            if (_series.OHLCType == SeriesTypeOHLC.Open || _series.OHLCType == SeriesTypeOHLC.Volume)
            {
                return(false);
            }
            Series sHigh = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (sHigh == null || sHigh.RecordCount == 0 || sHigh.Painted)
            {
                return(false);
            }
            Series sLow = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (sLow == null || sLow.RecordCount == 0 || sLow.Painted)
            {
                return(false);
            }
            Series sClose = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close);

            if (sClose == null || sClose.RecordCount == 0 || sClose.Painted)
            {
                return(false);
            }

            sHigh.Painted = sLow.Painted = sClose.Painted = true;

            StockChartX chartX = _series._chartPanel._chartX;

            double reversalSize = chartX._priceStyleParams[0];

            if (reversalSize > 50 || reversalSize < 0.0001)
            {
                reversalSize = 1;
            }

            double ptsOrPct = chartX._priceStyleParams[1];

            if (ptsOrPct != 2 && ptsOrPct != 1)
            {
                ptsOrPct = 1; // Points = 1, Percent = 2
            }
            chartX._priceStyleParams[1] = ptsOrPct;
            chartX._priceStyleParams[0] = reversalSize;

            double reverse;

            chartX._psValues1.Clear();
            chartX._psValues2.Clear();
            chartX._psValues3.Clear();

            double    nClose = 0, nClose2;
            double    start = 0;
            const int percent = 2;
            const int up = 1;
            const int down = 2;
            int       direction = 0; // up or down
            int       weight = 0;    // thick or thin
            int       totalBars = 0;
            double    max = 0, min = 0;
            double    oldMax = 0, oldMin = 0;

            if (sClose.RecordCount < 3)
            {
                return(false);
            }

            chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1];
            int cnt = 0;

            // Count columns that will fit on screen
            int n;

            for (n = 0; n < chartX._endIndex + 1; n++)
            {
                if (n >= sClose.RecordCount)
                {
                    continue;
                }
                if (!sClose[n].Value.HasValue)
                {
                    continue;
                }
                nClose = sClose[n].Value.Value;

                if (ptsOrPct == percent)
                {
                    reverse = nClose * reversalSize; // Percent
                }
                else
                {
                    reverse = reversalSize; // Points
                }
                if (direction == 0)
                { // First bar
                    nClose2 = sClose[n + 1].Value.Value;
                    if (nClose2 > nClose)
                    {
                        direction = up;
                        weight    = thick;
                        start     = nClose;
                        max       = nClose;
                    }
                    else
                    {
                        direction = down;
                        weight    = thin;
                        start     = nClose2;
                        min       = nClose2;
                    }
                }

                switch (direction)
                {
                case up:
                    if (nClose > max)
                    {
                        max = nClose;
                        if (max > start)
                        {
                            weight = thick;
                        }
                    }
                    else if (nClose < max - reverse)
                    {
                        direction = down;
                        start     = max;
                        min       = nClose;
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBars++;
                        }
                    }
                    break;

                case down:
                    if (nClose < min)
                    {
                        min = nClose;
                        if (min < start)
                        {
                            weight = thin;
                        }
                    }
                    else if (nClose > min + reverse)
                    {
                        direction = up;
                        start     = min;
                        max       = nClose;
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBars++;
                        }
                    }
                    break;
                }
            }

            chartX._xCount = totalBars;

            if (totalBars == 0)
            {
                return(false);
            }
            double space = chartX.PaintableWidth / totalBars;

            totalBars = 0;
            direction = 0;
            int pWeight = 0;

            _lines.C = _series._chartPanel._rootCanvas;
            _lines.Start();
            // Calculate from beginning, but only show between startIndex and endIndex
            double x = _series._chartPanel._chartX.LeftChartSpace;

            for (n = 0; n < chartX._endIndex; n++)
            {
                if (sClose[n].Value.HasValue)
                {
                    nClose = sClose[n].Value.Value;


                    if (ptsOrPct == percent)
                    {
                        reverse = nClose * reversalSize; // Percent
                    }
                    else
                    {
                        reverse = reversalSize; // Points
                    }
                    if (direction == 0)
                    { // First bar
                        nClose2 = sClose[n + 1].Value.Value;
                        if (nClose2 > nClose)
                        {
                            direction = up;
                            weight    = thick;
                            max       = nClose;
                            min       = nClose;
                            oldMin    = nClose2;
                            oldMax    = nClose;
                            pWeight   = thick;
                        }
                        else
                        {
                            direction = down;
                            weight    = thin;
                            min       = nClose2;
                            max       = nClose2;
                            oldMin    = nClose;
                            oldMax    = nClose2;
                            pWeight   = thin;
                        }
                    }

                    switch (direction)
                    {
                    case up:
                        if (nClose > max)
                        {
                            max = nClose;
                            if (max > oldMax)
                            {
                                weight = thick;
                            }
                        }
                        else if (nClose < max - reverse)
                        {
                            // Paint previous up bar
                            if (weight == pWeight)
                            {
                                oldMax = 0;
                            }
                            if (n >= chartX._startIndex && n <= chartX._endIndex)
                            {
                                PaintBar(x, space, max, min, up, weight, oldMax);
                                x += space;
                            }

                            pWeight   = weight;
                            direction = down;
                            oldMin    = min;
                            min       = nClose;
                            totalBars++;
                        }
                        break;

                    case down:
                        if (nClose < min)
                        {
                            min = nClose;
                            if (min < oldMin)
                            {
                                weight = thin;
                            }
                        }
                        else if (nClose > min + reverse)
                        {
                            // Paint previous down bar
                            if (weight == pWeight)
                            {
                                oldMin = 0;
                            }
                            if (n >= chartX._startIndex && n <= chartX._endIndex)
                            {
                                PaintBar(x, space, max, min, down, weight, oldMin);
                                x += space;
                            }

                            pWeight   = weight;
                            direction = up;
                            oldMax    = max;
                            max       = nClose;
                            totalBars++;
                        }
                        break;
                    }

                    // Record the x value
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        chartX._xMap[cnt] = x + (space / 2);
                        cnt++;
                    }
                }

                chartX._psValues1.Add(new PriceStyleValue(sClose[n].TimeStamp, max));
                chartX._psValues2.Add(new PriceStyleValue(sClose[n].TimeStamp, min));
                chartX._psValues3.Add(new PriceStyleValue(sClose[n].TimeStamp, (direction == up) ? 1 : -1));
            }

            switch (direction)
            {
            case up:
                if (nClose > max)
                {
                    max = nClose;
                    if (max >= oldMax)
                    {
                        weight = thick;
                    }
                }
                if (weight == pWeight)
                {
                    oldMax = 0;
                }
                break;

            case down:
                if (nClose <= min)
                {
                    min = nClose;
                    if (min < oldMin)
                    {
                        weight = thin;
                    }
                }
                if (weight == pWeight)
                {
                    oldMin = 0;
                }
                break;
            }

            if (direction == down)
            {
                PaintBar(x, 0, max, min, down, weight, oldMin);
            }
            else
            {
                PaintBar(x, 0, max, min, up, weight, oldMax);
            }

            chartX._psValues1.Add(new PriceStyleValue(sClose[n - 1].TimeStamp, max));
            chartX._psValues2.Add(new PriceStyleValue(sClose[n - 1].TimeStamp, min));
            chartX._psValues3.Add(new PriceStyleValue(sClose[n - 1].TimeStamp, (direction == up) ? 1 : -1));

            _lines.Stop();

            _lines.Do(l => l.ZIndex = ZIndexConstants.PriceStyles1);

            return(true);
        }
Exemple #15
0
    public override bool Paint()
    {
      //Find Series
      Series open = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open);
      if (open == null || open.RecordCount == 0 || open.Painted) return false;
      Series high = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);
      if (high == null || high.RecordCount == 0 || high.Painted) return false;
      Series low = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);
      if (low == null || low.RecordCount == 0 || low.Painted) return false;
      Series close = _series._chartPanel.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close);
      if (close == null || close.RecordCount == 0 || close.Painted) return false;

      open.Painted = high.Painted = low.Painted = close.Painted = true;

      StockChartX chartX = _series._chartPanel._chartX;
      chartX._xMap = new double[chartX._xCount = 0];

      const int iStep = 1;
      int rcnt = chartX.RecordCount;
      double x2 = chartX.GetXPixel(rcnt);
      double x1 = chartX.GetXPixel(rcnt - 1);
      double space = ((x2 - x1) / 2) - chartX._barWidth / 2;
      if (space > 20) space = 20;
      if (space > _series._chartPanel._chartX._barSpacing)
        _series._chartPanel._chartX._barSpacing = space;

      space = Math.Ceiling(space * 0.75);

      Color upColor = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor;
      Color downColor = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor;
      _upBrush = !chartX.ThreeDStyle
                   ? (Brush)new SolidColorBrush(upColor)
                   : new LinearGradientBrush
                       {
                         StartPoint = new Point(0, 0.5),
                         EndPoint = new Point(1, 0.5),
                         GradientStops =
                           {
                             new GradientStop { Color = upColor, Offset = 0 },
                             new GradientStop { Color = Constants.FadeColor, Offset = 1.25 }
                           }
                       };
      _downBrush = !chartX.ThreeDStyle
                     ? (Brush)new SolidColorBrush(downColor)
                     : new LinearGradientBrush
                         {
                           StartPoint = new Point(0, 0.5),
                           EndPoint = new Point(1, 0.5),
                           GradientStops =
                             {
                               new GradientStop { Color = downColor, Offset = 0 },
                               new GradientStop { Color = Constants.FadeColor, Offset = 1.25 }
                             }
                         };
      if (chartX._candleDownOutlineColor.HasValue)
        _candleDownOutlineBrush = new SolidColorBrush(chartX._candleDownOutlineColor.Value);
      if (chartX._candleUpOutlineColor.HasValue)
        _candleUpOutlineBrush = new SolidColorBrush(chartX._candleUpOutlineColor.Value);

      double wick = chartX._barWidth;
      double halfwick = wick / 2;
      if (halfwick < 1)
        halfwick = 1;

      int n;

      //int t = Environment.TickCount;
      _candles.C = _series._chartPanel._rootCanvas;
      _candles.Start();

      Debug.WriteLine("StartIndex " + chartX._startIndex + " EndIndex " + chartX._endIndex);

      for (n = chartX._startIndex; n < chartX._endIndex; n += iStep)
      {
        if (n == 0 && (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue))
          continue;
        if (n > 0 && (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue ||
          !open[n - 1].Value.HasValue || !close[n - 1].Value.HasValue))
          continue;

        CandleHeikinAshi candle = _candles.GetPaintObject(_upBrush, _downBrush);
        candle.Init(_series);
        candle.SetBrushes(_upBrush, _downBrush, _candleUpOutlineBrush, _candleDownOutlineBrush);
        candle.SetValues(open[n], high[n], low[n], close[n], space, halfwick, n - chartX._startIndex);
      }
      _candles.Stop();

      _candles.Do(c => c.ZIndex = ZIndexConstants.PriceStyles1);

      Debug.WriteLine("Candles count " + _candles.Count);

      return true;
    }
Exemple #16
0
        public override bool Paint()
        {
            if (_series._seriesTypeOHLC != SeriesTypeOHLC.Close)
            {
                return(false);
            }

            StockChartX chartX = _series._chartPanel._chartX;
            Series      open   = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open);
            Series      high   = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (high == null || high.Painted || high.RecordCount == 0)
            {
                return(false);
            }

            Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (low == null || low.Painted || low.RecordCount == 0)
            {
                return(false);
            }

            Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close);

            if (close == null || close.Painted || close.RecordCount == 0)
            {
                return(false);
            }

            high.Painted = low.Painted = close.Painted = true;

            if (!_subscribedToCustomBrush)
            {
                _subscribedToCustomBrush    = true;
                chartX.OnCandleCustomBrush += ChartX_OnCandleCustomBrush;
            }

            bool  changeBrushes = false;
            Color upColor       = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor;
            Color downColor     = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor;

            if (!_oldUpColor.HasValue || _oldUpColor.Value != upColor)
            {
                _upBrush = new SolidColorBrush(upColor);
                _upBrush.Freeze();
                _oldUpColor   = upColor;
                changeBrushes = true;
            }

            if (!_oldDownColor.HasValue || _oldDownColor.Value != downColor)
            {
                _downBrush = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor);
                _downBrush.Freeze();
                _oldDownColor = downColor;
                changeBrushes = true;
            }

            if (!_oldStrokeColor.HasValue || _oldStrokeColor.Value != _series._strokeColor)
            {
                _customBrush = new SolidColorBrush(_series._strokeColor);
                _customBrush.Freeze();
                _oldStrokeColor = _series._strokeColor;
                changeBrushes   = true;
            }

            int    rcnt  = chartX.RecordCount;
            double x2    = chartX.GetXPixel(rcnt);
            double x1    = chartX.GetXPixel(rcnt - 1);
            double space = ((x2 - x1) / 2) - chartX._barWidth / 2;

            if (space > 20)
            {
                space = 20;
            }

            chartX._barSpacing = space;

            int cnt = 0;

            ((ModulusFE.Stock)_series)._priceStyleStock = this;

            _stocks.C = _series._chartPanel._rootCanvas;
            _stocks.Start();

            for (int n = chartX._startIndex; n < chartX._endIndex; n++, cnt++)
            {
                if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue)
                {
                    continue;
                }

                PaintObjects.Stock stock = _stocks.GetPaintObject(_upBrush, _downBrush, _customBrush);
                stock.Init(_series);
                if (changeBrushes)
                {
                    stock.SetBrushes(_upBrush, _downBrush, _customBrush);
                }

                stock.SetValues(open != null ? open[n].Value : null, high[n].Value.Value, low[n].Value.Value, close[n].Value.Value, space, n - chartX._startIndex);
            }

            _stocks.Stop();
            _stocks.Do(s => s.ZIndex = ZIndexConstants.PriceStyles1);

            return(true);
        }
        public override bool Paint()
        {
            /*
             * pCtrl->priceStyleParams[0] = lines
             * 7 columns
             * width = 300
             * 300 / 7 = 42.85 pixels per column
             */

            if (_series.OHLCType == SeriesTypeOHLC.Open)
            {
                return(false);
            }

            StockChartX chartX = _series._chartPanel._chartX;
            Series      high   = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

            if (high == null || high.Painted || high.RecordCount == 0)
            {
                return(false);
            }
            Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low);

            if (low == null || low.Painted || low.RecordCount == 0)
            {
                return(false);
            }
            Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close);

            if (close == null || close.Painted || close.RecordCount == 0)
            {
                return(false);
            }

            high.Painted = low.Painted = close.Painted = true;

            double width = chartX.PaintableWidth;

            double lines = chartX._priceStyleParams[0];

            if (lines > 50 || lines < 1)
            {
                lines = 3;
                chartX._priceStyleParams[0] = lines;
            }

            _highs = new double[(int)lines];
            _lows  = new double[(int)lines];

            double    nClose, nHH = 0, nLL = 0;
            const int white       = 1;
            const int black       = 2;
            double    nStart      = 0;
            int       block       = 0; // black or white
            int       totalBlocks = 0;

            chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1];
            int cnt = 0;

            chartX._psValues1.Clear();
            chartX._psValues2.Clear();
            chartX._psValues3.Clear();

            // Count columns that will fit on screen
            int n;

            for (n = 0; n < chartX._endIndex; n++)
            {
                if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue)
                {
                    continue;
                }
                // Calculate N Line Break
                nClose = (double)close[n].Value;


                switch (block)
                {
                case white:
                    if (IsNewBlock(-1, nClose))
                    {
                        nHH    = nStart; // New black block
                        nLL    = nClose;
                        nStart = nClose;
                        block  = black;
                        AddBlock(nHH, nLL);
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBlocks++;
                        }
                    }
                    if (IsNewBlock(1, nClose))
                    {
                        nHH    = nClose; // New white block
                        nLL    = nStart;
                        nStart = nClose;
                        block  = white;
                        AddBlock(nHH, nLL);
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBlocks++;
                        }
                    }
                    break;

                case black:
                    if (IsNewBlock(1, nClose))
                    {
                        nHH    = nClose; // New white block
                        nLL    = nStart;
                        nStart = nClose;
                        block  = white;
                        AddBlock(nHH, nLL);
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBlocks++;
                        }
                    }
                    if (IsNewBlock(-1, nClose))
                    {
                        nHH    = nStart; // New black block
                        nLL    = nClose;
                        nStart = nClose;
                        block  = black;
                        AddBlock(nHH, nLL);
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            totalBlocks++;
                        }
                    }
                    break;
                }

                if (block != 0)
                {
                    continue;     // Prime first block
                }
                double nClose2 = (double)close[n + 1].Value;
                if (nClose2 > nClose)
                {
                    block = white; nHH = nClose2; nLL = nClose; nStart = nClose;
                }
                else
                {
                    block = black; nHH = nClose; nLL = nClose2; nStart = nClose2;
                }
                AddBlock(nHH, nLL);
                if (n >= chartX._startIndex && n <= chartX._endIndex)
                {
                    totalBlocks++;
                }
            }

            chartX._xCount = totalBlocks;
            _highs         = new double[(int)lines];
            _lows          = new double[(int)lines];
            Color upColor       = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor;
            Color downColor     = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor;
            Brush upBrush       = new SolidColorBrush(upColor);
            Brush downBrush     = new SolidColorBrush(downColor);
            Brush upGradBrush   = Utils.CreateFadeVertBrush(upColor, Colors.Black);
            Brush downGradBrush = Utils.CreateFadeVertBrush(downColor, Colors.Black);

            _rects.C = _series._chartPanel._rootCanvas;
            _rects.Start();


            // Paint columns
            block = 0;
            double x = chartX.LeftChartSpace;

            if (totalBlocks == 0)
            {
                return(false);
            }
            double space = width / totalBlocks;

            totalBlocks = 0;

            // Calculate from beginning, but only show between startIndex and endIndex
            for (n = 0; n < chartX._endIndex; n++)
            {
                if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue)
                {
                    continue;
                }
                // Calculate N Line Break
                nClose = (double)close[n].Value;

                switch (block)
                {
                case white:
                    if (IsNewBlock(-1, nClose))
                    {
                        // Paint last white block
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, 1, n, close);
                            x += space;
                        }

                        nHH    = nStart; // New black block
                        nLL    = nClose;
                        nStart = nClose;
                        block  = black;
                        AddBlock(nHH, nLL);
                        totalBlocks++;
                    }
                    if (IsNewBlock(1, nClose))
                    {
                        // Paint last black block
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, 1, n, close);
                            x += space;
                        }

                        nHH    = nClose; // New white block
                        nLL    = nStart;
                        nStart = nClose;
                        block  = white;
                        AddBlock(nHH, nLL);
                        totalBlocks++;
                    }
                    break;

                case black:
                    if (IsNewBlock(1, nClose))
                    {
                        // Paint last white block
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, -1, n, close);
                            x += space;
                        }

                        nHH    = nClose; // New white block
                        nLL    = nStart;
                        nStart = nClose;
                        block  = white;
                        AddBlock(nHH, nLL);
                        totalBlocks++;
                    }
                    if (IsNewBlock(-1, nClose))
                    {
                        // Paint last black block
                        if (n >= chartX._startIndex && n <= chartX._endIndex)
                        {
                            PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, -1, n, close);
                            x += space;
                        }

                        nHH    = nStart; // New black block
                        nLL    = nClose;
                        nStart = nClose;
                        block  = black;
                        AddBlock(nHH, nLL);
                        totalBlocks++;
                    }
                    break;
                }

                if (block == 0)
                { // Prime first block
                    double nClose2 = (double)close[n + 1].Value;
                    if (nClose2 > nClose)
                    {
                        block = white; nHH = nClose2; nLL = nClose; nStart = nClose;
                    }
                    else
                    {
                        block = black; nHH = nClose; nLL = nClose2; nStart = nClose2;
                    }
                    AddBlock(nHH, nLL);
                    if (n >= chartX._startIndex && n <= chartX._endIndex)
                    {
                        totalBlocks = 1;
                    }
                    x = chartX.LeftChartSpace;
                }

                // Record the x value
                if (n >= chartX._startIndex && n <= chartX._endIndex)
                {
                    chartX._xMap[cnt] = x + (space / 2);
                    cnt++;
                }
            }

            // Finish last block
            if (block == black)
            {
                PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, -1, n, close);
            }
            else
            {
                PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, 1, n, close);
            }

            _rects.Stop();

            _rects.Do(r => r.ZIndex = ZIndexConstants.PriceStyles1);

            return(true);
        }
        internal override void Paint()
        {
            //Debug.WriteLine("ChartPanel heat map paint");
            if (!_templateLoaded || _painting)
            {
                _timers.StopTimerWork(TimerSizeChanged);
                return;
            }
            _rects.C = _rootCanvas;
            _rects.Start();
            _labels.C = _rootCanvas;
            _labels.Start();

            List <Series> indicators       = _chartX.IndicatorsCollection.Cast <Series>().ToList();
            var           seriesForHeatMap = _chartX.SeriesCollection.Where(s => s.ShowInHeatMap);

            indicators.AddRange(seriesForHeatMap);

            //IEnumerable<Indicator> indicators = _chartX.IndicatorsCollection;
            if (indicators.Count() == 0)
            {
                _timers.StopTimerWork(TimerSizeChanged);
                _rects.Stop();
                _labels.Stop();
                return;
            }
            _painting = true;

            double panelHeight = _rootCanvas.ActualHeight / indicators.Count;
            double rectWidth   = _chartX.PaintableWidth / (_chartX._endIndex - _chartX._startIndex);

            int indicatorIndex = 0;

            foreach (Series indicator in indicators)
            {
                double min;
                double max;

                indicator.DM.VisibleMinMax(indicator.SeriesIndex, out min, out max);
                if (indicator.RecordCount == 0)
                {
                    continue;
                }

                int cnt = 0;
                for (int i = _chartX._startIndex; i < _chartX._endIndex; i++, cnt++)
                {
                    double?value = indicator[i].Value;

                    if (!value.HasValue || min == max)
                    {
                        continue;
                    }

                    Brush brush = _brushes[(int)((_brushes.Length - 1) * (value.Value - min) / (max - min))];

                    double    x         = cnt * rectWidth + _chartX.LeftChartSpace;
                    double    y         = indicatorIndex * panelHeight;
                    Rectangle rectangle = Utils.DrawRectangle(x, y, x + rectWidth + 1, y + panelHeight, brush, _rects);
                    rectangle._rectangle.Stroke = brush;
                }
                Label lbl = Utils.DrawText(_chartX.LeftChartSpace + 10, indicatorIndex * panelHeight + 2,
                                           indicator.Title, _chartX.HeatPanelLabelsForeground,
                                           _chartX.HeatPanelLabelsFontSize, _chartX.FontFamily, _labels);
#if WPF
                lbl._textBlock.Background = _chartX.HeatPanelLabelsBackground;
#endif

                indicatorIndex++;
            }
            _rects.Stop();
            _labels.Stop();

            _rects.Do(r => r.ZIndex  = ZIndexConstants.DarvasBoxes1);
            _labels.Do(l => l.ZIndex = ZIndexConstants.DarvasBoxes2);

            _painting = false;
            _timers.StopTimerWork(TimerSizeChanged);
        }
Exemple #19
0
        internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus)
        {
            if (lineStatus == LineStatus.StartPaint)
            {
                for (int i = 0; i < _lines.Length; i++)
                {
                    _lines[i] = new System.Windows.Shapes.Line {
                        Tag = this
                    };
                    Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1);
                    C.Children.Add(_lines[i]);
                }

                if (_contextLine == null)
                {
                    _contextLine = new ContextLine(this);
                    _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this));
                }

                _internalObjectCreated = true;

                return;
            }

            rect.Normalize();

            if (rect.Width == 0)
            {
                return;
            }

            int revX1 = (int)(_chartX.GetReverseXInternal(rect.Left) + _chartX._startIndex);
            int revX2 = (int)(_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex);

            if (revX1 < 0)
            {
                revX1 = 0;
            }
            if (revX2 < 0)
            {
                revX2 = 0;
            }

            if (revX1 == revX2)
            {
                return;
            }

            // Get the highest high of the high series.
            // Note: this code makes the vague assumption
            // that only one symbol exists on this panel.
            Series sHigh = GetSeriesOHLC(SeriesTypeOHLC.High);

            if (sHigh == null)
            {
                return;
            }
            Series sLow = GetSeriesOHLC(SeriesTypeOHLC.Low);

            if (sLow == null)
            {
                return;
            }
            Series sClose = GetSeriesOHLC(SeriesTypeOHLC.Close);

            if (revX1 >= sHigh.RecordCount)
            {
                revX1 = sHigh.RecordCount;
            }
            if (revX2 >= sHigh.RecordCount)
            {
                revX2 = sHigh.RecordCount;
            }

            //**********
            // Perform linear regression on the data
            double xSum = 0, ySum = 0, xSquaredSum = 0, xYSum = 0;
            int    n, j;

            if (revX1 > revX2)
            {
                revX2 = revX1;
            }
            int x = revX2 - revX1;

            for (n = 1; n != x + 1; ++n)
            {
                j            = revX1 + n - 1;
                xSum        += n;
                ySum        += sClose[j].Value.Value;
                xSquaredSum += (n * n);
                xYSum       += (sClose[j].Value.Value * n);
            }
            n = x;
            double q1         = n != 0 ? (xYSum - ((xSum * ySum) / n)) : 0;
            double q2         = n != 0 ? (xSquaredSum - ((xSum * xSum) / n)) : 0;
            double slope      = q2 != 0 ? (q1 / q2) : 0;
            double leftValue  = slope != 0 ? (((1 / (double)n) * ySum) - (((int)((double)n / 2)) * slope)) : 0.0;
            double rightValue = ((n * slope) + leftValue);
            double right      = (x - 1);
            double inc        = 0;

            if (right != 0)
            {
                inc = (rightValue - leftValue) / right;
            }

            double prevVal = 0.0;

            j = 0;
            // Find max distance from linear regression line
            double lowestLow   = sHigh[0].Value.Value;
            double highestHigh = 0;

            for (n = revX1; n < revX2; ++n)
            {
                j++;
                double val = leftValue + inc * (j - 1);
                if (prevVal != 0)
                {
                    if (sHigh[n].Value.Value - val > highestHigh)
                    {
                        highestHigh = sHigh[n].Value.Value - val;
                    }
                    if (val - sLow[n].Value.Value < lowestLow &&
                        val - sLow[n].Value.Value > 0)
                    {
                        lowestLow = val - sLow[n].Value.Value;
                    }
                }
                prevVal = val;
            }
            if (highestHigh > lowestLow)
            {
                lowestLow = highestHigh;
            }
            if (lowestLow > highestHigh)
            {
                highestHigh = lowestLow;
            }

            _linesSel.C = C;

            double lX1 = _chartX.GetXPixel(revX1 - _chartX._startIndex);
            double lX2 = _chartX.GetXPixel(revX2 - _chartX._startIndex + 1);

            j = 0;
            for (n = revX1; n < revX2; n++, j++)
            {
                double val = leftValue + inc * (j - 1);
                double lY1 = _chartPanel.GetY(prevVal - lowestLow);
                double lY2 = _chartPanel.GetY(val - lowestLow);
                if (prevVal != 0)
                {
                    Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _lines[0]);
                }

                lY1 = _chartPanel.GetY(prevVal);
                lY2 = _chartPanel.GetY(val);
                if (prevVal != 0)
                {
                    Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _lines[1]);
                }

                lY1 = _chartPanel.GetY(prevVal + highestHigh);
                lY2 = _chartPanel.GetY(val + highestHigh);
                if (prevVal != 0)
                {
                    Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _lines[2]);
                }

                prevVal = val;
            }

            _linesSel.Start();
            if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting)
            {
                Utils.DrawLine(lX1, 0, lX1, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, _linesSel);
                Utils.DrawLine(lX2, 0, lX2, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, _linesSel);
            }
            _linesSel.Stop();
            _linesSel.Do(l => l.ZIndex = ZIndexConstants.LineStudies1);
        }
Exemple #20
0
        internal void Paint()
        {
            try
            {
                if (_painting)
                {
                    return;
                }

                _painting = true;

                _timerRepaint.StopTimerWork(TimerRepaint);
#if WPF
#if DEMO
                if (!string.IsNullOrEmpty(_demoText) && _labelDemo == null)
                {
                    _labelDemo = new Label();
                    _labelDemo.AddTo(this);
                    _labelDemo.Left = 10;
                    _labelDemo.Top  = 2;
//        _labelDemo._textBlock.Opacity = 0.7;
                    _labelDemo._textBlock.Foreground = Brushes.Red;
                    _labelDemo.Text = _demoText;
                    _labelDemo._textBlock.FontSize = 16;
                    _labelDemo.ZIndex = 100;
                }
#endif
#endif
                Rect rcBounds = new Rect(0, 0, ActualWidth, ActualHeight);

                if (_linesPath == null)
                {
                    _linesPath = new Path
                    {
                        Stroke          = _chartX.GridStroke,
                        StrokeThickness = 1,
                    };
                    Children.Add(_linesPath);
                }

                //Background = _chartX.Background;
                //_lines.C = this;
                _labels.C = this;
                //_lines.Start();
                _labels.Start();

                int           startIndex = _chartX._startIndex;
                GeometryGroup lines      = new GeometryGroup();

                //Utils.DrawLine(rcBounds.Left, 0, rcBounds.Right, 0, _chartX.GridStroke, LinePattern.Solid, 1, _lines);
                lines.Children.Add(new LineGeometry
                {
                    StartPoint = new Point(rcBounds.Left, 0),
                    EndPoint   = new Point(rcBounds.Right, 0),
                });

                int    rcnt         = _chartX.VisibleRecordCount;
                double periodPixels = _chartX.GetXPixel(rcnt) / rcnt;
                if (periodPixels < 1)
                {
                    periodPixels = 1;
                }

                _chartX._xGridMap.Clear();
                double tradeWeek  = periodPixels * 5;                // 5 trading days in a week (avg)
                double tradeMonth = periodPixels * 20;               // 20 trading days in a month (avg)
                double tradeYear  = periodPixels * 253;              // 253 trading days in a year (avg)

                double averageCharWidth = _chartX.GetTextWidth("0");

                // Level 1:
                // YYYY
                double level1 = averageCharWidth * 4;

                // Level 2:
                // YY F M A M J J A S O N D
                double level2 = averageCharWidth * 2;

                // Level 3:
                // YY Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
                double level3 = averageCharWidth * 3;

                // Level 4:
                // YYYY February March April May June July August September October November December
                double level4 = averageCharWidth * 9;

                // Level 5:
                // From -5 periods on right end, begin:
                // Jan DD  Feb DD  Mar DD  Apr DD  May DD  Jun DD  Jul DD  Aug DD  Sep DD  Oct DD  Nov DD  Dec DD
                double level5 = averageCharWidth * 6;

                // Level 6
                // Jan DD HH:MM
                double level6 = averageCharWidth * 10;

                double incr;
                int    xGrid = 0;
                double x, lx = 0;

                if (_chartX.RealTimeXLabels)
                {
                    string prevDay = "";

                    incr = level6;
                    string timeFormat = "HH:mm";
                    if (_chartX.ShowSeconds)
                    {
                        incr      += averageCharWidth * 2;
                        timeFormat = "HH:mm:ss";
                    }

                    for (int period = 0; period < rcnt; period++)
                    {
                        x = _chartX.GetXPixel(period);
                        if (x == lx)
                        {
                            continue;
                        }
                        DateTime dDate = DM.GetTimeStampByIndex(period + startIndex);
                        //if (dDate.Minute % 15 != 0) continue;
                        if (incr > level6)
                        {
                            incr = 0;
                            //Draw vertical line
                            //_renderDevice.PlotUnitSeparator((float)x, true, 0);
                            //Utils.DrawLine(x, 0, x, rcBounds.Height / 2, _chartX.GridStroke, LinePattern.Solid, 1, _lines);
                            lines.Children.Add(new LineGeometry
                            {
                                StartPoint = new Point(x, 0),
                                EndPoint   = new Point(x, rcBounds.Height / 2)
                            });

                            string szTime  = dDate.ToString(timeFormat);
                            string szDay   = dDate.ToString("dd");
                            string szMonth = dDate.ToString("MMM");

                            string szDate;
                            if (prevDay != szDay)
                            {
                                prevDay = szDay;
                                szDate  = szMonth + " " + szDay + " " + szTime;
                                level6  = averageCharWidth * 12;
                                lx     += level6 / 2;
                            }
                            else
                            {
                                szDate = szTime;
                            }

                            //_renderDevice.PlotUnitText((float)x, szDate, 0);
                            var lb = _labels.GetPaintObject();
                            lb.Left = x;
                            lb.Top  = 1;
                            lb.Text = szDate;
                            //Utils.DrawText(x, 1, szDate, _chartX.FontForeground, _chartX.FontSize, _chartX.FontFamily, _labels);
                            _chartX._xGridMap[xGrid++] = x;
                        }

                        incr += x - lx;
                        lx    = x;
                    }

                    _painting = false;

                    _linesPath.Data = (System.Windows.Media.Geometry)lines.GetAsFrozen();
                    //_lines.Stop();
                    _labels.Stop();
                    return;
                }

                lx = 0;
                double   oldX   = -1;
                string   sCache = "#";
                string   sDate;
                DateTime timestamp;
                DateTime?prevDate = null;
                if (level5 <= tradeWeek)
                {
                    incr = level5;
                    for (int period = 0; period < rcnt; period++)
                    {
                        x         = _chartX.GetXPixel(period);
                        timestamp = DM.GetTimeStampByIndex(period + startIndex);

                        if (prevDate.HasValue && prevDate.Value.Year != timestamp.Year)
                        {
                            sDate = timestamp.ToString("yyyy MMM");
                        }
                        else
                        {
                            sDate = timestamp.ToString("dd MMM");
                        }

                        prevDate = timestamp;

                        if (incr > level5 && sCache != sDate && oldX != x)
                        {
                            incr = 0;                             //Reset

                            lines.Children.Add(new LineGeometry
                            {
                                StartPoint = new Point(x, 0),
                                EndPoint   = new Point(x, rcBounds.Height / 2)
                            });

                            var lb = _labels.GetPaintObject();
                            lb.Left = x + 2;
                            lb.Top  = 1;
                            lb.Text = sDate;

                            sCache = sDate;
                            oldX   = x;
                            _chartX._xGridMap[xGrid++] = x;
                        }
                        incr += (x - lx);
                        lx    = x;
                    }
                }
                else if (level4 <= tradeMonth)
                {
                    incr = level4;
                    for (int period = 0; period < rcnt; period++)
                    {
                        x = _chartX.GetXPixel(period);

                        timestamp = DM.GetTimeStampByIndex(period + startIndex);
                        sDate     = timestamp.ToString("MMMM");
                        if (timestamp.Month == 1)
                        {
                            sDate = timestamp.ToString("yyyy MMM");
                        }

                        if (incr > level4 && sDate != sCache)
                        {
                            incr = 0;
                            lines.Children.Add(new LineGeometry
                            {
                                StartPoint = new Point(x, 0),
                                EndPoint   = new Point(x, rcBounds.Height / 2)
                            });

                            var lb = _labels.GetPaintObject();
                            lb.Left = x;
                            lb.Top  = 1;
                            lb.Text = sDate;

                            xGrid++;
                        }
                        sCache = sDate;
                        incr  += (x - lx);
                        lx     = x;

                        _chartX._xGridMap[xGrid] = x;
                    }
                }
                else if (level3 + 2 <= tradeMonth)
                {
                    incr   = level3;
                    sCache = "#";
                    for (int period = 0; period < rcnt; period++)
                    {
                        x = _chartX.GetXPixel(period);

                        timestamp = DM.GetTimeStampByIndex(period + startIndex);

                        sDate = timestamp.ToString("MMM");
                        if (timestamp.Month == 1)
                        {
                            sDate = timestamp.ToString("yy");
                        }

                        if (incr > level3 && sCache != sDate)
                        {
                            incr = 0;
                            lines.Children.Add(new LineGeometry
                            {
                                StartPoint = new Point(x, 0),
                                EndPoint   = new Point(x, rcBounds.Height / 2)
                            });

                            var lb = _labels.GetPaintObject();
                            lb.Left = x;
                            lb.Top  = 1;
                            lb.Text = sDate;

                            xGrid++;
                        }
                        sCache = sDate;
                        incr  += (x - lx);
                        lx     = x;

                        _chartX._xGridMap[xGrid] = x;
                    }
                }
                else if (level2 <= tradeMonth)
                {
                    incr   = level2;
                    sCache = "#";
                    for (int period = 0; period < rcnt; period++)
                    {
                        x = _chartX.GetXPixel(period);

                        timestamp = DM.GetTimeStampByIndex(period + startIndex);
                        sDate     = timestamp.ToString("MMM");
                        string sTemp;
                        if (timestamp.Month == 1)
                        {
                            sDate = timestamp.ToString("yy");
                            sTemp = sDate;
                        }
                        else
                        {
                            sTemp = sDate.Substring(0, 1);
                        }
                        if (incr > level2 && sCache != sDate)
                        {
                            incr = 0;

                            lines.Children.Add(new LineGeometry
                            {
                                StartPoint = new Point(x, 0),
                                EndPoint   = new Point(x, rcBounds.Height / 2)
                            });

                            var lb = _labels.GetPaintObject();
                            lb.Left = x;
                            lb.Top  = 1;
                            lb.Text = sTemp;

                            xGrid++;
                        }
                        sCache = sDate;
                        incr  += (x - lx);
                        lx     = x;

                        _chartX._xGridMap[xGrid] = x;
                    }
                }
                else if (level1 <= tradeYear)
                {
                    incr   = level1;
                    sCache = "#";
                    for (int period = 0; period < rcnt; period++)
                    {
                        x = _chartX.GetXPixel(period);
                        if (x == -1)
                        {
                            break;
                        }

                        timestamp = DM.GetTimeStampByIndex(period + startIndex);
                        sDate     = timestamp.ToString("yyyy");

                        if (incr > level1 && sDate != sCache)
                        {
                            incr = 0;

                            lines.Children.Add(new LineGeometry
                            {
                                StartPoint = new Point(x, 0),
                                EndPoint   = new Point(x, rcBounds.Height / 2)
                            });

                            var lb = _labels.GetPaintObject();
                            lb.Left = x;
                            lb.Top  = 1;
                            lb.Text = sDate;

                            xGrid++;
                        }
                        sCache = sDate;
                        incr  += (x - lx);
                        lx     = x;

                        _chartX._xGridMap[xGrid] = x;
                    }
                }

                //_lines.Stop();
                _linesPath.Data = (System.Windows.Media.Geometry)lines.GetAsFrozen();
                _labels.Stop();
            }
            finally
            {
                _painting = false;

                //after calendar is painted must instruct each panel to repaint the X Grid if needed
                if (_chartX.XGrid)
                {
                    foreach (var panel in _chartX.PanelsCollection)
                    {
                        panel.PaintXGrid();
                    }
                }
            }
        }
        internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus)
        {
            if (lineStatus == LineStatus.StartPaint)
            {
                for (int i = 0; i < _lines.Length; i++)
                {
                    _lines[i] = new Line {
                        Tag = this
                    };
                    Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1);
                    C.Children.Add(_lines[i]);
                }

                if (_contextLine == null)
                {
                    _contextLine = new ContextLine(this);
                    _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this));
                }

                return;
            }
            // ****************************************************************
            // *Note: This line study requires OHLC series in the owner panel!*
            // ****************************************************************

            rect.Normalize();
            if (rect.Width == 0)
            {
                return;
            }

            int revX1 = (int)(_chartX.GetReverseXInternal(rect.Left) + _chartX._startIndex);
            int revX2 = (int)(_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex);

            if (revX1 < 0)
            {
                revX1 = 0;
            }
            if (revX2 < 0)
            {
                revX2 = 0;
            }

            if (revX1 == revX2)
            {
                return;
            }

            // Get the highest high of the high series.
            // Note: this code makes the vague assumption
            // that only one symbol exists on this panel.
            Series sHigh = GetSeriesOHLC(SeriesTypeOHLC.High);

            if (sHigh == null)
            {
                return;
            }
            Series sLow = GetSeriesOHLC(SeriesTypeOHLC.Low);

            if (sLow == null)
            {
                return;
            }

            double highestHigh = sHigh.MaxFromInterval(ref revX1, ref revX2);
            double lowestLow   = sLow.MinFromInterval(ref revX1, ref revX2);

            double value = highestHigh + ((highestHigh - lowestLow) / 4);

            _linesSel.C = C;
            _linesSel.Start();
            for (int i = 0; i < _lines.Length; i++)
            {
                value   -= ((highestHigh - lowestLow) / 4);
                rect.Top = _chartPanel.GetY(value);
                Utils.DrawLine(rect.Left, rect.Top, rect.Right, rect.Top,
                               Stroke, i == 2 ? LinePattern.Dot : StrokeType, StrokeThickness, Opacity, _lines[i]);
            }

            if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting)
            {
                Utils.DrawLine(rect.Left, 0, rect.Left, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, Opacity, _linesSel);
                Utils.DrawLine(rect.Right, 0, rect.Right, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, Opacity, _linesSel);
            }

            _linesSel.Stop();

            _internalObjectCreated = true;

            _linesSel.Do(l => l.ZIndex = ZIndexConstants.LineStudies1);
        }
Exemple #22
0
        internal void Render()
        {
            if (_linesPath == null)
            {
                _linesPath = new Path
                {
                    StrokeThickness = 1
                };
                Children.Add(_linesPath);
                SetZIndex(_linesPath, ZIndexConstants.GridLines);

                _linesPath.SetBinding(Shape.StrokeProperty, _chartPanel._chartX.CreateOneWayBinding("GridStroke"));
            }

            _labels.C = this;
            _labels.Start();

            Rect rcBounds = new Rect(0, 0, ActualWidth, ActualHeight);

            if (Utils.GetIsInDesignMode(this))
            {
                _min = 0;
                _max = 1;
            }

            if (rcBounds.Height < 2)
            {
                return;
            }

            //int decimals = _chartPanel._hasVolume ? 0 : _chartPanel._chartX.ScalePrecision;
            string formatString = _chartPanel.FormatYValueString;
            bool   isVolume     = _chartPanel._hasVolume; // && (_chartPanel._chartX.VolumePostfixLetter.Length > 0);


            double k = rcBounds.Height / LabelCount;

            double min = _chartPanel.ScalingType == ScalingTypeEnum.Linear || isVolume
        ? _min
        : (_min > 0 ? Math.Log10(_min) : 0);
            double max = _chartPanel.ScalingType == ScalingTypeEnum.Linear || isVolume ? _max : Math.Log10(_max);

            double startValue = min + (max - min) * (_chartPanel._yOffset / rcBounds.Height);

            GridStep = (max - min) / LabelCount;

            _chartPanel.StartPaintingYGridLines();

            GeometryGroup gLines = new GeometryGroup();

            StringBuilder stringBuilder = new StringBuilder();
            double        textHeight    = _chartPanel._chartX.GetTextHeight("9");

            for (int i = 0; i < LabelCount; i++)
            {
                double y = rcBounds.Height - (i * k);
                if (double.IsNaN(y))
                {
                    continue;
                }

                if (y < 0)
                {
                    break;
                }

                if (i > 0)
                {
                    gLines.Children.Add(new LineGeometry
                    {
                        StartPoint = new Point(_isLeftAligned ? rcBounds.Width - 10 : 0, y),
                        EndPoint   = new Point(_isLeftAligned ? rcBounds.Width : 10, y),
                    });

                    _chartPanel.PaintYGridLine(y);
                }

                stringBuilder.Length = 0;
                double value = startValue + (GridStep * i);
                if (_chartPanel.ScalingType == ScalingTypeEnum.Semilog && !isVolume)
                {
                    value = Math.Pow(10, value);
                }

                if (isVolume)
                {
                    value /= _chartPanel._chartX.VolumeDivisor;
                }

                stringBuilder.AppendFormat(formatString, value);

                if (isVolume && !string.IsNullOrEmpty(_chartPanel._chartX.VolumePostfixLetter))
                {
                    stringBuilder.Append(" ").Append(_chartPanel._chartX.VolumePostfixLetter);
                }

                if (!string.IsNullOrEmpty(_chartPanel.YAxisPostFix))
                {
                    stringBuilder.Append(_chartPanel.YAxisPostFix);
                }

                Label tb = _labels.GetPaintObject();
                tb.Text = stringBuilder.ToString();
                tb.Left = _isLeftAligned ? rcBounds.Width -
                          _chartPanel._chartX.GetTextWidth(stringBuilder.ToString()) - 2 : 2;
                tb.Top = y - textHeight - 2;
            }

            gLines.Children.Add(new LineGeometry
            {
                StartPoint = new Point(_isLeftAligned ? rcBounds.Width - 1 : 1, 0),
                EndPoint   = new Point(_isLeftAligned ? rcBounds.Width - 1 : 1, rcBounds.Height),
            });

            _chartPanel.StopPaintingYGridLines();
            _painted = true;
            _labels.Stop();
            _linesPath.Data = gLines;
        }