Callbacks for trading events initiated from UI

Created at 17 Mar 2014, 16:20
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!
AlexanderRC's avatar

AlexanderRC

Joined 04.02.2014

Callbacks for trading events initiated from UI
17 Mar 2014, 16:20


Hello.

Are there any hooks that can be used when the trader creates/modifies/closes a position or a pending stop/limit order or when an advanced position protection is modifying the position (trailing stop loss, etc.)?

There are Positions.Opened and Positions.Closed events, but they do not cover all of the possible events which happen with pending orders or opened positions...


@AlexanderRC
Replies

Spotware
17 Mar 2014, 17:35

At the moment you can use only Positions.Opened and Positions.Closed events. You can post your idea to vote.spotware.com.


@Spotware

AimHigher
17 Mar 2014, 18:34

I would vote in favor of this. I definitely need a way to instantly be notified if a pending order (for any symbol) has been created, cancelled or modified and I can't figure out how, without using a timer with a small interval.


@AimHigher

AlexanderRC
17 Mar 2014, 18:35

RE:

Spotware said:

At the moment you can use only Positions.Opened and Positions.Closed events. You can post your idea to vote.spotware.com.

I have posted a new idea at vote.spotware.com. Please vote for Async callbacks for all trading events (requests and responses to the cServer), including from GUI

Currently I am trying to hack around in main AppDomain for these events.


@AlexanderRC

AimHigher
17 Mar 2014, 19:43

RE: RE:

AlexanderRC said:

Spotware said:

At the moment you can use only Positions.Opened and Positions.Closed events. You can post your idea to vote.spotware.com.

I have posted a new idea at vote.spotware.com. Please vote for Async callbacks for all trading events (requests and responses to the cServer), including from GUI

Currently I am trying to hack around in main AppDomain for these events.

I voted for it. However, in the meantime I need something that works reasonably well, with only a small chance of crashing the app. So I would appreciated feedback on where the following code could make the app blow up, assuming of course that OnTick() would be more involved than it is in the code below.

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC)]
     public class SomeRobot : Robot
    {
        private readonly Timer _timer = new Timer();

      //ms used by timer
        private int iTimerIntervalMs = 50;

       protected override void OnStart()
        {
            // Put your initialization logic here
            _timer.Elapsed += OnTimedEvent;
            _timer.Interval = (iTimerIntervalMs);
            _timer.Enabled = true;
            _timer.Start();
           
            }

           protected override void OnTick()
        {
                
            _timer.Stop();

            //Do core logic here            
            int iPosCnt = Positions.Count;
            int iPendCnt = PendingOrders.Count;
            //....

           _timer.Start();
        }

       private void OnTimedEvent(object sender, ElapsedEventArgs e)
        {
         OnTick();
        }
}

 


@AimHigher

AlexanderRC
19 Mar 2014, 12:51

There are no guaranties of internal cAlgo/cTrader code to be reentrant. With the approach of the timer, I would have moved all of the custom code into a separate method. That method should be called from OnTimedEvent(), OnTick() and OnBar(). That method should include some sort of synchronization primitive to guard against simultaneous invocation from OnTick()/OnBar() and from OnTimedEvent().

But even that does not guarantee that you do not go through some non-reentrant internal code paths when executing that method from OnTimedEvent().


@AlexanderRC

Spotware
19 Mar 2014, 14:25

RE:

AlexanderRC said:

There are no guaranties of internal cAlgo/cTrader code to be reentrant. With the approach of the timer, I would have moved all of the custom code into a separate method. That method should be called from OnTimedEvent(), OnTick() and OnBar(). That method should include some sort of synchronization primitive to guard against simultaneous invocation from OnTick()/OnBar() and from OnTimedEvent().

But even that does not guarantee that you do not go through some non-reentrant internal code paths when executing that method from OnTimedEvent().

AlexanderRC is right. Please avoid of using Timer classes.

In future we will introduce cAlgo.API.Timer which will guarantee that only one thread is working with API objects.


@Spotware

AimHigher
19 Mar 2014, 15:19

Thank you Alexander and Spotware for your responses.

To Spotware specifically, while knowing that existing timers should be avoided is great, the problem I have is that the way it looks now, until you either introduce cAlgo.API.Timer or introduce something like RefreshData() so position information can be retrieved inside a loop, cTrader is borderline useless to me.

Knowing that you will introduce something in the future doesn't help much since that could be next week or two years from now, based on previous comments on introduction of new features (Visual Studio integration/debugging anyone?). This also makes it hard to figure out if I should abandon cTrader for now and move to some of my other projects or should I keep it "active" hoping/wishing/praying that you will release a fix in the very near future.

Aim


@AimHigher

Spotware
21 Mar 2014, 17:30

Alexander and AimHigher, thank you for your informative feedbacks.

We have decided to increase priority of RefreshData functionality. Current plan is to implement it after Visual Studio integration will be finished. Stay tuned.


@Spotware

AimHigher
21 Mar 2014, 19:42

RE:

Spotware said:

Alexander and AimHigher, thank you for your informative feedbacks.

We have decided to increase priority of RefreshData functionality. Current plan is to implement it after Visual Studio integration will be finished. Stay tuned.

Thanks for the update and thanks for making RefreshData a high priority.


@AimHigher

AlexanderRC
11 Apr 2014, 21:14

AimHigher, if your requirements allow it, I would do only reading in OnTimedEvent() and then postpone all the work until OnTick() or OnBar() happen. But even that does not bear any guaranties that reading is done on objects in "good" state. Even that reading may lead to a crash.

As another idea, to make OnTick() to be called more frequently I would "subscribe" to all possible Symbols by calling MarketData.GetSymbol() for all possible symbols your broker provides. I am yet to test this approach, though.


@AlexanderRC

AimHigher
13 Apr 2014, 19:56

RE:

Alexander,

I very much appreciate that you are taking the time out to provide me with possible solutions. So far I have been testing out

MarketData.GetMarketDepth(Symbol).Updated += OnTick;

but I never thought about including more symbols so thanks for that suggestion.

As far as doing only reading in OnTimedEvent(), is there a way for a C# layman like me to figure out in advance if a certain procedure would constitute "safe" reading vs something else?

Intuitively I would think that

int iPosCnt = Positions.Count;

would be considered reading since I am not changing or setting anything. However, I don't know what would happen if my timed event is executing this code at the same time as some code in OnTick() would trigger a change to the count e.g. by opening or closing a position.

 What about

File.WriteAllText(PathToFile, StringToWrite); ?

Obviously this is not just reading but since it involves a file separate from anything internal to cAlgo, is it still unsafe?

I am clearly not going to blame anyone but myself if I use a timer and it causes a crash since I have been warned, but I still would like to know the ways that are the least likely to cause cAlgo to crash, so I appreciate the input you have provided.

Regards,

Aim

AlexanderRC said:

AimHigher, if your requirements allow it, I would do only reading in OnTimedEvent() and then postpone all the work until OnTick() or OnBar() happen. But even that does not bear any guaranties that reading is done on objects in "good" state. Even that reading may lead to a crash.

As another idea, to make OnTick() to be called more frequently I would "subscribe" to all possible Symbols by calling MarketData.GetSymbol() for all possible symbols your broker provides. I am yet to test this approach, though.

 


@AimHigher

AlexanderRC
14 Apr 2014, 13:11

RE: RE:

AimHigher said:

int iPosCnt = Positions.Count;

would be considered reading since I am not changing or setting anything. However, I don't know what would happen if my timed event is executing this code at the same time as some code in OnTick() would trigger a change to the count e.g. by opening or closing a position.

That may still be unsafe. Positions is an interface, the actual implementation may crash if Count getter tries to read the positions collection for counting and in another thread that collection is modified when a new position just has been opened. I do not know the underlying implementation and assume the worst. The reality may be much better that Count is actually thread-safe.

What about

File.WriteAllText(PathToFile, StringToWrite); ?

Obviously this is not just reading but since it involves a file separate from anything internal to cAlgo, is it still unsafe?

 WriteAllText() is a thread-safe method. Calling it from different threads should never crash. But I not sure about the written text, it may be garbled. I would guard it by some synchronization primitive.


@AlexanderRC

AimHigher
15 Apr 2014, 15:49

RE: RE: RE:

Alexander,

Thank you for that additional clarification.

Aim

 

AlexanderRC said:

AimHigher said:

int iPosCnt = Positions.Count;

would be considered reading since I am not changing or setting anything. However, I don't know what would happen if my timed event is executing this code at the same time as some code in OnTick() would trigger a change to the count e.g. by opening or closing a position.

That may still be unsafe. Positions is an interface, the actual implementation may crash if Count getter tries to read the positions collection for counting and in another thread that collection is modified when a new position just has been opened. I do not know the underlying implementation and assume the worst. The reality may be much better that Count is actually thread-safe.

What about

File.WriteAllText(PathToFile, StringToWrite); ?

Obviously this is not just reading but since it involves a file separate from anything internal to cAlgo, is it still unsafe?

 WriteAllText() is a thread-safe method. Calling it from different threads should never crash. But I not sure about the written text, it may be garbled. I would guard it by some synchronization primitive.

 


@AimHigher