Postdictive errors

Top  Previous  Next



The discussion thus far has centered around avoiding the unintentional introduction of postdictive errors, and we have shown the classic example, which is buying todays open after referencing todays close or any other price that occurred today, since doing so is an impossibility in the real world...even though Mechanica gives you the flexibility to test that historically.

With any new system, and particularly one whos performance blows the lights out early in the development stage, you should immediately try and disprove its results. One of the first things to search for in this circumstance is the existence of an unintentional postdictive error.



As weve seen, Mechanicas today-centric orientation gives you the flexibility to introduce postdictive errors. Some users take advantage of this flexibility and intentionally invoke postdictive errors to stress-test candidate systems.

For instance, for a long-term trend following system that ordinarily buys on the open today (BUYOPEN / SELLOPEN) based on something that happened yesterday, you could simulate maximum slippage by (instead), buying the days HIGH for all trades taken in the long direction, and selling the days LOW for trades in the short direction.

Keep in mind that such a strenuous test may give misleading results by destroying the profitability. For a shorter-term system that trades, for example, only the e-mini stock indexes (typically very little slippage) a less strenuous stress test may be in order.

Another benefit of allowing such testing is to simulate during-the-day decision making where each new trade is entered with knowledge of those that were previously entered on the same day. Mechanica's include today feature lets you try this. It works in conjunction with Category-related keywords.

Yet another benefit is that you will see some really exceptional results. True, you can't replicate those in actual trading. But seeing the sometimes astonishing simulated results that can be produced could lead one to consider working to create predictive algorithms.  One might, for instance seek to develop an algorithm that is reasonably good at predicting the low of today based on past market action.  Then he could use the (predicted) low as a trade entry or exit price.


Leaking into the SIZ side

The discussion thus far centered around avoiding the unintentional introduction of postdictive errors when your system is being run (Signals side operation).

But let's say you are employing USERDEFINEDRISK to define risk instead of using Mechanica's built-in risk definitionor or you are passing a value to your SIZ code in SIZING[n]. In either case it would be possible to create an untentional postdictive error on the SIG side that later leaks to the SIZ side. This would affect not only Initial Size operations, but Resize operations as well.

Lets look at an example of how to avoid this.


To prevent leakage of (into the SIZ side)

The code shown below, and the discussion that follows, will explain how to correctly pass information from the SIG to the SIZ side, without introducing a postdictive error. This example uses the SIZING[n] variable to carry the risk measure.

SYSTEM = 3        'mandatory system identification

       'miscellaneous code here

COL3 = SMA[CLOSE,34]  'EXIT indic. (long and short)


COL4 = (CLOSE  COL3)        'risk in points

COL5 = ABS[COL4]        'abs. value of risk in points


SIZING[1] = COL5[1] * COL6[1]  'Yesterdays risk (per contract), in dollars


COL4 computes a measure of risk (Close Exit), in points.
In order to eliminate the possibility of negative numbers showing up in our risk measure, COL5 returns the absolute value of COL4.
The SIZING[n] variable is used to pass risk information from the SIG side to the SIZ side, for later use in the Initial Sizing of positions (when the Position Sizing Rules are run).
In order to obtain the risk in dollars, COL5 is multiplied by the point value of the currently processing symbol, and the product is assigned to SIZING[1]. The POINTVALUE keyword returns the dollar value of a 1 point move of a single contract or share. We use [1] here because in the case of foreign denominated markets, that value can change each day and needs to be referenced as of yesterday's exchange rate.
Please note that the SIZING[1] statement references COL5[1], which is the value of COL5 yesterday. Why? Because if the SIZING[1] statementwhich is dependent on COL5s valuewere not offset by one day...then you would be sizing a position for a trade that enters the market today, but does so using todays closing price to calculate risk, which constitutes a postdictive error.
Dont confuse the numbers in the brackets!
nTo reiterate, the [1] notation in COL5[1] is an offset that tells Mechanica to look at the value of COL5 yesterday
nThe “n” in SIZING[n] can assume a value of 1-8, which means that Mechanica allows you to simultaneously use up to eight different SIZING variables. Thus, SIZING[1] simply identifies which of the eight possible SIZING[n] variables is being used, so that Mechanica can keep track of the corresponding value(s).



Anytime you pass values from the SIG side to the SIZ side using either SIZING[n] or USERDEFINEDRISK, make certain that they always reference yesterdays information in the SIG code...just like we did above. The same goes for POINTVALUE if it can return anything other than a simple static value.