public override bool Paint() { /* * highestVolume = highest volume up to current record (not after) * * x = volume / highestVolume * if x = 0 then x = 1 * * 1,0.25,0.5,0.75,0.25,0.5,1 * total=4.25 * * /4.25 total * 0.235,0.058,0.117,0.176,0.058,0.117,0.235=1 * * 300* pixels * 70.5,17.4,35.1,52.8,17.4,35.1,70.5=300 * */ if (_series.OHLCType == SeriesTypeOHLC.Volume) { return(false); } StockChartX chartX = _series._chartPanel._chartX; Series open = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open); if (open == null || open.Painted || open.RecordCount == 0) { return(false); } Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.Painted || high.RecordCount == 0) { return(false); } Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.Painted || low.RecordCount == 0) { return(false); } Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close); if (close == null || close.Painted || close.RecordCount == 0) { return(false); } Series volume = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Volume); if (volume == null || volume.RecordCount == 0) { return(false); } open.Painted = high.Painted = low.Painted = close.Painted = true; double width = chartX.PaintableWidth; const int up = 1; const int down = 2; double highestVolume; double x; double equiVol; double total = 0; Types.RectEx box; Brush customBrush = new SolidColorBrush(_series._strokeColor); Brush upBrush = new SolidColorBrush(_series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor); Brush downBrush = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor); Brush upGradBrush = Utils.CreateFadeVertBrush(_series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor, Colors.Black); Brush downGradBrush = Utils.CreateFadeVertBrush(Colors.Black, _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor); chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1]; int cnt = 0; _lines.C = _rects.C = _rects3D.C = _series._chartPanel._rootCanvas; _lines.Start(); _rects.Start(); _rects3D.Start(); // Count total Equi-Volume int n; for (n = chartX._startIndex; n < chartX._endIndex; n++) { if (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue || !volume[n].Value.HasValue) { continue; } // Calculate Equi-Volume highestVolume = HighestVolumeToRecord(n, volume); x = highestVolume != 0.0 ? volume[n].Value.Value / highestVolume : 0; total += x; if (!chartX._darwasBoxes) { continue; } equiVol = volume[n].Value.Value / highestVolume; equiVol = equiVol / total; equiVol = width * equiVol; x += equiVol; // Record the x value chartX._xMap[cnt] = x; cnt++; } cnt = 0; x = chartX.LeftChartSpace; double px = x; for (n = chartX._startIndex; n < chartX._endIndex; n++) { if (!open[n].Value.HasValue || !high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue || !volume[n].Value.HasValue) { continue; } // Calculate Equi-Volume highestVolume = HighestVolumeToRecord(n, volume); equiVol = highestVolume != 0 ? volume[n].Value.Value / highestVolume : 0.0; equiVol = equiVol / total; equiVol = width * equiVol; x += equiVol; // Record the x value chartX._xMap[cnt] = x; cnt++; double x1 = px; double x2 = x; double y1 = _series._chartPanel.GetY(high[n].Value.Value); double y2 = _series._chartPanel.GetY(low[n].Value.Value); if (y2 == y1) { y1 = y2 - 2; } box = new Types.RectEx(x1, y1, x2, y2); Types.RectEx frame = box; if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow) { if (close[n].Value > open[n].Value) { box.Top = _series._chartPanel.GetY(close[n].Value.Value); } else { box.Bottom = _series._chartPanel.GetY(close[n].Value.Value); } } double wx = x1 + (x2 - x1) / 2; if (chartX._priceStyle == PriceStyleEnum.psCandleVolume) { if (close[n].Value > open[n].Value) { box.Top = _series._chartPanel.GetY(close[n].Value.Value); box.Bottom = _series._chartPanel.GetY(open[n].Value.Value); } else { box.Top = _series._chartPanel.GetY(open[n].Value.Value); box.Bottom = _series._chartPanel.GetY(close[n].Value.Value); } if (box.Bottom == box.Top) { box.Top = box.Bottom - 2; } Utils.DrawLine(wx, y1, wx, y2, customBrush, _series.StrokePattern, _series._strokeThickness, _lines); frame = box; } // Is the bar up or down? int direction; if (n == 0) { direction = close[n].Value > open[n].Value ? up : down; } else { direction = close[n].Value > close[n - 1].Value ? up : down; } if (chartX.ThreeDStyle) { if (direction == up) { Utils.DrawRectangle(box, upGradBrush, _rects); if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow) { Utils.Draw3DRectangle(frame, upBrush, downBrush, _rects3D); } } else { Utils.DrawRectangle(box, downGradBrush, _rects); if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow) { Utils.Draw3DRectangle(frame, upBrush, downBrush, _rects3D); } } } else { if (direction == up) { Utils.DrawRectangle(box, upBrush, _rects); if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow) { Utils.Draw3DRectangle(frame, upBrush, upBrush, _rects3D); } } else { Utils.DrawRectangle(box, downBrush, _rects); if (chartX._priceStyle == PriceStyleEnum.psEquiVolumeShadow) { Utils.Draw3DRectangle(frame, downBrush, downBrush, _rects3D); } } } px = x; } _lines.Stop(); _rects.Stop(); _rects3D.Stop(); _lines.Do(l => l.ZIndex = ZIndexConstants.PriceStyles1); _rects.Do(r => r.ZIndex = ZIndexConstants.PriceStyles2); _rects3D.Do(r => r.ZIndex = ZIndexConstants.PriceStyles3); return(true); }
public override bool Paint() { if (_series.OHLCType != SeriesTypeOHLC.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); }
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() { 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); }
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); }