huge bug

Created at 08 Sep 2016, 03:36
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!
SE

sebnet

Joined 11.08.2016

huge bug
08 Sep 2016, 03:36


The event Positions.Opened has a bug.

The PositionsOpenedEventArgs object does not carry the StopLoss and TakeProfit of the opened position.

 

I have open the position manually throught cTrader setting both SL and TP.

 


@sebnet
Replies

afhacker
08 Sep 2016, 10:22

I had same problem but I think cTrader set TP / SL of positions some milliseconds latter after the position opened so I used a timer to solve this problem.


@afhacker

sebnet
09 Sep 2016, 00:54

Great, thanks for the tip!


@sebnet

ClickAlgo
09 Sep 2016, 07:40

I have a customer request to duplicate manually opened orders. I have also noticed that the first time the OnPositionOpened method is called the position object does not contain the SL or TP values of the opened order, all subsequent calls work correctly and they have the correct SL and TP values.

I set a timer for 5 seconds and it did not correct the problem. So I would say there is an issue with the API


@ClickAlgo

ClickAlgo
09 Sep 2016, 07:44

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class DuplicateOrders : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        protected override void OnStart()
        {
            Positions.Opened += OnPositionOpened;
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

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


        private void OnPositionOpened(PositionOpenedEventArgs args)
        {
            System.Threading.Thread.Sleep(5000);
            var p = args.Position;

            for (int i = 0; i < 2; i++)
            {
                if (p.Label != "duplicates")
                {
                    ExecuteMarketOrder(p.TradeType, this.Symbol, p.Volume, "duplicates", p.StopLoss, p.TakeProfit);
                }
            }
        }
    }
}

 


@ClickAlgo

ClickAlgo
09 Sep 2016, 08:07

afhacker is correct

There is a hack workaround to this issue and you can use a timer to check for the last open position that opened and get the SL and TP.


@ClickAlgo

rmssf
09 Sep 2016, 10:44

Indeed this is critical, I've never noticed before and I'm surprised with this kind of bug.

It looks like the API sets the TP/SL values only after Positions.Opened() returns.

Rui


@rmssf

rmssf
09 Sep 2016, 12:55 ( Updated at: 21 Dec 2023, 09:20 )

It looks more like a design problem than a bug.

There are 2 events, the order is opened without SL/TP set, then the platform modifies that position with the chosen SL/TP.

The  OnPositionOpened() is called after the position is opened and before the position is modified.

 

 

Position Opened


@rmssf

rmssf
09 Sep 2016, 14:59

RE:

Paul_Hayes said:

I have a customer request to duplicate manually opened orders. I have also noticed that the first time the OnPositionOpened method is called the position object does not contain the SL or TP values of the opened order, all subsequent calls work correctly and they have the correct SL and TP values.

I set a timer for 5 seconds and it did not correct the problem. So I would say there is an issue with the API

The API is missing an additional event type -  OnPositionModified()

It would solve this problem and would be much more efficient to catch subsequent modifications than using a timer instead.

Rui


@rmssf

ClickAlgo
09 Sep 2016, 15:16

I agree the problem is a design issue. I am very surprised the event type OnPositionModified is not included in the API, maybe in the future they will add it, but in the meantime we can only do workarounds.


@ClickAlgo

sebnet
09 Sep 2016, 17:34

RE: Sample Code

Paul_Hayes said:

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class DuplicateOrders : Robot
    {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        protected override void OnStart()
        {
            Positions.Opened += OnPositionOpened;
        }

        protected override void OnTick()
        {
            // Put your core logic here
        }

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


        private void OnPositionOpened(PositionOpenedEventArgs args)
        {
            System.Threading.Thread.Sleep(5000);
            var p = args.Position;

            for (int i = 0; i < 2; i++)
            {
                if (p.Label != "duplicates")
                {
                    ExecuteMarketOrder(p.TradeType, this.Symbol, p.Volume, "duplicates", p.StopLoss, p.TakeProfit);
                }
            }
        }
    }
}

 

I think you should access the "this.Positions" collection to get the SL and TP because the args.Position is not updated after the Sleep.


@sebnet

ClickAlgo
09 Sep 2016, 20:34

RE: RE: Sample Code

Thank you Sebnet, 

The problem is capturing the event when a position is filled, the subscribed event OnPositionedOpen will get fired as soon as a position is opened and the object gets passed to the method to be handled, if you use this.positions you will only access all open positions and not the most recent position that has opened. You can use a hack to access the most recent opened position and use the data from this.

The sleep was just a test and did nothing as the previous poster mentioned that the SL and TP were modified after the position was opened by as this was by design by the developers of the API.


@ClickAlgo

sebnet
11 Sep 2016, 02:08

RE:

Ok, I am storing the SL and TP values on the comment field. Not the ideal solution but it works because it is done for my own trading.

cAlgo could easily solve this if they store the SL and TP values (in pips) as properties of the object, no matter if the position is yet modified or not, just as another descriptive fields. Then you have the real SL and TP expressed in prices (not pips) as the real values after the trade was updated.

Besides, it's better to have those values in pips instead of converted to prices, because we have to do some math to get back the value in pips.


@sebnet