This page reviews the 3 main settings (Quantity, Price, Action) associated with a Trading Rule used in a Trading System. The use of SHOW statements and NOTE tokens as diagnostic tools is highlighted. A full list of RTL "backtesting" tokens, with a focus on the "Context" Token (CTX), is also presented.
1) Trading "Rule Quantity"
The rule quantity represents either the number of shares or contracts to be bought or sold when entering positions or adding to positions, or a given dollar amount.
In the second case, the total number of shares or contracts purchased or sold will be automatically calculated according to the specified dollar amount. For stocks, the number of shares purchased or sold will be rounded to the nearest multiple of a "block" of shares that does not exceed the specified dollar amount. The size of a block of shares (ie 1, 10, 100 shares etc) is defined in the backtest setup window. If the dollar amount specified is insufficient to buy or sell a single block of shares of the particular stock, no action will be taken.
The rule quantity popup menu includes "All" as the first choice in the list. When an exit rule specifies "All" as the rule quantity and the rule is triggered, the remainder of the position will be closed out regardless of whether the position size is expressed in dollars or shares/contracts and regardless of whether the position size is the entire position opened or some remainder due to partial closing rules triggered earlier. Note that "All" can be used as well to open a new position. The position size in this case will be obtained from the backtest setup maximum position size specified by the user in the backtest setup window.
Finally, V# Variable can be used as a Rule Quantity. In this case, the corresponding V# value is ttypically adjusted according to a SET statement inside Trading Rule. This way, multiple position sizing strategies can be implemented, as the corresponding information about the position cost, the ongoing trade P&L, etc can be accessed through dedicated backtesting tokens (see below).
2) Trading "Rule Price"
The pop list includes multiple Historical Token options (ie CL, OP, etc) together with the STOP and TARGET tokens, and V# Variables that can be controlled by SET statement inside the Rules of the Trading systems. What this means is that trading rules can set the value one or more V# variables and a particular V# variable can be used as the rule price to enter or exit a position. When a V# variable is used as an entry or exit price is a rule, InvestorRT will check to see if the value of the V#1 is between the high and low extremes for the particular bar when the rule is being tested. If so the V#1 variable will be used "as is". If the V# variable is higher than the high of the bar, then the high price of the bar will be used in place of the V# variable. Similarly, if the V# variable is lower than the low of the bar, the low will be used to enter or exit the position. This behaviour can be deactivated with the checkbox "Allow Entry/Exit Prices outside range of bar" in the trading system setup window.
Next Bar option
Finally, a check box is available to the right of the "Rule Price" to enable the user to specify that the price to be used should be taken from the "Next Bar" rather than the bar where the signal occurred. For example, when doing a backtest on daily data, the rule for entering a new position can now specify "Next Bar" and Open, so that the entry price will be the open price of the next day. This enables trading signals to be formulated from the perspective of the current bar and the rule price to be taken from the open, high, low, or close of the next bar AFTER the signal triggers.
Note that "Next Bar" can also be used with (Hi+Lo)/2 or other calculated prices in the menu. However, "Next Bar" cannot be used with Stop Price or for V# variables.
3) Trading "Rule Actions"
BUY / SELLSHORT vs SELL / COVERSHORT rules
Buy and Sell Short rules are dedicated to initiate new position when the Trading system is flat. On the opposite, SELL and COVERSHORT rules to sell or cover all or a portion of the position. The POS_SIZE token can be useful in coding signals that consider the size of the position currently held. Use the QTY "All" when the trading rule is designed to exit the market. If a fixed quantity of a SELL or COVERSHORT rule exceeds the position size, the entire position is closed.
BUYSTOP / SELLSTOP rules
Investor/RT only tests BUYSTOP rules when the trading system is short. Similarly, SELLSTOP rules sell to exit a long position if the market falls below some level after you open the position.
If you click on BUYSTOP in the list of actions, the description appears "Buy to Exit Short Position". This rule action is normally used as a stop loss rule to buy (cover) the short position if the market rises against you above some level. For example, you can have a BUYSTOP rule with the signal formula CL > ENTRY * 1.05; This would exit the short position if the price of the stock rose more than 5% higher than the price at which you shorted.
Investor/RT tests each trading rule from top to bottom for each bar, skipping over those rules that do not apply.
Thus BUYSTOP rules are skipped when the backtest is either out of the market or when the system is in a long position. SELLSTOP rules are skipped unless the backtest is in a long position. BUY and SELLSHORT rules are tested only when the trading system is out of the market.
The order of rules is important. If you are testing a long system and you put your SELLSTOP stop loss rule after your BUY rule, as soon as you go long, the SELLSTOP rule will be tested on the same bar at which you entered the long position. Putting the SELLSTOP rule above the BUY rule means that the SELLSTOP rule will be ignored until the bar after the system goes long.
An important trading system design criteria, that will influence the order of trading rule within the list (and which is pretty common to the majority of backtesting software), is that only one single buy or sell trading rule action can take place for a given bar. This means that you should typically design your system to avoid such situations, when possible. Let's assume you are running a system on a one-minute periodicity and that both STOP and profit TARGET rules are being hit on the same (wide range) bar. As you don't know (with such a data granularity) which one will be hit first, it is then a common practice to put the Stop action ahead of the Profit taking action within the trading rule list.
Using the STOP Token and V# Variables
You can use V# variables to keep track of either a fixed or dynamic stop loss level, or you can use the built-in variable named STOP to implement trailing stops. The value of STOP can be SET just like a V# variable, however, when a SET statement sets STOP, IRT will not set a value into this variable unless the value is higher than before (when you are long). In other words, when you are long, SET(STOP, ...) statements cannot lower the stop only raise it. The reverse is true when the system is short, namely, the STOP can only be lowered by a SET statement. STOP is always zero when you first enter a new position. Include a rule like SET(STOP, CL * .95) to set the stop 5% below the current price (long case). If the market goes up the STOP will keep increasing but once lower closes begin to happen, the stop will not be lowered and eventually, a SELLSTOP rule with the formula CL <= STOP will trigger the stop loss exit if the price ever fall below 5% of any higher closed reached during the trade.
BUYMORE / SELLMORE rules
BUY rules can only initiate a new long position. BUYMORE rules are tested only when the backtest is already long. If true, a BUYMORE rule can add to the position, subject to the limitation on position size specified in the backtest setup page.SELLSHORT rules initiate short positions. SELLMORE rules can add to the short position (sell short more). We designed the BUY/BUYMORE and SELLSHORT/SELLMORE actions to make it easier to design trading systems and add to the long or short position once the initial position is established. Once the system is long, BUY rules are skipped, but BUYMORE rules are tested. Similar, once you are short, SELLSHORT rules are skipped but SELLMORE rules, if present, are tested.
CONFIRM Rules
CONFIRM rules are special. If a CONFIRM rules signals true, the rule following the CONFIRM rules is tested to confirm the signal and the action of that next rule determines what is done. You can have a series of CONFIRM rules leading up to a BUY or SELL action or whatever. When a CONFIRM rule tests false, the next rule is skipped altogether. If you have a series of CONFIRM rules and anywhere down the line one of them signals FALSE, the whole series of remaining CONFIRM rules is skipped, including the final rule beneath the last CONFIRM rule in the sequence, and rule testing continues. Once all of the rules in the backtest have been tested for the bar, the system moves on to the next bar and rule testing begins again at the top of the rule list.
NONE and TEST Rules
A "NONE" action (no action) rule is a rule whose signal is evaluated for each bar during the backtest, but no action is taken. Such rules typically will be used for housekeeping work such as setting stops, displaying values using the SHOW token, or setting V# variables. Note that the signal associated with a NONE action may take into account the state of the backtest (long, short, out of market). For example, if you wanted to set a STOP if you are long but not when short, then the signal might be something like:
IF (POS_STATE = POS_LONG) THEN SET(STOP, ENTRY - 3)
or
IF (POS_STATE = POS_LONG) THEN (SET(V#1, expression1) AND SET(V#2, expression2))
A TEST rule is very similar to a NONE rule in that no action is taken after the signal is evaluated. TEST rules will often be used for SHOW statements and other diagnostic work. TEST rules will be ignored during the backtest unless the user has designated to run the backtest in "TEST Mode". This is accomplished in the Backtest Setup dialog. Once a trading system is debugged and working properly, the TEST rules can be turned off by unchecking the "TEST Mode" checkbox. This way, SHOW statements and other diagnostic calculations you may have put into your trading system during the development phase can be isolated from the actual trading signals themselves. The diagnostic output produced by the SHOW statements can then be turned on or off at will by checking a single checkbox, without having the edit the text of any rules.
4) SHOW statements and NOTE token inside Trading Rules
TEST and NONE no action rules will often contain SHOW statements used to display the numeric value of any technical indicators or market data items as the backtest proceeds from bar to bar. For example, the signal:
SHOW(OP) and SHOW(HI) and SHOW(LO) and SHOW(CL)
Would produce four lines of diagnostic output for each bar tested during the backtest. To enable more powerful diagnostic messaging during backtesting, the Annotation indicator (from InvestorRT charting system) has been added to the RTL language. The token is NOTE. The NOTE token is simply a way to output instrument specific values to the backtesting detail report. Typically, the NOTE token ( considered a "logical" token not an arithmetic one) could be added to an existing rule's signal, e.g.
NOTE and MACD.1 < 0 and MACD > 0
Or, the NOTE can be isolated into a NONE or TEST rule as simply:
NOTE = TRUE
The NOTE token always evaluated as TRUE. The NOTE token, like any other technical token can be qualified, e.g. a TEST rule may look like:
NOTE.1 and NOTE.2 and NOTE.0
The NOTE can be setup as a string of text plus instrument specific RTL tokens preceded by the % percent sign. For example, the NOTE text of:
%TICKER at %CL, HI=%HI LO=%LO displays messages like the following in the backtesting detail report:
IBM at 104.50, HI=105.75 LO=104.00
When you qualify a NOTE, e.g. NOTE.1, the values displayed will be for the preceding bar. This applies to historical tokens like %OP, %HI, %LO, %CL, %VO, %OI. It does not apply to V# variables. A NOTE text that contains "%V#1" for example will display the current value of V#1 for the instrument regardless of the qualifier.
"Conditional" NOTE Tokens (Please review the RTL conditional operator documentation for more information)
In a Signal employed in a trading system, it is sometimes desirable to include NOTE tokens in the signal formula to output textual data to the backtest detail report. Sometimes, different NOTE annotations are needed under different conditions. A conditional expression such as:
(POS_STATE = 0 ? NOTE_A : NOTE_B)
references two NOTE tokens with differing setups. When the trading system is out of the market (POS_STATE is zero) the NOTE_A annotation text will be output; NOTE_B will be output when the trading system is either long or short. Since a signal must be a true false expression, and since the conditional expression above is considered a numeric expression, you can append this expression to other signal criteria like this:
... AND (POS_STATE = 1 ? NOTE_A : NOTE_B) > 0
using AND to append it and adding the > 0 to make the appended expression a true false expression.
Using SHOW and NOTE tokens inside signals that are used to form TEST or NONE action rules provides the user with a powerful diagnostic capability to see step-by-step for each bar why the trading system is performing the way it is.
5) Backtesting Tokens
RTL language includes several tokens dedicated to backtesting and for use in composing trading signals. Using these tokens in the trading signals within a trading system allows the user to compose decision criteria that take into account: the entry price, the current stop price, the number of bars or minutes or days the position has been open, the position size and/or cost and the profitability of the position at any stage.
- POS_STATE A numeric code indicating whether the backtest is long (1), short (2), or out of the market (0).
- POS_ASIDE/POS_LONG/POS_SHORT: tokens used for testing the POS_STATE status
- POS_SIZE: The size of the current position, i.e. the number of shares or contracts long or short. The number is negative if the position is short. Use ABS(POS_SIZE) as appropriate in your trading signals.
- POS_COST: The dollar cost of the current position.
- ENTRY: The price at which the current position was entered.
- EXIT: The most recent exit price.
- STOP: The STOP price. A variable the user may calculate and set using the SET command and use in a stop loss rule. Note that when a position is long, the STOP price can only be set higher by the SET command. Conversely, when short, the STOP price can only be set lower by the SET command.
- TARGET: The Target price. A variable the user may calculate and set using the SET command and use in a Target Profit rule. (a V# variable would act the same way).
- BARSOPEN: The number of bars (periods) that the current position has been open.
- MINOPEN: The number of minutes that the current position has been open. This token would be used only in intra-day trading system backtesting.
- DAYSOPEN : The number of days that current position has been open. This token would be used in daily/weekly/monthly trading systems, and may be useful at times in intra-day systems.
- GL: The gain/loss in dollars for the position.
- GLPCT: The percent gain/loss in the position. Negative numbers mean "loss percentage". The GLPCT value does not take commission costs into account just the price movement from the entry price to the current last price.
- BT_NET : the Cumulative Net profit
- BTBAR: This is the bar number being tested. BTBAR will be 1 for the first bar tested during the backtest. Thus a signal that includes the expression BTBAR = 1 would be true only when the very first bar is being tested.
- BT_ENT: The Number of Entries
- BT_EXIT: The Number of Exits
- BT_POS: The Number of Closed Positions
- TNUM: the number of trades that have been entered into for the instrument since the start of the backtest period. TNUM will be zero at the beginning of the backtest for each instrument. Each entry into a new long or new short position will cause TNUM to be incremented by one. If a "Buy More" or "Sell More" rule is triggered to add to an existing position, TNUM is not incremented. This token enables a trading system to consider whether any trades have yet been executed during the backtest of the instrument and/or how many trades the system has triggered thus far.
6) Focus on the Context Token (CTX)
The RTL CTX token can be used to determine within an RTL formula whether the formula is being evaluated in the context of a Quotepage Scan, a backtest, an optimization, a realization or inside a Trading System Indicator, using the built in constants CTX_QPSCAN, CTX_BKTST, CTX_OPTI, CTX_REAL and CTX_TSYS.
This token may be useful in cases where you may want a trading signal to be computed or a V# variable to be set differently depending on the context. This makes it possible to write one signal instead of two to take the different context into account.
For example, you may have a trading system that uses V#22 as a trailing stop value. If you have a trading rule that sets the value of V#22, this would present a problem if you were running an optimisation that tests various values for V#22 to determine the optimal value. Using the CTX token you can augment the trading rule by adding:
IF (CTX != CTX_OPTI) THEN SET(V#22, <expression>);
Here is another syntax using the RTL conditional operator : Let's assume that you are using a V#4 variable inside a backtest, and that variable is set to 1. In the optimization runs, you want to optimize this V#4 variable. In this case, in your backtest trading rule, you may use the following syntax :
SET(V#4,CTX!=CTX_OPTI?1:V#4)
This will guarantee that the V#4 value is set to 1 when the trading rule context is a backtest, but it will allow I/RT to modify successively the value of V#4 during an optimisation run.
The numeric constant tokens that can be used for comparison with CTX are:
- CTX_BKTST: Context is a backtest, optimization is NOT in progress.
- CTX_OPTI: Context is a backtest, optimization in progress.
- CTX_REAL: Context is a backtest, realization in progress
- CTX_QPSCAN: A quotepage is being scanned using the scan or signal. This context does not apply to custom indicators.
- CTX_TSYS: Context is a trading system deployment inside a chart via the TSYS Indicator
- CTX_OTHER: The constant token CTX_OTHER (CTX = 0) will be true if none of the others are, e.g. a formula running inside a custom indicator assigned to a custom column in a quotepage.