コード例 #1
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);
        }
コード例 #2
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);
        }
コード例 #3
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);
        }
コード例 #4
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);
        }
コード例 #5
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);
        }