December 6, 2007
Buy And Hold
FIRST DRAFT - SUBJECT TO CHANGE
OBJECTIVE
INTRO
Uses and limitations of B&H - benchmarking - (to be added?????????????????????)
Stepping through the process of emulating a Buy&Hold (B&H) on a single stock - initially excluding the back-tester (BT) (working only with indicators) and then comparing the ‘manual’ B&H to the methods/results obtained in the BT- using indicator plots for visual confirmation and proving the formulas.
The manual emulation versus back-test comparison is then repeated for a simple ‘trading system’ - a set of buy (entry) and sell (exit) rules.
basic conditions (for system) - to simplify the explanation for newer users == 100% of equity per trade and enter one trade at a time (additional signals will be ignored) - reverse of the entry signal is the exit - no stops required - (BT is capable of advanced analysis - not considered in this example).
Using ABK, which was chosen at random from a US-Stocks database with 10 years of history (the formulas can be used on any stock with any number of bars).
MANUALLY CALCULATING THE B&H OUTCOME FOR A SINGLE STOCK
The B&H strategy, in it’s simplest form, buys a fixed $ value of shares and calculates their relative value at a later time (any time) - time frame can be anything - daily, weekly, monthly. This example uses EOD daily bars. In order to compare the results across periods the entry and exit are nominally made at the same point for each bar (for this example the close is used - since the close of the last bar, for the period under consideration, is the most convenient time to exit the strategy, the close on the first bar is the corresponding entry point (technically introduces a small possible error when using B&H as a benchmark for system evaluation).
Based on that it is necessary to know the close on the first bar. The following code shows how that can be done in AFL.
Note: Whether or not the shares ‘purchased’ are actually ’sold’ on the close of the final bar is irrelevant, since the purchase and sale of the shares is only a nominal exercise (the outcomes may vary slightly from AB mode to mode, depending on whether the ’sale’ is encoded in AFL, or not, and so this drives the need to ’sell’ or ‘not to sell’ e.g. if the user wants to plot a buy and sell arrow on the chart and the code does that accurately, for the current mode, then that is ‘good’ code for that mode).
1 2 3 4 5 6 7 | //P_BuyAndHold v4 //STEP 1A //right click on the formula and select Edit to open it in the Formula Editor (FE) //insert it as an indicator in its own pane (from the FE toolbar) //do not close the FE - keep it open and edit the code to step through the examples (the plot in the bottom pane will change after every FE save). B = BeginValue(Close); Plot(B,_DEFAULT_NAME(),colorBlack,1) |
The close on the first bar is 19.78 - BeginValue plots this as a constant for the entire 10 year period.
Figure 1
BeginValue can be used to manually calculate the equity curve for a Buy&Hold strategy.
1 2 3 4 5 6 7 | //P_BuyAndHold //STEP 1B //manually enter the initial equity - in this case 100,000 B = BeginValue(Close); InitialEquity = 100000; BH = InitialEquity/B * Close; Plot(BH,_DEFAULT_NAME(),colorBlack,1); |
Figure 2
The number of shares purchased at the close on the first bar can be calculated.
Note: Decimal places displayed can be changed in Tools >> Preferences (normally two deci places is all the that is required but can be increased for this demonstration).
Shares purchased == Initial Equity/Initial Price
== 100000/19.78
== 5055.611729
Fractional shares can’t be purchased in ‘real life’ but, to allow for accurate mathematical computation, it is nominally permitted in AB (Automatic Analysis).
The value of 5055.xx shares can be calculated at any time by multiplying by the current close price e.g. referring to the bar marked on the chart by the selector line.
BuyAndHold Equity == shares held (purchased) * current price
== (100000/19.78) * 22.41
== 113296.25 (which is consistent with the method used in Step 1A and plotted in Figure 2).
The expression BuyAndHold Equity == (Initial Equity/Initial Price) * current price can be also restated:
BuyAndHold Equity == Initial Equity * (Current Price/Initial Price)
So the Buy& Hold Equity, is always proportional to the ratio of the Current Price to the Initial Price, which is a relative measure.
1 2 3 4 5 6 7 8 | //P_BuyAndHold v4 //STEP 2A //B = BeginValue(Close); InitialEquity = 100000; //BH = (InitialEquity/B) * Close; //Plot(BH,_DEFAULT_NAME(),colorBlack,1); eRatio = Close/BeginValue(Close); Plot(eRatio,"PseudoEquity",colorRed,1); |
Figure 3
At the bar marked on the chart, by the selector line, there is a 13.29% gain in the Buy&Hold equity ratio (if the Initial Equity was 100,000 the B&H equity curve would be 113,296.3 - the same as that calculated value in Figure 2, at the same point in time).
1 2 3 4 5 6 7 8 | //STEP 2B //manually enter the initial equity - in this case 100,000 //B = BeginValue(Close); InitialEquity = 100000; //BH = (InitialEquity/B) * Close; //Plot(BH,_DEFAULT_NAME(),colorBlack,1); eRatio = Close/BeginValue(Close); Plot(eRatio * InitialEquity,"PseudoEquity",colorRed,1); |
Figure 4
AmiBroker has a built-in function that automatically calculates equity.
Note: The Equity() function is a special function that is part of the Automatic Analyzer suite and it references various AA settings (normally it will automatically use the default AA settings but for this example they will be ’manually’ overwritten within the code).
1 2 3 4 5 6 7 8 9 10 11 | //STEP 3 //adapted from code by Tomasz Janeczko //manually enter the Initial Equity value as the second SetOption parameter Buy = 1; SetOption("InitialEquity", 100000 ); PositionSize = -100; SetTradeDelays( 0,0,0,0); ApplyStop(0, 0,0,0); ApplyStop(1, 0,0,0); ApplyStop(2, 0,0,0); Plot( Equity(0,0), "Equity",colorGreen,1 ); |
Note: In this mode (Indicator plots) it is irrelevant whether the Sell is included in the code or not.
The outcome is exactly the same as in the previous ‘manual’ equity calculations.
In the default BT mode, redundant symbols are ignored when calculating Equity().
To demonstrate this:
If Buy =1 is plotted, with shapes, it produces a buy arrow on every bar (the Buy expression is always true).
1 2 3 4 5 | //P_BuyAndHoldOverlay //save as a separate formula and overlay on a price chart Buy = 1; shape = Buy * shapeUpArrow; PlotShapes( shape,colorGreen,Low ); |
Adding the ExRem function allows users to see the Buy signals as they are processed by the Automatic Analyzer, in tandem with the equity() function.
1 2 3 4 5 6 7 8 | //P_BuyAndHoldOverlay //save as a separate formula and overlay on a price chart Buy = 1; Sell = 0; Buy = ExRem(Buy,Sell); Sell = ExRem(Sell,Buy); shape = Buy * shapeUpArrow + Sell * shapeDownArrow; PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) ); |
Note: In indicator mode the Sell = 0; expression is redundant when calculating Equity(). It has been included in this example as it is conditional when using the ExRem() function.
BUY AND HOLD ON A SINGLE STOCK USING THE AUTOMATIC ANALYZER
Zooming to full range on the ABK chart and placing the selector line on the last bar brings up the final value of the Buy&Hold equity ‘curve’ for full number of bars i.e. 434,175.91
Note: Any of the ‘manual’ methods demonstrated will produce the same ‘final’ result.
Figure ????
The back-tester can also be used to calculate the B&H outcome.
1) First setup the chart to display trading arrows after the back-test.
Right click inside the current price chart and pick Show trading arrows
2) Enter AA Settings
100000 Initial Equity, Long, Daily, Round lot size = 0 and no commission (0)
Min shares set to additional decimal points allows for more accurate calculations (depending on the situation??? not required for this example now?????).
plus defaults - should be nothing to change - - the other settings are more or less arbitrary for this example.
1 2 3 4 5 | //B_BuyAndHold //run as an Individual Backtest on current stock, all quotes Buy = 1; Sell = 0; PositionSize = -100; |
Back-test by clicking on the Back Test button and selecting Individual Backtest.
To plot the trade arrows from the back-test.
Right click inside Results pane and select Show arrows for actual trades
To plot the equity curve for a single stock back-test.
Drop-down Equity button and select Individual Equity.
The resultant chart shows that the trade was entered on the first bar and sold on the last and that the Buy&Hold equity matches the (yellow) Equity() curve exactly (positioning the selector bar on the last line also shows that it tallies with the B&H equity values calculated earlier in the post).
Right clicking inside the pane, that contains the Equity() plot, and selecting Edit Formula reveals the AmiBroker code that produced the graph.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | _SECTION_BEGIN("Individual"); #include @LastBacktestFormula MaxGraph=0;GraphXSpace=5; GraphZOrder=1; Plot( Equity( 0, -2 ), "Equity", -8, styleArea ); if( ParamToggle("Show Buy-and-Hold?", "No|Yes", 1 ) ) { /* now buy and hold simulation */ Short=Cover=0; Buy=Status("firstbarintest"); Sell=Status("lastbarintest"); SetTradeDelays(0,0,0,0); PositionSize = -100; ApplyStop(0,0,0,0); ApplyStop(1,0,0,0); ApplyStop(2,0,0,0); Plot( Equity( 0, -2 ), "Buy&Hold", -9 ); } _SECTION_END(); |
COMPARING BUY AND HOLD TO A TRADING SYSTEM
ADD A 3MA EQUITY CURVE
The following code meets the buy conditions as described by Walter (they can be changed to anything).
1 2 3 4 5 6 7 8 | //ADD EQUITY CURVE FOR 3MA TRADING SYSTEM Condition1 = Ref(Close,-1) > Ref(MA(C,40),-1); Condition2 = Ref(Close,-1) > Ref(MA(C,80),-1); Condition3 = Ref(Close,-1) > Ref(MA(C,200),-1); Buy = Condition1 == 1 AND Condition2 == 1 AND Condition3 == 1; Sell = Condition1 == 0 AND Condition2 == 0 AND Condition3 == 0; shape = Buy * shapeUpArrow + Sell * shapeDownArrow; PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) ); |
When plotted as an overlay all signals are shown - the arrows mark when the close is above, or below, all three MA’s as requested.
Note: it is looking back to the previous bar since the entry will be on to-days open if yesterday reports a buy signal.
The code is modified to remove extra signals since in ‘real life’ we can only be in one trade at a time.
1 2 3 4 5 6 7 8 | //ADD EQUITY CURVE FOR 3MA TRADING SYSTEM Condition1 = Ref(Close,-1) > Ref(MA(C,40),-1); Condition2 = Ref(Close,-1) > Ref(MA(C,80),-1); Condition3 = Ref(Close,-1) > Ref(MA(C,200),-1); Buy = Condition1 == 1 AND Condition2 == 1 AND Condition3 == 1; Sell = Condition1 == 0 AND Condition2 == 0 AND Condition3 == 0; shape = ExRem(Buy,Sell) * shapeUpArrow + ExRem(Sell,Buy) * shapeDownArrow; PlotShapes( shape, IIf( Buy, colorGreen, colorRed ), 0, IIf( Buy, Low, High ) ); |
Removes extra signals marked by the arrows -
Note: that there is a penalty period for the first 200 bars while we wait for the 200 MA to start.
Also code is an approximation as it says above and it does not say cross (this would need more advanced code but I will keep it simple to start).

Filed by brian_z at 6:29 am under Backtester

