Topics
Replies
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
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
AimHigher
31 Mar 2014, 01:08
/api/reference/robot/closeposition-8635
ClosePosition(position, position.Volume);
or to close the entire position without specifying volume
ClosePosition(position);
@AimHigher
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
AimHigher
20 Mar 2014, 02:28
A working example for using named pipes would indeed be great.
@AimHigher
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
AimHigher
18 Mar 2014, 18:03
RE:
Spotware said:
So if using a timer isn't safe, data isn't updated inside a loop and there is no event triggered for pending orders, how do you suggest that one writes code to be instantly notified of changes to pending orders?
You can not implement it in current version of API
I appreciate your reply and hope the necessary changes you are working on will be completed soon. In the meantime, I need solution that "works" i.e. has only a small chance of causing a crash. Could you please take a look at my code sample in the post I linked to below and tell me if that is likely to cause a data corruption/crash?
@AimHigher
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
AimHigher
17 Mar 2014, 18:47
RE:
Spotware said:
System.Timers.Timer uses ThreadPool threads. Please avoid using System.Timers.Timer because while you are accessing cAlgo.API objects from timer's thread, cAlgo could decide to update such objects from another thread. In such case there is a possibility that data will be corrupted and entire application could fail.
We are going to implement cAlgo.API.Timer which will guarantee that only one thread works with API objects per time.
So if using a timer isn't safe, data isn't updated inside a loop and there is no event triggered for pending orders, how do you suggest that one writes code to be instantly notified of changes to pending orders?
Using MarketData.GetMarketDepth(Symbol).Updated is far from instant in a slow moving market.
Based on history, implementing something like cAlgo.API.Timer could take many, many months unless you decided to actually make it a high priority.
@AimHigher
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
AimHigher
17 Mar 2014, 15:55
RE:
Spotware said:
OnTick method is invoked when platform receives new quotes for the corresponding symbol.
Using of System.Threading.Timer class is not recommended, because its callback is invoked in different thread, while cAlgo.API is not thread safe. It could cause crash of application.
If you want to invoke OnTick handler more frequently than ticks come, you can subscribe OnTick handler to MarketDepth.Updated event.
For example:
protected override void OnStart() { MarketData.GetMarketDepth(Symbol).Updated += OnTick; }In this case OnTick handler will be invoked on any update of DOM.
Thank you for showing how me how to trigger a tick e.g. on MarketDepth.Updated.
I am a bit puzzled by you comment regarding using a timer. To be specific, I am using System.Timers.Timer and not System.Threading.Timer and I am following the example from Spotware in this post /forum/cbot-support/357#4
If this is not "safe" to use, would it not be safe either to run a separate cBot that would simply call base.OnTick() at a specified interval? Part of the code would then look something like this:
using System.Timers; //... namespace cAlgo.Robots { [Robot(TimeZone = TimeZones.UTC)] public class RobotWithTimer : RobotWithOnTick { private readonly Timer _timer = new Timer(); protected override void OnStart() { _timer.Elapsed += base.OnTick(); _timer.Interval = (Interval); // Timer will tick every Interval (milliseconds) _timer.Enabled = true; _timer.Start(); } protected override void OnTick() { // Will be empty } protected override void OnStop() { // Put your deinitialization logic here _timer.Stop(); } //...
If this is still not "safe", is there a way to add conditions to make it safer, i.e. reduce the risk of a crash?
Thanks for your help.
Aim
@AimHigher
AimHigher
14 Mar 2014, 22:14
Actually, looking at it a bit further and after playing around with the "other" platforms OnTimer() event, it appears that if all I am looking for is data like positions and pending orders, I can use System.Timers and run my logic inside of a method like the one below
private void OnTimedEvent(object sender, ElapsedEventArgs e)
It appears to be working when i tested it, e.g using Positions.Count and PendingOrders.Count.
By working I mean that Positions.Count would update to reflect a position opening or closing without any tick coming in.
I might be wrong here so I'd appreciate some confirmation.
Aim
@AimHigher
AimHigher
14 Mar 2014, 18:06
First of all, I really want to like your platform, especially since I can't stand how the company behind the "other" platform is forcing things on the users, and being able to code in .NET is a huge plus. However, the more I try to write code for cAlgo, the more roadblocks I find. I can possible understand that market prices are not updated outside of a tick but why on earth is position/order data not updated? That should have been implemented from day 1.
Just to make sure that you answered all parts of my question, is there no way to artificially trigger OnTick() either?
In the other platform, one can use applications like https://fx1.net/mt4ticker.php that will simulate sending ticks to the platform. Is something like that possible in cAlgo?
In the other platform, at least in builds as of last year, ticks could be simulated by using the following code inside a loop e.g. in a script:
int InternalMsg = RegisterWindowMessageA("OtherPlatform_Internal_Message");
int hWnd = WindowHandle(Symbol(),Period());
PostMessageA(hWnd,InternalMsg,2,1);
This would trigger a tick on the chart the script was attached to (obviously requiring reference to user32.dll).
Since an application like mt4ticker does not, to my knowledge, exist for cAlgo, could you share with us what triggers a tick in cAlgo? That way, a simulated tick could be created either by
a separate robot or by a separate application, while we wait for a RefreshData() feature to be available.
Regards,
Aim
@AimHigher
AimHigher
11 Mar 2014, 20:14
Added a follow up question here /forum/cbot-support/1739?page=2#13
@AimHigher
AimHigher
10 Mar 2014, 18:53
I am having the same problem as Hyperloop and since I am also new to C#, setting the correct references and objects is still hit or miss for me. As I believe Hyperloop was trying to do, I am trying to create a dll to hold methods that I will use in different robots. I have created other dlls that are working fine but I am struggling with using cAlgo,API in my custom dll.
I am working in VS 2010. I have added cAlgo.API in References (for this project) so I get IntelliSense and I can view it fine through the Object Browser. I also have no problem using VS2010 to write cBots in general. That part is working great. It is creating a custom dll that uses cAlgo.API dll that has me stomped.
The code I have so far for my custom dll is this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using cAlgo.API; namespace cAlgoGeneralMethods { public class General { private int GetPosCnt() { int iPosCnt; iPosCnt = Positions.Count; return iPosCnt; } } }
As anyone who knows C# (I don't) the line
iPosCnt = Positions.Count; will not work and I would get the same error as Hyperloop got.
I have looked at the responses that Hyperloop got but I have not found a specific example of how to get it to work. I would very much appreciate a quick sample of what I need to add to get cAlgo.API objects/methods recognized in my custom dll.
Regards,
Aim
@AimHigher
AimHigher
04 Mar 2014, 19:51
RE: RE: RE:
AimHigher said:
Forex19 said:
Spotware said:
Probably you do not filter positions by the label somewhere in your code.
As I said he made several tests to filter the label in the various parts of the code.
But I think there is another problem because the two cbots (as I have shown in the screenshot) are two different locations with the right label.
The problem is in TP, which is not assigned.
Do you have any suggestions on how and where to change the code?Thanks
You have defined Point using Symbol.TickSize while the API Guide uses Symbol.PipSize to set a stop loss price when the stop loss is specified as a number of pips, which your trailing stop is. However, I am very new to cAlgo so I don't know if that solves it.
Nevermind. When I tested it, Symbol.Bid - 50 * Symbol.TickSize still appears to generate a valid price so I don't think that is it.
@AimHigher
AimHigher
04 Mar 2014, 19:35
RE: RE:
Forex19 said:
Spotware said:
Probably you do not filter positions by the label somewhere in your code.
As I said he made several tests to filter the label in the various parts of the code.
But I think there is another problem because the two cbots (as I have shown in the screenshot) are two different locations with the right label.
The problem is in TP, which is not assigned.
Do you have any suggestions on how and where to change the code?Thanks
You have defined Point using Symbol.TickSize while the API Guide uses Symbol.PipSize to set a stop loss price when the stop loss is specified as a number of pips, which your trailing stop is. However, I am very new to cAlgo so I don't know if that solves it.
@AimHigher
AimHigher
24 Feb 2014, 01:06
RE:
Spotware said:
To check current time you can use Server.Time:
if (Server.Time.Year == 2013 && Server.Time.Month == 10 && ...)For placing orders you can use PlaceLimitOrder or PlaceStopOrder functions.
I think the question is if you can backtest a set of trades with entry and exit times and entry and exit prices that are already determined regardless of whether those prices match the prices in the price history in cAlgo. Personally i think that kind of analysis is preferable to set up in Excel, assuming that you have a list of trades e.g in a csv file.
@AimHigher
AimHigher
27 Feb 2015, 23:26
Thank you. The new Timer and RefreshData() have increased the value (to me) of your platform tremendously.
Regards,
Aim
@AimHigher