The Array User Variable (ARRAY) technical indicator will be instrumental in accomplishing an overall stop loss on a system which tests a basket/quotepage of stocks. In our example, we'll assume that our system is an intraday system running on a given quotepage of stocks, and when the overall system gets down a certain dollar amount, we want to get out of all positions and not re-enter until the next day. Otherwise, the process should be system-independent.
We'll call our generic system "XYZ", and create a maintenance rule/signal that will be the first rule/signal in the system and give the signal a name of XYZ_Main. This signal should be setup with Action: NONE. This rule will have no effect on the overall system other than to manage the setting of our historical ARRAY. The XYZ_Main signal will have the following syntax:
IF(BT_BAR = 1) THEN (SET(V#3, BT_NET));
SET(ARRAY, ARRAY + (BT_NET - V#3));
SET(V#3, BT_NET);
The ARRAY indicator should be setup with preference similar to those below.
I would recommend replacing XYZ with a three letter code that identifies your system (here and wherever you see XYZ throughout this tutorial). I started the ticker symbol, !XYZ, with an exclamation point just to make sure it was unique (and not an actual stocks ticker symbol).
Now, taking a closer look at the signal syntax again:
IF(BT_BAR = 1) THEN (SET(V#3, BT_NET));
SET(ARRAY, ARRAY + (BT_NET - V#3));
SET(V#3, BT_NET);
The first and third lines of the signal both are there to manage V#3, which will keep a record of the net profit as of the last bar. Our goal is to have ARRAY accumulate the P&L on each bar. Since V#3 records the cumulative profit as of that bar, BT_NET - V#3 will give us the P&L contributed by the symbol being tested on the bar being tested. (BT_NET provides the overall P&L of the system as of each bar tested.) These values will be accumulated in the ARRAY historical ticker symbol, !XYZ.
When the backtest is run, we should be able to open a chart of !XYZ (using the same periodicity and viewing period as that of the backtest), and the open, high, low, and closing prices of the !XYZ symbol should be set to the P&L of the overall symbol for each bar. Let's assume we're looking at 10-minute data. A closing price of 130.50 would signify that our overall system gained $130.50 during that 10-minute bar/period.
You only need to run the backtest once to set the array. After you've run it once, you should either comment out the array SET statement or just delete the rule from the system entirely (easy enough to add back in later when needed).
Now, I would recommend creating a second trading system. This system will be very simple, with one rule setup with Action: NONE. The system should be setup to run over the exact same period and same periodicity as the original XYZ system. We'll call this second system XYZ_Set_Arrays. This system will be setup to run on only one symbol, that symbol being the !XYZ symbol that we've already created when we last ran our XYZ system. The rule will use a signal with the following syntax:
SET(ARRAY_PL, SESST_PL) AND SET(ARRAY_MAE, SESST_MAE) AND SET(ARRAY_MFE, SESST_MFE)
This rule is designed to create three new ticker symbol via the ARRAY indicator. Each will be setup identically to the ARRAY window seen above, except ARRAY_PL will be setup with ticker "!XYZPL", ARRAY_MAE will be setup with ticker "!XYZMAE", and ARRAY_MFE will be setup with ticker "!XYZMFE". SESST_PL will be setup with "Sum of Price: Close: First 999 Bars". SESST_MAE will be setup with "Lowest Price: Close: First 999 Bars". SESST_MFE will be setup with "Highest Price: Close: First 999 Bars".
After this system is run (run it only once), you'll have 4 "ARRAY-generate" ticker symbols. You can add all 4 to a chart that's built using the same periodicity and viewing period as the backtest did. !XYZ should give you the P&L of each individual bar. !XYZPL should give you the cumulative P&L for each day as of each bar. !XYZMAE should give you the maximum adverse excursion for the day as of each bar. !XYZMFE should give you the maximum favorable excursion.
Now, you're free to use the ARRAY token, referencing !XYZMAE, in order to create a stoploss on the overall system. The rule would simple be something to the effect:
ARRAY
for an overall stoploss of $1,000. Similarly, an ARRAY setup with !XYZMFE ticker could be use to create an overall target condition:
ARRAY >= 2000
for an overall target of $2,000.
It's important that before trying to rebuild these ARRAYs, you should either delete all the (array-generated) ticker symbols, delete all the data for all the ticker symbols, or run a system that initializes all the ticker symbols to zero with:
SET(ARRAY, 0) AND SET(ARRAY_PL, 0) AND SET(ARRAY_MFE, 0) AND SET(ARRAY_MAE, 0)
with the system setup to run over the same period and periodicity originally tested.
Combining global arrays with backtesting really opens up a lot of possibilities, with this tutorial only scratching the surface.