Beispiel #1
0
        private void PaintBox(Brush upBrush, Brush downBrush, Brush upGradBrush, Brush downGradBrush, double x, double space, double top, double bottom, int direction)
        {
            Types.RectEx box = new Types.RectEx
            {
                Top    = _series._chartPanel.GetY(top),
                Bottom = _series._chartPanel.GetY(bottom),
                Left   = x,
                Right  = (x + space)
            };
            StockChartX chartX = _series._chartPanel._chartX;

            if (chartX.ThreeDStyle)
            {
                switch (direction)
                {
                case 1:
                    Utils.DrawRectangle(box, upGradBrush, _rects);
                    break;

                case 2:
                    Utils.DrawRectangle(box, downGradBrush, _rects);
                    break;
                }
            }
            else
            {
                switch (direction)
                {
                case 1:
                    Utils.DrawRectangle(box, upBrush, _rects);
                    break;

                case 2:
                    Utils.DrawRectangle(box, downBrush, _rects);
                    break;
                }
            }
        }
Beispiel #2
0
        //    private void Candle_OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        //    {
        //      PaintCandle();
        //    }
        //
        //    private void Wick_OnPropertyChanged(object sender, PropertyChangedEventArgs e)
        //    {
        //      PaintWick();
        //    }
        //
        internal void PaintWick()
        {
            ChartPanel  chartPanel = _series._chartPanel;
            StockChartX chartX     = chartPanel._chartX;

            CalculateXValues();
            //if (_xHigh == _xLow) return;

            double x  = chartX.GetXPixel(_index);
            double y1 = _series.GetY(_xHigh);
            double y2 = _series.GetY(_xLow);

            if (y2 == y1)
            {
                y1 = y2 - 2;
            }
            _lineWick.StrokeThickness = _series._strokeThickness;
            _lineWick.Stroke          = new SolidColorBrush(_series._strokeColor);
            _lineWick.X1  = _lineWick.X2 = x;
            _lineWick.Y1  = y1;
            _lineWick.Y2  = y2;
            _lineWick.Tag = _series;
        }
Beispiel #3
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);
        }
Beispiel #4
0
 internal void SetChartPanel(ChartPanel chartPanel)
 {
     _chartPanel = chartPanel;
     _chartX     = _chartPanel._chartX;
 }
Beispiel #5
0
        public override bool Paint()
        {
            if (_series.OHLCType != SeriesTypeOHLC.High && _series.OHLCType != SeriesTypeOHLC.Low)
            {
                return(false);
            }
            StockChartX chartX = _series._chartPanel._chartX;
            Series      high   = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High);

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

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

            high.Painted = low.Painted = true;

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

            double width = chartX.PaintableWidth;

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

            double boxSize = chartX._priceStyleParams[0];

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

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

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

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

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

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

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

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

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

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

            chartX._xCount = totalColumns;

            column = 0;
            double x = chartX.LeftChartSpace;

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

            totalColumns = 0;

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

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

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

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

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

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

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

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

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

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

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

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

                        x = chartX.LeftChartSpace;
                    }

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

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

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

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

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

            return(true);
        }
Beispiel #6
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);
        }
Beispiel #7
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);
        }
Beispiel #8
0
 public CustomHorLineValueGetter(StockChartX chart)
 {
     _chart = chart;
 }
Beispiel #9
0
        internal void PaintCandle()
        {
            ChartPanel  chartPanel = _series._chartPanel;
            StockChartX chartX     = chartPanel._chartX;

            double x = chartX.GetXPixel(_index);

            Rect   rc;
            double y1;
            double y2;

            if (_rectCandle.Tag == null)
            {
                _rectCandle.Tag = _series;
            }
            if (_open > _close) //down
            {
                y1 = _series.GetY(_open);
                y2 = _series.GetY(_close);
                if (y1 + 3 > y2)
                {
                    y2 += 2;
                }
                rc = new Rect(x - _space - _halfwick, y1, 2 * (_space + _halfwick), y2 - y1);
                if (_brushMustBeChanged)
                {
                    _rectCandle.Fill    = chartX.GetBarBrush(_series.FullName, _index + chartX._startIndex, _down);
                    _brushMustBeChanged = false;
                }
                if (_candleDownOutline == null)
                {
                    _rectCandle.StrokeThickness = 0;
                }
                else
                {
                    _rectCandle.StrokeThickness = 1;
                    _rectCandle.Stroke          = _candleDownOutline;
                }

                //        Canvas.SetLeft(_rectCandle, rc.Left);
                //        Canvas.SetTop(_rectCandle, rc.Top);
            }
            else if (_open < _close) //up
            {
                y1 = _series.GetY(_close);
                y2 = _series.GetY(_open);
                if (y1 + 3 > y2)
                {
                    y2 += 2;
                }
                rc = new Rect(x - _space - _halfwick, y1, 2 * (_space + _halfwick), y2 - y1);
                if (_brushMustBeChanged)
                {
                    _rectCandle.Fill    = chartX.GetBarBrush(_series.FullName, _index + chartX._startIndex, _up);
                    _brushMustBeChanged = false;
                }
                if (_candleUpOutline == null)
                {
                    _rectCandle.StrokeThickness = 0;
                }
                else
                {
                    _rectCandle.StrokeThickness = 1;
                    _rectCandle.Stroke          = _candleUpOutline;
                }
                //        Canvas.SetLeft(_rectCandle, rc.Left);
                //        Canvas.SetTop(_rectCandle, rc.Top);
                //        _rectCandle.Width = rc.Width;
                //        _rectCandle.Height = rc.Height;
            }
            else //No change, flat bar
            {
                y1 = _series.GetY(_close);
                y2 = _series.GetY(_open);
                if (y2 == y1)
                {
                    y1 = y2 - 1;
                }
                rc = new Rect(x - _space - _halfwick, y1, 2 * (_space + _halfwick), y2 - y1);
                if (_brushMustBeChanged)
                {
                    _rectCandle.Fill    = chartX.GetBarBrush(_series.FullName, _index + chartX._startIndex, _down);
                    _brushMustBeChanged = false;
                }
                _rectCandle.StrokeThickness = 0;
                //        Canvas.SetLeft(_rectCandle, rc.Left);
                //        Canvas.SetTop(_rectCandle, rc.Top);
                //        _rectCandle.Width = rc.Width;
                //        _rectCandle.Height = rc.Height;
            }

            _rcTransform.X = rc.Left;
            _rcTransform.Y = rc.Top;
            if (_rectCandle.Width != rc.Width)
            {
                _rectCandle.Width = rc.Width;
            }
            if (_rectCandle.Height != rc.Height)
            {
                _rectCandle.Height = rc.Height;
            }
        }
Beispiel #10
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);
        }
Beispiel #11
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;
    }
Beispiel #12
0
        public static void SetStyle(this StockChartX chart)
        {
            chart.CrossHairsPattern         = new DoubleCollection(new double[] { 3, 3 });
            chart.InfoPanelItemsOrientation = Controls.InfoPanelItemsOrientation.Vertical;
            chart.CandleUpHollow            = true;
            chart.CandleUpOutlineColor      = Colors.Red;
            // 十字光标时间格式
            //chart.CrossHairsTextTimeFormat = "yyyy-MM-dd";
            chart.CrossHairsTextTimeFormat = "hh:mm:ss";

            chart.HorizontalGridLinePattern = chart.VerticalGridLinePattern = new DoubleCollection(new double[] { 3, 3 });

            chart.CalenderXAxisDateTimeFormat = "yyyy/MM";

            /* 背景颜色 */
            chart.Background = (Brush)System.Windows.Application.Current.Resources["AccentColorBrush"];
            /* 字体颜色 */
            chart.FontForeground = Brushes.White;
            /* 各种颜色 */
            chart.HeatPanelLabelsBackground      = (Brush)System.Windows.Application.Current.Resources["AccentColorBrush"];
            chart.CalendarBackground             = (Brush)System.Windows.Application.Current.Resources["AccentColorBrush"];
            chart.IndicatorDialogLabelForeground = (Brush)System.Windows.Application.Current.Resources["AccentColorBrush"];
            chart.CalendarBackground             = ChartPanelBackground;

            chart.ChartScrollerProperties.Background      = ChartPanelBackground;
            chart.ChartScrollerProperties.TrendBackground = ChartPanelBackground;
            chart.ChartScrollerProperties.TrendStroke     = TrendStroke;
            chart.ChartScrollerProperties.ThumbBackground = ThumbBackground;

            /* Y坐标设置在左侧 */
            chart.ScaleAlignment = ScaleAlignmentTypeEnum.Left;

            /* 消息面板固定位置 */
            //chart.InfoPanelPosition = InfoPanelPositionEnum.FixedPosition;
            /* 消息面板样式 */
            chart.InfoPanelLabelsBackground = InfoPanelBackground;
            chart.InfoPanelValuesBackground = InfoPanelBackground;
            chart.InfoPanelLabelsForeground = Brushes.WhiteSmoke;
            chart.InfoPanelValuesForeground = Brushes.WhiteSmoke;

            /* 涨跌颜色 */
            chart.DownColor = Color.FromRgb(0x29, 0xb8, 0x1e);
            chart.UpColor   = Color.FromRgb(0xf5, 0x1d, 0x27);

            /* 左右保留距离 */
            chart.LeftChartSpace  = 0;
            chart.RightChartSpace = 0;

            /* 不显示X轴Grid */
            chart.XGrid = false;

            /* 显示Y轴Grid */
            chart.YGrid = true;

            /* Grid颜色 */
            chart.GridStroke = new SolidColorBrush(Color.FromRgb(0x27, 0x2C, 0x32));

            /* Grid分布类型 */
            chart.YGridStepType = YGridStepType.NiceStep;

            /* 最大可显示记录 */
            chart.MaxVisibleRecords = 100;

            /* X轴时间 */
            chart.RealTimeXLabels = true;

            /* 必须设置 */
            chart.OptimizePainting = true;

            /* 十字线 */
            chart.CrossHairs = true;

            /* 十字线颜色 */
            chart.CrossHairsStroke = new SolidColorBrush(Colors.White);

            /* 成交量颜色随OHLC变化 */
            chart.UseVolumeUpDownColors = true;

            /* 不显示矩形拉框放大 */
            chart.DisableZoomArea = true;
        }
Beispiel #13
0
        public override bool Paint()
        {
            if (_series._seriesTypeOHLC != SeriesTypeOHLC.Close)
            {
                return(false);
            }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            chartX._barSpacing = space;

            int cnt = 0;

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

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

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

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

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

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

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

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

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

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

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

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

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

            double width = chartX.PaintableWidth;

            double lines = chartX._priceStyleParams[0];

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

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

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

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

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

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

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


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

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

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

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

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


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

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

            totalBlocks = 0;

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

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

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

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

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

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

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

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

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

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

            _rects.Stop();

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

            return(true);
        }
Beispiel #15
0
        internal void PaintCandle()
        {
            ChartPanel  chartPanel = _series._chartPanel;
            StockChartX chartX     = chartPanel._chartX;

            double x = chartX.GetXPixel(_index);

            Rect   rc;
            double y1;
            double y2;

            CalculateXValues();

            _rectCandle.Tag = _series;
            if (_xOpen > _xClose)
            {
                y1 = _series.GetY(_xOpen);
                y2 = _series.GetY(_xClose);
                if (y1 + 3 > y2)
                {
                    y2 += 2;
                }
                rc = new Rect(x - _space - _halfwick, y1, 2 * (_space + _halfwick), y2 - y1);
                _rectCandle.Fill = chartX.GetBarBrush(_index + chartX._startIndex, _down);
                if (_candleDownOutline == null)
                {
                    _rectCandle.StrokeThickness = 0;
                }
                else
                {
                    _rectCandle.StrokeThickness = 1;
                    _rectCandle.Stroke          = _candleDownOutline;
                }

                Canvas.SetLeft(_rectCandle, rc.Left);
                Canvas.SetTop(_rectCandle, rc.Top);
                _rectCandle.Width  = rc.Width;
                _rectCandle.Height = rc.Height;
            }
            else if (_xOpen < _xClose)
            {
                y1 = _series.GetY(_xClose);
                y2 = _series.GetY(_xOpen);
                if (y1 + 3 > y2)
                {
                    y2 += 2;
                }
                rc = new Rect(x - _space - _halfwick, y1, 2 * (_space + _halfwick), y2 - y1);
                _rectCandle.Fill = chartX.GetBarBrush(_index + chartX._startIndex, _up);
                if (_candleUpOutline == null)
                {
                    _rectCandle.StrokeThickness = 0;
                }
                else
                {
                    _rectCandle.StrokeThickness = 1;
                    _rectCandle.Stroke          = _candleUpOutline;
                }
                Canvas.SetLeft(_rectCandle, rc.Left);
                Canvas.SetTop(_rectCandle, rc.Top);
                _rectCandle.Width  = rc.Width;
                _rectCandle.Height = rc.Height;
            }
            else
            {
                y1 = _series.GetY(_xClose);
                y2 = _series.GetY(_xOpen);
                if (y2 == y1)
                {
                    y1 = y2 - 1;
                }
                rc = new Rect(x - _space - _halfwick, y1, 2 * (_space + _halfwick), y2 - y1);
                _rectCandle.Fill            = chartX.GetBarBrush(_index + chartX._startIndex, _down);
                _rectCandle.StrokeThickness = 0;
                Canvas.SetLeft(_rectCandle, rc.Left);
                Canvas.SetTop(_rectCandle, rc.Top);
                _rectCandle.Width  = rc.Width;
                _rectCandle.Height = rc.Height;
            }
        }