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; } } }
// 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; }
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); }
internal void SetChartPanel(ChartPanel chartPanel) { _chartPanel = chartPanel; _chartX = _chartPanel._chartX; }
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() { /* * 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); }
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 CustomHorLineValueGetter(StockChartX chart) { _chart = chart; }
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; } }
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); }
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; }
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; }
public override bool Paint() { if (_series._seriesTypeOHLC != SeriesTypeOHLC.Close) { return(false); } StockChartX chartX = _series._chartPanel._chartX; Series open = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Open); Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.Painted || high.RecordCount == 0) { return(false); } Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.Painted || low.RecordCount == 0) { return(false); } Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close); if (close == null || close.Painted || close.RecordCount == 0) { return(false); } high.Painted = low.Painted = close.Painted = true; if (!_subscribedToCustomBrush) { _subscribedToCustomBrush = true; chartX.OnCandleCustomBrush += ChartX_OnCandleCustomBrush; } bool changeBrushes = false; Color upColor = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor; Color downColor = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor; if (!_oldUpColor.HasValue || _oldUpColor.Value != upColor) { _upBrush = new SolidColorBrush(upColor); _upBrush.Freeze(); _oldUpColor = upColor; changeBrushes = true; } if (!_oldDownColor.HasValue || _oldDownColor.Value != downColor) { _downBrush = new SolidColorBrush(_series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor); _downBrush.Freeze(); _oldDownColor = downColor; changeBrushes = true; } if (!_oldStrokeColor.HasValue || _oldStrokeColor.Value != _series._strokeColor) { _customBrush = new SolidColorBrush(_series._strokeColor); _customBrush.Freeze(); _oldStrokeColor = _series._strokeColor; changeBrushes = true; } int rcnt = chartX.RecordCount; double x2 = chartX.GetXPixel(rcnt); double x1 = chartX.GetXPixel(rcnt - 1); double space = ((x2 - x1) / 2) - chartX._barWidth / 2; if (space > 20) { space = 20; } chartX._barSpacing = space; int cnt = 0; ((ModulusFE.Stock)_series)._priceStyleStock = this; _stocks.C = _series._chartPanel._rootCanvas; _stocks.Start(); for (int n = chartX._startIndex; n < chartX._endIndex; n++, cnt++) { if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue) { continue; } PaintObjects.Stock stock = _stocks.GetPaintObject(_upBrush, _downBrush, _customBrush); stock.Init(_series); if (changeBrushes) { stock.SetBrushes(_upBrush, _downBrush, _customBrush); } stock.SetValues(open != null ? open[n].Value : null, high[n].Value.Value, low[n].Value.Value, close[n].Value.Value, space, n - chartX._startIndex); } _stocks.Stop(); _stocks.Do(s => s.ZIndex = ZIndexConstants.PriceStyles1); return(true); }
public override bool Paint() { /* * pCtrl->priceStyleParams[0] = lines * 7 columns * width = 300 * 300 / 7 = 42.85 pixels per column */ if (_series.OHLCType == SeriesTypeOHLC.Open) { return(false); } StockChartX chartX = _series._chartPanel._chartX; Series high = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.High); if (high == null || high.Painted || high.RecordCount == 0) { return(false); } Series low = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Low); if (low == null || low.Painted || low.RecordCount == 0) { return(false); } Series close = chartX.GetSeriesOHLCV(_series, SeriesTypeOHLC.Close); if (close == null || close.Painted || close.RecordCount == 0) { return(false); } high.Painted = low.Painted = close.Painted = true; double width = chartX.PaintableWidth; double lines = chartX._priceStyleParams[0]; if (lines > 50 || lines < 1) { lines = 3; chartX._priceStyleParams[0] = lines; } _highs = new double[(int)lines]; _lows = new double[(int)lines]; double nClose, nHH = 0, nLL = 0; const int white = 1; const int black = 2; double nStart = 0; int block = 0; // black or white int totalBlocks = 0; chartX._xMap = new double[chartX._endIndex - chartX._startIndex + 1]; int cnt = 0; chartX._psValues1.Clear(); chartX._psValues2.Clear(); chartX._psValues3.Clear(); // Count columns that will fit on screen int n; for (n = 0; n < chartX._endIndex; n++) { if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue) { continue; } // Calculate N Line Break nClose = (double)close[n].Value; switch (block) { case white: if (IsNewBlock(-1, nClose)) { nHH = nStart; // New black block nLL = nClose; nStart = nClose; block = black; AddBlock(nHH, nLL); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalBlocks++; } } if (IsNewBlock(1, nClose)) { nHH = nClose; // New white block nLL = nStart; nStart = nClose; block = white; AddBlock(nHH, nLL); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalBlocks++; } } break; case black: if (IsNewBlock(1, nClose)) { nHH = nClose; // New white block nLL = nStart; nStart = nClose; block = white; AddBlock(nHH, nLL); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalBlocks++; } } if (IsNewBlock(-1, nClose)) { nHH = nStart; // New black block nLL = nClose; nStart = nClose; block = black; AddBlock(nHH, nLL); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalBlocks++; } } break; } if (block != 0) { continue; // Prime first block } double nClose2 = (double)close[n + 1].Value; if (nClose2 > nClose) { block = white; nHH = nClose2; nLL = nClose; nStart = nClose; } else { block = black; nHH = nClose; nLL = nClose2; nStart = nClose2; } AddBlock(nHH, nLL); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalBlocks++; } } chartX._xCount = totalBlocks; _highs = new double[(int)lines]; _lows = new double[(int)lines]; Color upColor = _series._upColor.HasValue ? _series._upColor.Value : chartX.UpColor; Color downColor = _series._downColor.HasValue ? _series._downColor.Value : chartX.DownColor; Brush upBrush = new SolidColorBrush(upColor); Brush downBrush = new SolidColorBrush(downColor); Brush upGradBrush = Utils.CreateFadeVertBrush(upColor, Colors.Black); Brush downGradBrush = Utils.CreateFadeVertBrush(downColor, Colors.Black); _rects.C = _series._chartPanel._rootCanvas; _rects.Start(); // Paint columns block = 0; double x = chartX.LeftChartSpace; if (totalBlocks == 0) { return(false); } double space = width / totalBlocks; totalBlocks = 0; // Calculate from beginning, but only show between startIndex and endIndex for (n = 0; n < chartX._endIndex; n++) { if (!high[n].Value.HasValue || !low[n].Value.HasValue || !close[n].Value.HasValue) { continue; } // Calculate N Line Break nClose = (double)close[n].Value; switch (block) { case white: if (IsNewBlock(-1, nClose)) { // Paint last white block if (n >= chartX._startIndex && n <= chartX._endIndex) { PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, 1, n, close); x += space; } nHH = nStart; // New black block nLL = nClose; nStart = nClose; block = black; AddBlock(nHH, nLL); totalBlocks++; } if (IsNewBlock(1, nClose)) { // Paint last black block if (n >= chartX._startIndex && n <= chartX._endIndex) { PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, 1, n, close); x += space; } nHH = nClose; // New white block nLL = nStart; nStart = nClose; block = white; AddBlock(nHH, nLL); totalBlocks++; } break; case black: if (IsNewBlock(1, nClose)) { // Paint last white block if (n >= chartX._startIndex && n <= chartX._endIndex) { PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, -1, n, close); x += space; } nHH = nClose; // New white block nLL = nStart; nStart = nClose; block = white; AddBlock(nHH, nLL); totalBlocks++; } if (IsNewBlock(-1, nClose)) { // Paint last black block if (n >= chartX._startIndex && n <= chartX._endIndex) { PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, -1, n, close); x += space; } nHH = nStart; // New black block nLL = nClose; nStart = nClose; block = black; AddBlock(nHH, nLL); totalBlocks++; } break; } if (block == 0) { // Prime first block double nClose2 = (double)close[n + 1].Value; if (nClose2 > nClose) { block = white; nHH = nClose2; nLL = nClose; nStart = nClose; } else { block = black; nHH = nClose; nLL = nClose2; nStart = nClose2; } AddBlock(nHH, nLL); if (n >= chartX._startIndex && n <= chartX._endIndex) { totalBlocks = 1; } x = chartX.LeftChartSpace; } // Record the x value if (n >= chartX._startIndex && n <= chartX._endIndex) { chartX._xMap[cnt] = x + (space / 2); cnt++; } } // Finish last block if (block == black) { PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, -1, n, close); } else { PaintBox(upBrush, downBrush, upGradBrush, downGradBrush, x, space, nHH, nLL, 1, n, close); } _rects.Stop(); _rects.Do(r => r.ZIndex = ZIndexConstants.PriceStyles1); return(true); }
internal 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; } }