TradeManager.TradingData.Orders... callbacks not firing

Questions about MultiCharts .NET and user contributed studies.
mt99
Posts: 18
Joined: 24 Mar 2014
Has thanked: 1 time
Been thanked: 1 time

TradeManager.TradingData.Orders... callbacks not firing

Postby mt99 » 27 Aug 2014

Hi,

I'm using MultiCharts .NET64 Version 8.8 Release (Build 9191), and am trying to have a callback fire in my study when I place an order in the DOM. The study is attached to the same instrument as I am placing the order in, although I would like it to fire regardless of what instrument the order is placed in. Just whenever the order set changes.

Following is the code, as bare as I can possibly make it. Compile it, attach it to the chart of instrument X, place an order in the instrument X through the DOM. Nothing is printed in the Output window.

What am I doing wrong?

Bonus question: once the callback issue is sorted, can you tell me how to make the study recalculate immediately?

Thank you.

Code: Select all

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using ATCenterProxy.interop;

namespace PowerLanguage.Strategy
{
[IOGMode(IOGMode.Enabled)]
public class MT_FinishChangingTest : SignalObject
{
public MT_FinishChangingTest(object _ctx):base(_ctx){}

protected override void Create()
{
}

protected override void StartCalc()
{
TradeManager.TradingData.Orders.Added += this.Orders_Added;
TradeManager.TradingData.Orders.Changed += this.Orders_Changed;
TradeManager.TradingData.Orders.Deleted += this.Orders_Deleted;
TradeManager.TradingData.Orders.FinishChanging += this.Orders_FinishChanging;
}

protected override void CalcBar()
{
Output.WriteLine( DateTime.UtcNow.ToString(" yyyy-MM-dd HH:mm:ss.fff" ) + " CalcBar()" );
}

private void Orders_FinishChanging( object sender, EventArgs e )
{
Output.WriteLine( DateTime.UtcNow.ToString(" yyyy-MM-dd HH:mm:ss.fff" ) + " Orders_FinishChanging()" );
}

private void Orders_Added( TradeManager.Order[] items )
{
Output.WriteLine( DateTime.UtcNow.ToString(" yyyy-MM-dd HH:mm:ss.fff" ) + " Orders_Added()" );
}

private void Orders_Changed( TradeManager.Order[] items )
{
Output.WriteLine( DateTime.UtcNow.ToString(" yyyy-MM-dd HH:mm:ss.fff" ) + " Orders_Changed()" );
}

private void Orders_Deleted( TradeManager.Order[] items )
{
Output.WriteLine( DateTime.UtcNow.ToString(" yyyy-MM-dd HH:mm:ss.fff" ) + " Orders_Deleted()" );
}
}
}

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby Henry MultiСharts » 27 Aug 2014

Hello mt99,

In order to receive updates you need to call TradeManager.ProcessEvents();
Bonus question: once the callback issue is sorted, can you tell me how to make the study recalculate immediately?
Please see ICalculationControl.RecalcLastBarAfter Method

mt99
Posts: 18
Joined: 24 Mar 2014
Has thanked: 1 time
Been thanked: 1 time

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby mt99 » 27 Aug 2014

Thanks for the quick reply. Can I ask you to clarify it a bit please?
In order to receive updates you need to call TradeManager.ProcessEvents();
Where do I call it from, CalcBar()? Do I call it just once to register for the events or do I need to call it every time to process the event queue?
Please see ICalculationControl.RecalcLastBarAfter Method
As the name suggests, this method schedules a recalculation, but does not trigger it immediately. I want to recalculate immediately on the event of the order set change. If RecalcLastBarAfter() is the only way of getting a study to recalculate, is there an acceptable workaround, such as maybe:

Code: Select all

ExecControl.RecalcLastBarAfter( TimeSpan.FromMilliseconds( 1 ) );
Is there not a chicken-and-egg problem here: if CalcBar() is the method that must be called to process the events, how can I make the event callback call CalcBar()?

mt99
Posts: 18
Joined: 24 Mar 2014
Has thanked: 1 time
Been thanked: 1 time

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby mt99 » 28 Aug 2014

I have tried the approach of adding the following three lines to CalcBar()...

Code: Select all

protected override void CalcBar()
{
Output.WriteLine( DateTime.UtcNow.ToString(" yyyy-MM-dd HH:mm:ss.fff" ) + " CalcBar()" );
TradeManager.ProcessEvents();
ExecControl.RecalcLastBarAfter( TimeSpan.FromMilliseconds( 1 ) );
}
...in order to see how often the recalculation took place. While it does indeed now call the callbacks when ProcessEvents() is called, the frequency of recalculation, and hence the speed with which the callbacks are called after the event, is disappoingly slow:
...
2014-08-28 08:09:05.797 CalcBar()
2014-08-28 08:09:05.897 CalcBar()
2014-08-28 08:09:05.998 CalcBar()
2014-08-28 08:09:06.097 CalcBar()
2014-08-28 08:09:06.197 CalcBar()
2014-08-28 08:09:06.297 CalcBar()
2014-08-28 08:09:06.397 CalcBar()
2014-08-28 08:09:06.497 CalcBar()
2014-08-28 08:09:06.597 CalcBar()
...
Is there a way to get CalcBar() to run more often than every 0.1s?

Or (this would be the proper solution), is it possible to run the event callbacks when the events actually occur?

Thank you.

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby Henry MultiСharts » 28 Aug 2014

ProcessEvents should be called in CalcBar on each calculation, as often as you need it. The more often it is called - the faster you know about order status updates. At the moment this is the only solution.

We understand these limitations and are going to introduce the new backtesting/auto trading engine that will provide more order control to the user in the next major platform update:
https://www.multicharts.com/pm/viewissu ... no=MC-1497

Next study calculation is performed after the previous calculation is finished. The time it takes to calculate the study depends on the script and PC.

mt99
Posts: 18
Joined: 24 Mar 2014
Has thanked: 1 time
Been thanked: 1 time

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby mt99 » 28 Aug 2014

Thanks for the reply once again.
Next study calculation is performed after the previous calculation is finished. The time it takes to calculate the study depends on the script and PC.
The one thing that sticks out is that it does not take a PC 0.1s to perform a one line printout, and that's all there is in my test script (see above).

Please take a closer look at the times printed out. They are all 0.1 seconds apart, where as the next recalc is, in theory, scheduled 0.001 seconds into the future. Why does it only recalculate every 0.1s?

Thank you.

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby Henry MultiСharts » 29 Aug 2014

mt99, execution speed/performance can be limited due to the code logic. Debug/Release compilation types can also affect that. This is the nature of C#. Please study the related information available in the Internet, especially regarding "ToString".

mt99
Posts: 18
Joined: 24 Mar 2014
Has thanked: 1 time
Been thanked: 1 time

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby mt99 » 29 Aug 2014

Hi,

I don't really know how to say this any other way, but C#, regardless of its nature, does not take a tenth of a second to print out a string with a DateTime.ToString() call. That is all my example does. If you print the same string in a while ( true ) {} loop, you'll see that it takes under a thousandth of a second to print it, on any machine.

Can you please ask the developers where the 0.1s limitation comes in and why it is there? It is not an unreasonable expectation to want to recalculate the study (if only to process the events!) a lot more often than every 0.1s.

At the very least there should be some sort of warning or an exception thrown if I am asking the study to be recalculated "too often". At the moment, I ask MC to recalc in 0.001s and it recals in 0.1s, which is deceptive. Scheduling recalculation for periods longer than 0.1s does indeed result in the correct recalculation time. Why is 0.1s such a hard limit?

User avatar
JoshM
Posts: 2195
Joined: 20 May 2011
Location: The Netherlands
Has thanked: 1544 times
Been thanked: 1565 times
Contact:

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby JoshM » 30 Aug 2014

Next study calculation is performed after the previous calculation is finished. The time it takes to calculate the study depends on the script and PC.
The one thing that sticks out is that it does not take a PC 0.1s to perform a one line printout, and that's all there is in my test script (see above).

Please take a closer look at the times printed out. They are all 0.1 seconds apart, where as the next recalc is, in theory, scheduled 0.001 seconds into the future. Why does it only recalculate every 0.1s?
For what it's worth, my PC with a script that does not call `TradeManager` and during the weekend (so no incoming ticks to process) has the same 0.1 second time gap:

Code: Select all

11:21:20.348
11:21:20.444
11:21:20.545
11:21:20.644
11:21:20.746
11:21:20.844
11:21:20.944
11:21:21.044
11:21:21.144
11:21:21.244
11:21:21.344
11:21:21.444
11:21:21.544
11:21:21.644
11:21:21.745
11:21:21.844
11:21:21.944
11:21:22.049
11:21:22.144
11:21:22.245
11:21:22.344
11:21:22.444
11:21:22.544
11:21:22.645
11:21:22.746
11:21:22.844
11:21:22.944

Code: Select all

using System;
using System.Drawing;
using System.Linq;
using PowerLanguage.Function;
using System.Collections.Generic;

namespace PowerLanguage.Indicator
{
public class Test_Indicator : IndicatorObject
{
public Test_Indicator(object _ctx) : base(_ctx) { }

protected override void CalcBar()
{
if (Bars.LastBarOnChart)
{
ExecControl.RecalcLastBarAfter(
new TimeSpan(0, 0, 0, 0, 1));

Output.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff"));
}
}

protected override void OnRecalcLastBarAfterEvent()
{
this.CalcBar();
}
}
}
So this does not seem to be related to the PC or how busy MultiCharts .NET is: it seems more like a software limitation.
We understand these limitations and are going to introduce the new backtesting/auto trading engine that will provide more order control to the user in the next major platform update:
https://www.multicharts.com/pm/viewissu ... no=MC-1497
Can I read that statement as saying that MC .NET 9.1 will have code that uses events much more frequently than the current version?

If so, that would be great news. If not, when can we expect more event-based processing?
At the very least there should be some sort of warning or an exception thrown if I am asking the study to be recalculated "too often". At the moment, I ask MC to recalc in 0.001s and it recals in 0.1s, which is deceptive. Scheduling recalculation for periods longer than 0.1s does indeed result in the correct recalculation time. Why is 0.1s such a hard limit?
Is this possible Henry? The manual (p 19) says: "In the calculation process various .NET exceptions can be generated. It can be easily seen during debugging. You should not intercept any exceptions other than yours, as many mechanisms, for example, BarsBack auto detect, are realized through the generation and further processing of a specific exception."

But ironically I could not detect any exception when a script is recalculated with `OnRecalcLastBarAfterEvent()`. Is that correct?

User avatar
Henry MultiСharts
Posts: 9165
Joined: 25 Aug 2011
Has thanked: 1264 times
Been thanked: 2957 times

Re: TradeManager.TradingData.Orders... callbacks not firing

Postby Henry MultiСharts » 03 Sep 2014

Can you please ask the developers where the 0.1s limitation comes in and why it is there? It is not an unreasonable expectation to want to recalculate the study (if only to process the events!) a lot more often than every 0.1s.
For what it's worth, my PC with a script that does not call `TradeManager` and during the weekend (so no incoming ticks to process) has the same 0.1 second time gap: So this does not seem to be related to the PC or how busy MultiCharts .NET is: it seems more like a software limitation.
I have consulted with our developers and I apologize for misinformation. It is indeed an intended application limitation that was linked to it's x86 origin.
At the very least there should be some sort of warning or an exception thrown if I am asking the study to be recalculated "too often". At the moment, I ask MC to recalc in 0.001s and it recals in 0.1s, which is deceptive. Scheduling recalculation for periods longer than 0.1s does indeed result in the correct recalculation time. Why is 0.1s such a hard limit?
Is this possible Henry? The manual (p 19) says: "In the calculation process various .NET exceptions can be generated. It can be easily seen during debugging. You should not intercept any exceptions other than yours, as many mechanisms, for example, BarsBack auto detect, are realized through the generation and further processing of a specific exception."
But ironically I could not detect any exception when a script is recalculated with `OnRecalcLastBarAfterEvent()`. Is that correct?
There is no warning or exception notification regarding this limitation. We will update the documentation to cover that. In MultiCharts 9.1 we will also add a registry key for changing the predefined RecalcLastBarAfter timer value to a desired user value.
We understand these limitations and are going to introduce the new backtesting/auto trading engine that will provide more order control to the user in the next major platform update
Can I read that statement as saying that MC .NET 9.1 will have code that uses events much more frequently than the current version? If so, that would be great news. If not, when can we expect more event-based processing?
That is correct. The new engine will introduce more event based order processing.


Return to “MultiCharts .NET”