/// <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="coord"></param> public void PaintCrossLines(Point coord, GCandles.CandleInfo candle) { Panel.Clear(); var canvas = Panel.GetGraphics; string time = ""; Data = new DataCross(); if (candle.NotIsNull()) { Data.Candle = candle; Data.Time = Data.Candle.Candle.Time; string d = Data.Time.Day.ToString(); string m = Data.Time.Month.ToString(); string y = Data.Time.Year.ToString(); string min = Data.Time.Minute.ToString(); string hour = Data.Time.Hour.ToString(); time = (d.Length < 2 ? '0' + d : d) + "." + (m.Length < 2 ? '0' + m : m) + "." + y + " " + (hour.Length < 2 ? '0' + hour : hour) + ":" + (min.Length < 2 ? '0' + min : min); } Data.Price = GMath.GetValueFromCoordinate(this.HeightForPrice, Panel.Params.MaxPrice, Panel.Params.MinPrice, coord.Y, Panel.Params.CountFloat); var lineVer = new VerLine(); lineVer.ColorLine = lineVer.ColorText = Color.Black; lineVer.WidthLine = 1; lineVer.FillText = true; lineVer.Paint(canvas, time, new Point(coord.X, 0), new Point(coord.X, Panel.Rect.Height)); Data.Point.X = coord.X; var horLine = new HorLine(); horLine.ColorLine = horLine.ColorText = Color.Black; horLine.FillText = true; horLine.Paint(canvas, Panel.Rect.Rectangle, coord.Y, Data.Price.ToString(), Panel.Params.MaxPrice, Panel.Params.MinPrice); Data.Point.Y = coord.Y; var priceText = new TextDraw(); var TextAppendByCandle = ""; //Данные по свечи в углу if (Data.Candle.NotIsNull()) { priceText.Color = Color.Black; priceText.SetFontSize(8); priceText.Paint(canvas, "T: " + time + "\r\n" + "O: " + Data.Candle.Candle.Open.ToString() + "\r\n" + "H: " + Data.Candle.Candle.High.ToString() + "\r\n" + "L: " + Data.Candle.Candle.Low.ToString() + "\r\n" + "C: " + Data.Candle.Candle.Close.ToString() + "\r\n" + "V: " + Data.Candle.Candle.Volume.ToString() + "\r\n" , 0, 0); TextAppendByCandle = "Vol:" + Data.Candle.Candle.Volume; } //Текщие данные по цене и времени priceText.Color = Color.Black; priceText.SetFontSize(8); priceText.Paint(canvas, Data.Price.ToString() + "\r\n" + time + "\r\n" + TextAppendByCandle , coord.X + 10, coord.Y + 20); }
/// <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); }