Investor/RT
Tutorials
Backtest Tutorial by F_Trader (User Submitted)
Revision 1.00 / February 26, 2003

 

Click here to download Word (.doc) Document

 

INTRODUCTION:

 

These pages are intended to help IRT users making their debut with the backtesting feature. Basic knowledge on RTL language and IRT syntax for Trading Signals and custom indicators will of course help. Anyhow, this document was not written to replace the current Linnsoft documentation that you may find there:

 

http://www.linnsoft.com/tour/tradingSystems.htm

http://www.linnsoft.com/tutorials/ruleTesting.htm

 

but is mainly intended to bridge the GAP between :

 

ð      how one manage, in his realtime daytrading activities, the signals which can be generated by his own indicators on his charts

AND

 

ð      the best way to build a full trading systems from these indicators (and implement money management rules) with the very powerful tools available in the RTL programming language and the IRT backtesting features.

 

 

Finally, being a mainly E-minis trader located in Europe, you will notice in my scripts that:

  • the main US trading session runs here from 1530 to 2200
  • all trading systems examples are based on a 5 minute timeframe, the default trading size being two ES contracts.

 

Of course, all explanations can be easily adapted for systems based on daily bars or on stocks…

 

I really hope you will enjoy this Tutorial which gathers together most of my backtesting experience with IRT for the past year.

 

All scripts here should be run with IRT version 5.9.7 or later.

 

Do not hesitate to contact me for question on this paper, or for reporting possible tipping errors or inconsistencies by email at f_trader02@yahoo.fr, using the Linnsoft Yahoo group or thru the #Linnsoft chatroom on the OTHERNET IRC server.

 

 

Happy Backtesting

 

Eddy

 

 

PS: please consider this very first version as a DRAFT / Check for any new revision of this document which will be most likely advertised on the Yahoo group or on www.linnsoft.com


 _ACTUAL TABLE OF CONTENT__ 

 

 

CHAPTER 1: Basic guidelines for writing entry and exit trading signals  

 

1.1)      Distinction between End Of Bar (EOB) and Intra-Bar (INB) signals

 

1.2)      Market order type and slippage considerations for EOB and INB signals

 

1.3)      Adding a “filter” to our entry rules

 

1.4)      Managing reverse rules

 

1.5)      Tips for getting EOB / INB  signals markers on your chart and about the equity curve charts

 

1.6)        Detailed scripts of the trading systems discussed in Chapter 1

 

 

CHAPTER 2: How to add Money Management rules to an IRT trading system

 

2.1) Using an EOB approach for money management rules: a logical choice

 

2.2) Definition of the Money Management V# variables.

 

2.3) The Money Management (MM) rules explained step by step

 

2.4) How to simplify the “maintenance” works around backtest or how to use exactly the same single trading system for testing different strategies

 

2.5) Detailed scripts of the trading systems discussed in Chapter 2

 

 

 

_VIRTUAL ADDITIONAL TABLE OF CONTENT__ 

 

 

For information only, here are the chapters, NOT yet on paper, but which could get out of my head one day and follow the existing chapters 1 and 2

 

3) Custom reporting with the NOTE Token

This NOTE token allows you to show any V# variable value in the detailed report file: you may use it to build a fully customize report

 

4) Getting your backtest rules in realtime on your charts

or how to get live on your charts you’re the same entry/exit/MM signals than the one you get in your backtest (without running any backtest ..)

 

5) Managing multi-periodicity (and even multi-instrument) signals  

This issue is already discussed a bit in section 1.5

 

 

6) Optimisation of your trading system parameters

IRT allows you to automatically find for example the Initial Stop level producing the highest overall profit : using the scheduler features, and adequate V variables setting, you may implementing very easily this hidden optimisation feature on any existing trading systems

 

7) Max Favorable / Adversary excursion and Intra-trade Drawdown analysis

Detailed MFE/MAE analysis and reporting for all backtested trades can be achieved using some V# variables

 

 


 

 

 

 

CHAPTER 1 : Basic guidelines for writing entry and exit trading signals  

 

We will start explaining here the distinction between:

A) an “End Of Bar” (or EOB) Signal

B) an “Intra-Bar” (or INB) Signal

and the impact of this essential choice on the way you may write ALL your trading rules whatever their type : i.e. entry signals, filters, profit taking rules, stop loss rules, etc

 

In fact, when designing a trading system, the first step is to check that you have a coherent approach between:

ð      your trading style, i.e. how you manage your signals in realtime

ð      and the way you intend to transcript them for backtesting purpose

 

In order to write coherent trading rules and not cheat with your backtest (ie enter a signal at a given time using “future” data), it is essential that you understand all nuances between EOB and INB signals. By experience, I guarantee you that the main pitfall before getting “realistic” backtest results are here...

 

You will find that it might be interesting to open twice this document so that you may follow at the same time how the systems are building, and how the final result (ie IRT text transcript of all the rules) looks like. These transcripts are located at the end of each chapter.


1.1) the distinctions between EOB and INB signal

 

We will consider in this chapter a basic breakout system based on 5 minute bar chart.

In this system, you enter a long position when there is a breakout of the Highest High of the 10 previous bars, and you exit it at the break of the Lowest Low for the 7 previous bars..

 


A) End of Bar Signal (EOB)

 

If your system is : wait for the first CLOSE of a given bar to be
higher than the highest high of the 10 preceding bars to go long,
then your entry rule will have following logic :

If CL > STAT.1 Then BUY 2 at Close Price


with  STAT = Maximum Close for Preceding 10 Bars

Of course, you need to use STAT.1 in this trading signal in order to simulate the highest high of the 10 PREVIOUS bar and exclude the high of the current tested bar

Note: Since version 5.9.7, you could also use the syntax: CL > MAX (HI.1, 10)

In this case, what is important is that you wait UNTIL the end of the 5 min bar to make a decision about entering a trade, because your rule is : wait that the CLOSE of the current bar breaks the highest high of the 10 previous bar (by the way, this particular value is known since the start of the current 5 minute bar)

 

ie with EOB signals, you don’t care at all about what the market could do during 5 minute : there could be 1000’s of trades (which will be compacted into the Open / Low and High information), you will be using only ONE trade data to take a decision : the CLOSE of the bar

 

The corresponding trading system, incl. Filter rules (as explained later in section 1.3) will be named REF_SYSTEM_A_EOB and its scripts, as other in this chapter is available in section 1.6.1)

 

 

 

B) Intra-Bar Signal (INB)

 

In this case, your entry signal can be described as:

As soon as there is one trade done at a value higher than the previous 10 bars high, you enter the trade.

While trading in realtime with this approach, this requires you (or trading platform) monitor all the trades as they might appear in a “Time and sales” windows for example, because you need only one tick i.e. one trade with the adequate price to trigger your entry.

 

Anyhow, in the backtest, your entry price will be the Highest High of the previous 10 bar. This value is not listed by default in the “Rule Price” window, so you need to store it using a V variable.

In IRT syntax, this will be done thru a SET statement like SET(V#2,STAT.1) which will appear in a Trading signal at the top of the rules list (the STAT token has the same setting than in A))

We will name it Store_Bkout_value and it will be associated to a NONE rule (i.e. "no action" rule)

 

Please note that you will need to rename the STAT token in the Trading signals definition because he will be used several time.

This way, the value will be updated at every backtest iteration, i.e. for every new 5 minute bar.

 

The entry trading signal associated to the BUY action will be then:

If HI > V#2 Then BUY 2 at Value V#2 Price

For more: see the script of the system named REF_SYSTEM_A_INB in 1.6.2)

 

Note:

Do not forget to go to the “Set Up / Preferences / User variables” menu to give a title to this V variable.

 

 

1.2) Market order type and slippage consideration for EOB and INB signals

 

OK, this part is not fully linked to IRT issue but it helps understand the difference between EOB and INB signals

 

 

A) End of Bar Signal

 

In such a system, you do not know “in advance” what will be your entry price as long as the 5 minute bar is completed (of course, you do try to enter on the CLOSE of the bar)

So basically, if your system trigger when the CL data is printed, you would enter the market as soon as possible, typically with a market order, i.e. you will experience slippage. Of course, this impact of the slippage (let’s say one or two ticks for futures) on the Trade PL will be relatively less if you are running a longer timeframe... (because then your average profit is larger..)

Indeed, it might take you between 5 and 30 seconds to send you order thru your broker platform, not so an issue if you are working with 30 minute bars, but this is a big issue if your are working with 1 minute bars…

 

 

B) Intra-Bar Signal

 

In this case, you know “in advance” (i.e. as soon as a 5 minute period starts) what could be your entry price for both a long or short trade. But, at the opposite of EOB signals, the signal could trigger (in realtime) at any time, not only at the completion of the 5 minute bars. But knowing in advance the possible entry price allows you to use pre-programmed limit orders (for both long and short entry): i.e.

you will be updating the corresponding values of the resting go long/short orders every 5 minutes, at the start of every new bar… Such an operation could take few seconds, so in this case:

ð      either you may experienced slippage is the breakout occur just at the start of the bar (because you don’t have updated yet the value of your resting limit order)

ð      either, and this is the case most of the time, you won’t experienced any slippage at all, i.e. your limit order will be filled at the exact price

 

 
C) The bid/ask story or how to make sure that the “backtest fill” is a realistic one

 

Personally, I trade the S&P E mini which always have (during the day session) a single tick (i.e. 0.25 point) difference between the ask and the bid.

However, having a bid/ask at 835 / 835.25 and a buy limit order at 835.25 do NOT guarantee you a fill.

 

This is why I would write, in such a case, my entry rule as

HI > STAT.1   

and NOT as       HI > = STAT.1

Indeed, I want to make sure that the limit order (I simulated in the backtest) would be filled.

 

There will be more example of this conservative approach later in this tutorial. The main idea is that I prefer to have a pessimistic backtest result than an optimistic one…
1.3) Adding a “filter” to our entry rules

 

Adding Filter provides a very good illustration to the difference between EOB and INB signals. Let’s consider the typical ADX filter, i.e. a breakout will be only traded if the ADX is above 25 AND the ADX is increasing

 

A) For EOB rules

In such system, you enter a trade as soon as the signal is triggered, i.e. when the 5 minute bar is completed. So you may use all the price data of the current bar in your filter calculation, including of course the CLOSE

The entry signal for a long signal would be then:

 

If ( CL > STAT.1  AND  ADX > 25  AND  ADX > ADX.1) Then BUY 2 at Close Price

 

B) Intra-Bar rules

In this case, as your signal may trigger as soon as the new bar starts to form, it is not possible to use the current close in the filter calculation

If this is not clear yet in your mind, remember that the IRT backtesting makes calculation ONCE at the end of every time frame (here 5 minutes), so if you simulate an entry during the current bar, you need to limit your data until the previous Bar data (i.e. CL.1 or ADX.1), so that IRT does not use the CLOSE which will historically be printed after your possible trade entry time.

 

This is why the entry signal for a long trade would be then be here:

 

If (HI > V#2 and ADX.1 > 25 and ADX.1 > ADX.2) Then BUY 2 at Value V#2 Price

 

(with V#2 being set as STAT.1)

 

WARNING: The rules:   If (HI > V#2 and ADX > 25) Then BUY 2 at Value V#2 Price is clearly incorrect because “future” data is used to take a decision in the past.

 

By the way, IRT or (any other trading software) doesn't have sufficient logic to warn the user with “an error message”. So always verify the rules logic behind any backtesting report producing some extraordinary results…

 

Note:

For INB and EOB, I have used exactly the same filter rule for both LNG and SHT sides, so I could have basically have used a unique trading signal name : of course, there are usually different, so I'll keep naming them __LNG_FILTER and __SHT_FILTER

 

C) Adding Filter as CONFIRM rules

As soon as your trading system starts to be a bit complex, I would recommend to have a modular approach, i.e. for example, you may include your filter with a CONFIRM rules, just before the actual BUY or SELL actions in the list of trading rules.

This is the way the script features at the end of this chapter are structured.

Indeed, such CONFIRM rules will greatly improve:

1)    the legibility of the structure of the trading rules

2)    the execution times of your backtest (as the possibly complex entry rules calculation will be only done IF the filter rules returns true)

3)    allow you to use the same filter rules in different trading systems

 

Please note that the most common filter will be in fact a TIME FILTER

Let’s say that you will not enter trade on the first or last 10 minutes of the daysession, you could write it in a Trading signal as: (TIME > 1540) AND (TIME<2150)

You will notice that I do prefer write this rule as:   (TIME > 1540)*(TIME<2150) > 0

because it look like such approach results in quicker calculation

 

For example if you want to enter a trade only on the first or last hour, you may write the corresponding signals as:

(TIME > 1530 AND TIME<1630)   OR   (TIME > 2100 AND TIME < 2200)

or as : (  (TIME > 1530)*(TIME<1630)  + (TIME > 2100)*(TIME < 2200)  ) > 0

 

PS : As I never hold any position overnight, all my trading systems will include a Market close rule (MKT_CL), i.e. exit all position when the trading signal TIME=2200 returns true…

 

Do not forget to use such Time filter if you have 24 hours data available (like it is the case for ES), otherwise you will end up triggering trade at 3 in the night: indeed the IRT backtesting data will be based on the default session of the instrument tested


 

 

1.4) Managing reverse rules

 

OK, before investigating the implementation of money management rules, we need to see how to manage reverse rules, which can be a bit tricky when combined with filter rules… You might think: reverse rules are easy to master!

I will answer that this might be the second major sources of mistakes after the confusion between EOB and INB signals.

By the way, please note that following comments are fully valid for both EOB and INB type of rules

 

A)    With no dedicated filters rules

 

Let’s start with a system having “NO filter rules” and a set of symmetrical rules: i.e. the exit rules of a Short trade ALWAYS trigger the start of a long position

 

In our example, this would mean that breakout period for entering and exiting a position are the same (let’s say 10 bars). SO the LNG_EXIT_SIG_EOB rule is still:

CL < STAT.1 but with STAT = Minimum of the Low of 10 preceding bars (instead of 7 bars)

 

In this case, implementing the reverse rules is quite an easy task:

 

For exiting a long position, you just replace SELL by a REVERSE-SELL & SELL SHORT action

For exiting a short position, you just replace COVERSHORT by a REVERSE-COVERSHORT & BUY action

So the order of the rules could be as follow:

 

BUY rule

SELL rule

REVERSE-SELL & SELL SHORT

REVERSE-COVERSHORT & BUY action

 

In IRT, these REVERSE rules allow to Exit a long position and Enter a short position on the same bar! We will tell more on that later, in section 2.3

 

 

B) With a filter rule prior to the entry signal

 

Let’s consider now our breakout system having the same 10 bar period, BUT with some a filter for initiating a NEW position (short or Long)

 

Here it is just a bit trickier. Indeed, in this case, when you get your signal for exiting a Long Position, you must make check the “filter” status to know if this breakout of the 10 previous bar results in:

 

ð      Exiting a Long position and remaining flat (filter status = false)

ð      Exiting a Long position and entering a Short (filter status = true)

 

In this case, you just need to write in the following order (let’s consider first only the LONG side rules before mixing both SHORT and LONG positions)

 

LNG FILTER CONFIRM rule

BUY rule

SHT REV FILTER CONFIRM rule

REVERSE-SELL & SELL SHORT rule

SELL rule

 

What is important to understand is that you are managing here TWO exit signals, and that you absolutely need to put your Reverse Rules Statement (which will be activated if the associated Filter CONFIRM rule returns true) BEFORE the usual exit rules statement… The order in which you place your trading actions on the rules list is vital in IRT.


 

Please note as well that an SHT_FILTER_EOB_REV for example will be almost identical to the SHT_FILTER_EOB one  except that we will add to it a check for “POS_STATE=1”, i.e. this filter can only returns true in a REVERSE situation, i.e. when a LONG trade is ongoing

 

Ok, this might sound a bit complex for a implementing a reverse rules, but remind here that we are managing in fact two exit signals.

Of course, one could decrease the number of rules by incorporating the “Filter rules” within the actual SELL and REVERSE-SELL & SELL SHORT rules.

But I really prefer this modular approach and use of CONFIRM rules.

There are further advantages that will appear only in the coming chapters..

 

 

For the Short side, the set of rules will be:

           

SHT FILTER CONFIRM rule

SELL SHORT rule

LNG REV FILTER CONFIRM rule

REVERSE-COVERSHORT & BUY rule

COVERSHORT rule

 

And if we combined both long and short rules:

 

LNG FILTER CONFIRM rule

BUY rule

SHT FILTER CONFIRM rule

SELL SHORT rule

LNG REV FILTER CONFIRM rule

REVERSE-COVERSHORT & BUY rule

COVERSHORT rule

SHT REV FILTER CONFIRM rule

REVERSE-SELL & SELL SHORT rule

SELL rule

 

You have noticed that rules for initiating new trades are of course situated before the exit signals.

 

In EOB type of approach, you usually won’t have at the Close both Short and Long trades triggering at the same time (otherwise, recheck your rules logic!!), so the respective order between the SHT and LNG rules (within the ENTRY or EXIT set of rules) doesn’t matter.

 

HOWEVER, with the INB approach, it is fully possible that the same bar trigger a BUY and SELL actions (imagine a very wide outside bars breaking at the same time the previous 10 bars Low and Highs). In this quite rare situation, there is no magic, with the above set of rules, the BUY signal would be triggered first.

Anyhow, as there is no way to know if the HI or LO of a bar occurred first, it is impossible to simulate correctly in this case what could happen in realtime…

Moreover, with our present set of rules, what would happen is that the trade will be then systematically closed on the same bar, resulting in a negative PL…

At least, this will not “over-optimize” our system performance…

So I consider these point to be really a very minor inconvenient compared to the benefits of an INB approach for simulating breakouts…

 

Please remember as well, there is many ways to manage Filter and Reverse rules in IRT. I am just showing you one possible approach! If you select another approach, just be careful to have a set of coherent rules…

 

I have attached in 1.6.3 the full script for an EOB system including Filter and Reverse rules

 

 

 


 

1.5) Tips for getting EOB / INB signals markers on your chart and about the equity curve chart

 

We will be discussing here quickly charting issue related to:

 

A) Entry and exit trade signals markers

 

Breakout types of entry are the easy one to program using a INB method. What is very nice with such approach is that you do not have any blinking signals on your chart.

Here is what I mean:

Let’s say that I have a Signal marker associated to the rule:

HI > STAT.1

In this case, as soon as the marker appears once during the life of a 5 minute bars, it will remains: indeed, the High can only goes higher (except may be in case of bad ticks, which are really rare with E-minis)…

 

On the other hand, let's consider the EOB rules:

CL > STAT.1

Depending on the last trade value, during the building of the 5 min bars, you could have a “blinking marker” if the ongoing trades “oscillate” successively above and below the trigger level. This is a good indication a trade could be trigger soon, when the bar is completed, but is quite annoying at the end of the day if you follow this marker to actually pull the trigger on your broker platform.

 

My tip is the following in case of EOB entry signals:

 

1)    I would use a color marker BELOW the chart for showing different colors depending on the status of the CL > STAT.1 statement

 

2)    I use on the chart a signal marker, but it is :

ð      associated to the signal CL.1 > STAT.2

ð      the marker is shifted one bar on the left

ð      and is linked to a given wav sound

 

This way, if the signal triggers indeed at the close of the bar, the marker you then appears ONCE on the chart (will not blink of course) and a sound alarm will tell me that I have a CONFIRMED buy signal.

 

There is much more to say on this charting and markers issue. Indeed, the problem with using the embedded “Chart rules” features in IRT is that it does not take into account the preceding CONFIRM rules. So, on my side, I will use another approach.

I have already detailed it a bit in the Yahoo forum:

You may have a look for example at this particular message:

http://groups.yahoo.com/group/LinnSoft/message/5601

which illustrate a very interesting use of the powerful Signal Statistics token (SSTAT)

 

More on that may be one day in a possible chapter 4

 

 

B) the Equity curve Chart :

 

OK, there is a lot to say here as well but I will try to keep it to the essential:

The equity curve information is stored in the $REF_SYSTEM_A_EOB instrument which will be only generated if you check the box “Account Balance charts” of the “Setup backtest” window.

 

If you have an intraday system (based on 5 minute bars) and if you want to have a nice equity curve of the past 2 years (if this is your backtest period) fitting on your screen width (with no scrolling), you need to create a chart with

ð      a style being continuous line

ð      a low pixel per bar set up(1 or 2)

ð      a periodicity typically equal to your day session duration in minutes (i.e. like 405 minutes)

ð      a gridline color being the same than your background color (this is require to make the daily start of session vertical line, which will be highly compacted with a 405 min. periodicity) invisible

 

 

Then, I recommend to add some vertical reference line at given date (like at every year or month start).

This way, you get a nice chart dedicated for equity curve AND you should save this charts as being the default one for the instrument $REF_SYSTEM_A_EOB. This way, each time your backtest is finished, this chart will automatically pop up (instead of the standard default chart)

 

 

Below the equity curve, I would suggest to chart the following information in separate pane:

ð      The ongoing Drawdown

This is showing you at a given time the current drawdown (on a daily basis if your periodicity is equal to the daysession duration): this curve can be obtained using a (quite simple) custom indicator equal to “STAT – CL” with STAT being the “Maximum Close” since a fixed date (i.e. the start date of your backtesting period)

ð      The instrument data

 

Please note that the equity curve is an instrument like any other, so it is possible to apply to it any kind of technical indicators, including custom indicators…

 

The final result could look like the following screenshot

 

 

 

1.6) Detailed scripts of the trading systems discussed in Chapter 1

Before going further, here the transcript of trading system with Long and Short rules and filters, for both an EOB and INB approach, and with all rules mentioned before...

 

You will notice that, for legibility purpose, all my Trading signals names can be cuts in 3 part

 

First part is either __LNG / __SHT / __L_S meaning this is either a dedicated LONG / SHT rules or a rules common to both type.

It is generally followed by the type of action, i.e. ENTRY / Exit or FILTER

Finally, if the trading signal is specifically linked to an EOB/INB approach or used f