TestData and StratData are specialized variations of the Data section.
To summarize their similarities and differences:
|
Data Section
|
TestData Section
|
StratData Section
|
When is it calculated?
|
before any test starts, for all bars of all stocks
|
during each test, for each stock, at the end of each test date
|
during each test, for each strategy at the end of each test date
|
How is it calculated?
|
optimized for speed using multiple threads, one-pass for many indicators, and only recalculating formulas that changed since last time
|
single-threaded, can't use one-pass, all items recalculated every test, but still quite fast if long-looback indicators are avoided
|
like TestData but with only one column per strategy, so speed is not a concern
|
What can its formulas reference?
|
bar data, Parameters, previously calculated Data items (including itself), or Library items that only reference these things
|
everything that Data formulas can reference, anything that Strategy formulas can reference, and other TestData items (including itself)
|
nothing symbol-specific, just the summary-level stats (S.xxx) of the strategy
|
Cross-sectional (breadth) support?
|
yes
|
yes
|
yes
|
How is it stored?
|
8 bytes per item times number of stocks times number of bars
|
ditto
|
8 bytes per item times number of strategies times number of test periods
|
TestData and StratData formulas are evaluated during a test at the end of processing for each test date (BarSize period).
TestData formulas are evaluated for the current bar of every stock that has a bar for that date, with the value then stored in the TestData item's memory array.
StratData formulas are evaluated for the current day of every strategy being tested (including Benchmarks, StatsGroups and Combined), with the value then stored in the StratData item's memory array.
As with Data items, TestData and StratData items can be referenced by name for the current bar, any past bar (using [n] offset notation) or as parameters to any multi-bar indicator.
TestData and StratData items can also refer to themselves in the same way that Data items can.
As an example of how TestData is useful, consider a strategy like the ndx_rotate.rts example where you want to incorporate a liquidity filter based on current S.Equity (account balance) as the test proceeds (assuming no withdrawals).
This example uses the #rank breadth operator to calculate its posrank variable:
.png)
However, since Data is calculated before the test starts, you can't refer to S.Equity in that formula.
The solution is to move the last two Data items into a TestData section, and add a liquidity calculation:
.png)
Note that in the above example, S.Equity is referenced directly. This works because there's only one strategy in the script.
A key point to remember, however, is that TestData is not strategy-specific. It is similar to TestScan in this regard. References to test stats, position information, etc. each have an implied Combined wrapper, i.e., the above S.Equity is interpreted as Combined(S.Equity).
If this script contained other strategies, and you wanted to use only this strategy's equity value for your liquidity constraint, you would need to change the above to Extern(@ndx_rotate, S.Equity).
Notice that we've also added a count item, to make it easier to see the impact over time of this liquidity constraint.
By temporarily adding a Graphs item that displays count, we can see at a glance what the impact of this liquidity constraint would have been in this model:
.png)
In a $3M+ account, if you applied this constraint, the "Nasdaq 100" would become the "Nasdaq 10" ...
The example above requires TestData because it needs to calculate a rank factor formula for each symbol.
Use StratData when you want to calculate and store values that do not require individual symbol data, and/or when you'd like to be able to apply cross-sectional calculations to your set of strategies and/or benchmarks.
The oex_tf_auto_track.rts example script demonstrates this:
.png)
This part of the script implements the auto-tracker mechanism. The script includes five versions of the same trend-following strategy that each use the above template. The "maxrank" parameter loops from 1 to 5 to test how many of the top-ranked strategies to allow new entries for.
These are the results with maxrank = 2:
.png)
Note that this trades all five strategies, but on any given date will only add new positions in the top two.
To see more detail about how this works, change the Tracker setting to Visible, rerun the script, add a graph to show the rankings, and open it:
.png)
Now we see the five auto-tracker benchmarks and the changes in their rank numbers.
(This also shows how to add your own graphs at the end of the default ones by including the default script first.)
|