public void Draw(GraphicsWrapper g, RectangleF clipping, RectangleF space, float totalItemWidth) { if (Visible == false) { return; } if (VerticalLineSpacing.HasValue) { float actualSpacing = _verticalLineSpacing.Value * totalItemWidth; if (ConsiderScale) { int xScaling = Math.Abs((int)(1 / g.DrawingSpaceTransformClone.Elements[0])); if (xScaling > 1) { actualSpacing = actualSpacing * xScaling; } } // Set starting to the closes compatible position. float starting = (int)(space.Left / actualSpacing); starting = starting * actualSpacing; for (float x = starting; x <= space.Right; x += actualSpacing) {// Vertical lines. if (x >= clipping.X && x <= clipping.X + clipping.Width + actualSpacing) { g.DrawLine(_pen, x, Math.Max(space.Top, clipping.Top), x, Math.Min(space.Bottom, clipping.Bottom)); } } } if (HorizontalLineSpacing.HasValue) { float actualSpacing = _horizontalLineSpacing.Value; if (ConsiderScale && double.IsInfinity(g.DrawingSpaceTransformClone.Elements[3]) == false && g.DrawingSpaceTransformClone.Elements[3] != 0) { int yScaling = Math.Abs((int)(1 / g.DrawingSpaceTransformClone.Elements[3])); if (yScaling > 1) { actualSpacing = actualSpacing * yScaling; } } // Set starting to the closes compatible position. float starting = (int)(space.Top / actualSpacing); starting = starting * actualSpacing; for (float y = starting; y <= space.Bottom; y += actualSpacing) {// Horizontal lines. if (y >= clipping.Y && y <= clipping.Y + clipping.Height) { g.DrawLine(_pen, Math.Max(space.Left, clipping.Left), y, Math.Min(space.Right, clipping.Right), y); } } } }
public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } PointF point1 = _controlPoints[0]; PointF point2; if (_controlPoints.Count < 2) { point2 = mousePosition.Value; } else { point2 = _controlPoints[1]; } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } // Draw base line. g.DrawLine(_dashedLinePen, point1, point2); float baseLevel = point1.Y; float height = point2.Y - point1.Y; // Draw fibbonacci levels. float[] levels = new float[] { 0, 23.6f, 38.2f, 50, 61.8f, 100 }; for (int i = 0; i < levels.Length; i++) { float actualLevel = baseLevel + height * levels[i] / 100f; g.DrawLine(_solidLinePen, point1.X, actualLevel, point2.X, actualLevel); g.DrawString(levels[i].ToString(), DefaultDynamicObjectFont, Brushes.White, point1.X, actualLevel); } if (Selected) { DrawControlPoints(g); } }
/// <summary> /// /// </summary> protected void DrawItemSet(LinesChartSeries.ChartTypeEnum type, GraphicsWrapper g, Pen pen, Brush fill, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin, object tag) { PointF drawingPoint = new PointF(); int startIndex, endIndex; GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); // Need to go up to (ItemsCount + unitsUnification) since the size of the step is (unitsUnification). for (int i = startIndex + unitsUnification - 1; i < endIndex && i < ItemsCount + unitsUnification; i += unitsUnification) { int actualIndex = i; int actualPreviousIndex = Math.Max(0, i - unitsUnification); if (actualIndex < 0 || actualIndex >= ItemsCount) {// Cycle conditions are loose and this is possible. continue; } switch (type) { case LinesChartSeries.ChartTypeEnum.ColoredArea: DrawColorAreaItem(g, ref drawingPoint, pen, fill, actualIndex, actualPreviousIndex, itemWidth, itemMargin, tag); break; case LinesChartSeries.ChartTypeEnum.Histogram: DrawHistogramBar(g, ref drawingPoint, pen, fill, actualIndex, actualPreviousIndex, itemWidth, itemMargin, unitsUnification, tag); break; case LinesChartSeries.ChartTypeEnum.Line: { float previousValue = GetDrawingValueAt(actualPreviousIndex, tag); float value = GetDrawingValueAt(actualIndex, tag); if (float.IsNaN(previousValue) == false && float.IsNaN(value) == false && float.IsInfinity(previousValue) == false && float.IsInfinity(value) == false) { g.DrawLine(pen, drawingPoint.X, drawingPoint.Y + previousValue, drawingPoint.X + itemMargin + itemWidth, drawingPoint.Y + value); } break; } default: break; } drawingPoint.X = (i + 1) * (itemMargin + itemWidth); } }
/// <summary> /// Enter locked. /// </summary> void DrawBar(GraphicsWrapper g, ref PointF startingPoint, DataBar barData, float itemWidth, float itemMargin, int itemUnitification) { float xMiddle = startingPoint.X + itemWidth / 2; float xHalfWidth = itemWidth / 2; Pen pen = _risingBarPen; if (barData.IsRising == false) { pen = _fallingBarPen; } if (pen == null) { return; } float yDisplacement = startingPoint.Y; g.DrawLine(pen, xMiddle, yDisplacement + (float)barData.Low, xMiddle, yDisplacement + (float)barData.High); g.DrawLine(pen, xMiddle, yDisplacement + (float)barData.Open, xMiddle - xHalfWidth, yDisplacement + (float)barData.Open); g.DrawLine(pen, xMiddle, yDisplacement + (float)barData.Close, xMiddle + xHalfWidth, yDisplacement + (float)barData.Close); }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } foreach (double level in _levels) { if (level >= drawingSpace.Y && level <= drawingSpace.Y + drawingSpace.Height) { g.DrawLine(_pen, drawingSpace.X, (float)level, drawingSpace.X + drawingSpace.Width, (float)level); } } }
public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } foreach (double level in _levels) { if (level >= drawingSpace.Y && level <= drawingSpace.Y + drawingSpace.Height) { g.DrawLine(_pen, drawingSpace.X, (float)level, drawingSpace.X + drawingSpace.Width, (float)level); } } }
///// <summary> ///// Helper method, draws histogram bars. ///// </summary> //protected void DrawHistogramBars(GraphicsWrapper g, Pen pen, Brush fill, int unitsUnification, // RectangleF clippingRectangle, float itemWidth, float itemMargin, object tag) //{ // PointF drawingPoint = new PointF(); // int startIndex, endIndex; // GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); // for (int i = startIndex + unitsUnification - 1; i < endIndex && i < MaximumIndex + unitsUnification - 1; i += unitsUnification) // { // int actualIndex = i; // int actualPreviousIndex = i - unitsUnification; // if (actualIndex >= MaximumIndex) // { // actualIndex = MaximumIndex - 1; // } // DrawHistogramBar(g, ref drawingPoint, pen, fill, actualIndex, actualPreviousIndex, // itemWidth, itemMargin, unitsUnification, tag); // drawingPoint.X = i * (itemMargin + itemWidth); // } //} //protected void DrawColoredArea(GraphicsWrapper g, Pen pen, Brush fill, int unitsUnification, // RectangleF clippingRectangle, float itemWidth, float itemMargin, object tag) //{ // PointF drawingPoint = new PointF(); // int startIndex, endIndex; // GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); // for (int i = startIndex + unitsUnification - 1; i < endIndex && i < MaximumIndex + unitsUnification - 1; i += unitsUnification) // { // int actualIndex = i; // int actualPreviousIndex = i - unitsUnification; // if (actualIndex >= MaximumIndex) // { // actualIndex = MaximumIndex - 1; // } // DrawColorAreaItem(g, ref drawingPoint, pen, fill, actualIndex, // actualPreviousIndex, itemWidth, itemMargin, tag); // drawingPoint.X = i * (itemMargin + itemWidth); // } //} protected void DrawColorAreaItem(GraphicsWrapper g, ref PointF drawingPoint, Pen pen, Brush fill, int index, int previousItemIndex, float itemWidth, float itemMargin, object tag) { float indexValue = GetDrawingValueAt(index, tag); float previousItemIndexValue = GetDrawingValueAt(previousItemIndex, tag); int unificationCount = index - previousItemIndex; for (int i = previousItemIndex; i <= index; i++) { if (float.IsNaN(previousItemIndexValue)) { previousItemIndexValue = GetDrawingValueAt(i, tag); } else if (float.IsNaN(indexValue)) { indexValue = GetDrawingValueAt(i, tag); } } if (float.IsNaN(indexValue) || float.IsNaN(previousItemIndexValue)) {// Failed to find reasonable values to draw. return; } if (fill != null) { g.FillPolygon(fill, new PointF[] { drawingPoint, new PointF(drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y), new PointF(drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y + indexValue), new PointF(drawingPoint.X, drawingPoint.Y + previousItemIndexValue) }); } if (pen != null) { g.DrawLine(pen, drawingPoint.X, drawingPoint.Y + previousItemIndexValue, drawingPoint.X + (itemMargin + itemWidth) * unificationCount, drawingPoint.Y + indexValue); } }
public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false || _controlPoints.Count < 1) { return; } if (clippingRectangle.Contains(_controlPoints[0]) == false) {// Clipping opitmization. return; } SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont); if (size.Height < 0) { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height); } else { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height); } g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]); if (Selected || IsBuilding) { g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y)); } // Rounding rectangle. //g.DrawRectangle(Pens.White, _rectangle); if (Selected) { DrawControlPoints(g); } }
public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } PointF point1 = _controlPoints[0]; PointF point2; if (mousePosition.HasValue) { point2 = mousePosition.Value; } else { point2 = point1; } if (_controlPoints.Count == 2) { point2 = _controlPoints[1]; } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } SimpleLine line = new SimpleLine(point1, point2); PointF vec = new PointF(line.XDelta, line.YDelta); vec = g.DrawingSpaceToActualSpace(vec, false); vec = new PointF(vec.Y, vec.X); // Rotate PointF vec1 = SimpleLine.RotatePoint(vec, -(float)Math.PI / 2 + 0.3f); PointF vec2 = SimpleLine.RotatePoint(vec, -(float)Math.PI / 2 - 0.3f); // Scale vec1 = new PointF(vec1.X * 0.35f, vec1.Y * 0.35f); vec2 = new PointF(vec2.X * 0.35f, vec2.Y * 0.35f); vec1 = g.ActualSpaceToDrawingSpace(vec1, false); vec2 = g.ActualSpaceToDrawingSpace(vec2, false); g.DrawLine(_pen, point1, point2); g.FillPolygon(_brush, new PointF[] { point2, new PointF(point2.X + vec1.X, point2.Y + vec1.Y), new PointF(point2.X + vec2.X, point2.Y + vec2.Y) }); if (Selected) { DrawControlPoints(g); } }
/// <summary> /// Main drawing routine. /// </summary> public override void Draw(ChartPane managingPane, GraphicsWrapper g, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin) { //TracerHelper.Trace(TracerHelper.GetCallingMethod(2).Name); if (Visible == false) { return; } if (_dataProvider == null) { return; } IDataBarHistoryProvider dataBarProvider = CurrentDataBarProvider; if (dataBarProvider == null) { return; } lock (dataBarProvider) { base.Draw(g, dataBarProvider.BarsUnsafe, unitsUnification, clippingRectangle, itemWidth, itemMargin, _maxVolume, null); } // Draw ask/bid line. if (_dataProvider.OperationalState == CommonSupport.OperationalStateEnum.Operational && _dataProvider.Quotes != null && _dataProvider.Quotes.Bid.HasValue && _dataProvider.Quotes.Ask.HasValue) { if (_showCurrentAskLine) { float price = (float)_dataProvider.Quotes.Ask; g.DrawLine(_priceLevelPen, clippingRectangle.X, price, clippingRectangle.X + clippingRectangle.Width, price); } if (_showCurrentBidLine) { float price = (float)_dataProvider.Quotes.Bid; g.DrawLine(_priceLevelPen, clippingRectangle.X, price, clippingRectangle.X + clippingRectangle.Width, price); } } List <Order> ordersOpening; // Draw orders locations on chart. lock (this) { if (_orderExecutionProvider == null) { return; } } // Render orders. ordersOpening = new List <Order>(); ITradeEntityManagement history = _orderExecutionProvider.TradeEntities; if (history != null && _dataProvider != null) { lock (history) { ordersOpening.AddRange(history.GetOrdersBySymbol(_dataProvider.SessionInfo.Symbol)); } } // Use for orders closes. List <Order> ordersClosing = new List <Order>(); foreach (Order order in ordersOpening) { if (order.State == OrderStateEnum.Closed) {// Only add orders already closed. ordersClosing.Add(order); } } // This is used later on, since ordersClosing is modified. List <Order> ordersClosed = new List <Order>(ordersClosing); // TradeEntities opening at current bar. List <Order> pendingOpeningOrders = new List <Order>(); // Order closing at current bar. List <Order> pendingClosingOrders = new List <Order>(); PointF drawingPoint = new PointF(); int startIndex, endIndex; GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); lock (dataBarProvider) { float lastBarX = (itemMargin + itemWidth) * dataBarProvider.BarCount; for (int i = startIndex; i < endIndex && i < dataBarProvider.BarCount && (ordersOpening.Count > 0 || ordersClosing.Count > 0); i++) { // Foreach bar, draw orders (and closeVolume). while (ordersOpening.Count > 0) { // All orders before now. if (ordersOpening[0].OpenTime < (dataBarProvider.BarsUnsafe[i].DateTime - Period)) { // Order before time period. if ((ordersOpening[0].State == OrderStateEnum.Executed /*|| * ordersOpening[0].State == OrderInformation.OrderStateEnum.Submitted*/) && _showPendingOrdersTracing) {// Since it is an open pending order, we shall also need to draw it as well. pendingOpeningOrders.Add(ordersOpening[0]); } ordersOpening.RemoveAt(0); continue; } if (ordersOpening[0].OpenTime > dataBarProvider.BarsUnsafe[i].DateTime) {// Order after time period - look no further. break; } // Order open is within the current period. // Only if order is part of the current period - add to pending. pendingOpeningOrders.Add(ordersOpening[0]); ordersOpening.RemoveAt(0); } for (int j = ordersClosing.Count - 1; j >= 0; j--) { if (ordersClosing[j].CloseTime >= (dataBarProvider.BarsUnsafe[i].DateTime - dataBarProvider.Period) && ordersClosing[j].CloseTime <= dataBarProvider.BarsUnsafe[i].DateTime) {// Order close is within the current period. pendingClosingOrders.Add(ordersClosing[j]); ordersClosing.RemoveAt(j); } } drawingPoint.X = i * (itemMargin + itemWidth); DrawOrders(g, i, drawingPoint, itemWidth, itemMargin, pendingOpeningOrders, pendingClosingOrders, dataBarProvider.BarsUnsafe[i], lastBarX); pendingOpeningOrders.Clear(); pendingClosingOrders.Clear(); } if (_showClosedOrdersTracing && dataBarProvider.BarCount > 0 && startIndex < dataBarProvider.BarCount) {// Since a closed order may be before or after (or during) the curren set of periods - make a special search and render for them. endIndex = Math.Max(0, endIndex); endIndex = Math.Min(dataBarProvider.BarCount - 1, endIndex); foreach (Order order in ordersClosed) { if (order.OpenTime.HasValue && order.CloseTime.HasValue && order.OpenTime.Value <= dataBarProvider.BarsUnsafe[endIndex].DateTime && order.CloseTime.Value >= dataBarProvider.BarsUnsafe[startIndex].DateTime - dataBarProvider.Period) { int openIndex = dataBarProvider.GetIndexAtTime(order.OpenTime.Value); int closeIndex = dataBarProvider.GetIndexAtTime(order.CloseTime.Value); Pen pen = _buyDashedPen; if (order.IsBuy == false) { pen = _sellDashedPen; } Decimal?doubleOpenValue = order.OpenPrice; Decimal?doubleCloseValue = order.ClosePrice; if (doubleOpenValue.HasValue == false) { SystemMonitor.Error("Invalid open price value for closed order to draw."); continue; } if (doubleCloseValue.HasValue == false) { SystemMonitor.Error("Invalid close price value for closed order to draw."); continue; } g.DrawLine(pen, new PointF(openIndex * (itemWidth + itemMargin), (float)doubleOpenValue), new PointF(closeIndex * (itemWidth + itemMargin), (float)doubleCloseValue)); } } } } // Lock }
void DrawOrder(GraphicsWrapper g, ref PointF updatedImageDrawingPoint, Order order, float itemWidth, float itemMargin, float yToXScaling, DataBar orderBarData, float lastBarX, bool drawOpening) { Image image = _imageUp; Brush brush = Brushes.Green; Pen dashedPen = _buyDashedPen; Pen pen = Pens.GreenYellow; if (order.IsBuy == false) { image = _imageDown; brush = Brushes.Red; pen = Pens.Red; dashedPen = _sellDashedPen; } if (drawOpening == false) { image = _imageCross; } if (order.OpenPrice.HasValue == false) { SystemMonitor.OperationError("Order with no open price assigned for drawing.", TracerItem.PriorityEnum.Low); return; } float price = (float)order.OpenPrice.Value; if (drawOpening == false) { if (order.ClosePrice.HasValue == false) { return; } price = (float)order.ClosePrice.Value; } if (drawOpening && _showPendingOrdersTracing && (order is ActiveOrder && order.State == OrderStateEnum.Executed) && _dataProvider.Quotes.Bid.HasValue && _dataProvider.Quotes.Ask.HasValue) {// Open orders tracking line. PointF point1 = new PointF(updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + price); float sellPrice = (float)_dataProvider.Quotes.Bid; if (order.IsBuy == false) { sellPrice = (float)_dataProvider.Quotes.Ask; } PointF point2 = new PointF(lastBarX - itemWidth / 2f, updatedImageDrawingPoint.Y + sellPrice); g.DrawLine(dashedPen, point1, point2); } //if (drawOpening && _showClosedOrdersTracing && order.IsOpen == false) //{// Closed order tracking. // Close order tracing is implemented in main draw function. //} if (_showOrderSpot) { PointF basePoint = new PointF(updatedImageDrawingPoint.X, updatedImageDrawingPoint.Y + price); float height = (yToXScaling * itemWidth); if (order.IsBuy == false) { height = -height; } if (drawOpening) { g.FillPolygon(brush, new PointF[] { basePoint, new PointF(basePoint.X + itemWidth, basePoint.Y), new PointF(basePoint.X + (itemWidth / 2f), basePoint.Y + height) }); g.DrawPolygon(Pens.White, new PointF[] { basePoint, new PointF(basePoint.X + itemWidth, basePoint.Y), new PointF(basePoint.X + (itemWidth / 2f), basePoint.Y + height) }); float drawToLeft = (float)(1.5 * itemWidth); float drawToRight = (float)(2.5 * itemWidth); // Take profit level. if (order.TakeProfit.HasValue && order.TakeProfit.Value != 0) { g.DrawLine(pen, updatedImageDrawingPoint.X - drawToLeft, updatedImageDrawingPoint.Y + (float)order.TakeProfit, updatedImageDrawingPoint.X + drawToRight, updatedImageDrawingPoint.Y + (float)order.TakeProfit); g.DrawLine(pen, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.TakeProfit, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.TakeProfit - height); } // Stop loss level. if (order.StopLoss.HasValue && order.StopLoss.Value != 0) { g.DrawLine(pen, updatedImageDrawingPoint.X - drawToLeft, updatedImageDrawingPoint.Y + (float)order.StopLoss, updatedImageDrawingPoint.X + drawToRight, updatedImageDrawingPoint.Y + (float)order.StopLoss); g.DrawLine(pen, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.StopLoss, updatedImageDrawingPoint.X + itemWidth / 2f, updatedImageDrawingPoint.Y + (float)order.StopLoss + height); } } else { g.DrawRectangle(Pens.White, basePoint.X, basePoint.Y, itemWidth, yToXScaling * itemWidth); } } float imageHeight = 2 * (yToXScaling * itemWidth); if (_showOrderArrow) { float x = updatedImageDrawingPoint.X - (itemWidth / 2f); float y = updatedImageDrawingPoint.Y + (float)orderBarData.Low - (yToXScaling * itemWidth); float width = 2 * itemWidth; float height = -imageHeight; GraphicsWrapper.NormalizedRectangle(ref x, ref y, ref width, ref height); RectangleF rectange = new RectangleF(x, y, width, height); // Draw up image. g.DrawImage(image, rectange.X, rectange.Y, rectange.Width, rectange.Height); if (order == _selectedOrder) {// This is selected order. g.DrawRectangle(Pens.White, rectange); } _ordersArrows[order] = rectange; updatedImageDrawingPoint.Y -= 1.2f * imageHeight; } }
/// <summary> /// Drawing routine, invoke from child class to draw dataDelivery bars in common uniform way. /// </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 void Draw(GraphicsWrapper g, ReadOnlyCollection<DataBar> dataBars, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin, float maxVolume, object tag) { if (Visible == false) { return; } PointF drawingPoint = new PointF(); lock (this) { if (_chartType == ChartTypeEnum.Line) { base.DrawItemSet(LinesChartSeries.ChartTypeEnum.Line, g, _risingBarPen, null, unitsUnification, clippingRectangle, itemWidth, itemMargin, null); } else if (_chartType == ChartTypeEnum.Histogram) { base.DrawItemSet(LinesChartSeries.ChartTypeEnum.Histogram, g, _risingBarPen, _risingBarFill, unitsUnification, clippingRectangle, itemWidth, itemMargin, tag); } else if (_chartType == ChartTypeEnum.ColoredArea) { base.DrawItemSet(LinesChartSeries.ChartTypeEnum.ColoredArea, g, _risingBarPen, _risingBarFill, unitsUnification, clippingRectangle, itemWidth, itemMargin, tag); } else if (_chartType == ChartTypeEnum.CandleStick || _chartType == ChartTypeEnum.BarChart) {// Unit unification is done trough combining many bars together. List<DataBar> combinationDatas = new List<DataBar>(); bool timeGapFound = false; int startIndex, endIndex; GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); float volumeDisplayRange = clippingRectangle.Height / 4f; decimal volumeDisplayMultiplicator = 0; if (maxVolume > 0) { volumeDisplayMultiplicator = (decimal)(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) { DataBar combinedData = DataBar.CombinedBar(combinationDatas.ToArray()); 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)(dataDelivery.High))); //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, (float)(dataDelivery.High + dataDelivery.BarTotalLength / 2f)), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height)); } if (_chartType == ChartTypeEnum.CandleStick) { DrawCandleStick(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification); } else { DrawBar(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification); } // Draw closeVolume for this bar. if (_showVolume) { float actualHeight = (float)(combinedData.Volume * volumeDisplayMultiplicator); g.DrawLine(_volumePen, drawingPoint.X, clippingRectangle.Y, drawingPoint.X, clippingRectangle.Y + actualHeight); } } drawingPoint.X = (i + 1) * (itemMargin + itemWidth); } } } } }
/// <summary> /// Enter locked. /// </summary> void DrawCandleStick(GraphicsWrapper g, ref PointF startingPoint, DataBar barData, float itemWidth, float itemMargin, int itemUnitification) { if (barData.IsRising) { if (_risingBarFill != null) { g.FillRectangle(_risingBarFill, startingPoint.X, startingPoint.Y + (float)barData.Open, itemWidth, (float)barData.AbsoluteBodyHeight); } if (_risingBarPen != null) { if (itemWidth > 4) { g.DrawRectangle(_risingBarPen, startingPoint.X, startingPoint.Y + (float)barData.Open, itemWidth, (float)barData.AbsoluteBodyHeight); } else { g.FillRectangle(Brushes.Green, startingPoint.X, startingPoint.Y + (float)barData.Open, itemWidth, (float)barData.AbsoluteBodyHeight); } // Draw a horizontal line for 0 height bars. if (barData.AbsoluteBodyHeight == 0) { g.DrawLine(_fallingBarPen, startingPoint.X, startingPoint.Y + (float)barData.Close, startingPoint.X + itemWidth, startingPoint.Y + (float)barData.Close); } // Lower shadow g.DrawLine(_risingBarPen, startingPoint.X + itemWidth / 2, startingPoint.Y + (float)barData.Low, startingPoint.X + itemWidth / 2, startingPoint.Y + (float)barData.Open); // Upper shadow g.DrawLine(_risingBarPen, startingPoint.X + itemWidth / 2, (float)(startingPoint.Y + (float)barData.High), startingPoint.X + itemWidth / 2, (float)(startingPoint.Y + (float)barData.Close)); } } else { if (_fallingBarFill != null) { g.FillRectangle(_fallingBarFill, startingPoint.X, startingPoint.Y + (float)barData.Close, itemWidth, (float)barData.AbsoluteBodyHeight); } if (_fallingBarPen != null) { if (itemWidth >= 4) {// Only if an item is clearly visible, show the border, otherwise, hide to improve. overal visibility. // Showing this border adds nice detail on close zooming, but not useful otherwise. g.DrawRectangle(_fallingBarPen, startingPoint.X, startingPoint.Y + (float)barData.Close, itemWidth, (float)barData.AbsoluteBodyHeight); } // Draw a horizontal line for 0 height bars. if (barData.AbsoluteBodyHeight == 0) { g.DrawLine(_fallingBarPen, startingPoint.X, startingPoint.Y + (float)barData.Close, startingPoint.X + itemWidth, startingPoint.Y + (float)barData.Close); } // Lower shadow g.DrawLine(_fallingBarPen, startingPoint.X + itemWidth / 2, startingPoint.Y + (float)barData.Low, startingPoint.X + itemWidth / 2, startingPoint.Y + (float)barData.Close); // Upper shadow g.DrawLine(_fallingBarPen, startingPoint.X + itemWidth / 2, (float)(startingPoint.Y + (float)barData.High), startingPoint.X + itemWidth / 2, (float)(startingPoint.Y + (float)barData.Open)); } } }
/// <summary> /// Initial part of drawing, called by Draw(). /// Method takes care of setting up the basic drawing parameters of the chart, required for the drawing /// to be done; also draws the system overlays. /// </summary> protected virtual void DrawInitialActualSpaceOverlays(GraphicsWrapper g, TimeBasedChartSeries timeBasedSeries) { // Since this is dependant on current graphics scaling, also recalculate it here now. UpdateYAxisSpacings(); CalculateActualDrawingSpaceAreaMarginTopAndBottom(); if (XAxisLabels) {// X Axis Labels float totalItemWidth = _seriesItemWidth + _seriesItemMargin; float actualXSpacing = _xAxisLabelSpacing * totalItemWidth; // Consider X axis label scaling. int xScaling = Math.Abs((int)(1 / _graphicsWrapper.DrawingSpaceTransformClone.Elements[0])); if (xScaling > 1) { actualXSpacing = actualXSpacing * xScaling; } // Set starting to the closes compatible positionactualXSpacing // TODO : this can be optimized further by narrowing the range of xStart to end float xStart = (int)(_drawingSpaceDisplayLimit.X / actualXSpacing); xStart = xStart * actualXSpacing; SizeF xAxisLabelTypicalSize = g.MeasureString("00/00/000 00:00", _axisLabelsFont); for (float i = xStart; i < _drawingSpaceDisplayLimit.X + _drawingSpaceDisplayLimit.Width; i += actualXSpacing) { PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(i, 0), true); if (point.X > (_actualDrawingSpaceArea.X - 2) && point.X < (_actualDrawingSpaceArea.X + _actualDrawingSpaceArea.Width + 2 - xAxisLabelTypicalSize.Width)) { int index = (int)(i / totalItemWidth); string message = string.Empty; if (timeBasedSeries != null) {// If there is a leading dateAssignedSeries show labels based on its timing. if (index < timeBasedSeries.ItemsCount) { message = GeneralHelper.GetShortDateTime(timeBasedSeries.GetTimeAtIndex(index)); } } else { message = index.ToString(_xAxisLabelsFormat); } if (_axisLabelsFont != null && _xAxisLabelsFontBrush != null) { g.DrawString(message, _axisLabelsFont, _xAxisLabelsFontBrush, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height); } // Draw the small line indicating where the string applies for. g.DrawLine(_actualDrawingSpaceAreaBorderPen, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height, point.X, _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height + 5); } } } // X Axis Labels. _actualDrawingSpaceAreaMarginLeft = _additionalDrawingSpaceAreaMarginLeft + 5; _actualDrawingSpaceAreaMarginRight = _additionalDrawingSpaceAreaMarginRight + 5; if (YAxisLabels) {// Y Axis Labels. int yAxisLabelsWidth = 0; // Set starting to the closes compatible positionactualYSpacing int maxDecimalPlaces = _autoYAxisLabelSpacing.ToString().Length - 1; float yStart = (int)(_drawingSpaceDisplayLimit.Y / _autoYAxisLabelSpacing); yStart = yStart * _autoYAxisLabelSpacing; // Round off to a fixed number of post decimal point digits, will only work for values under 1 yStart = (float)Math.Round(yStart, maxDecimalPlaces); // This must auto adjust to format the number properly and always fit in 6 spaces. // Specify positive, negative and zero formats. //_yAxisLabelsFormat = " #0.###;-#0.###; Zero"; int separatorPosition = _yAxisLabelsFormat.IndexOf(";", 0) - 1; // The default is 6 positions total for the y axis labels. yAxisLabelsWidth = ((int)g.MeasureString(_yAxisLabelsFormat.Substring(0, separatorPosition), _axisLabelsFont).Width); // Calculate the current margin and confirm with any controling subscriber. int labelSpacingMargin = yAxisLabelsWidth; if (_yAxisLabelsPosition == YAxisLabelPosition.Left || _yAxisLabelsPosition == YAxisLabelPosition.Both) { _actualDrawingSpaceAreaMarginLeft += labelSpacingMargin; } if (_yAxisLabelsPosition == YAxisLabelPosition.Right || _yAxisLabelsPosition == YAxisLabelPosition.Both) { _actualDrawingSpaceAreaMarginRight += labelSpacingMargin; } if (_yAxisLabelsPosition != YAxisLabelPosition.None) { // A maximum of 10000 steps allowed for this drawing, otherwise some bug is probably present. if ((_drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height - yStart) / _autoYAxisLabelSpacing < 10000) { // Pass 2 - actually draw the labels and label lines at the established and confirmed location. for (float i = yStart; i < _drawingSpaceDisplayLimit.Y + _drawingSpaceDisplayLimit.Height; i += _autoYAxisLabelSpacing) { float iRound = (float)Math.Round(i, maxDecimalPlaces); PointF point = GraphicsWrapper.DrawingSpaceToActualSpace(new PointF(0, iRound), true); if (point.Y <= _actualDrawingSpaceArea.Y - 5 || point.Y >= _actualDrawingSpaceArea.Y + _actualDrawingSpaceArea.Height) { continue; } // Draw labels on the left. if (_yAxisLabelsPosition == YAxisLabelPosition.Left || _yAxisLabelsPosition == YAxisLabelPosition.Both) { if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null) { g.DrawString((iRound).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush, _actualDrawingSpaceAreaMarginLeft - yAxisLabelsWidth - 3, point.Y); } // Draw the small line indicating where the string applies for. g.DrawLine(_actualDrawingSpaceAreaBorderPen, _actualDrawingSpaceAreaMarginLeft - 5, point.Y, _actualDrawingSpaceAreaMarginLeft, point.Y); } // Draw labels on the right. if (_yAxisLabelsPosition == YAxisLabelPosition.Right || _yAxisLabelsPosition == YAxisLabelPosition.Both) { if (_axisLabelsFont != null && _yAxisLabelsFontBrush != null) { g.DrawString((iRound).ToString(_yAxisLabelsFormat), _axisLabelsFont, _yAxisLabelsFontBrush, this.Width - yAxisLabelsWidth - 3, point.Y); } if (point.Y >= _actualDrawingSpaceArea.Y) { // Draw the small line indicating where the string applies for. g.DrawLine(_actualDrawingSpaceAreaBorderPen, this.Width - yAxisLabelsWidth - 6, point.Y, this.Width - yAxisLabelsWidth - 3, point.Y); } } } } else { SystemMonitor.OperationError("Too many steps in drawing planned."); } } } foreach (ChartSeries series in _series) { series.DrawInitialActualSpaceOverlays(this, g); } UpdateActualDrawingSpaceArea(); // Actual space, drawing area, grid. _actualSpaceGrid.Draw(g, _actualDrawingSpaceArea, _actualDrawingSpaceArea, 1); if (ShowSeriesLabels) { DrawGraphicSeriesLabels(g, _actualDrawingSpaceArea.Left); } // Show if (_customObjectsManager.IsBuildingObject) { g.DrawImageUnscaledAndClipped(_customObjectDrawingImage, new Rectangle(4, (int)LabelsTopMargin, _customObjectDrawingImage.Width, _customObjectDrawingImage.Height)); } }
public override void Draw(ChartPane managingPane, GraphicsWrapper g, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin) { if (this.Visible == false || Indicator == null) { return; } lock (Indicator.Results) { foreach (string name in Indicator.Results.SetsNamesUnsafe) { LinesChartSeries.ChartTypeEnum? chartType = Indicator.Results.GetResultSetChartType(name); if (chartType.HasValue == false) {// No specific value assigned means go for default. chartType = DefaultChartType; } base.DrawItemSet(chartType.Value, g, _outputResultSetsPens[name], _defaultBrush, unitsUnification, clippingRectangle, itemWidth, itemMargin, name); } } foreach(string name in Indicator.Parameters.DynamicNames) {// Render fixed lines. if (name.Contains(FixedLinePrefix)) { object value = Indicator.Parameters.GetDynamic(name); if (value == null) { continue; } float floatValue = Convert.ToSingle(value); int dashMove = 0;// ((int)x % DashSize); g.DrawLine(_defaultDashedPen, clippingRectangle.X + dashMove, floatValue, clippingRectangle.X + clippingRectangle.Width, floatValue); } } }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } if (_mode == ModeEnum.HorizontalLine || _mode == ModeEnum.VerticalLine) { PointF point1 = _controlPoints[0]; PointF point2 = new PointF(drawingSpace.X + drawingSpace.Width, _controlPoints[0].Y); if (_mode == ModeEnum.VerticalLine) { point2 = new PointF(_controlPoints[0].X, drawingSpace.Y + drawingSpace.Height); } StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace); g.DrawLine(_pen, point1, point2); if (Selected) { DrawControlPoints(g); } } else if (_controlPoints.Count == 1 && mousePosition.HasValue) { PointF point1 = _controlPoints[0]; PointF point2 = mousePosition.Value; if (_mode == ModeEnum.Line) { StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace); } g.DrawLine(_pen, point1, point2); } else if (_controlPoints.Count == 2) { PointF point1 = _controlPoints[0]; PointF point2 = _controlPoints[1]; if (_mode == ModeEnum.Line) { StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace); } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } //if (_isSegment == false) //{// Draw the central line piece separately. //g.DrawLine(_pen, _controlPoints[0], _controlPoints[1]); //} g.DrawLine(_pen, point1, point2); if (Selected) { DrawControlPoints(g); } } }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } PointF point1 = _controlPoints[0]; PointF point2; if (mousePosition.HasValue) { point2 = mousePosition.Value; } else { point2 = point1; } if (_controlPoints.Count == 2) { point2 = _controlPoints[1]; } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } SimpleLine line = new SimpleLine(point1, point2); PointF vec = new PointF(line.XDelta, line.YDelta); vec = g.DrawingSpaceToActualSpace(vec, false); vec = new PointF(vec.Y, vec.X); // Rotate PointF vec1 = SimpleLine.RotatePoint(vec, -(float)Math.PI/2 + 0.3f); PointF vec2 = SimpleLine.RotatePoint(vec, -(float)Math.PI/2 -0.3f); // Scale vec1 = new PointF(vec1.X * 0.35f, vec1.Y * 0.35f); vec2 = new PointF(vec2.X * 0.35f, vec2.Y * 0.35f); vec1 = g.ActualSpaceToDrawingSpace(vec1, false); vec2 = g.ActualSpaceToDrawingSpace(vec2, false); g.DrawLine(_pen, point1, point2); g.FillPolygon(_brush, new PointF[] { point2, new PointF(point2.X + vec1.X, point2.Y + vec1.Y), new PointF(point2.X + vec2.X, point2.Y + vec2.Y) }); if (Selected) { DrawControlPoints(g); } }
public void Draw(GraphicsWrapper g, RectangleF clipping, RectangleF space, float totalItemWidth) { if (Visible == false) { return; } if (VerticalLineSpacing.HasValue) { float actualSpacing = _verticalLineSpacing.Value * totalItemWidth; if (ConsiderScale) { int xScaling = Math.Abs((int) (1 / g.DrawingSpaceTransformClone.Elements[0])); if (xScaling > 1) { actualSpacing = actualSpacing * xScaling; } } // Set starting to the closes compatible position. float starting = (int)(space.Left / actualSpacing); starting = starting * actualSpacing; for (float x = starting; x <= space.Right; x += actualSpacing) {// Vertical lines. if (x >= clipping.X && x <= clipping.X + clipping.Width + actualSpacing) { g.DrawLine(_pen, x, Math.Max(space.Top, clipping.Top), x, Math.Min(space.Bottom, clipping.Bottom)); } } } if (HorizontalLineSpacing.HasValue) { float actualSpacing = _horizontalLineSpacing.Value; if (ConsiderScale && double.IsInfinity(g.DrawingSpaceTransformClone.Elements[3]) == false && g.DrawingSpaceTransformClone.Elements[3] != 0) { int yScaling = Math.Abs((int) (1 / g.DrawingSpaceTransformClone.Elements[3])); if (yScaling > 1) { actualSpacing = actualSpacing * yScaling; } } // Set starting to the closes compatible position. float starting = (int)(space.Top / actualSpacing); starting = starting * actualSpacing; for (float y = starting; y <= space.Bottom; y += actualSpacing) {// Horizontal lines. if (y >= clipping.Y && y <= clipping.Y + clipping.Height) { g.DrawLine(_pen, Math.Max(space.Left, clipping.Left), y, Math.Min(space.Right, clipping.Right), y); } } } }
public override void Draw(GraphicsWrapper g, PointF?mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } if (_mode == ModeEnum.HorizontalLine || _mode == ModeEnum.VerticalLine) { PointF point1 = _controlPoints[0]; PointF point2 = new PointF(drawingSpace.X + drawingSpace.Width, _controlPoints[0].Y); if (_mode == ModeEnum.VerticalLine) { point2 = new PointF(_controlPoints[0].X, drawingSpace.Y + drawingSpace.Height); } StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace); g.DrawLine(_pen, point1, point2); if (Selected) { DrawControlPoints(g); } } else if (_controlPoints.Count == 1 && mousePosition.HasValue) { PointF point1 = _controlPoints[0]; PointF point2 = mousePosition.Value; if (_mode == ModeEnum.Line) { StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace); } g.DrawLine(_pen, point1, point2); } else if (_controlPoints.Count == 2) { PointF point1 = _controlPoints[0]; PointF point2 = _controlPoints[1]; if (_mode == ModeEnum.Line) { StretchSegmentToDrawingSpace(ref point1, ref point2, drawingSpace); } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } //if (_isSegment == false) //{// Draw the central line piece separately. //g.DrawLine(_pen, _controlPoints[0], _controlPoints[1]); //} g.DrawLine(_pen, point1, point2); if (Selected) { DrawControlPoints(g); } } }
/// <summary> /// Main drawing routine. /// </summary> public override void Draw(ChartPane managingPane, GraphicsWrapper g, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin) { //TracerHelper.Trace(TracerHelper.GetCallingMethod(2).Name); if (Visible == false) { return; } if (_dataProvider == null) { return; } IDataBarHistoryProvider dataBarProvider = CurrentDataBarProvider; if (dataBarProvider == null) { return; } lock (dataBarProvider) { base.Draw(g, dataBarProvider.BarsUnsafe, unitsUnification, clippingRectangle, itemWidth, itemMargin, _maxVolume, null); } // Draw ask/bid line. if (_dataProvider.OperationalState == CommonSupport.OperationalStateEnum.Operational && _dataProvider.Quotes != null && _dataProvider.Quotes.Bid.HasValue && _dataProvider.Quotes.Ask.HasValue) { if (_showCurrentAskLine) { float price = (float)_dataProvider.Quotes.Ask; g.DrawLine(_priceLevelPen, clippingRectangle.X, price, clippingRectangle.X + clippingRectangle.Width, price); } if (_showCurrentBidLine) { float price = (float)_dataProvider.Quotes.Bid; g.DrawLine(_priceLevelPen, clippingRectangle.X, price, clippingRectangle.X + clippingRectangle.Width, price); } } List<Order> ordersOpening; // Draw orders locations on chart. lock(this) { if (_orderExecutionProvider == null) { return; } } // Render orders. ordersOpening = new List<Order>(); ITradeEntityManagement history = _orderExecutionProvider.TradeEntities; if (history != null && _dataProvider != null) { lock (history) { ordersOpening.AddRange(history.GetOrdersBySymbol(_dataProvider.SessionInfo.Symbol)); } } // Use for orders closes. List<Order> ordersClosing = new List<Order>(); foreach (Order order in ordersOpening) { if (order.State == OrderStateEnum.Closed) {// Only add orders already closed. ordersClosing.Add(order); } } // This is used later on, since ordersClosing is modified. List<Order> ordersClosed = new List<Order>(ordersClosing); // TradeEntities opening at current bar. List<Order> pendingOpeningOrders = new List<Order>(); // Order closing at current bar. List<Order> pendingClosingOrders = new List<Order>(); PointF drawingPoint = new PointF(); int startIndex, endIndex; GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); lock (dataBarProvider) { float lastBarX = (itemMargin + itemWidth) * dataBarProvider.BarCount; for (int i = startIndex; i < endIndex && i < dataBarProvider.BarCount && (ordersOpening.Count > 0 || ordersClosing.Count > 0); i++) {// Foreach bar, draw orders (and closeVolume). while (ordersOpening.Count > 0) {// All orders before now. if (ordersOpening[0].OpenTime < (dataBarProvider.BarsUnsafe[i].DateTime - Period)) {// Order before time period. if ((ordersOpening[0].State == OrderStateEnum.Executed /*|| ordersOpening[0].State == OrderInformation.OrderStateEnum.Submitted*/) && _showPendingOrdersTracing) {// Since it is an open pending order, we shall also need to draw it as well. pendingOpeningOrders.Add(ordersOpening[0]); } ordersOpening.RemoveAt(0); continue; } if (ordersOpening[0].OpenTime > dataBarProvider.BarsUnsafe[i].DateTime) {// Order after time period - look no further. break; } // Order open is within the current period. // Only if order is part of the current period - add to pending. pendingOpeningOrders.Add(ordersOpening[0]); ordersOpening.RemoveAt(0); } for (int j = ordersClosing.Count - 1; j >= 0; j--) { if (ordersClosing[j].CloseTime >= (dataBarProvider.BarsUnsafe[i].DateTime - dataBarProvider.Period) && ordersClosing[j].CloseTime <= dataBarProvider.BarsUnsafe[i].DateTime) {// Order close is within the current period. pendingClosingOrders.Add(ordersClosing[j]); ordersClosing.RemoveAt(j); } } drawingPoint.X = i * (itemMargin + itemWidth); DrawOrders(g, i, drawingPoint, itemWidth, itemMargin, pendingOpeningOrders, pendingClosingOrders, dataBarProvider.BarsUnsafe[i], lastBarX); pendingOpeningOrders.Clear(); pendingClosingOrders.Clear(); } if (_showClosedOrdersTracing && dataBarProvider.BarCount > 0 && startIndex < dataBarProvider.BarCount) {// Since a closed order may be before or after (or during) the curren set of periods - make a special search and render for them. endIndex = Math.Max(0, endIndex); endIndex = Math.Min(dataBarProvider.BarCount - 1, endIndex); foreach (Order order in ordersClosed) { if (order.OpenTime.HasValue && order.CloseTime.HasValue && order.OpenTime.Value <= dataBarProvider.BarsUnsafe[endIndex].DateTime && order.CloseTime.Value >= dataBarProvider.BarsUnsafe[startIndex].DateTime - dataBarProvider.Period) { int openIndex = dataBarProvider.GetIndexAtTime(order.OpenTime.Value); int closeIndex = dataBarProvider.GetIndexAtTime(order.CloseTime.Value); Pen pen = _buyDashedPen; if (order.IsBuy == false) { pen = _sellDashedPen; } Decimal? doubleOpenValue = order.OpenPrice; Decimal? doubleCloseValue = order.ClosePrice; if (doubleOpenValue.HasValue == false) { SystemMonitor.Error("Invalid open price value for closed order to draw."); continue; } if (doubleCloseValue.HasValue == false) { SystemMonitor.Error("Invalid close price value for closed order to draw."); continue; } g.DrawLine(pen, new PointF(openIndex * (itemWidth + itemMargin), (float)doubleOpenValue), new PointF(closeIndex * (itemWidth + itemMargin), (float)doubleCloseValue)); } } } } // Lock }
/// <summary> /// Drawing routine, invoke from child class to draw dataDelivery bars in common uniform way. /// </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 void Draw(GraphicsWrapper g, ReadOnlyCollection <DataBar> dataBars, int unitsUnification, RectangleF clippingRectangle, float itemWidth, float itemMargin, float maxVolume, object tag) { if (Visible == false) { return; } PointF drawingPoint = new PointF(); lock (this) { if (_chartType == ChartTypeEnum.Line) { base.DrawItemSet(LinesChartSeries.ChartTypeEnum.Line, g, _risingBarPen, null, unitsUnification, clippingRectangle, itemWidth, itemMargin, null); } else if (_chartType == ChartTypeEnum.Histogram) { base.DrawItemSet(LinesChartSeries.ChartTypeEnum.Histogram, g, _risingBarPen, _risingBarFill, unitsUnification, clippingRectangle, itemWidth, itemMargin, tag); } else if (_chartType == ChartTypeEnum.ColoredArea) { base.DrawItemSet(LinesChartSeries.ChartTypeEnum.ColoredArea, g, _risingBarPen, _risingBarFill, unitsUnification, clippingRectangle, itemWidth, itemMargin, tag); } else if (_chartType == ChartTypeEnum.CandleStick || _chartType == ChartTypeEnum.BarChart) {// Unit unification is done trough combining many bars together. List <DataBar> combinationDatas = new List <DataBar>(); bool timeGapFound = false; int startIndex, endIndex; GetDrawingRangeIndecesFromClippingRectange(clippingRectangle, drawingPoint, unitsUnification, out startIndex, out endIndex, itemWidth, itemMargin); float volumeDisplayRange = clippingRectangle.Height / 4f; decimal volumeDisplayMultiplicator = 0; if (maxVolume > 0) { volumeDisplayMultiplicator = (decimal)(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) { DataBar combinedData = DataBar.CombinedBar(combinationDatas.ToArray()); 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)(dataDelivery.High))); //g.DrawLine(_timeGapsLinePen, new PointF(drawingPoint.X, (float)(dataDelivery.High + dataDelivery.BarTotalLength / 2f)), new PointF(drawingPoint.X, clippingRectangle.Y + clippingRectangle.Height)); } if (_chartType == ChartTypeEnum.CandleStick) { DrawCandleStick(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification); } else { DrawBar(g, ref drawingPoint, combinedData, itemWidth, itemMargin, unitsUnification); } // Draw closeVolume for this bar. if (_showVolume) { float actualHeight = (float)(combinedData.Volume * volumeDisplayMultiplicator); g.DrawLine(_volumePen, drawingPoint.X, clippingRectangle.Y, drawingPoint.X, clippingRectangle.Y + actualHeight); } } drawingPoint.X = (i + 1) * (itemMargin + itemWidth); } } } } }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false) { return; } if (_controlPoints.Count < 1) { return; } PointF point1 = _controlPoints[0]; PointF point2; if (_controlPoints.Count < 2) { point2 = mousePosition.Value; } else { point2 = _controlPoints[1]; } // Clipping opitmization. RectangleF rectangle = new RectangleF( Math.Min(point1.X, point2.X), Math.Min(point1.Y, point2.Y), Math.Abs(point2.X - point1.X), Math.Abs(point2.Y - point1.Y)); if (rectangle.IntersectsWith(clippingRectangle) == false) { return; } // Draw base line. g.DrawLine(_dashedLinePen, point1, point2); float baseLevel = point1.Y; float height = point2.Y - point1.Y; // Draw fibbonacci levels. float[] levels = new float[] { 0, 23.6f, 38.2f, 50, 61.8f, 100 }; for (int i = 0; i < levels.Length; i++) { float actualLevel = baseLevel + height * levels[i] / 100f; g.DrawLine(_solidLinePen, point1.X, actualLevel, point2.X, actualLevel); g.DrawString(levels[i].ToString(), DefaultDynamicObjectFont, Brushes.White, point1.X, actualLevel); } if (Selected) { DrawControlPoints(g); } }
public override void Draw(GraphicsWrapper g, PointF? mousePosition, RectangleF clippingRectangle, RectangleF drawingSpace) { if (Visible == false || _controlPoints.Count < 1) { return; } if (clippingRectangle.Contains(_controlPoints[0]) == false) {// Clipping opitmization. return; } SizeF size = g.MeasureString(_text, DefaultDynamicObjectFont); if (size.Height < 0) { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y + size.Height, size.Width, -size.Height); } else { _rectangle = new RectangleF(_controlPoints[0].X, _controlPoints[0].Y, size.Width, size.Height); } g.DrawString(_text, DefaultDynamicObjectFont, _brush, _controlPoints[0]); if (Selected || IsBuilding) { g.DrawLine(Pens.Red, _rectangle.Location, new PointF(_rectangle.X + _rectangle.Width, _rectangle.Y)); } // Rounding rectangle. //g.DrawRectangle(Pens.White, _rectangle); if (Selected) { DrawControlPoints(g); } }