Check if Position is closed

Created at 05 Nov 2016, 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!
Mikro's avatar

Mikro

Joined 20.06.2015

Check if Position is closed
05 Nov 2016, 23:28


Hi folks,

I assume there may be an easy Solution but I couldn't find the propper Thread I guess...

In a Bot I am using a list to store and track the executed positions in. Depending on the strategy to positions StopLoss and TakeProfit are modified. Now if the position has been closed it still is stored in the list and I can retrieve all its properties (Profit, Type and so on) but I cannot check if it was allready closed!

How do I check by the Position.ID if it has been closed or not? I want to use the ID in order to make sure it is a unique identifier.

Any Ideas???

 

THX


@Mikro
Replies

... Deleted by UFO ...

Mikro
06 Nov 2016, 13:45

Hi Lucian,

thanks for the tip. This probably could work if I introduced a kind of a callback function that uses the position.Id as an argument.

But is there another way to directly check if a position is closed without having to wait for the PositionsOnClosed Method???

THX


@Mikro

whis.gg
06 Nov 2016, 22:25

Hi Mikro,

You could use Linq to check if collection of current opened positions contain desired position. See the sample below.

using System.Linq;

bool isOpened = Positions.Contains(position);

 


@whis.gg

Mikro
08 Nov 2016, 23:14

Hi tmc,

nice Approach. The following  Method is called in another Class where MyDirector is an Object Link to the actual cAlgo Robot.

I tried it like that.

    public void ProccessClosedTrade(PositionClosedEventArgs args)
    {
        bool allStratPositionsClosed = this.StratPositions.Contains(args.Position) && this.StratPositions.TrueForAll(pos => MyDirector.History.Contains(pos)) ? SetStrategyMode(StrategyMode.Closed) : false;
    }

The Contains extension works, but I seem to have something wrong in the TrueForAll Extension. It throw this Error

Error    1    'cAlgo.API.History' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.ParallelEnumerable.Contains<TSource>(System.Linq.ParallelQuery<TSource>, TSource)' has some invalid arguments    c:\users\mirko\documents\calgo\sources\robots\cea4\cea4\strategyblueprint.cs    165    125    cEA4


This is odd because to Tooltips show a 'Contains' extension for the History...

Any Idea???

 

THX


@Mikro

Mikro
08 Nov 2016, 23:27

RE:
SetStrategyMode(StrategyMode.Closed)

of course needs to be a Method Call in the next line inside an if()...

Mikro said:

Hi tmc,

nice Approach. The following  Method is called in another Class where MyDirector is an Object Link to the actual cAlgo Robot.

I tried it like that.

    public void ProccessClosedTrade(PositionClosedEventArgs args)
    {
        bool allStratPositionsClosed = this.StratPositions.Contains(args.Position) && this.StratPositions.TrueForAll(pos => MyDirector.History.Contains(pos)) ? SetStrategyMode(StrategyMode.Closed) : false;
    }

The Contains extension works, but I seem to have something wrong in the TrueForAll Extension. It throw this Error

Error    1    'cAlgo.API.History' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.ParallelEnumerable.Contains<TSource>(System.Linq.ParallelQuery<TSource>, TSource)' has some invalid arguments    c:\users\mirko\documents\calgo\sources\robots\cea4\cea4\strategyblueprint.cs    165    125    cEA4


This is odd because to Tooltips show a 'Contains' extension for the History...

Any Idea???

 

THX

 


@Mikro

whis.gg
09 Nov 2016, 00:19

Currently opened positions "Positions" and historical trades "History" are two different collections of objects. You can't compare them like that, compare Position.ID and HistoricalTrade.PositionId. Personally I would create collection of positions hold in cBot memory, adding and removing positions during the process so you can handle them easily, see sample below.

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class CollectionOfPositions : Robot
    {
        private List<Position> openedPositions = new List<Position>();

        protected override void OnStart()
        {
            Positions.Closed += OnPositionClosed;
        }

        private void OnPositionClosed(PositionClosedEventArgs obj)
        {
            if (openedPositions.Contains(obj.Position))
            {
                openedPositions.Remove(obj.Position);
            }
        }

        protected override void OnTick()
        {
            if (true)
            {
                TradeResult result = ExecuteMarketOrder(TradeType.Sell, Symbol, 1000);

                if (result.IsSuccessful)
                {
                    openedPositions.Add(result.Position);
                }
            }

            bool allPositionsClosed = openedPositions.Count() == 0 ? true : false;
        }
    }
}

 


@whis.gg

whis.gg
09 Nov 2016, 00:33

If you need collection of historical trades (closed positions) you can do following.

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class CollectionOfPositions : Robot
    {
        private List<Position> openedPositions = new List<Position>();
        private List<HistoricalTrade> closedPositions = new List<HistoricalTrade>();

        protected override void OnStart()
        {
            Positions.Closed += OnPositionClosed;
        }

        private void OnPositionClosed(PositionClosedEventArgs obj)
        {
            if (openedPositions.Contains(obj.Position))
            {
                openedPositions.Remove(obj.Position);
                closedPositions.Add(History.First(x => x.PositionId == obj.Position.Id));
            }
        }

        protected override void OnBar()
        {
            if (true)
            {
                TradeResult result = ExecuteMarketOrder(TradeType.Sell, Symbol, 1000);

                if (result.IsSuccessful)
                {
                    openedPositions.Add(result.Position);
                }
            }

            bool allPositionsClosed = openedPositions.Count() == 0 ? true : false;
        }
    }
}

 


@whis.gg

GammaQuant
23 Jun 2017, 00:40

RE:

tmc. said:

Currently opened positions "Positions" and historical trades "History" are two different collections of objects. You can't compare them like that, compare Position.ID and HistoricalTrade.PositionId. Personally I would create collection of positions hold in cBot memory, adding and removing positions during the process so you can handle them easily, see sample below.

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class CollectionOfPositions : Robot
    {
        private List<Position> openedPositions = new List<Position>();

        protected override void OnStart()
        {
            Positions.Closed += OnPositionClosed;
        }

        private void OnPositionClosed(PositionClosedEventArgs obj)
        {
            if (openedPositions.Contains(obj.Position))
            {
                openedPositions.Remove(obj.Position);
            }
        }

        protected override void OnTick()
        {
            if (true)
            {
                TradeResult result = ExecuteMarketOrder(TradeType.Sell, Symbol, 1000);

                if (result.IsSuccessful)
                {
                    openedPositions.Add(result.Position);
                }
            }

            bool allPositionsClosed = openedPositions.Count() == 0 ? true : false;
        }
    }
}

 

Hello i wonder if you can help me? i am new to c# and cAlgo but i really need to use this bit of code you have put here to help me set groups for my trades that i can change on the fly. How would i go about setting a new property called "Group" for example to the openedPositions list?  i will then be able use it  to sort trades into groups that can be changed and regrouped. The reson i ask this is that the cAlgo Api position label cant be changed so im looking for a way to group trades together and change the groups on the fly when some market action has happend of other reson for changing the group in c# and i will then hold that grouping in memory in this List.

Kind regards


@GammaQuant

whis.gg
23 Jun 2017, 00:49

Hi, could you be more specific? What groups are you talking about?


@whis.gg

GammaQuant
23 Jun 2017, 02:13

RE:

tmc. said:

Hi, could you be more specific? What groups are you talking about?

Hi when i say groups this is just my own groups that i want to use to group some trades. for instance lets say there is a cbot with a unique label but the cbot can have open trades which could have 3 different states that i want the cbot to easily set, track and change depending on how the trading system works. These state can be viewd as groups that ihe cbot can define each trade in and change on the fly. this would just be in the c# code as there is no provision in calgo api to store this on each position.

My question was how can i over ride or  set a property on the openedPositions list that you have detailed above that i will then use to put a new type of label just in c to define a group that each position can be put into. with this i will then be able to return all the postions in a particular group so that i may modify them or change there group name or close them with ease.

Kind regards


@GammaQuant

whis.gg
23 Jun 2017, 11:47

You could write an enum with all three states, then make public class with position and state. Then instead of list of positions you would make a list of your custom class containing positions and state. You could use LINQ queries afterwards.

Do you want to group trades opened by the instance only or across all instances?


@whis.gg

whis.gg
23 Jun 2017, 11:48

Or you could make 3 collections of positions, each representing one state and then move items from one to other.


@whis.gg

GammaQuant
23 Jun 2017, 15:12

RE:

tmc. said:

You could write an enum with all three states, then make public class with position and state. Then instead of list of positions you would make a list of your custom class containing positions and state. You could use LINQ queries afterwards.

Do you want to group trades opened by the instance only or across all instances?

Hi TMC thank you for getting back to me and for detailing the two solutions you have detailed. I think it would be better to use this method i have quoted as a more robust solution. I also think the group needs to work across all instances so this is a singleton. Im very sorry im very new to c#. i literally only started programing it this week. Haveing experiance of php a few years ago as a webdeveloper.


@GammaQuant

GammaQuant
23 Jun 2017, 17:18

Hi i was able to do what i wanted with your second sugestion becasue it quite easy. Thank you very much


@GammaQuant

whis.gg
23 Jun 2017, 17:56

By the instance I meant cBot instance. You could make static collections so they would be shared across all instances. Anyway, let me know if you want me to help you with first solution and I will write you an example.


@whis.gg

GammaQuant
23 Jun 2017, 21:51

RE:

tmc. said:

By the instance I meant cBot instance. You could make static collections so they would be shared across all instances. Anyway, let me know if you want me to help you with first solution and I will write you an example.

Hello TMC, Right sorry about the misunderstanding about the instances. Yes could do me an example of the first solution please also if its not to hard could you do both a sandboxed collection and a shared one. Thank you.


@GammaQuant

whis.gg
29 Jun 2017, 15:15

Hi GammaQuant, sorry for late response I was very busy lately. I have posted the solution on your thread. /forum/cbot-support/11619?page=1#4


@whis.gg