[BUG] PositionOpenedEventArgs missing TP and SL

Created at 22 Jan 2018, 12:57
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!
Jiri's avatar

Jiri

Joined 31.08.2015

[BUG] PositionOpenedEventArgs missing TP and SL
22 Jan 2018, 12:57


Hi, position opened event is not returning any take profit and stop loss in all cases except from market order. See the code below and its output.

using System;
using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleOnPositionOpenedBug : Robot
    {
        private readonly Action[] _actions = new Action[6];
        private int _index;

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

            _actions[0] = () => PlaceStopOrderAsync(TradeType.Buy, Symbol, 1000, Symbol.Ask, "label", 5, 5, null, "Stop Order Async");
            _actions[1] = () => PlaceLimitOrderAsync(TradeType.Buy, Symbol, 1000, Symbol.Bid, "label", 5, 5, null, "Limit Order Async");
            _actions[2] = () => ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 1000, "label", 5, 5, null, "Market Order Async");
            _actions[3] = () => PlaceStopOrder(TradeType.Buy, Symbol, 1000, Symbol.Ask, "label", 5, 5, null, "Stop Order");
            _actions[4] = () => PlaceLimitOrder(TradeType.Buy, Symbol, 1000, Symbol.Bid, "label", 5, 5, null, "Limit Order");
            _actions[5] = () => ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, "label", 5, 5, null, "Market Order");

            Timer.Start(2);
        }

        protected override void OnTimer()
        {
            if (_index >= _actions.Length) 
            {
                Stop();
            }

            _actions[_index]();
            _index++;
        }

        private void Positions_Opened(PositionOpenedEventArgs e)
        {
            if (e.Position.Label == "label")
            {
                Print("{0} filled (TP: {1} SL: {2})", e.Position.Comment, e.Position.TakeProfit, e.Position.StopLoss);
            }
        }
    }
}

All the orders were executed with take profit and stop loss


@Jiri
Replies

Jiri
26 Jan 2018, 00:42

Is it going to be fixed any time soon?


@Jiri

PanagiotisCharalampous
26 Jan 2018, 10:05

Hi tmc,

cAlgo issue is currently investigating this issue. We still don't know when this is going to be resolved.

Best Regards,

Panagiotis


@PanagiotisCharalampous

Jiri
09 Feb 2018, 15:45

Any progress? I find it as a critical bug since I can't get TP and SL values of filled pending orders on the position opened event using the API.


@Jiri

PanagiotisCharalampous
09 Feb 2018, 17:04

Hi tmc. 

It is going to take some time to fix this issue due to some architectural changes that need to take place. The issue has to do with the fact that TP and SL messages are sent slightly after the position is opened resulting to the arguments not having this information. However if you can wait for a little you can TP and SL are updated and you can read the information. See my code sample below

using System;
using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleOnPositionOpenedBug : Robot
    {
        private readonly Action[] _actions = new Action[6];
        private int _index;
        protected override void OnStart()
        {
            Positions.Opened += Positions_Opened;

            _actions[0] = () => PlaceStopOrderAsync(TradeType.Buy, Symbol, 1000, Symbol.Ask, "label", 5, 5, null, "Stop Order Async");
            _actions[1] = () => PlaceLimitOrderAsync(TradeType.Buy, Symbol, 1000, Symbol.Bid, "label", 5, 5, null, "Limit Order Async");
            _actions[2] = () => ExecuteMarketOrderAsync(TradeType.Buy, Symbol, 1000, "label", 5, 5, null, "Market Order Async");
            _actions[3] = () => PlaceStopOrder(TradeType.Buy, Symbol, 1000, Symbol.Ask, "label", 5, 5, null, "Stop Order");
            _actions[4] = () => PlaceLimitOrder(TradeType.Buy, Symbol, 1000, Symbol.Bid, "label", 5, 5, null, "Limit Order");
            _actions[5] = () => ExecuteMarketOrder(TradeType.Buy, Symbol, 1000, "label", 5, 5, null, "Market Order");

            Timer.Start(2);
        }
        protected override void OnTick()
        {
            foreach (var position in Positions)
            {
                Print("{0} (TP: {1} SL: {2})", position.Comment, position.TakeProfit, position.StopLoss);
            }
        }
        protected override void OnTimer()
        {
            if (_index >= _actions.Length)
            {
                Stop();
            }

            _actions[_index]();
            _index++;
        }

        private void Positions_Opened(PositionOpenedEventArgs e)
        {
            if (e.Position.Label == "label")
            {
                Print("{0} filled (TP: {1} SL: {2})", e.Position.Comment, e.Position.TakeProfit, e.Position.StopLoss);
            }
        }
    }
}

Could we work on a workaround based on the above?

Best Regards,

Panagiotis


@PanagiotisCharalampous

Jiri
09 Feb 2018, 20:44

Not sure how this is a workaround but thanks for the information about the messages being sent later. I have applied this logic which seems to work.

private void Positions_Opened(PositionOpenedEventArgs e)
{
    if (e.Position.Label != "label")
    {
        return;
    }

    if (IsBacktesting)
    {
        Print("{0} filled (TP: {1} SL: {2})", e.Position.Comment, e.Position.TakeProfit, e.Position.StopLoss);
    }
    else
    {
        var task = new Task(() =>
        {
            Thread.Sleep(50);
            BeginInvokeOnMainThread(() => Print("{0} filled (TP: {1} SL: {2})", e.Position.Comment, e.Position.TakeProfit, e.Position.StopLoss));
        });

        task.Start();
    }
}

 


@Jiri