private static void PaintPreviewWithPaintBars(Graphics g, Pen pen) { OHLCBar bar; double x, y; PointF[] points = new PointF[(int)Math.Floor(g.VisibleClipBounds.Width)]; int i = 0; double min = double.MaxValue; double max = double.MinValue; double open = double.NaN; for (x = g.VisibleClipBounds.Left; x < g.VisibleClipBounds.Right; x++) { y = (Math.Sin(x * Math.PI * 6.0 / g.VisibleClipBounds.Width) * 0.4f * g.VisibleClipBounds.Height); points[i].X = (float)x; points[i].Y = (float)(y - (g.VisibleClipBounds.Top - g.VisibleClipBounds.Bottom) / 2.0f); if (double.IsNaN(open)) { open = points[i].Y; } min = Math.Min(min, points[i].Y); max = Math.Max(max, points[i].Y); if (i % 8 == 0) { bar = new OHLCBar((float)points[i].X, (float)open, (float)(min - (max - min) / 3), (float)(max + (max - min) / 3), (float)points[i].Y); bar.Width = 3f; bar.Draw(g, pen); open = points[i].Y; min = double.MaxValue; max = double.MinValue; } i++; } }
protected override void PaintTmpGraph(Graphics aGraphic) { using (MethodLogger ml = new MethodLogger(this)) { #region Draw Grid // Draw grid if (this.ShowGrid) { #region Draw Horizontal lines float step = (float)Math.Pow(10, Math.Floor(Math.Log10((maxValue - minValue)))); if ((maxValue - minValue) / step < 3) { step /= 4; } else if ((maxValue - minValue) / step < 6) { step /= 2; } else { if ((maxValue - minValue) / step > 13) { step *= 4; } else if ((maxValue - minValue) / step > 7) { step *= 2; } } float val; if (minValue < 0) { val = -(float)Math.Pow(10, Math.Ceiling(Math.Log10((Math.Abs(minValue))))); } else { val = (float)Math.Pow(10, Math.Floor(Math.Log10((minValue)))); } if (val > 0 && step > val) val = step; if (val < 0 && step > Math.Abs(val)) val = -step; PointF p1; while (val < maxValue) { if (val > minValue) { p1 = GetScreenPointFromValuePoint(this.StartIndex, val); aGraphic.DrawLine(gridPen, GraphRectangle.X, p1.Y, GraphRectangle.X + GraphRectangle.Width, p1.Y); aGraphic.DrawString(val.ToString("0.##"), axisFont, Brushes.Black, 0, p1.Y - 8); } val += step; } #endregion #region Draw vertical lines DrawVerticalGridLines(aGraphic, true, this.StartIndex, this.EndIndex); #endregion } aGraphic.DrawString(this.dateSerie[this.EndIndex].ToString("dd/MM"), axisFont, Brushes.Black, GraphRectangle.Right - 3, GraphRectangle.Y + GraphRectangle.Height); aGraphic.DrawString(this.dateSerie[this.EndIndex].ToString("yyyy"), axisFont, Brushes.Black, GraphRectangle.Right - 1, GraphRectangle.Y + GraphRectangle.Height + 8); #endregion #region Draw HLine // Paint horizontal lines first this.PaintHorizontalLines(aGraphic); #endregion #region Draw orders if (ShowOrders && this.Portofolio != null) { if (ShowSummaryOrders) { PaintSummaryOrders(aGraphic); } else { PaintOrders(aGraphic); } } #endregion #region Draw values and curves PointF[] tmpPoints = null; PointF[] tmpOpenPoints = null; PointF[] tmpHighPoints = null; PointF[] tmpLowPoints = null; // Draw indicator1Name first not to hide the value if (!HideIndicators) { #region DISPLAY TRAIL STOPS if (this.CurveList.TrailStop != null && this.CurveList.TrailStop.Series[0].Count > 0) { FloatSerie longStopSerie = this.CurveList.TrailStop.Series[0]; FloatSerie shortStopSerie = this.CurveList.TrailStop.Series[1]; Pen longPen = this.CurveList.TrailStop.SeriePens[0]; Pen shortPen = this.CurveList.TrailStop.SeriePens[1]; PointF srPoint1; PointF srPoint2; if (float.IsNaN(shortStopSerie[this.StartIndex])) { srPoint1 = GetScreenPointFromValuePoint(this.StartIndex, longStopSerie[this.StartIndex]); } else { srPoint1 = GetScreenPointFromValuePoint(this.StartIndex, shortStopSerie[this.StartIndex]); } for (int i = StartIndex + 1; i <= this.EndIndex; i++) { if (float.IsNaN(shortStopSerie[i])) // upTrend { srPoint2 = GetScreenPointFromValuePoint(i, longStopSerie[i]); aGraphic.DrawLine(longPen, srPoint1, srPoint2); } else { srPoint2 = GetScreenPointFromValuePoint(i, shortStopSerie[i]); aGraphic.DrawLine(shortPen, srPoint1, srPoint2); } srPoint1 = srPoint2; } } #endregion #region DISPLAY INDICATORS foreach (IStockIndicator stockIndicator in CurveList.Indicators) { for (int i = 0; i < stockIndicator.SeriesCount; i++) { if (stockIndicator.SerieVisibility[i] && stockIndicator.Series[i].Count > 0) { bool isHilbertSR = stockIndicator.Name.StartsWith("HILBERT"); bool isTrailSR = stockIndicator.Name.StartsWith("TRAILHLSR"); bool isSupport = stockIndicator.SerieNames[i].EndsWith(".S"); bool isResistance = stockIndicator.SerieNames[i].EndsWith(".R"); if (isSupport || isResistance) { PointF srPoint = PointF.Empty; FloatSerie srSerie = stockIndicator.Series[i]; float pointSize = stockIndicator.SeriePens[i].Width; using (Brush srBrush = new SolidBrush(stockIndicator.SeriePens[i].Color)) { for (int index = this.StartIndex; index <= this.EndIndex; index++) { float sr = srSerie.Values[index]; if (float.IsNaN(sr)) { continue; } srPoint = GetScreenPointFromValuePoint(index, sr); aGraphic.FillEllipse(srBrush, srPoint.X - pointSize, srPoint.Y - pointSize, 2 * pointSize, 2 * pointSize); const int textOffset = 4; float yPos = isSupport ? srPoint.Y + pointSize : srPoint.Y - 2 * pointSize - 12; if (this.ShowIndicatorText) { // Draw PB and EndOfTrend text if (stockIndicator.Events[2][index]) { // Pullback in trend detected this.DrawString(aGraphic, "PB", axisFont, srBrush, this.backgroundBrush, srPoint.X - textOffset, yPos, false); } else if (stockIndicator.Events[3][index]) { // End of trend detected this.DrawString(aGraphic, "End", axisFont, srBrush, this.backgroundBrush, srPoint.X - textOffset, yPos, false); } else if (!isHilbertSR) { if (stockIndicator.Events[4][index]) { this.DrawString(aGraphic, "HL", axisFont, srBrush, this.backgroundBrush, srPoint.X - textOffset, yPos, false); } else if (stockIndicator.Events[5][index]) { this.DrawString(aGraphic, "LH", axisFont, srBrush, this.backgroundBrush, srPoint.X - textOffset, yPos, false); } } } } } } else { tmpPoints = GetScreenPoints(StartIndex, EndIndex, stockIndicator.Series[i]); if (tmpPoints != null) { aGraphic.DrawLines(stockIndicator.SeriePens[i], tmpPoints); } } } } } #endregion #region DISPLAY DECORATORS if (this.ShowIndicatorDiv && CurveList.ShowMes.Count > 0) { for (int j = 0; j < CurveList.ShowMes.Count; j++) { IStockDecorator decorator = CurveList.ShowMes[j]; for (int i = 0; i < decorator.EventCount; i++) { if (decorator.EventVisibility[i] && decorator.IsEvent[i] && decorator.Events[i].Count > 0) { FloatSerie dataSerie = (i % 2 == 0) ? highCurveType.DataSerie : lowCurveType.DataSerie; Pen pen = decorator.EventPens[i]; using (Brush brush = new SolidBrush(pen.Color)) { BoolSerie decoSerie = decorator.Events[i]; for (int index = this.StartIndex; index <= this.EndIndex; index++) { if (decoSerie[index]) { PointF point = new PointF(index, dataSerie[index]); PointF point2 = GetScreenPointFromValuePoint(point); aGraphic.FillEllipse(brush, point2.X - pen.Width * 1.5f, point2.Y - pen.Width * 1.5f, pen.Width * 3f, pen.Width * 3f); } } } } } } } #endregion } #endregion #region Display drawing items if (this.ShowDrawings && this.drawingItems != null) { foreach (DrawingItem item in this.drawingItems) { item.Draw(aGraphic, this.matrixValueToScreen, new Rectangle2D(this.GraphRectangle), this.IsLogScale); // display support résistance value if (item.GetType() == typeof(Line2D)) { Line2D line = (Line2D)item; if (line.IsHorizontal) { PointF textLocation = GetScreenPointFromValuePoint(new PointF(StartIndex, line.Point1.Y)); this.DrawString(aGraphic, line.Point1.Y.ToString("0.##"), axisFont, textBrush, backgroundBrush, new PointF(1, textLocation.Y - 8), true); } } } } #endregion #region Display the stock value // Then draw the value if (closeCurveType != null && closeCurveType.IsVisible) { tmpPoints = GetScreenPoints(StartIndex, EndIndex, closeCurveType.DataSerie); // Store in member for future use (Display mouse marquee) //this.points = tmpPoints; switch (this.ChartMode) { case GraphChartMode.Line: aGraphic.DrawLines(closeCurveType.CurvePen, tmpPoints); break; case GraphChartMode.BarChart: { FloatSerie openSerie = openCurveType.DataSerie; FloatSerie highSerie = highCurveType.DataSerie; FloatSerie lowSerie = lowCurveType.DataSerie; tmpOpenPoints = GetScreenPoints(StartIndex, EndIndex, openSerie); tmpHighPoints = GetScreenPoints(StartIndex, EndIndex, highSerie); tmpLowPoints = GetScreenPoints(StartIndex, EndIndex, lowSerie); OHLCBar bar = new OHLCBar(); bar.Width = 0.40f * aGraphic.VisibleClipBounds.Width / tmpPoints.Count(); Pen barPen; for (int i = 0; i < tmpPoints.Count(); i++) { barPen = this.closeCurveType.CurvePen; if (!this.HideIndicators && this.CurveList.PaintBar != null) { // Get pen from paintBar IStockPaintBar pb = this.CurveList.PaintBar; if (pb.Events[0].Count == this.dateSerie.Length) { for (int pbIndex = 0; pbIndex < pb.SeriesCount; pbIndex++) { if (pb.SerieVisibility[pbIndex] && pb.Events[pbIndex][i + this.StartIndex]) { barPen = pb.SeriePens[pbIndex]; break; } } } } bar.X = tmpPoints[i].X; bar.Close = tmpPoints[i].Y; bar.High = tmpHighPoints[i].Y; bar.Open = tmpOpenPoints[i].Y; bar.Low = tmpLowPoints[i].Y; bar.Draw(aGraphic, barPen); } } break; case GraphChartMode.CandleStick: { FloatSerie openSerie = openCurveType.DataSerie; FloatSerie highSerie = highCurveType.DataSerie; FloatSerie lowSerie = lowCurveType.DataSerie; tmpOpenPoints = GetScreenPoints(StartIndex, EndIndex, openSerie); tmpHighPoints = GetScreenPoints(StartIndex, EndIndex, highSerie); tmpLowPoints = GetScreenPoints(StartIndex, EndIndex, lowSerie); CandleStick candleStick = new CandleStick(); candleStick.Width = 0.40f * aGraphic.VisibleClipBounds.Width / tmpPoints.Count(); for (int i = 0; i < tmpPoints.Count(); i++) { candleStick.X = tmpPoints[i].X; candleStick.Close = tmpPoints[i].Y; candleStick.High = tmpHighPoints[i].Y; candleStick.Open = tmpOpenPoints[i].Y; candleStick.Low = tmpLowPoints[i].Y; Color? color = null; if (!this.HideIndicators && this.CurveList.PaintBar != null) { // Get pen from paintBar IStockPaintBar pb = this.CurveList.PaintBar; if (pb.Events[0].Count == this.dateSerie.Length) { for (int pbIndex = 0; pbIndex < pb.SeriesCount; pbIndex++) { if (pb.SerieVisibility[pbIndex] && pb.Events[pbIndex][i + this.StartIndex]) { color = pb.SeriePens[pbIndex].Color; break; } } } if (color == null) { candleStick.Draw(aGraphic, closeCurveType.CurvePen, backgroundBrush); } else { using (Brush brush = new SolidBrush(color.Value)) { candleStick.Draw(aGraphic, closeCurveType.CurvePen, brush); } } } else { candleStick.Draw(aGraphic, closeCurveType.CurvePen, null); } } } break; default: break; } } #endregion #region Display the secondary stock value if (this.SecondaryFloatSerie != null) { PointF[] secondaryPoints = GetSecondaryScreenPoints(StartIndex, EndIndex); if (secondaryPoints.Length > 0) { aGraphic.DrawLines(SecondaryPen, secondaryPoints); } } #endregion #region Draw frame, axis and axis values // Draw main frame aGraphic.DrawRectangle(framePen, GraphRectangle.X, GraphRectangle.Y, GraphRectangle.Width, GraphRectangle.Height); // Display values and dates string lastValue = closeCurveType.DataSerie.Last.ToString(); aGraphic.DrawString(lastValue, axisFont, Brushes.Black, GraphRectangle.Right + 1, tmpPoints[tmpPoints.Count() - 1].Y - 8); #endregion #region Display event marquee if (this.ShowEventMarquee) { bool eventFound = false; for (int i = this.StartIndex; i <= this.EndIndex; i++) { eventFound = false; // Indicators foreach (IStockIndicator indicator in this.CurveList.Indicators.Where(indic => indic.Events != null)) { for (int j = 0; j < indicator.EventCount; j++) { if (indicator.IsEvent[j] && indicator.Events[j] != null && indicator.Events.Count() > 0) { BoolSerie eventSerie = indicator.Events[j]; if (eventSerie[i]) { eventFound = true; break; } } } if (eventFound) break; } // Trail Stops if (!eventFound && this.CurveList.TrailStop != null && this.CurveList.TrailStop.EventCount > 0) { for (int j = 0; j < this.CurveList.TrailStop.EventCount; j++) { if (this.CurveList.TrailStop.IsEvent[j] && this.CurveList.TrailStop.Events[j] != null && this.CurveList.TrailStop.Events.Count() > 0) { BoolSerie eventSerie = this.CurveList.TrailStop.Events[j]; if (eventSerie[i]) { eventFound = true; break; } } } } // Paint bars if (!eventFound && this.CurveList.PaintBar != null && this.CurveList.PaintBar.EventCount > 0) { int j = 0; foreach ( BoolSerie eventSerie in this.CurveList.PaintBar.Events.Where(ev => ev != null && ev.Count > 0)) { if (this.CurveList.PaintBar.SerieVisibility[j] && this.CurveList.PaintBar.IsEvent != null && this.CurveList.PaintBar.IsEvent[j] && eventSerie[i]) { eventFound = true; break; } j++; } } if (eventFound) { PointF[] marqueePoints = GetEventMarqueePointsAtIndex(i); aGraphic.FillPolygon(Brushes.DarkBlue, marqueePoints); } } } #endregion #region Display comment marquee if (this.ShowCommentMarquee) { for (int i = StartIndex; i <= EndIndex; i++) { DateTime commentDate = this.dateSerie[i]; if (this.Comments.ContainsKey(commentDate)) { string comment = this.Comments[commentDate]; if (!string.IsNullOrWhiteSpace(comment)) { PointF[] marqueePoints = GetCommentMarqueePointsAtIndex(i); aGraphic.FillPolygon(Brushes.DarkBlue, marqueePoints); } } } } #endregion } }