/// <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);
        }
Exemple #3
0
        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);
        }
Exemple #4
0
        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 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;
 }
        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;
        }
Exemple #16
0
        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;
            }
        }