internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { rect.Normalize(); _lines.C = C; _lines.Start(); Utils.DrawLine(rect.Left, rect.Top, rect.Left, rect.Bottom, Stroke, StrokeType, StrokeThickness, _lines); Utils.DrawLine(rect.Right, rect.Top, rect.Right, rect.Bottom, Stroke, StrokeType, StrokeThickness, _lines); foreach (double d in _fib) { double x = rect.Left + rect.Width * d; Utils.DrawLine(x, rect.Top, x, rect.Bottom, Stroke, StrokeType, StrokeThickness, _lines); } _lines.Stop(); _internalObjectCreated = true; if (_firstPaint) { _firstPaint = false; _lines.Do(l => { l._line.Tag = this; l.ZIndex = ZIndexConstants.LineStudies1; }); _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { rect.Normalize(); if (lineStatus == LineStatus.StartPaint) { _internalObjectCreated = true; for (int i = 0; i < _ellipses.Length; i++) { _ellipses[i] = new System.Windows.Shapes.Ellipse { Tag = this, Stroke = Stroke, StrokeThickness = StrokeThickness, Fill = Brushes.Transparent }; C.Children.Add(_ellipses[i]); } new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } double elSize = Math.Max(rect.Width, rect.Height); Rect rc = new Rect(rect.Left, rect.Top, elSize, elSize); for (int i = 0; i < _ellipses.Length; i++) { if (rc.IsEmpty) { break; } #if SILVERLIGHT rc.X -= -elSize * 0.1; rc.Y -= -elSize * 0.1; rc.Width += 2 * (-elSize * 0.1); rc.Height += 2 * (-elSize * 0.1); #endif Canvas.SetLeft(_ellipses[i], rc.Left); Canvas.SetTop(_ellipses[i], rc.Top); _ellipses[i].Height = rc.Width; _ellipses[i].Width = rc.Height; #if WPF rc.Inflate(-elSize * 0.1, -elSize * 0.1); #endif } foreach (System.Windows.Shapes.Ellipse ellipse in _ellipses) { Canvas.SetZIndex(ellipse, ZIndexConstants.LineStudies1); } }
public static Rectangle3D Draw3DRectangle(Types.RectEx bounds, Brush topLeft, Brush bottomRight, PaintObjectsManager <Rectangle3D> rects) { Rectangle3D rectangle3D = rects.GetPaintObject(); rectangle3D.SetPos(bounds, topLeft, bottomRight); return(rectangle3D); }
private void PaintBox(Brush upBrush, Brush downBrush, Brush upGradBrush, Brush downGradBrush, double x, double space, double top, double bottom, int direction, int index, Series close) { StockChartX chartX = _series._chartPanel._chartX; for (int i = _prevIndex + 1; i < index; i++) { chartX._psValues1.Add(new PriceStyleValue(close[i].TimeStamp, top)); chartX._psValues2.Add(new PriceStyleValue(close[i].TimeStamp, bottom)); chartX._psValues3.Add(new PriceStyleValue(close[i].TimeStamp, direction)); } _prevIndex = index; Types.RectEx box = new Types.RectEx { Top = _series._chartPanel.GetY(top), Bottom = _series._chartPanel.GetY(bottom), Left = x, Right = (x + space) }; if (box.Height < 1) { box.Bottom++; } if (chartX.ThreeDStyle) { switch (direction) { case 1: Utils.DrawRectangle(box, upGradBrush, _rects); break; default: Utils.DrawRectangle(box, downGradBrush, _rects); break; } } else { switch (direction) { case 1: Utils.DrawRectangle(box, upBrush, _rects); break; default: Utils.DrawRectangle(box, downBrush, _rects); break; } } }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (_valuePresenter == null && lineStatus != LineStatus.StartPaint) { DrawLineStudy(rect, LineStatus.StartPaint); return; } if (lineStatus == LineStatus.StartPaint) { _line = new Line { Stroke = Stroke, StrokeThickness = 1, Tag = this }; Types.SetShapePattern(_line, StrokeType); C.Children.Add(_line); Canvas.SetZIndex(_line, ZIndexConstants.LineStudies1); _line.MouseLeftButtonDown += (sender, args) => MouseDown(sender, args); _line.MouseEnter += (sender, args) => MouseEnter(sender, args); _line.MouseLeave += (sender, args) => MouseLeave(sender, args); _line.MouseMove += (sender, args) => MouseMove(sender, args); _line.MouseLeftButtonUp += (sender, args) => MouseUp(sender, args); CreateValuePresenter(); if (LineStudyValue == null) { LineStudyValue = new HorizontalLineDefStudyValue { FontFamily = new FontFamily(_chartX.FontFace), FontSize = _chartX.FontSize, Foreground = _chartX.FontForeground, }; } new ContextLine(this); _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } _line.X1 = 0; _line.X2 = C.ActualWidth; _line.Y1 = _line.Y2 = rect.Bottom; //Debug.WriteLine("Bottom: " + rect.Bottom); SetDisplayValue(); }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (_line == null && lineStatus != LineStatus.StartPaint) { DrawLineStudy(rect, LineStatus.StartPaint); } if (lineStatus == LineStatus.StartPaint) { _line = new Line { Stroke = Stroke, StrokeThickness = StrokeThickness, Tag = this }; Types.SetShapePattern(_line, StrokeType); C.Children.Add(_line); Canvas.SetZIndex(_line, ZIndexConstants.LineStudies1); if (_contextLine == null) { _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } _internalObjectCreated = true; _segment.BindToLine(_line); return; } if (double.IsInfinity(rect.Top)) { return; } // _line.X1 = rect.Left; // _line.Y1 = rect.Top; // // _line.X2 = rect.Right; // _line.Y2 = rect.Bottom; _segment.X1 = rect.Left; _segment.Y1 = rect.Top; _segment.X2 = rect.Right; _segment.Y2 = rect.Bottom; }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { // if (_ellipse == null && lineStatus != LineStatus.StartPaint) // DrawLineStudy(rect, LineStatus.StartPaint); // // if (_ellipse == null) // throw new NullReferenceException(); // if (lineStatus == LineStatus.StartPaint) { _ellipse.StrokeThickness = StrokeThickness; _ellipse.Stroke = Stroke; if (_ellipse.Fill == null) { _ellipse.Fill = new SolidColorBrush(Colors.Transparent); } _ellipse.Tag = this; C.Children.Add(_ellipse); if (_contextLine == null) { _contextLine = new ContextLine(this); } _ellipse.MouseLeftButtonDown += (sender, args) => MouseDown(sender, args); _ellipse.MouseEnter += (sender, args) => MouseEnter(sender, args); _ellipse.MouseLeave += (sender, args) => MouseLeave(sender, args); _ellipse.MouseMove += (sender, args) => MouseMove(sender, args); _ellipse.MouseLeftButtonUp += (sender, args) => MouseUp(sender, args); Canvas.SetZIndex(_ellipse, ZIndexConstants.LineStudies1); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } rect.Normalize(); Canvas.SetLeft(_ellipse, rect.Left); Canvas.SetTop(_ellipse, rect.Top); _ellipse.Width = rect.Width; _ellipse.Height = rect.Height; }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (Element == null) { Debug.WriteLine("FrameworkElement NULL"); return; } if (lineStatus == LineStatus.StartPaint) { C.Children.Add(Element); Canvas.SetZIndex(Element, ZIndexConstants.LineStudies1); Element.Tag = this; Element.SetBinding(Canvas.TopProperty, this.CreateOneWayBinding("CanvasTop")); Element.SetBinding(Canvas.LeftProperty, this.CreateOneWayBinding("CanvasLeft")); Element.SetBinding(System.Windows.FrameworkElement.WidthProperty, this.CreateOneWayBinding("ElementWidth")); Element.SetBinding(System.Windows.FrameworkElement.HeightProperty, this.CreateOneWayBinding("ElementHeight")); _internalObjectCreated = true; xEnumVisuals(Element); return; } if (Element.Visibility == Visibility.Collapsed) { Element.Visibility = Visibility.Visible; } rect.Normalize(); //Canvas.SetLeft(Element, rect.Left); //Canvas.SetTop(Element, rect.Top); //Element.Width = rect.Width; //Element.Height = rect.Height; CanvasLeft = rect.Left; CanvasTop = rect.Top; ElementWidth = rect.Width; ElementHeight = rect.Height; }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (!_internalObjectCreated && lineStatus != LineStatus.StartPaint) { DrawLineStudy(rect, LineStatus.StartPaint); } if (lineStatus == LineStatus.StartPaint) { _rectangle.StrokeThickness = StrokeThickness; _rectangle.Stroke = Stroke; if (_rectangle.Fill == null) { _rectangle.Fill = new SolidColorBrush(Colors.Transparent); } _rectangle.Tag = this; C.Children.Add(_rectangle); Canvas.SetZIndex(_rectangle, ZIndexConstants.LineStudies1); _rectangle.MouseLeftButtonDown += (sender, args) => MouseDown(sender, args); _rectangle.MouseEnter += (sender, args) => MouseEnter(sender, args); _rectangle.MouseLeave += (sender, args) => MouseLeave(sender, args); _rectangle.MouseMove += (sender, args) => MouseMove(sender, args); _rectangle.MouseLeftButtonUp += (sender, args) => MouseUp(sender, args); new ContextLine(this); _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } rect.Normalize(); Canvas.SetLeft(_rectangle, rect.Left); Canvas.SetTop(_rectangle, rect.Top); _rectangle.Width = rect.Width; _rectangle.Height = rect.Height; }
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; } } }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (_txt == null && lineStatus != LineStatus.StartPaint) { DrawLineStudy(rect, LineStatus.StartPaint); } if (lineStatus == LineStatus.StartPaint) { FontFamily = new FontFamily(_fontName = _chartX.FontFace); Foreground = Stroke; _txt = new TextBlock { Tag = this, Visibility = Visibility.Collapsed }; C.Children.Add(_txt); _txt.SetBinding(TextBlock.TextProperty, this.CreateOneWayBinding("Text")); _txt.SetBinding(TextBlock.FontFamilyProperty, this.CreateOneWayBinding("FontFamily")); _txt.SetBinding(TextBlock.FontSizeProperty, this.CreateOneWayBinding("FontSize")); _txt.SetBinding(TextBlock.ForegroundProperty, this.CreateOneWayBinding("Foreground")); _txt.SetBinding(UIElement.OpacityProperty, this.CreateOneWayBinding("Opacity")); _txt.MouseLeftButtonDown += (sender, args) => MouseDown(sender, args); _txt.MouseEnter += (sender, args) => MouseEnter(sender, args); _txt.MouseLeave += (sender, args) => MouseLeave(sender, args); _txt.MouseMove += (sender, args) => MouseMove(sender, args); _txt.MouseLeftButtonUp += (sender, args) => MouseUp(sender, args); if (_contextLine == null) { _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } _internalObjectCreated = true; _txt.SetBinding(Canvas.TopProperty, this.CreateOneWayBinding("CanvasTop")); _txt.SetBinding(Canvas.LeftProperty, this.CreateOneWayBinding("CanvasLeft")); _txt.SetBinding(Canvas.ZIndexProperty, this.CreateOneWayBinding("CanvasZIndex")); return; } if (_txt == null) { return; } if (_txt.Visibility == Visibility.Collapsed) { _txt.Visibility = Visibility.Visible; _txt.UpdateLayout(); } //Canvas.SetLeft(_txt, rect.Right); //Canvas.SetTop(_txt, rect.Bottom); CanvasLeft = rect.Right; CanvasTop = rect.Bottom; CanvasZIndex = ZIndexConstants.LineStudies1; //Canvas.SetZIndex(_txt, ZIndexConstants.LineStudies1); }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (lineStatus == LineStatus.StartPaint) { for (int i = 0; i < _lines.Length; i++) { _lines[i] = new Line { Tag = this }; Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1); C.Children.Add(_lines[i]); } _contextLine = new ContextLine(this); _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } // for (int i = 0; i < _lines.Length; i++ ) // { // double cx = C.ActualWidth - rect.Right; // double cy = rect.Bottom - (cx * _angles[i]); // Utils.DrawLine(rect.Right, rect.Bottom, C.ActualWidth, cy, Stroke, StrokeType, StrokeThickness, _lines[i]); // } double x = 0; double cx = 0; double y = 0; double cy = 0; //rect.Normalize(); for (int n = 0; n != 10; n++) { bool flip = true; double ay = 0; if (lineStatus == LineStatus.Painting || lineStatus == LineStatus.Moving) { ay = rect.Bottom; } else { ay = _y1; } if (ay > C.ActualHeight - 30) { flip = true; } else if (ay < 30) { flip = false; } else { flip = _prevUp; } double right = rect.Left + ((rect.Right + MAX_VISIBLE) * ((n + 3) * 0.125)); cx = right; if (flip) { cy = rect.Top - MAX_VISIBLE; if (n == 4) { n = 5; } if (n == 5) { cx = rect.Right + MAX_VISIBLE; } y = rect.Bottom; x = rect.Left; } else { cy = rect.Bottom + MAX_VISIBLE; y = rect.Top; x = rect.Left; } Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, Opacity, _lines[n]); } }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (lineStatus == LineStatus.StartPaint) { for (int i = 0; i < _lines.Length; i++) { _lines[i] = new System.Windows.Shapes.Line { Tag = this }; Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1); C.Children.Add(_lines[i]); } if (_contextLine == null) { _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } _internalObjectCreated = true; return; } rect.Normalize(); if (rect.Width == 0) { return; } int revX1 = (int)(_chartX.GetReverseXInternal(rect.Left) + _chartX._startIndex); int revX2 = (int)(_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex); if (revX1 < 0) { revX1 = 0; } if (revX2 < 0) { revX2 = 0; } if (revX1 == revX2) { return; } // Get the highest high of the high series. // Note: this code makes the vague assumption // that only one symbol exists on this panel. Series sHigh = GetSeriesOHLC(SeriesTypeOHLC.High); if (sHigh == null) { return; } Series sLow = GetSeriesOHLC(SeriesTypeOHLC.Low); if (sLow == null) { return; } Series sClose = GetSeriesOHLC(SeriesTypeOHLC.Close); if (revX1 >= sHigh.RecordCount) { revX1 = sHigh.RecordCount; } if (revX2 >= sHigh.RecordCount) { revX2 = sHigh.RecordCount; } //********** // Perform linear regression on the data double xSum = 0, ySum = 0, xSquaredSum = 0, xYSum = 0; int n, j; if (revX1 > revX2) { revX2 = revX1; } int x = revX2 - revX1; for (n = 1; n != x + 1; ++n) { j = revX1 + n - 1; xSum += n; ySum += sClose[j].Value.Value; xSquaredSum += (n * n); xYSum += (sClose[j].Value.Value * n); } n = x; double q1 = n != 0 ? (xYSum - ((xSum * ySum) / n)) : 0; double q2 = n != 0 ? (xSquaredSum - ((xSum * xSum) / n)) : 0; double slope = q2 != 0 ? (q1 / q2) : 0; double leftValue = slope != 0 ? (((1 / (double)n) * ySum) - (((int)((double)n / 2)) * slope)) : 0.0; double rightValue = ((n * slope) + leftValue); double right = (x - 1); double inc = 0; if (right != 0) { inc = (rightValue - leftValue) / right; } double prevVal = 0.0; j = 0; // Find max distance from linear regression line double lowestLow = sHigh[0].Value.Value; double highestHigh = 0; for (n = revX1; n < revX2; ++n) { j++; double val = leftValue + inc * (j - 1); if (prevVal != 0) { if (sHigh[n].Value.Value - val > highestHigh) { highestHigh = sHigh[n].Value.Value - val; } if (val - sLow[n].Value.Value < lowestLow && val - sLow[n].Value.Value > 0) { lowestLow = val - sLow[n].Value.Value; } } prevVal = val; } if (highestHigh > lowestLow) { lowestLow = highestHigh; } if (lowestLow > highestHigh) { highestHigh = lowestLow; } _linesSel.C = C; double lX1 = _chartX.GetXPixel(revX1 - _chartX._startIndex); double lX2 = _chartX.GetXPixel(revX2 - _chartX._startIndex + 1); j = 0; for (n = revX1; n < revX2; n++, j++) { double val = leftValue + inc * (j - 1); double lY1 = _chartPanel.GetY(prevVal - lowestLow); double lY2 = _chartPanel.GetY(val - lowestLow); if (prevVal != 0) { Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _lines[0]); } lY1 = _chartPanel.GetY(prevVal); lY2 = _chartPanel.GetY(val); if (prevVal != 0) { Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _lines[1]); } lY1 = _chartPanel.GetY(prevVal + highestHigh); lY2 = _chartPanel.GetY(val + highestHigh); if (prevVal != 0) { Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _lines[2]); } prevVal = val; } _linesSel.Start(); if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting) { Utils.DrawLine(lX1, 0, lX1, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, _linesSel); Utils.DrawLine(lX2, 0, lX2, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, _linesSel); } _linesSel.Stop(); _linesSel.Do(l => l.ZIndex = ZIndexConstants.LineStudies1); }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (_txt == null && lineStatus != LineStatus.StartPaint) { DrawLineStudy(rect, LineStatus.StartPaint); } if (lineStatus == LineStatus.StartPaint) { _line.Stroke = Stroke; _line.StrokeThickness = StrokeThickness; Types.SetShapePattern(_line, StrokeType); _line.Tag = this; C.Children.Add(_line); Canvas.SetZIndex(_line, ZIndexConstants.LineStudies1); _txt = new TextBlock { FontFamily = new FontFamily(_chartX.FontFace), FontSize = _chartX.FontSize, Foreground = Stroke, Tag = this }; C.Children.Add(_txt); Canvas.SetZIndex(_txt, ZIndexConstants.LineStudies1); if (_contextLine == null) { _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } _internalObjectCreated = true; return; } if (_txt == null) { return; } _txt.Visibility = _showLineText ? Visibility.Visible : Visibility.Collapsed; int recordIndex = (int)_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex; if (_showLineText) { if (_showRecordNumber) { _txt.Text = (recordIndex + 1).ToString(); //+1 cause we need record number, not record index } else { DateTime timestamp = _chartPanel._chartX._dataManager.GetTimeStampByIndex(recordIndex); _txt.Text = string.IsNullOrEmpty(_customDateFormat) ? timestamp.ToString() : timestamp.ToString(_customDateFormat); } Canvas.SetTop(_txt, 2); double textWidth = _chartX.GetTextWidth(_txt.Text); if (rect.Right + textWidth + 2 < C.ActualWidth) { Canvas.SetLeft(_txt, rect.Right + 2); } else { Canvas.SetLeft(_txt, rect.Right - textWidth - 2); } } _line.X1 = _line.X2 = rect.Right; _line.Y1 = 0; _line.Y2 = C.ActualHeight; }
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 override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { int i; if (lineStatus == LineStatus.StartPaint) { for (i = 0; i < LinesCount + 1; i++) { _lines[i] = new Line { Stroke = Stroke, StrokeThickness = StrokeThickness, Tag = this, }; C.Children.Add(_lines[i]); _txts[i] = new TextBlock { Foreground = _chartX.FontForeground, FontFamily = new FontFamily(_chartX.FontFace), FontSize = _chartX.FontSize, Tag = this, }; C.Children.Add(_txts[i]); Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1); Canvas.SetZIndex(_txts[i], ZIndexConstants.LineStudies1); } _handle = new Line { Stroke = Stroke, StrokeThickness = StrokeThickness, Tag = this }; C.Children.Add(_handle); Canvas.SetZIndex(_handle, ZIndexConstants.LineStudies1); if (_contextLine == null) { _contextLine = new ContextLine(this); } _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } if (!_firstY.HasValue) { _firstY = rect.Top; } bool upsideDown = _firstY > rect.Bottom; if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting) { _handle.Visibility = Visibility.Visible; _handle.X1 = rect.Left; _handle.Y1 = rect.Top; _handle.X2 = rect.Right; _handle.Y2 = rect.Bottom; } else { _handle.Visibility = Visibility.Collapsed; } rect.Normalize(); rect.Right = C.ActualWidth; double max = _chartPanel.GetY(rect.Top); rect.Right -= _chartX.GetTextWidth(string.Format("{0:f2} ", max)); //Comentado por Felipe em 29-08 //if (_params.Count > 1) //{ // upsideDown = _params[0] < _params[1]; //} if ((_params.Count > 5) && (_params[5] == 1)) { upsideDown = false; } else { upsideDown = !upsideDown; } //bloco alterado por Felipe double fibNum = 1.618033; List <double> values = new List <double>(); double minFib = double.MaxValue; double maxFib = double.MinValue; // prepare values to be painted //Thx to Rekhender Dhawan if (upsideDown) { // prepare values to be painted for (i = 0; i < LinesCount; i++) { if (i < _params.Count) { fibNum = _params[i]; } else { fibNum *= 0.618; } values.Add(fibNum); minFib = Math.Min(minFib, fibNum); maxFib = Math.Max(maxFib, fibNum); } } else { for (i = LinesCount - 1; i >= 0; i--) { if (i < _params.Count) { fibNum = _params[i]; } else { fibNum *= 0.618; } values.Add(fibNum); minFib = Math.Min(minFib, fibNum); maxFib = Math.Max(maxFib, fibNum); } } double k = maxFib - minFib; // paint values string formatString = "{0:f" + _chartX.ScalePrecision + "}"; for (i = 0; i < LinesCount && k != 0; i++) { fibNum = values[i]; double norm = (fibNum - minFib) / k; //Comenatado por Felipe em 29-08 //if (upsideDown) // norm = 1 - norm; double textTop = rect.Top + rect.Height * norm; _lines[i].X1 = rect.Left; _lines[i].Y1 = _lines[i].Y2 = textTop; _lines[i].X2 = rect.Right; //string strNum1 = string.Format("{0:0}%", !upsideDown ? (1 - norm) * 100.0 : norm * 100.0); string strNum1 = (!upsideDown) ? (values[(values.Count - 1) - i] * 100.0).ToString("N1") + "%" : (norm * 100.0).ToString("N1") + "%"; double y = _chartPanel.GetReverseY(textTop); string strNum2 = string.Format(formatString, y); _txts[i].Text = string.Format("{0} ({1})", strNum2, strNum1); Canvas.SetLeft(_txts[i], rect.Right + 2); Canvas.SetTop(_txts[i], textTop); } _lines[i].X1 = rect.Left; _lines[i].Y1 = _lines[i].Y2 = rect.Bottom; _lines[i].X2 = rect.Right; }
internal void Paint(double x, double y, LineStatus lineStatus, Types.Corner corner) { if (!_drawn && lineStatus == LineStatus.RePaint) { _drawn = true; Update(); DrawLineStudy(new Types.RectEx(), LineStatus.StartPaint); } switch (lineStatus) { case LineStatus.StartPaint: _dStartX = x; _dStartY = y; DrawLineStudy(new Types.RectEx(), lineStatus); break; case LineStatus.Painting: SetRect(x, y); DrawLineStudy(_newRect, lineStatus); break; case LineStatus.EndPaint: SetXY(x, y, lineStatus); _dStartX = _dStartY = 0.0; Reset(); _newRect = new Types.RectEx(_x1, _y1, _x2, _y2); DrawLineStudy(_newRect, lineStatus); break; case LineStatus.RePaint: DrawLineStudy(_newRect = new Types.RectEx(_x1, _y1, _x2, _y2), lineStatus); break; case LineStatus.StartMove: _dStartX = x; _dStartY = y; break; case LineStatus.Moving: switch (corner) { case Types.Corner.BottomRight: _x2 = x; _y2 = y; break; case Types.Corner.MiddleRight: _x2 = x; break; case Types.Corner.TopRight: _x2 = x; _y1 = y; break; case Types.Corner.TopCenter: _y1 = y; break; case Types.Corner.TopLeft: _x1 = x; _y1 = y; break; case Types.Corner.MiddleLeft: _x1 = x; break; case Types.Corner.BottomLeft: _x1 = x; _y2 = y; break; case Types.Corner.BottomCenter: _y2 = y; break; case Types.Corner.MoveAll: _x1 -= (_dStartX - x); _y1 -= (_dStartY - y); _x2 -= (_dStartX - x); _y2 -= (_dStartY - y); _dStartX = x; _dStartY = y; break; } _newRect = new Types.RectEx(_x1, _y1, _x2, _y2); DrawLineStudy(_newRect, lineStatus); ShowSelection(true); _oldRect = _newRect; break; case LineStatus.EndMove: SetXY(x, y, lineStatus); Reset(); _newRect = new Types.RectEx(_x1, _y1, _x2, _y2); DrawLineStudy(_newRect, lineStatus); _resizingCorner = Types.Corner.None; break; } if (lineStatus == LineStatus.RePaint) { ShowSelection(_selected); } _drawn = true; }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { double cy = 0; if (rect.IsZero) { return; } if (_lines.Count == 0) { for (int i = 0; i < 4; i++) { Line line = new Line { Tag = this }; Canvas.SetZIndex(line, ZIndexConstants.LineStudies1); _lines.Add(line); C.Children.Add(line); } _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } double value = (rect.Bottom - rect.Top) / 3; rect.Bottom += 15; double b = (rect.Top - rect.Bottom) / (rect.Left - rect.Right); double c = rect.Top - b * rect.Left; double cx = C.ActualWidth; cy = (b * cx + c) + cy * 0.3; double y = rect.Top; double x = rect.Left; Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, Opacity, _lines[0]); b = ((rect.Top + value * 1) - rect.Bottom) / (rect.Left - rect.Right); c = (rect.Top + value * 1) - b * rect.Left; cx = C.ActualWidth; cy = (b * cx + c) + cy * 0.5; y = rect.Top; x = rect.Left; Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, Opacity, _lines[1]); b = (rect.Top + value * 2 - rect.Bottom) / (rect.Left - rect.Right); c = rect.Top + value * 2 - b * rect.Left; cx = C.ActualWidth; cy = (b * cx + c) + cy * 0.8; y = rect.Top; x = rect.Left; Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, Opacity, _lines[2]); rect.Bottom -= 15; Utils.DrawLine(rect.Left, rect.Top, rect.Right, rect.Bottom, Stroke, StrokeType, StrokeThickness, Opacity, _lines[3]); if (_contextLine == null) { _contextLine = new ContextLine(this); } }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (lineStatus == LineStatus.StartPaint) { Debug.Assert(_imagePath.Length > 0); _image = new Image { Tag = this, Visibility = Visibility.Collapsed, Stretch = Stretch.None }; _image.SetBinding(Canvas.TopProperty, this.CreateOneWayBinding("CanvasTop")); _image.SetBinding(Canvas.LeftProperty, this.CreateOneWayBinding("CanvasLeft")); _image.SetBinding(ToolTipService.ToolTipProperty, this.CreateOneWayBinding("Tooltip")); #if WPF BitmapImage bi = new BitmapImage(); bi.BeginInit(); bi.CacheOption = BitmapCacheOption.OnLoad; bi.UriSource = new Uri(_imagePath, UriKind.RelativeOrAbsolute); bi.EndInit(); _image.Source = bi; #endif #if SILVERLIGHT _image.SetValue(Image.SourceProperty, new BitmapImage(new Uri(_imagePath, UriKind.RelativeOrAbsolute))); #endif _image.MouseLeftButtonDown += (sender, args) => MouseDown(sender, args); _image.MouseEnter += (sender, args) => MouseEnter(sender, args); _image.MouseLeave += (sender, args) => MouseLeave(sender, args); _image.MouseMove += (sender, args) => MouseMove(sender, args); _image.MouseLeftButtonUp += (sender, args) => MouseUp(sender, args); _firstResize = true; _firstRect = rect; _image.SizeChanged += (o, eventArgs) => { if (_firstResize) { _firstResize = false; SetImagePos(_firstRect); } }; C.Children.Add(_image); Canvas.SetZIndex(_image, ZIndexConstants.LineStudies1); if (_contextLine == null) { _contextLine = new ContextLine(this); } _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } if (_firstResize) { _firstRect = rect; } SetImagePos(rect); }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (lineStatus == LineStatus.StartPaint) { for (int i = 0; i < _lines.Length; i++) { _lines[i] = new Line { Tag = this }; Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1); C.Children.Add(_lines[i]); } _handle = new Line { Tag = this }; Canvas.SetZIndex(_handle, ZIndexConstants.LineStudies1); C.Children.Add(_handle); if (_contextLine == null) { _contextLine = new ContextLine(this); } _internalObjectCreated = true; _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); return; } if (rect.IsZero) { return; } // Draw three trend lines that go out from // the three horizontal box sections to form the speed lines. int value = (int)((rect.Bottom - rect.Top) / 3); rect.Bottom += 15; double b = (rect.Top - rect.Bottom) / (rect.Left - rect.Right); double c = rect.Top - b * rect.Left; double cx = C.ActualWidth; double cy = (b * cx + c); double y = rect.Top; double x = rect.Left; Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, _lines[0]); b = ((rect.Top + value * 1) - rect.Bottom) / (rect.Left - rect.Right); c = (rect.Top + value * 1) - b * rect.Left; cx = C.ActualWidth; cy = (b * cx + c); y = rect.Top; x = rect.Left; Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, _lines[1]); b = (rect.Top + value * 2 - rect.Bottom) / (rect.Left - rect.Right); c = rect.Top + value * 2 - b * rect.Left; cx = C.ActualWidth; cy = (b * cx + c); y = rect.Top; x = rect.Left; Utils.DrawLine(x, y, cx, cy, Stroke, StrokeType, StrokeThickness, _lines[2]); rect.Bottom -= 15; // Draw the handle Utils.DrawLine(rect.Left, rect.Top, rect.Right, rect.Bottom, Stroke, StrokeType, StrokeThickness, _handle); }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (lineStatus == LineStatus.StartPaint) { return; } rect.Normalize(); if (rect.Width == 0 || rect.Left < 0) { return; } int revX1 = (int)(_chartX.GetReverseXInternal(rect.Left) + _chartX._startIndex); int revX2 = (int)(_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex); if (revX1 < 0) { revX1 = 0; } if (revX2 < 0) { revX2 = 0; } if (revX1 == revX2) { return; } // Note: this code makes the vague assumption // that only one symbol exists on this panel. // Get the close series Series sClose = GetSeriesOHLC(SeriesTypeOHLC.Close); if (sClose == null) { return; } //Debug.Assert(sClose.RecordCount == _chartX.RecordCount); if (revX1 >= _chartX.RecordCount) { revX1 = _chartX.RecordCount - 1; } if (revX2 >= _chartX.RecordCount) { revX2 = _chartX.RecordCount - 1; } // Get the highest high of the high series. double highestHigh = 0; Series sHigh = GetSeriesOHLC(SeriesTypeOHLC.High); if (sHigh == null) { return; } //Debug.Assert(revX1 <= revX2); for (int i = revX1; i <= revX2; i++) { if (sHigh[i].Value > highestHigh) { highestHigh = sHigh[i].Value.Value; } } //Get the lowest low of the low series. double lowestLow = highestHigh; Series sLow = GetSeriesOHLC(SeriesTypeOHLC.Low); if (sLow == null) { return; } for (int i = revX1; i <= revX2; i++) { if (sLow[i].Value < lowestLow) { lowestLow = sLow[i].Value.Value; } } double range = (highestHigh - lowestLow) * 0.5; if (_rangeScale.HasValue) { range = (highestHigh - lowestLow) * _rangeScale.Value; } // Perform linear regression on the data double xSum = 0, ySum = 0, xSquaredSum = 0, xYSum = 0; int x = revX2 - revX1; int j, n; for (n = 1; n != x + 1; ++n) { j = revX1 + n - 1; xSum += n; ySum += sClose[j].Value.Value; xSquaredSum += (n * n); xYSum += (sClose[j].Value.Value * n); } n = x; double q1 = n != 0 ? (xYSum - ((xSum * ySum) / n)) : 0; double q2 = n != 0 ? (xSquaredSum - ((xSum * xSum) / n)) : 0; double slope = q2 != 0 ? (q1 / q2) : 0; double leftValue = slope != 0 ? (((1 / (double)n) * ySum) - (((int)((double)n / 2)) * slope)) : 0.0; double rightValue = ((n * slope) + leftValue); double inc = (x - 1) != 0 ? (rightValue - leftValue) / (x - 1) : 0; j = 0; double prevVal = 0; double lX1 = rect.Left; //_chartX.GetX(revX1 - _chartX._startIndex); double lX2 = rect.Right; // _chartX.GetX((revX2 - 1) - _chartX._startIndex + 1); if (_linesError.Count == 0) { for (int i = 0; i < 3; i++) { System.Windows.Shapes.Line line = new System.Windows.Shapes.Line { Tag = this }; Canvas.SetZIndex(line, ZIndexConstants.LineStudies1); C.Children.Add(line); _linesError.Add(line); } _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } _internalObjectCreated = true; _lines.C = C; _lines.Start(); for (n = revX1; n <= revX2; n++, j++) { double val = leftValue + inc * (j - 1); //double lX1 = _chartX.GetX(n - _chartX._startIndex); //double lX2 = _chartX.GetX(n - _chartX._startIndex + 1); double lY1 = _chartPanel.GetY(prevVal + range); double lY2 = _chartPanel.GetY(val + range); if (prevVal != 0.0) { _errorLines[2].Y1 = lY1; _errorLines[2].Y2 = lY2; Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _linesError[0]); } lY1 = _chartPanel.GetY(prevVal - range); lY2 = _chartPanel.GetY(val - range); if (prevVal != 0.0) { _errorLines[0].Y1 = lY1; _errorLines[0].Y2 = lY2; Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _linesError[1]); } lY1 = _chartPanel.GetY(prevVal); lY2 = _chartPanel.GetY(val); if (prevVal != 0.0) { _errorLines[1].Y1 = lY1; _errorLines[1].Y2 = lY2; Utils.DrawLine(lX1, lY1, lX2, lY2, Stroke, StrokeType, StrokeThickness, _linesError[2]); } prevVal = val; } if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting) { Utils.DrawLine(rect.Left, 0, rect.Left, _chartPanel.Height, Stroke, StrokeType, StrokeThickness, _lines); Utils.DrawLine(rect.Right, 0, rect.Right, _chartPanel.Height, Stroke, StrokeType, StrokeThickness, _lines); } _lines.Stop(); _lines.Do(l => l.ZIndex = ZIndexConstants.LineStudies1); _errorLines[0].X1 = rect.Left; _errorLines[0].X2 = rect.Right; _errorLines[1].X1 = rect.Left; _errorLines[1].X2 = rect.Right; _errorLines[2].X1 = rect.Left; _errorLines[2].X2 = rect.Right; if (_contextLine == null && _linesError.Count > 0) { _contextLine = new ContextLine(this); } }
internal virtual void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { throw new NotImplementedException(); }
private void SetImagePos(Types.RectEx rect) { double top; double left; int x = (int)rect.Right; int y = (int)rect.Bottom; double height = _actualSize.HasValue ? _actualSize.Value.Height : _image.ActualHeight; double width = _actualSize.HasValue ? _actualSize.Value.Width : _image.ActualWidth; if (_image.Visibility == Visibility.Collapsed) { _image.Visibility = Visibility.Visible; } switch (Align) { case ImageAlign.TopLeft: top = y; left = x; break; case ImageAlign.TopMiddle: top = y; left = x - width / 2; break; case ImageAlign.TopRight: top = y; left = x - width; break; case ImageAlign.BottomLeft: top = y - height; left = x; break; case ImageAlign.BottomMiddle: top = y - height; left = x - width / 2; break; case ImageAlign.BottomRight: top = y - height; left = x - width; break; case ImageAlign.LeftMiddle: top = y - height / 2; left = x; break; case ImageAlign.RightMiddle: top = y - height / 2; left = x - width; break; case ImageAlign.Center: top = y - height / 2; left = x - width / 2; break; default: throw new ArgumentException("Align property must be set."); } //Canvas.SetTop(_image, top); //Canvas.SetLeft(_image, left); CanvasLeft = left; CanvasTop = top; }
public static Rectangle DrawRectangle(Types.RectEx rectEx, Brush fillBrush, PaintObjectsManager <Rectangle> rects) { return(DrawRectangle(rectEx.Left, rectEx.Top, rectEx.Right, rectEx.Bottom, fillBrush, rects)); }
internal override void DrawLineStudy(Types.RectEx rect, LineStatus lineStatus) { if (lineStatus == LineStatus.StartPaint) { for (int i = 0; i < _lines.Length; i++) { _lines[i] = new Line { Tag = this }; Canvas.SetZIndex(_lines[i], ZIndexConstants.LineStudies1); C.Children.Add(_lines[i]); } if (_contextLine == null) { _contextLine = new ContextLine(this); _chartX.InvokeLineStudyCreated(new StockChartX.LineStudyCreatedEventArgs(this)); } return; } // **************************************************************** // *Note: This line study requires OHLC series in the owner panel!* // **************************************************************** rect.Normalize(); if (rect.Width == 0) { return; } int revX1 = (int)(_chartX.GetReverseXInternal(rect.Left) + _chartX._startIndex); int revX2 = (int)(_chartX.GetReverseXInternal(rect.Right) + _chartX._startIndex); if (revX1 < 0) { revX1 = 0; } if (revX2 < 0) { revX2 = 0; } if (revX1 == revX2) { return; } // Get the highest high of the high series. // Note: this code makes the vague assumption // that only one symbol exists on this panel. Series sHigh = GetSeriesOHLC(SeriesTypeOHLC.High); if (sHigh == null) { return; } Series sLow = GetSeriesOHLC(SeriesTypeOHLC.Low); if (sLow == null) { return; } double highestHigh = sHigh.MaxFromInterval(ref revX1, ref revX2); double lowestLow = sLow.MinFromInterval(ref revX1, ref revX2); double value = highestHigh + ((highestHigh - lowestLow) / 4); _linesSel.C = C; _linesSel.Start(); for (int i = 0; i < _lines.Length; i++) { value -= ((highestHigh - lowestLow) / 4); rect.Top = _chartPanel.GetY(value); Utils.DrawLine(rect.Left, rect.Top, rect.Right, rect.Top, Stroke, i == 2 ? LinePattern.Dot : StrokeType, StrokeThickness, Opacity, _lines[i]); } if (lineStatus == LineStatus.Moving || lineStatus == LineStatus.Painting) { Utils.DrawLine(rect.Left, 0, rect.Left, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, Opacity, _linesSel); Utils.DrawLine(rect.Right, 0, rect.Right, C.ActualHeight, Stroke, LinePattern.Dot, StrokeThickness, Opacity, _linesSel); } _linesSel.Stop(); _internalObjectCreated = true; _linesSel.Do(l => l.ZIndex = ZIndexConstants.LineStudies1); }
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); }