How to detect user drag on chart object

Created at 13 Mar 2019, 06:51
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
NO

noppanon

Joined 17.05.2017

How to detect user drag on chart object
13 Mar 2019, 06:51


Hi All,

   I would like user to interact with horizontal line by draging up or down. Base on sample code below, I can only detect  when the line is selected. However, when user move mosue away from the line it will not get the unselected event. It will get unselect event only if user click on empty area on chart or select other object on the chart.

Questions

1. How can I get the event (or what event) when user release mouse button or when move away from the line?

2. How can I get the Y value of the line when user release the mouse button?

Thanks in advance

 

Noppanon

 

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class DragLine : Robot
    {
        [Parameter("Distance 1", DefaultValue = 10.0, MinValue = 1.0, Step = 1.0)]
        public double Distance1Param { get; set; }

        ChartHorizontalLine TargetLine1;
        

        // Chart decoration information when alert is triggered
        private string ChartID1;
        private readonly Color AlertColor1 = Color.Khaki;
        private readonly LineStyle AlertLineStyle = LineStyle.LinesDots;
        private readonly int AlertLineThick = 2;        

        protected override void OnStart()
        {
            ChartID1 = "Target1";
            double distance1;

            distance1 = (Symbol.Bid + Symbol.Ask) / 2 + (Distance1Param * Symbol.PipSize);

            Print("Distance 1 = {0}", distance1);

            if (RunningMode != RunningMode.Optimization)
            {
                TargetLine1 = Chart.DrawHorizontalLine(ChartID1, distance1, AlertColor1, AlertLineThick, AlertLineStyle);
                TargetLine1.IsInteractive = true;
                TargetLine1.Comment = "line 1";                
                Chart.ObjectSelectionChanged += OnObjectSelected;
            }

        }

        protected override void OnStop()
        {
            Chart.RemoveObject(TargetLine1.Name);
        }

        private void OnObjectSelected(ChartObjectSelectionChangedEventArgs args)
        {
            ChartObject line = args.ChartObject;
            if (args.IsObjectSelected )
            {
                if (line.Name == TargetLine1.Name)
                {
                    Print("Selecte Target Line 1  {0}", args.ChartObject.Comment);
                }
            }
            else
            {
                if (line.Name == TargetLine1.Name)
                {
                    Print("UNselect Target Line 1  {0}", args.ChartObject.Comment);
                }
            }
        }
    }
}

 


@noppanon
Replies

noppanon
13 Mar 2019, 08:17

Hi all,

   Say it in another word, I would like user to interact with horizental line similar to Take profit / Stop Loss line in position.

   How should the code look like?

 

Regards,

Noppanon


@noppanon

PanagiotisCharalampous
13 Mar 2019, 09:19

Hi Noppanon,

You can try Chart.ObjectUpdated event.

Best Regards,

Panagiotis


@PanagiotisCharalampous

noppanon
13 Mar 2019, 15:32

Hi Panagiotis,

   Thank you for your suggestion. It works. 

 

Regards

Noppanon


@noppanon

bienve.pf
14 Mar 2019, 16:16

How can we detect if an object is selected?
This is useful to avoid handling it while the user is modifying it

 

for example:

ChartTrendLine line = obj as ChartTrendLine;
if( line.IsSelected ){


}

 


@bienve.pf

PanagiotisCharalampous
15 Mar 2019, 10:00

Hi bienve.pf,

There is no Selected state for the objects in the chart. When you say modify, do you mean when objects are dragged on the chart? If yes, you can use DragStart and  DragEnd events.

Best Regards,

Panagiotis


@PanagiotisCharalampous

noppanon
16 Mar 2019, 03:00 ( Updated at: 21 Dec 2023, 09:21 )

Hi Panagiotis,

   I tried to use DrgStart and DragEnd. But it does not work. When I drag a line, there is no event called back. But I drag a chart, the drag evetns get call. see the image and modified code below.

   Do I misundertand anything?

Regards,

Noppanon

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class DragLine2 : Robot
    {
        [Parameter("Distance 1", DefaultValue = 10.0, MinValue = 1.0, Step = 1.0)]
        public double Distance1Param { get; set; }

        ChartHorizontalLine TargetLine1;


        // Chart decoration information when alert is triggered
        private string ChartID1;
        private readonly Color AlertColor1 = Color.Khaki;
        private readonly LineStyle AlertLineStyle = LineStyle.LinesDots;
        private readonly int AlertLineThick = 2;

        protected override void OnStart()
        {
            ChartID1 = "Target1";
            double distance1;

            distance1 = (Symbol.Bid + Symbol.Ask) / 2 + (Distance1Param * Symbol.PipSize);

            Print("Distance 1 = {0}", distance1);

            if (RunningMode != RunningMode.Optimization)
            {
                TargetLine1 = Chart.DrawHorizontalLine(ChartID1, distance1, AlertColor1, AlertLineThick, AlertLineStyle);
                TargetLine1.IsInteractive = true;
                TargetLine1.Comment = "line 1";
                Chart.ObjectSelectionChanged += OnObjectSelected;                
                Chart.DragStart += OnDragStart;
                Chart.Drag += OnDrag;
                Chart.DragEnd += OnDragEnd;
            }

        }

        protected override void OnStop()
        {
            Chart.RemoveObject(TargetLine1.Name);
        }

        private void OnDragStart(ChartDragEventArgs args)
        {
            Print("Start drag line {0} Y = {1}", args.ToString(), args.YValue);
        }

        private void OnDrag(ChartDragEventArgs args)
        {
            Print("Dragig line {0} Y = {1}", args.ToString(), args.YValue);
        }
        private void OnDragEnd(ChartDragEventArgs args)
        {
            Print("End drag line {0} Y = {1}", args.ToString(), args.YValue);
        }

        private void OnObjectSelected(ChartObjectSelectionChangedEventArgs args)
        {
            ChartObject line = args.ChartObject;
            if (args.IsObjectSelected)
            {
                if (line.Name == TargetLine1.Name)
                {
                    Print("Selecte Target Line 1  {0}", args.ChartObject.Comment);
                }
            }
            else
            {
                if (line.Name == TargetLine1.Name)
                {
                    Print("UNselect Target Line 1  {0}", args.ChartObject.Comment);
                }
            }
        }
    }
}

 


@noppanon

PanagiotisCharalampous
19 Mar 2019, 11:09

Hi noppanon,

I think I misunderstood what you are trying to do. The workaround below is closer to what you need, even though not perfect. It detects when an object is hovered.

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewcBot : Robot
    {
        [Parameter("Distance 1", DefaultValue = 10.0, MinValue = 1.0, Step = 1.0)]
        public double Distance1Param { get; set; }

        ChartHorizontalLine TargetLine1;
        ChartObject _selectedObject;
        // Chart decoration information when alert is triggered
        private string ChartID1;
        private readonly Color AlertColor1 = Color.Khaki;
        private readonly LineStyle AlertLineStyle = LineStyle.LinesDots;
        private readonly int AlertLineThick = 2;
        protected override void OnStart()
        {
            ChartID1 = "Target1";
            double distance1;

            distance1 = (Symbol.Bid + Symbol.Ask) / 2 + (Distance1Param * Symbol.PipSize);
            TargetLine1 = Chart.DrawHorizontalLine(ChartID1, distance1, AlertColor1, AlertLineThick, AlertLineStyle);
            TargetLine1.IsInteractive = true;
            TargetLine1.Comment = "line 1";
            Chart.ObjectHoverChanged += OnChartObjectHoverChanged;
        }

        void OnChartObjectHoverChanged(ChartObjectHoverChangedEventArgs obj)
        {
            if (obj.IsObjectHovered)
                _selectedObject = obj.ChartObject;
            else
                _selectedObject = null;
        }

        protected override void OnTick()
        {
            if (_selectedObject != null)
            {
                Print(_selectedObject.Name + " is selected");
            }
        }

        protected override void OnStop()
        {
            // Put your deinitialization logic here
        }
    }
}

Best Regards,

Panagiotis


@PanagiotisCharalampous

noppanon
22 Mar 2019, 05:07

Hi Panagiotis,

   Thank you for suggestion. But it is not what I am looking. Anyway, it is what cTrader Chart programing model. I will think another way to deal. 

regards

Noppanon


@noppanon

DanielFXS
29 Aug 2019, 12:34

Hi Panagiotis,

I've been attempting to create a stop loss that exits on barclose. This code is a good staring point.

Disclaimer - I'm not a programmer, just learning, there's so many languages. So I'm having difficulty even putting together the simplist code on calgo. 

When the line is dragged and dropped is the Y value saved in a variable? So that I can set the code to exit a buy position if price < line on barclose, and opposite for sell position. 

I'm surprised I can't find this already done. This being my quick and easy solution for the whipsaw spikes that close trades prematurely. 

 

Regards,

Daniel 


@DanielFXS