Modify Label or some other way for me to group trades and change grouping

Created at 22 Jun 2017, 23:28
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!
GA

GammaQuant

Joined 14.06.2017

Modify Label or some other way for me to group trades and change grouping
22 Jun 2017, 23:28


Hello, i am developing a cbot that i has some nive features but i am looking for an easy way to group trades together and then change/modify what trade is in want group on the fly in my cbot. Depending on the features of my cbot the status of an open trade can change many times as the functionality of the cbot defines each trade in a spoecifc group that can change at any one time. Is there a way to do this that will let me easily define a group of trades and find them at the broker.


@GammaQuant
Replies

croucrou
24 Jun 2017, 12:21

I don't think you can change the label, but couldn't you do that with bools?


@croucrou

GammaQuant
24 Jun 2017, 14:40

RE:

croucrou said:

I don't think you can change the label, but couldn't you do that with bools?

Sorry what do you mean?

How can i group trades and change those groups with a boolean True or False?

In any case.,

i have found a solution here:

/forum/cbot-support/10908?page=2

Thank you


@GammaQuant

Jiri
29 Jun 2017, 15:13

Here is a sample of grouping across all instances using static list of custom class called Order. The cBot executes a market order on each new bar and adds to the list. Each time price changes it updates position's State. The cBot also prints number of positions for each State using LINQ queries.

Be aware I haven't tested it so there might be some bugs.

using System.Collections.Generic;
using System.Linq;
using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class GroupsSample : Robot
    {
        public enum State
        {
            Gaining,
            BreakingEven,
            Loosing
        }

        public class Order
        {
            public Position Position { get; set; }
            public State State { get; set; }
        }

        private static List<Order> _orders;

        protected override void OnStart()
        {
            // creates new list if doesn't exist
            if (_orders == null)
            {
                _orders = new List<Order>();
            }

            // subscribes to Positions.Closed event
            Positions.Closed += OnPositionClosed;
        }

        /// <summary>
        /// Method called on position closed
        /// </summary>
        private static void OnPositionClosed(PositionClosedEventArgs obj)
        {
            // finds matching order
            var matchingOrder = _orders.FirstOrDefault(x => x.Position == obj.Position);

            // if found
            if (matchingOrder != null)
            {
                // removes order from our list
                _orders.Remove(matchingOrder);
            }
        }

        /// <summary>
        /// Method called on each new bar
        /// </summary>
        protected override void OnBar()
        {
            // executes market order and calls back OnPositionOpened method when filled
            ExecuteMarketOrderAsync(MarketSeries.Open.Count % 2 == 0 ? TradeType.Buy : TradeType.Sell, Symbol, 1000, OnPositionOpened);

            // counts how many positions have certain state
            var gaining = _orders.Count(x => x.State == State.Gaining);
            var breakingEven = _orders.Count(x => x.State == State.BreakingEven);
            var loosing = _orders.Count(x => x.State == State.Loosing);

            // prints number of positions that are gaining, breaking even, loosing
            Print("Gaining = {0}, BreakingEven = {1}, Loosing = {2}", gaining, breakingEven, loosing);
        }

        /// <summary>
        /// Method called when position opened
        /// </summary>
        private void OnPositionOpened(TradeResult result)
        {
            // prints error and skips rest of the iteration if result wasn't successful
            if (!result.IsSuccessful)
            {
                Print(result.Error);
                return;
            }

            // adds new order into our list
            _orders.Add(new Order { Position = result.Position });
        }

        /// <summary>
        /// Method called on each price change
        /// </summary>
        protected override void OnTick()
        {
            // loops through all orders in our list and sets their state
            foreach (var order in _orders)
            {
                if (order.Position.NetProfit > 0)
                {
                    order.State = State.Gaining;
                }
                else if (order.Position.NetProfit < 0)
                {
                    order.State = State.Loosing;
                }
                else
                {
                    order.State = State.BreakingEven;
                }
            }
        }
    }
}

 


@Jiri

GammaQuant
29 Jun 2017, 18:31

RE:

tmc. said:

Here is a sample of grouping across all instances using static list of custom class called Order. The cBot executes a market order on each new bar and adds to the list. Each time price changes it updates position's State. The cBot also prints number of positions for each State using LINQ queries.

Be aware I haven't tested it so there might be some bugs.

using System.Collections.Generic;
using System.Linq;
using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class GroupsSample : Robot
    {
        public enum State
        {
            Gaining,
            BreakingEven,
            Loosing
        }

        public class Order
        {
            public Position Position { get; set; }
            public State State { get; set; }
        }

        private static List<Order> _orders;

        protected override void OnStart()
        {
            // creates new list if doesn't exist
            if (_orders == null)
            {
                _orders = new List<Order>();
            }

            // subscribes to Positions.Closed event
            Positions.Closed += OnPositionClosed;
        }

        /// <summary>
        /// Method called on position closed
        /// </summary>
        private static void OnPositionClosed(PositionClosedEventArgs obj)
        {
            // finds matching order
            var matchingOrder = _orders.FirstOrDefault(x => x.Position == obj.Position);

            // if found
            if (matchingOrder != null)
            {
                // removes order from our list
                _orders.Remove(matchingOrder);
            }
        }

        /// <summary>
        /// Method called on each new bar
        /// </summary>
        protected override void OnBar()
        {
            // executes market order and calls back OnPositionOpened method when filled
            ExecuteMarketOrderAsync(MarketSeries.Open.Count % 2 == 0 ? TradeType.Buy : TradeType.Sell, Symbol, 1000, OnPositionOpened);

            // counts how many positions have certain state
            var gaining = _orders.Count(x => x.State == State.Gaining);
            var breakingEven = _orders.Count(x => x.State == State.BreakingEven);
            var loosing = _orders.Count(x => x.State == State.Loosing);

            // prints number of positions that are gaining, breaking even, loosing
            Print("Gaining = {0}, BreakingEven = {1}, Loosing = {2}", gaining, breakingEven, loosing);
        }

        /// <summary>
        /// Method called when position opened
        /// </summary>
        private void OnPositionOpened(TradeResult result)
        {
            // prints error and skips rest of the iteration if result wasn't successful
            if (!result.IsSuccessful)
            {
                Print(result.Error);
                return;
            }

            // adds new order into our list
            _orders.Add(new Order { Position = result.Position });
        }

        /// <summary>
        /// Method called on each price change
        /// </summary>
        protected override void OnTick()
        {
            // loops through all orders in our list and sets their state
            foreach (var order in _orders)
            {
                if (order.Position.NetProfit > 0)
                {
                    order.State = State.Gaining;
                }
                else if (order.Position.NetProfit < 0)
                {
                    order.State = State.Loosing;
                }
                else
                {
                    order.State = State.BreakingEven;
                }
            }
        }
    }
}

Thank you very much TMC! i will give it an go and let you know if there are any problems

 


@GammaQuant

GammaQuant
02 Jul 2017, 16:07

RE: RE:

Hi TMC, i just wanted to thank you again for taking the time to give me this example. :) i have been able to use your example as inspiration to add some advanced features to my cbot. I really like the C#/.net List Class. it can be used like a mini databse without the overhead of using a real database. Very powerfull. Ive been able to use your example to also add extra properties to trades so that i can make a robust advanced trading system. I wish i got into c# years ago ;). as its actually quite intuitive and logical once you get the hang of it.

Thank you


@GammaQuant

Jiri
03 Jul 2017, 13:42

Hi GammQuant, I am glad it helped. You're welcome!


@Jiri

GammaQuant
21 Sep 2017, 11:36

Hi TMC i wonder if you can help me in this thread please

/forum/cbot-support/11907?page=1#3


@GammaQuant

martins
05 Nov 2019, 01:57

In order to be as robust as an alterable Position.Label wouldn't the info in this Order class have to be stored in a file - otherwise only information that can be determined from the positions themselves could be reconstructed after cTrader restarted for whatever reason, for instance after pc crash or power outage.


@martins