Пример #1
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));
            }
        }
Пример #3
0
 internal void UpdateFontInformation()
 {
     _labels.Do(label =>
     {
         label._textBlock.FontSize   = _chartPanel._chartX.FontSize;
         label._textBlock.Foreground = _chartPanel._chartX.FontForeground;
         label._textBlock.FontFamily = new FontFamily(_chartPanel._chartX.FontFace);
     });
 }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
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;
            });
        }
Пример #8
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();
            }
        }
Пример #9
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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
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);
        }
Пример #13
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;
    }
Пример #14
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);
        }
Пример #15
0
        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);
            }
        }
Пример #16
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);
        }
Пример #17
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 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);
        }
Пример #18
0
        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);
        }