/// <summary> /// Отрисовка одного уровня /// </summary> /// <param name="canvas"></param> /// <param name="rectPaint"></param> /// <param name="Value"></param> /// <param name="index"></param> private void PaintOneLevel(Graphics canvas, Chart level, CandleInfo candle, bool paintLast = false) { int Y1 = GMath.GetCoordinate(Panel.Rect.Height, this.Max, this.Min, level.Volume > 0 ? level.Volume : 0); int Y2 = GMath.GetCoordinate(Panel.Rect.Height, this.Max, this.Min, level.Volume < 0 ? level.Volume : 0); float bodyWidth = candle.Body.Width < MAX_WIDTH ? candle.Body.Width : MAX_WIDTH;//Panel.Params.WidthCandle - Panel.Params.MarginCandle; //-2 чтобы свечки не слипались int bodyHeight = Y2 - Y1; int bodyX = (int)(candle.Body.X + (candle.Body.Width / 2) - (bodyWidth / 2)); int bodyY = Y1; //bodyHeight = bodyHeight - bodyY; bodyHeight = bodyHeight == 0 ? bodyHeight + 1 : bodyHeight; var rect = new RectDraw(); if (candle.Index != 0 || paintLast) { var Color = ValuePositive; if (candle.Candle.Close < candle.Candle.Open) { Color = ValueNegative; } rect.Paint(canvas, bodyX, bodyY, bodyWidth, bodyHeight, Color, Color); } var data = new DataLevel() { PaintRect = Panel.Rect.Rectangle, Value = level.Volume, MaxValue = this.Max, MinValue = this.Min, Index = candle.Index, DataPaint = rect, Body = new RectangleF(bodyX, bodyY, bodyWidth, bodyHeight) }; if (data.NotIsNull()) { if (data.Index == 1) { this.AllDataLevels.RemoveAll(l => l.Index == data.Index); AllDataLevels.Insert(0, data); } else { AllDataLevels.Add(data); } } }
/// <summary> /// Рисует уровень ввиде свободного прямоугольника /// </summary> /// <param name="g"></param> /// <param name="rect"></param> /// <param name="lev"></param> /// <param name="widthLine"></param> private void PaintRectangleLevel(Graphics g, Rectangle rect, DoubleLevel lev, float widthLine = 1) { int yTop = GMath.GetCoordinate(rect.Height, Panel.Params.MaxPrice, Panel.Params.MinPrice, lev.Top); int yBot = GMath.GetCoordinate(rect.Height, Panel.Params.MaxPrice, Panel.Params.MinPrice, lev.Bottom); if (yBot < 0 && yTop > 0) { yBot = rect.Y + rect.Height; } if (yTop < 0 && yBot > 0) { yTop = rect.Y; } var height = yBot - yTop; if (height <= 0) { return; } var rectLev = new RectDraw(); rectLev.ColorBorder = Color.FromArgb(100, Color.Black); rectLev.ColorFill = Color.FromArgb(40, Color.Blue); rectLev.WidthBorder = widthLine; rectLev.Paint(g, rect.X, yTop, rect.Width, height); var middleLine = new Line(); middleLine.Width = 1; middleLine.Style = System.Drawing.Drawing2D.DashStyle.Dot; middleLine.Paint(g, new PointF(rect.X, yTop + height / 2), new PointF(rect.X + rect.Width, yTop + height / 2), Color.FromArgb(100, Color.Black)); var topText = new TextDraw(); var dataText = topText.GetSizeText(g, lev.Top.ToString()); int HeightText = (int)dataText.Height; if (height > HeightText * 3 && rect.Width > dataText.Width) { topText.Paint(g, lev.Top.ToString(), rect.X, yTop); topText.Paint(g, lev.Bottom.ToString(), rect.X, yBot - HeightText); } }
/// <summary> Рисует одну свечку </summary> /// <param name="canvas"></param> /// <param name="rectPaint"></param> /// <param name="candleData"></param> /// <param name="index"></param> /// <param name="maxPrice"></param> /// <param name="minPrice"></param> private CandleInfo PaintOneCandle(Graphics canvas, ViewPanel panel, CandleData candleData, int index, bool paint = true) { int tailY1 = GMath.GetCoordinate(panel.Rect.Height, panel.Params.MaxPrice, panel.Params.MinPrice, candleData.High); int tailY2 = GMath.GetCoordinate(panel.Rect.Height, panel.Params.MaxPrice, panel.Params.MinPrice, candleData.Low); int tailX1 = (int)((panel.Rect.Width - panel.Params.WidthCandle * index) + panel.Params.WidthCandle / 2); int bodyX = (int)(panel.Rect.Width - panel.Params.WidthCandle * index); int bodyY = GMath.GetCoordinate(panel.Rect.Height, panel.Params.MaxPrice, panel.Params.MinPrice, candleData.Open > candleData.Close ? candleData.Open : candleData.Close); float bodyWidth = panel.Params.WidthCandle - MarginCandle > 0.3f ? panel.Params.WidthCandle - MarginCandle : 0.3f; //- чтобы свечки не слипались int bodyHeight = GMath.GetCoordinate(panel.Rect.Height, panel.Params.MaxPrice, panel.Params.MinPrice, candleData.Open < candleData.Close ? candleData.Open : candleData.Close); bodyHeight = bodyHeight - bodyY; bodyHeight = bodyHeight == 0 ? bodyHeight + 1 : bodyHeight; //tail var line = new Line(); line.Width = 1.5f; if (paint) { line.Paint(canvas, new Point(tailX1, tailY1), new Point(tailX1, tailY2), ColorBorderCandle); } //Body var rect = new RectDraw(); var colorCandle = candleData.Open > candleData.Close ? ColorFallCandle : ColorGrowCandle; var colorBorder = ColorBorderCandle; /*if (candleData.Open < candleData.Close && candleData.VolumeBuy - candleData.VolumeSell > 0) * { * colorBorder = colorCandle = Color.DarkGreen; * } * if (candleData.Open > candleData.Close && candleData.VolumeBuy - candleData.VolumeSell < 0) * { * colorBorder = colorCandle = Color.DarkRed; * }*/ if (paint) { rect.Paint(canvas, bodyX, bodyY, bodyWidth, bodyHeight, colorBorder, colorCandle); } if (MaxValues.MinCandle.IsNull()) { MaxValues.MinCandle = candleData; } if (MaxValues.MaxCandle.IsNull()) { MaxValues.MaxCandle = candleData; } if (MaxValues.MaxPrice < candleData.High) { MaxValues.MaxPrice = candleData.High; MaxValues.MaxCandle = candleData; } if (MaxValues.MinPrice > candleData.Low) { MaxValues.MinPrice = candleData.Low; MaxValues.MinCandle = candleData; } /*if (candleData.HorVolumes.HVolCollection.MaxVolume.NotIsNull()) * { * if (MaxValues.MaxHorVolume.Volume < candleData.HorVolumes.HVolCollection.MaxVolume.Volume) * { * MaxValues.MaxHorVolume = candleData.HorVolumes.HVolCollection.MaxVolume; * } * }*/ var dCandle = new CandleInfo() { PaintRect = panel.Rect.Rectangle, Candle = candleData, TailCoord = new TailCoord() { Low = new Point(tailX1, tailY2), High = new Point(tailX1, tailY1) }, Body = new RectangleF() { X = bodyX, Y = bodyY, Width = bodyWidth, Height = bodyHeight }, Index = index - 1, MaxHorVolume = MaxValues.MaxHorVolume, TimeFrame = CurrentTimeFrame }; VerticalLines[index - 1] = dCandle.TailCoord.High.X; if (index == 1) { AllDataPaintedCandle.RemoveAll(c => c.Index == index - 1); AllDataPaintedCandle.Insert(0, dCandle); } else { AllDataPaintedCandle.Add(dCandle); } if (OnPaintedCandle.NotIsNull()) { OnPaintedCandle(dCandle); } return(dCandle); }
/// <summary> /// Рисует линию горизонтального объема /// </summary> private int PaintLineHVol(Graphics canvas, RectangleF rect, Chart maxElem, Chart minElem, ChartFull hv, Color?colorVol = null, bool isDelta = false) { var widthLayoutVolume = rect.Width; var value = hv.VolBuy + hv.VolSell; if (isDelta) { value = hv.VolBuy - hv.VolSell; } float y = GMath.GetCoordinate(Panel.Rect.Height, Panel.Params.MaxPrice, Panel.Params.MinPrice, hv.Price); var height = GMath.GetCoordinate(Panel.Rect.Height, Panel.Params.MaxPrice, Panel.Params.MinPrice, hv.Price - Panel.Params.MinStepPrice) - y; if (y == 0 || y == Panel.Rect.Height) { return(-1); } int x1 = 0, x2 = 0; if (value < 0) { x1 = GMath.GetCoordinate(widthLayoutVolume, maxElem.Volume, minElem.Volume, value); x2 = GMath.GetCoordinate(widthLayoutVolume, maxElem.Volume, minElem.Volume, 0); } else { x1 = GMath.GetCoordinate(widthLayoutVolume, maxElem.Volume, minElem.Volume, 0); x2 = GMath.GetCoordinate(widthLayoutVolume, maxElem.Volume, minElem.Volume, value); } var p1 = new PointF(rect.X + widthLayoutVolume - x1, y); var p2 = new PointF(rect.X + widthLayoutVolume - x2, y); RectDraw rectVol = new RectDraw(); var color = ColorVol; if (isDelta) { if (value < 0) { color = this.ColorDeltaNegative; } else { color = this.ColorDeltaPositive; } } if (maxElem.Price == hv.Price) { color = ColorMaxVol; } if (minElem.Price == hv.Price) { color = ColorMaxVol; } if (colorVol.NotIsNull()) { color = (Color)colorVol; } rectVol.ColorBorder = color; rectVol.ColorFill = color; rectVol.Paint(canvas, p1.X, y - height / 2, p2.X - p1.X, height - 1 <= 0 ? 1 : height - 1); return(0); }