Pane and Window Execution order

Few users pay attention to the order in which tasks performed in the various Amibroker panes and Windows are executed. The order of pane-executions can have a major impact on the performance of a fast, Real-Time trading system. It is easy to assume that the pane-formulas execute top down, but they don’t. In fact, the order of execution is unpredictable and should, for all practical purposes, be considered Random by the user.

For example, when using Static or Persistent Variables, if you initialize a StaticVariable in the top pane for use in the lower pane, you want the top pane to execute first so that the newly assigned value can be used immediately, i.e., during the same refresh in the lower pane and not at the next Chart Refresh, which may happen a second or more later.

Now consider that the lower pane executes first. In this case, it would require waiting either until the next quote or, if you use the function RequestTimedRefresh(1), the next second (whichever comes first). In this case, the Static Variable would contain a value from the previous Refresh, which means the value of the Static Variable would lag by one Chart refresh. If the formula in the lower pane is placing orders with LMT prices based on the last quote (the one that triggered the refresh) and since the LMT price was calculated in the top pane during the previous Refresh, the LMT price used would be based on the previous and not the last quote. In most cases, this would decrease your probability of a LMT fill.

An obvious solution is both to append your ordering code to the code that initializes your Static variable and to execute in the same pane. However, this may be difficult to do if your formulas are long, or if each formula generates charts with different scales and/or incompatible Titles. Even so, if you decide to solve the problem this way, you should consider using #include files.

Another solution is to force a RefreshALL at the end of your initializing formula. This will refresh all panes without delay, but now some panes may be executed more than once for each Chart Refresh. You will have to decide if this is significant in your system. The following two lines can be appended to your code and will force a RefreshAll. Be aware that the minimum RefreshAll interval is one second, so if your quotes arrive faster, this may not work very well.

oAB = CreateObject("Broker.Application");
oAB.RefreshAll();

If order of execution is critical, you can make the RefreshAll() conditional on the count of a pane-counter and only force a RefreshAll if the pane execution order demands it. To find the pane execution order, you can add a pane execution counter to all pane formulas and log the count to DebugView. If the count is lower in, say, the upper pane compared to the lower, that means it was executed in the upper pane earlier. If the count is greater, it was executed later than the lower pane.

To be able to identify the formula being executed in your log, place the formula name at the very top of your formula:

Filename = StrLeft(_DEFAULT_NAME(),StrLen(_DEFAULT_NAME())-2);

To add the counter you append the following code to the very end of your formula:

PaneCounter = Nz(StaticVarGet("PaneCounter"));
StaticVarSet("PaneCounter",PaneCounter+1);
CounterDisplayLine = Filename +", ChartID: "+GetChartID()+", PaneCounter: "+NumToStr( PaneCounter,1.0,False);
_TRACE( "# "+CounterDisplayLine );

This will show the order and time of execution, in seconds, in the DebugView window:

snag-0770.jpg

You can study/analyze pane execution order without disturbing your code by Inserting the 4-line code below multiple times in the same window, thus creating multiple panes. Then change the order of panes using the small arrows in the menu that pops up when you hover your mouse pointer over the top right corner of the pane. In this example the pane order is shown in the Chart Title.

Filename = StrLeft(_DEFAULT_NAME(),StrLen(_DEFAULT_NAME())-2);
PaneCounter = Nz(StaticVarGet("PaneCounter"));
StaticVarSet("PaneCounter",PaneCounter+1);
Title = Filename +", PaneCounter: "+NumToStr( PaneCounter,1.0,False);

snag-0771.jpg

The above capture shows that the execution order is not top down. You may observe that, in your case, the execution order tracks the ChartID. This is because the panes were inserted in sequence one after another, but this would not normally be the case.

While this topic may not be important to everyone, it will become critical when you start tinkering with High-Frequency trading systems.

Edited by Al Venosa

Comments are closed.