Check if Position is closed
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
Replies
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
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
Jiri
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; } } }
@Jiri
Jiri
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; } } }
@Jiri
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
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
Jiri
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?
@Jiri
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
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
Jiri
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
@Jiri
... Deleted by UFO ...