/// <summary> /// /// </summary> /// <param name="g"></param> /// <param name="unitsUnification">Draw a few units as one. Used when zooming is too big to show each unit - so unify them. 1 means no unification, 10 means unify 10 units together</param> /// <param name="clippingRectangle"></param> /// <param name="itemWidth"></param> /// <param name="itemMargin"></param> public override void Draw(GraphicsWrapper g, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin) { if (Visible == false) { return; } PointF drawingPoint = new PointF(); lock (this) { if (_chartType == ChartTypeEnum.Line) { SetChartType(SimpleChartSeries.ChartTypeEnum.Line); base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin); } else if (_chartType == ChartTypeEnum.Histogram) { SetChartType(SimpleChartSeries.ChartTypeEnum.Histogram); base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin); } else if (_chartType == ChartTypeEnum.ColoredArea) { SetChartType(SimpleChartSeries.ChartTypeEnum.ColoredArea); base.Draw(g, unitsUnification, clippingRectangle, itemWidth, itemMargin); } else if (_chartType == ChartTypeEnum.CandleStick || _chartType == ChartTypeEnum.BarChart) {// Unit unification is done trough combining many bars together. List <BarData> combinationDatas = new List <BarData>(); bool timeGapFound = false; int startIndex, endIndex; GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); float volumeDisplayRange = clippingRectangle.Height / 4f; double volumeDisplayMultiplicator = volumeDisplayRange / _maxVolume; for (int i = startIndex; i < endIndex && i < _dataBars.Count; i++) { combinationDatas.Add(_dataBars[i]); if (unitsUnification == 1 && ShowTimeGaps && i > 0 && _dataBars[i].DateTime - _dataBars[i - 1].DateTime != _period) { timeGapFound = true; } if (i % unitsUnification == 0) { BarData combinedData = BarData.CombinedBar(combinationDatas.ToArray()); if (i == _dataBars.Count - 1) { Console.WriteLine(" LAST combinedData ###### " + combinedData); } combinationDatas.Clear(); if (combinedData.HasDataValues) //&& drawingPoint.X >= clippingRectangle.X //&& drawingPoint.X <= clippingRectangle.X + clippingRectangle.Width) { if (timeGapFound && ShowTimeGaps && _timeGapsLinePen != null) {// Draw time gap. timeGapFound = false; g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, clippingRectangle.Y), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height)); //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, clippingRectangle.Y), new PointF(drawingPoint.X, (float)(data.High))); //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, (float)(data.High + data.BarTotalLength / 2f)), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height)); } if (_chartType == ChartTypeEnum.CandleStick) { if (i > 0 && combinedData.Open > _dataBars[i - 1].Close) { combinedData.IsHigherPrev = true; } DrawCandleStick(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification); } else { DrawBar(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification); } // Draw volume for this bar. if (_showVolume) { float actualHeight = (float)(combinedData.Volume * volumeDisplayMultiplicator); g.DrawLine(_volumePen, drawingPoint.X, clippingRectangle.Y, drawingPoint.X, clippingRectangle.Y + actualHeight); } if (combinedData.Sar != 0) { float dy = drawingPoint.Y; float y = (drawingPoint.Y + (float)combinedData.Sar); float yts = Math.Abs(g.DrawingSpaceTransform.Elements[0] / g.DrawingSpaceTransform.Elements[3]); float x = drawingPoint.X + (1 + yts) * itemWidth * 3f / 16f; //float x = drawingPoint.X + (1 + yts) * itemWidth * 3f / 8f; if (combinedData.Sar >= combinedData.Low && combinedData.High >= combinedData.Sar) { g.DrawEllipse(new Pen(Color.White), x, y, yts * itemWidth / 2f, yts * itemWidth / 2f); } else { g.DrawEllipse(new Pen(Color.White), x, y, yts * itemWidth / 2f, yts * itemWidth / 2f); } if (combinedData.Boll != null) { float uy = dy + (float)combinedData.Boll[BOLL.UPPER]; float my = dy + (float)combinedData.Boll[BOLL.MID]; float ly = dy + (float)combinedData.Boll[BOLL.LOWER]; g.DrawEllipse(new Pen(Color.Cyan), x, uy, yts * itemWidth / 2f, yts * itemWidth / 2f); g.DrawEllipse(new Pen(Color.Cyan), x, my, yts * itemWidth / 2f, yts * itemWidth / 2f); g.DrawEllipse(new Pen(Color.Cyan), x, ly, yts * itemWidth / 2f, yts * itemWidth / 2f); } } // Harry --- Draw Signal //_dataBars[i].RefreshExValues(); float actualImageHeight = _imageDown.Height / Math.Abs(g.DrawingSpaceTransform.Elements[3]); float yToXScaling = Math.Abs(g.DrawingSpaceTransform.Elements[0] / g.DrawingSpaceTransform.Elements[3]); PointF upImageDrawingPoint = drawingPoint; PointF downImageDrawingPoint = drawingPoint; Order order = new Order(); BarData orderBarData = _dataBars[i]; float lastBarX = (itemMargin + itemWidth) * _dataBars.Count; if (_dataBars[i].SignalList != null && _dataBars[i].SignalList.Count > 0) { foreach (CandleSignal cs in _dataBars[i].SignalList) { cs.BarData = orderBarData; if (cs.Code == 1) { DrawSignal(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == -1) { DrawSignal(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == 2) { DrawGainTip(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == -2) { DrawGainTip(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == 3) { DrawStopLoss(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == -3) { DrawStopLoss(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == 4) { DrawStopGain(g, ref upImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } if (cs.Code == -4) { DrawStopGain(g, ref downImageDrawingPoint, order, itemWidth, itemMargin, yToXScaling, cs, lastBarX, false); } } } } drawingPoint.X = (i + 1) * (itemMargin + itemWidth); } } } } }