/// <summary> /// начать визуальное редактировние (перетаскивание) ордера /// </summary> public override bool OnMouseButtonDown(MouseEventArgs e, Keys modifierKeys) { if (e.Button != MouseButtons.Left) return false; draggedComment = null; var clientPoint = owner.PointToScreen(new Point(e.X, e.Y)); var x = clientPoint.X; var y = clientPoint.Y; // перетаскиваем ордер суммарной позы? var selectedCommentsLastBar = seriesCommentLastBar.GetObjectsUnderCursor(x, y, SeriesComment.DefaultMouseTolerance).Where(c => c.Name == "drag").ToList(); if (selectedCommentsLastBar.Count > 0) { draggedComment = (ChartComment) selectedCommentsLastBar[0]; draggedCommentSource = DraggedCommentSource.SummaryPositionOrder; } else if (selectedOrder != null) { // перетаскиваем ордер открытой позы? var selectedCommentsHit = seriesCommentSelected.GetObjectsUnderCursor(x, y, SeriesComment.DefaultMouseTolerance); draggedComment = (ChartComment)selectedCommentsHit.FirstOrDefault(c => c.Name == "drag"); draggedCommentSource = DraggedCommentSource.MarketOrder; } if (draggedComment == null) return false; startDragPrice = (float)draggedComment.PivotPrice; draggedComment.DrawFrame = true; draggedComment.HideBox = false; return true; }
public ChartCommentEditDialog(ChartComment obj, CandleChartControl chart) : this() { comment = obj;//new ChartComment(); ChartComment.Copy(comment, obj); // отобразить содержание полей tbText.Text = comment.Text; btnColorPicker.BackColor = comment.ColorText; tbText.ForeColor = comment.ColorText; tbText.BackColor = chart.chart.BackColor; cbShowArrow.Checked = !comment.HideArrow; cbShowFrame.Checked = comment.DrawFrame; btnColorLine.ForeColor = comment.Color; btnColorFill.ForeColor = comment.ColorFill; tbMagic.Text = comment.Magic.ToString(); transparencyControl.Transparency = comment.FillTransparency; // настройки выпадающих списков //cbTextStyle.SelectedIndex = SeriesComment.FontBold var patterns = new CommentaryPatternsList().GetStandardValues(); if (patterns == null) return; var items = new object[patterns.Count]; patterns.CopyTo(items, 0); cbTemplates.Items.AddRange(items); }
protected override void OnMouseDown(List <SeriesEditParameter> parameters, MouseEventArgs e, Keys modifierKeys, out IChartInteractiveObject objectToEdit) { objectToEdit = null; if (e.Button != MouseButtons.Left) { return; } var editedComment = data.Find(c => c.IsBeingCreated); if (editedComment != null) { return; } // получить время и цену var clientPoint = Chart.PointToScreen(new Point(e.X, e.Y)); clientPoint = Chart.StockPane.PointToClient(clientPoint); var x = clientPoint.X; var y = clientPoint.Y; var pointD = Conversion.ScreenToWorld(new PointD(x, y), Chart.StockPane.WorldRect, Chart.StockPane.CanvasRect); // начинается редактирование - выбрана первая точка var text = SeriesEditParameter.TryGetParamValue(parameters, "Text", "..."); var lineColor = SeriesEditParameter.TryGetParamValue(parameters, "Stroke", Color.Black); var fillColor = SeriesEditParameter.TryGetParamValue(parameters, "Filling", Color.White); var colorText = SeriesEditParameter.TryGetParamValue(parameters, "TextColor", Color.Black); var alphaColor = SeriesEditParameter.TryGetParamValue(parameters, "Transparency", 192); var hideArrow = SeriesEditParameter.TryGetParamValue(parameters, "HideArrow", false); var drawFrame = SeriesEditParameter.TryGetParamValue(parameters, "DrawFrame", true); var comment = new ChartComment { IsBeingCreated = true, PivotIndex = pointD.X, PivotPrice = pointD.Y, ArrowLength = 0, ArrowAngle = -45, Owner = this, Text = text, Color = lineColor, ColorFill = fillColor, FillTransparency = alphaColor, HideArrow = hideArrow, DrawFrame = drawFrame, ColorText = colorText }; if (Owner.Owner.Owner.AdjustObjectColorsOnCreation) { comment.AjustColorScheme(Owner.Owner.Owner); } data.Add(comment); }
public override IChartInteractiveObject LoadObject(XmlElement objectNode, CandleChartControl owner, bool trimObjectsOutOfHistory = false) { var obj = new ChartComment(); obj.LoadFromXML(objectNode, owner); obj.Owner = this; data.Add(obj); return(obj); }
public static void Copy(ChartComment dest, ChartComment src) { dest.ArrowAngle = src.ArrowAngle; dest.ArrowLength = src.ArrowLength; dest.Color = src.Color; dest.ColorFill = src.ColorFill; dest.ColorText = src.ColorText; dest.DrawFrame = src.DrawFrame; dest.FillTransparency = src.FillTransparency; dest.HideArrow = src.HideArrow; dest.HideBox = src.HideBox; dest.Magic = src.Magic; dest.Name = src.Name; dest.Owner = src.Owner; dest.PivotIndex = src.PivotIndex; dest.PivotPrice = src.PivotPrice; dest.Selected = src.Selected; dest.Text = src.Text; dest.TextArea = src.TextArea; }
protected override void OnMouseDown(List<SeriesEditParameter> parameters, MouseEventArgs e, Keys modifierKeys, out IChartInteractiveObject objectToEdit) { objectToEdit = null; if (e.Button != MouseButtons.Left) return; var editedComment = data.Find(c => c.IsBeingCreated); if (editedComment != null) return; // получить время и цену var clientPoint = Chart.PointToScreen(new Point(e.X, e.Y)); clientPoint = Chart.StockPane.PointToClient(clientPoint); var x = clientPoint.X; var y = clientPoint.Y; var pointD = Conversion.ScreenToWorld(new PointD(x, y), Chart.StockPane.WorldRect, Chart.StockPane.CanvasRect); // начинается редактирование - выбрана первая точка var text = SeriesEditParameter.TryGetParamValue(parameters, "Text", "..."); var lineColor = SeriesEditParameter.TryGetParamValue(parameters, "Stroke", Color.Black); var fillColor = SeriesEditParameter.TryGetParamValue(parameters, "Filling", Color.White); var colorText = SeriesEditParameter.TryGetParamValue(parameters, "TextColor", Color.Black); var alphaColor = SeriesEditParameter.TryGetParamValue(parameters, "Transparency", 192); var hideArrow = SeriesEditParameter.TryGetParamValue(parameters, "HideArrow", false); var drawFrame = SeriesEditParameter.TryGetParamValue(parameters, "DrawFrame", true); var comment = new ChartComment { IsBeingCreated = true, PivotIndex = pointD.X, PivotPrice = pointD.Y, ArrowLength = 0, ArrowAngle = -45, Owner = this, Text = text, Color = lineColor, ColorFill = fillColor, FillTransparency = alphaColor, HideArrow = hideArrow, DrawFrame = drawFrame, ColorText = colorText }; if (Owner.Owner.Owner.AdjustObjectColorsOnCreation) comment.AjustColorScheme(Owner.Owner.Owner); data.Add(comment); }
public override IChartInteractiveObject LoadObject(XmlElement objectNode, CandleChartControl owner, bool trimObjectsOutOfHistory = false) { var obj = new ChartComment(); obj.LoadFromXML(objectNode, owner); obj.Owner = this; data.Add(obj); return obj; }
public override string ActivateScript(CandleChartControl chart, PointD worldCoords) { var comment = chart.seriesComment.data.FirstOrDefault(c => c.Name == CommentSpecName); // удалить существующий if (comment != null) { chart.seriesComment.data.Remove(comment); chart.RedrawChartSafe(); return string.Empty; } // добавить новый MarketOrder sumPos; string scriptText; GetCommentText(chart, out scriptText, out sumPos); if (sumPos == null) return string.Empty; var colorFill = sumPos.ResultDepo > 0 ? Color.LightGreen : sumPos.ResultDepo < 0 ? Color.LightCoral : Color.Gray; var colorText = chart.chart.BackColor.GetBrightness() < 0.4f ? Color.White : Color.Black; comment = new ChartComment { FillTransparency = 80, ColorFill = colorFill, HideArrow = true, ArrowAngle = 90, ArrowLength = 1, PivotIndex = worldCoords.X, PivotPrice = worldCoords.Y, Owner = chart.seriesComment, Name = CommentSpecName, Text = scriptText, ColorText = colorText, Color = colorText }; chart.seriesComment.data.Add(comment); chart.RedrawChartSafe(); return string.Empty; }
private void MakeChartGraph(List<TrendLine> lines) { if (removeOldSigns) RemoveOldSigns(); int totalLosses = 0, totalProfits = 0; double totalPoints = 0; foreach (var line in lines) { line.Owner = chart.seriesTrendLine; chart.seriesTrendLine.data.Add(line); var sign = line.LineColor == ColorBuy ? 1 : -1; var deltaPoints = sign*(line.linePoints[1].Y - line.linePoints[0].Y); deltaPoints = DalSpot.Instance.GetPointsValue(chart.Symbol, (float) deltaPoints); totalPoints += deltaPoints; if (deltaPoints > 0) totalProfits++; if (deltaPoints < 0) totalLosses++; var comment = new ChartComment { Magic = LineMagic, PivotIndex = line.linePoints[1].X, PivotPrice = line.linePoints[1].Y, ArrowAngle = 120, ArrowLength = 30, Color = line.LineColor, ColorText = chart.chart.visualSettings.SeriesForeColor, Text = string.Format("{0:f1} пп", deltaPoints), Owner = chart.seriesComment }; chart.seriesComment.data.Add(comment); } var message = string.Format("{0:f1} пунктов всего, {1} \"профитов\", {2} \"лоссов\"", totalPoints, totalProfits, totalLosses); MessageBox.Show(message); }
public override string ActivateScript(CandleChartControl chart, PointD worldCoords) { var robots = MainForm.Instance.RobotFarm.GetRobotsAsIs().ToList(); var commentText = GetCommentForChart(chart.Symbol, chart.Timeframe, robots); if (string.IsNullOrEmpty(commentText)) return "Нет роботов для " + chart.Symbol + " " + BarSettingsStorage.Instance.GetBarSettingsFriendlyName(chart.Timeframe); // разместить комментарий на графике в указанной точке, удалить такой же, если был добавлен var comment = chart.seriesComment.data.FirstOrDefault(c => c.Name == CommentSpecName); if (comment != null) { chart.seriesComment.data.Remove(comment); chart.RedrawChartSafe(); return string.Empty; } var colorFill = Color.LightGreen; var colorText = chart.chart.BackColor.GetBrightness() < 0.4f ? Color.White : Color.Black; comment = new ChartComment { FillTransparency = 80, ColorFill = colorFill, HideArrow = true, ArrowAngle = 90, ArrowLength = 1, PivotIndex = worldCoords.X, PivotPrice = worldCoords.Y, Owner = chart.seriesComment, Name = CommentSpecName, Text = commentText, ColorText = colorText, Color = colorText }; chart.seriesComment.data.Add(comment); chart.RedrawChartSafe(); return string.Empty; }
/// <summary> /// нарисовать "полочки" уровней SL - TP /// </summary> private void ShowSelectedDealSlTpLines(MarketOrder order) { if (order.StopLoss == null && order.TakeProfit == null) return; var indexStart = (int) owner.StockSeries.GetDoubleIndexByTime(order.TimeEnter); var indexEnd = order.TimeExit.HasValue ? (int) owner.StockSeries.GetDoubleIndexByTime(order.TimeExit.Value) : indexStart; // линия не должна быть слишком короткой var sizePixel = Conversion.WorldToScreen(new SizeD(indexEnd - indexStart, 0), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); const int targetWidth = 35; if (sizePixel.Width < targetWidth) { var newSize = Conversion.ScreenToWorld(new SizeD(targetWidth, 0), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); var len = (int) Math.Round(newSize.Width); indexEnd += len; } var prices = new List<float>(); var tags = new List<string>(); if (order.StopLoss.HasValue) { prices.Add(order.StopLoss.Value); tags.Add("SL"); } if (order.TakeProfit.HasValue) { prices.Add(order.TakeProfit.Value); tags.Add("TP"); } // добавить линии var priceIndex = 0; foreach (var price in prices) { var posLine = new TrendLine { LineColor = owner.StockSeries.DownLineColor, ShapeAlpha = 255, ShapeFillColor = owner.StockSeries.DownLineColor, LineStyle = TrendLine.TrendLineStyle.Отрезок, PenWidth = 1, PenDashStyle = DashStyle.Dot, Name = "drag" }; posLine.AddPoint(indexStart, price); posLine.AddPoint(indexEnd, price); seriesSelectedLines.data.Add(posLine); // добавить с каждой стороны масенький комент: SL или TP var comment = new ChartComment { Text = tags[priceIndex], PivotPrice = price, ArrowAngle = 180, ArrowLength = 2, PivotIndex = indexStart, ColorText = owner.visualSettings.SeriesForeColor, Color = owner.visualSettings.SeriesForeColor, DrawFrame = false, HideBox = true, HideArrow = true, Name = "drag" }; seriesCommentSelected.data.Add(comment); comment = new ChartComment { Text = tags[priceIndex], PivotPrice = price, ArrowAngle = 0, ArrowLength = 2, PivotIndex = indexEnd, ColorText = owner.visualSettings.SeriesForeColor, Color = owner.visualSettings.SeriesForeColor, DrawFrame = false, HideBox = true, HideArrow = true, Name = "drag" }; seriesCommentSelected.data.Add(comment); priceIndex++; } }
/// <summary> /// добавить подробные коменты по сделке /// </summary> private void ShowSelectedDealComments(MarketOrder order, bool selectedByExitMark) { var listComments = new List<string>(); // данные по входу в рынок var commentMain = new StringBuilder (((DealType) order.Side).ToString() + " " + order.Volume.ToStringUniformMoneyFormat() + " " + order.Symbol + Environment.NewLine + order.TimeEnter.ToString("dd MMM HH:mm") + ", " + order.PriceEnter.ToStringUniformPriceFormat(true)); // SL, TP, результат выхода из рынка if (order.TimeExit.HasValue || order.StopLoss.HasValue || order.TakeProfit.HasValue) { commentMain.AppendLine(); if (order.StopLoss.HasValue || order.TakeProfit.HasValue) { if (order.StopLoss.HasValue) commentMain.AppendFormat("SL: {0}", order.StopLoss.Value.ToStringUniformPriceFormat()); if (order.StopLoss.HasValue && order.TakeProfit.HasValue) commentMain.Append(" "); if (order.TakeProfit.HasValue) commentMain.AppendFormat("TP: {0}", order.TakeProfit.Value.ToStringUniformPriceFormat()); if (order.TimeExit.HasValue) commentMain.AppendLine(); } if (order.TimeExit.HasValue) { commentMain.AppendFormat("Закрыт {0} по {1}", order.TimeExit.Value.ToString("dd MMM HH:mm"), // ReSharper disable PossibleInvalidOperationException order.PriceExit.Value.ToStringUniformPriceFormat()); // ReSharper restore PossibleInvalidOperationException commentMain.AppendLine(); commentMain.AppendFormat("Результат: {0}", order.ResultDepo.ToStringUniformMoneyFormat()); } } listComments.Add(commentMain.ToString()); // предложение закрыть или редактировать ордер //if (!order.TimeExit.HasValue) // listComments.Add("Редактировать /" + Environment.NewLine + "Закрыть"); // точка привязки (к маркеру входа или выхода) var pivot = selectedByExitMark // ReSharper disable PossibleInvalidOperationException ? new PointD(owner.StockSeries.GetDoubleIndexByTime(order.TimeExit.Value, true), order.PriceExit.Value) // ReSharper restore PossibleInvalidOperationException : new PointD(owner.StockSeries.GetDoubleIndexByTime(order.TimeEnter, true), order.PriceEnter); // по текущему результату определить, прибыльный ордер или убыточный var profitSide = Math.Sign(order.ResultDepo); if (order.IsOpened) { var curPrice = owner.StockSeries.Data.Candles[owner.StockSeries.DataCount - 1].close; profitSide = Math.Sign(order.Side*(curPrice - order.PriceEnter)); } var colorFill = profitSide > 0 ? Color.LightGreen : profitSide < 0 ? Color.LightCoral : Color.BlanchedAlmond; // таки добавить коменты var angle = selectedDealCommentAngle; const int arrowLen = 90; foreach (var text in listComments) { var x = pivot.X; var price = pivot.Y; var comment = new ChartComment { Text = text, ArrowLength = arrowLen, ArrowAngle = angle, HideBox = false, HideArrow = false, DrawFrame = true, FillTransparency = 200, ColorFill = colorFill, Color = owner.visualSettings.SeriesForeColor, ColorText = owner.visualSettings.SeriesForeColor, PivotIndex = x, PivotPrice = price }; // развернуть комментарий так, чтобы он не накрывал ничего лишнего и не вылезал за пределы экрана AdjustDealCommentArrowAngle(comment, order); if (order.IsClosed) comment.Name = "info"; seriesCommentSelected.data.Add(comment); angle += 120; } // пометить комментарий с предложением редактировать / закрыть ордер if (!order.TimeExit.HasValue) seriesCommentSelected.data[seriesCommentSelected.data.Count - 1].Name = "edit"; // сместить угол стрелок selectedDealCommentAngle += 45; if (selectedDealCommentAngle > 360) selectedDealCommentAngle -= 360; }
private void AdjustDealCommentArrowAngle(ChartComment comment, MarketOrder order) { if (!order.TimeExit.HasValue) return; // получить основное направление // (продолжение линии open - close) var ptE = Conversion.WorldToScreen( new PointD(owner.StockSeries.GetDoubleIndexByTime(order.TimeEnter), order.PriceEnter), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); var ptQ = Conversion.WorldToScreen( // ReSharper disable PossibleInvalidOperationException new PointD(owner.StockSeries.GetDoubleIndexByTime(order.TimeExit.Value), order.PriceExit.Value), // ReSharper restore PossibleInvalidOperationException owner.StockPane.WorldRect, owner.StockPane.CanvasRect); var ptPivot = Conversion.WorldToScreen(new PointD(comment.PivotIndex, comment.PivotPrice), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); var ptStart = (Math.Abs(ptPivot.X - ptE.X) < Math.Abs(ptPivot.X - ptQ.X)) ? ptQ : ptE; var mainAngle = Math.Atan2(ptPivot.Y - ptStart.Y, ptPivot.X - ptStart.X) * 180 / Math.PI; // "округлить" угол mainAngle = Math.Round(mainAngle/15) * 15; // расставить направления по приоритету const int numAngles = 8; var angles = new double[numAngles]; angles[0] = mainAngle; for (var i = 0; i < numAngles / 2 - 1; i++) { var delta = (i + 1) * 360 / numAngles; angles[i * 2 + 1] = mainAngle + delta; angles[i * 2 + 2] = mainAngle - delta; } angles[numAngles - 1] = -mainAngle; // выбрать направление, для которого комментарий не вылезает за рамки экрана var foundAngle = false; var screenRect = seriesComment.Owner.CanvasRect; using (var gr = owner.CreateGraphics()) foreach (var angle in angles) { comment.ArrowAngle = angle; var commentRect = comment.GetCommentRectangle(gr, owner.StockPane.WorldRect, owner.StockPane.CanvasRect); // не вылез ли комментарий за пределы экрана? if (commentRect.Left < screenRect.Left || commentRect.Top < screenRect.Top || commentRect.Right > screenRect.Right || commentRect.Bottom > screenRect.Bottom) continue; foundAngle = true; break; } // угол поворота по-умолчанию if (!foundAngle) comment.ArrowAngle = angles[0]; }
/// <summary> /// опеределить попадание в ордер, дабы "подсветить" его и произвести определенные действия /// (показать линии SL - TP, редактировать ордера) /// </summary> public override bool OnMouseButtonUp(MouseEventArgs e, Keys modifierKeys) { // закончить драг текстовой меточки if (draggedComment != null) { var newPrice = draggedComment.PivotPrice; var commentTitle = draggedComment.Text; // если цена сдвинута меньше, чем на 0.1 пп - ничего не предлагать var minDelta = DalSpot.Instance.GetAbsValue(owner.Symbol, 0.1f); // предложить пользователю изменить SL / TP if (commentTitle.Contains("SL") || commentTitle.Contains("TP")) { var isSl = commentTitle.Contains("SL"); if (Math.Abs(newPrice - startDragPrice) > minDelta) { // меняем рыночный ордер? if (draggedCommentSource == DraggedCommentSource.MarketOrder) ModifyMarketOrderAfterDrag(newPrice, isSl, selectedOrder); else if (draggedCommentSource == DraggedCommentSource.SummaryPositionOrder) ModifySummaryOrderAfterDrag(newPrice, isSl, commentTitle); } } // забыть о текстовой метке draggedComment.HideBox = true; draggedComment.DrawFrame = false; draggedComment = null; } if (e.Button != MouseButtons.Left) return false; var screenPoint = owner.PointToScreen(new Point(e.X, e.Y)); var x = screenPoint.X; var y = screenPoint.Y; // попали в специальные отметки для выделенного ордера (например, предложение редактировать // или закрыть ордер)? var selectedCommentsHit = seriesCommentSelected.GetObjectsUnderCursor(x, y, SeriesAsteriks.DefaultMouseTolerance); if (selectedCommentsHit.Count > 0) { if (selectedOrder.IsOpened)//selectedCommentsHit.Any(c => c.Name == "edit") && selectedOrder != null) { // открыть окно редактирования ордера owner.Owner.CallShowWindowEditMarketOrder(selectedOrder); } else if (selectedCommentsHit.Any(c => c.Name == "info") && selectedOrder != null) { // показать информацию по закрытому ордеру owner.Owner.CallShowWindowInfoOnClosedOrder(selectedOrder); } return false; } // найти выделенные кликом коменты или астериксы var comments = seriesComment.GetObjectsUnderCursor(x, y, SeriesComment.DefaultMouseTolerance); var asters = seriesAsteriks.GetObjectsUnderCursor(x, y, SeriesAsteriks.DefaultMouseTolerance); var orders = comments.Where(p => p.Magic > 0).Select(p => p.Magic).ToList(); orders.AddRange(asters.Where(a => a.Magic > 0).Select(a => a.Magic)); // ордер не выбран и до того не был выбран if (orders.Count == 0 && selectedOrder == null) return false; // ордер не выбран, но был уже выбран ранее - снять выделение if (selectedOrder != null) { DeselectOrder(); return true; } // найти ордер в списке открытых или закрытых позиций var order = openPositions.FirstOrDefault(p => orders.Contains(p.ID)) ?? closedPositions.FirstOrDefault(p => orders.Contains(p.ID)); if (order == null) return false; var ptPane = Conversion.ScreenToWorld(new PointD(e.X, e.Y), owner.StockPane.WorldRect, owner.StockPane.CanvasRect); var pointTime = owner.StockSeries.GetCandleOpenTimeByIndex((int) Math.Round(ptPane.X)); SelectOrder(order, pointTime); return true; }
private void DrawCommentForSelected(Graphics g, RectangleD worldRect, Rectangle canvasRect, PenStorage pens, BrushesStorage brushes) { if (string.IsNullOrEmpty(Comment)) return; var commentBox = new ChartComment { Color = LineColor, ColorFill = ShapeFillColor, Text = Comment, HideArrow = true, FillTransparency = 160 }; var textRect = commentBox.GetCommentRectangle(g, worldRect, canvasRect); // прикинуть, куда лучше захреначить комментарий - в центр или в конец // спроецировать координаты курсора на линию var cursorPoint = Owner.Owner.PointToClient(Control.MousePosition); var screenPoints = linePoints.Select(p => Conversion.WorldToScreenF(p, worldRect, canvasRect)).ToList(); var pivot = Geometry.GetProjectionPointOnLine(cursorPoint, screenPoints[0], screenPoints[1]); // пробуем два варианта размещения - привязываем левый верхний или // правый нижний углы комментария, смотрим, какой вариант ближе к центру экрана var potentialPivots = new [] { new PointF(pivot.X, pivot.Y + textRect.Height/2), new PointF(pivot.X - textRect.Width, pivot.Y - textRect.Height/2) }; var cx = canvasRect.Left + canvasRect.Width / 2; var cy = canvasRect.Top + canvasRect.Height / 2; var bestPivotIndex = potentialPivots.IndexOfMin(p => (p.X - cx)*(p.X - cx) + (p.Y - cy)*(p.Y - cy)); pivot = potentialPivots[bestPivotIndex]; var worldPivotPoint = Conversion.ScreenToWorld(pivot, worldRect, canvasRect); commentBox.PivotPrice = worldPivotPoint.Y; commentBox.PivotIndex = worldPivotPoint.X; // таки нарисовать using (var fonts = new FontStorage(Owner.Owner.Owner.Font)) commentBox.DrawComment(g, fonts, worldRect, canvasRect, pens, brushes, new List<Rectangle>()); }
public void BuildSeries(ChartControl chart) { var commentText = GetStatText(); if (string.IsNullOrEmpty(commentText)) return; var candles = chart.StockSeries.Data.Candles; // добавить комментарий с текстом var series = chart.Owner.seriesComment; var indiTitle = MakeCommentTitle(); var comment = series.data.FirstOrDefault(c => c.Magic == CommentMagic && c.Text.StartsWith(indiTitle)); if (comment != null) { comment.Text = commentText; return; } // таки создать новый комментарий comment = new ChartComment { ArrowAngle = nextAngle, ArrowLength = 50, Magic = CommentMagic, Text = commentText, Owner = series, PivotIndex = candles.Count - 1, PivotPrice = candles[candles.Count - 1].open, }; nextAngle += 45; series.data.Add(comment); }
private void AddChartCommentOnRobotState(int dealsOpened) { var commentLines = new List<string> { selectedBot.GetUniqueName() }; if (selectedBot is FiboLevelRobot) { var fiboBot = ((FiboLevelRobot) selectedBot); commentLines.Add("открыто " + dealsOpened + " из " + fiboBot.MaxDealsInSeries + " сделок"); commentLines.Add("цена A: " + fiboBot.PriceA.ToStringUniformPriceFormat() + ", цена B: " + fiboBot.PriceB.ToStringUniformPriceFormat()); } else { commentLines.Add("открыто " + dealsOpened + " сделок"); } var commentStr = string.Join(Environment.NewLine, commentLines); // найти на графике существующий комментарий или создать новый var comment = chart.seriesComment.data.FirstOrDefault(c => c.Name == CommentSpecName); if (comment == null) { comment = new ChartComment { Name = CommentSpecName, PivotIndex = scriptActivatedCoords.X, PivotPrice = scriptActivatedCoords.Y, HideArrow = true, Color = chart.chart.visualSettings.SeriesForeColor, ColorFill = Color.DarkTurquoise, Text = commentStr, Owner = chart.seriesComment }; chart.seriesComment.data.Add(comment); } else { comment.Text = commentStr; } }