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

BAndH001

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

BAndH002

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

BAndH006

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

BAndH023

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.

BAndH024

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 );

BAndH009

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.

BAndH010

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 ????

BAndH025

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

BAndH014

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?????).

BAndH015

plus defaults - should be nothing to change - - the other settings are more or less arbitrary for this example.

BAndH016

BAndH017

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.

BAndH018

To plot the trade arrows from the back-test.

Right click inside Results pane and select Show arrows for actual trades

BAndH019

To plot the equity curve for a single stock back-test.

Drop-down Equity button and select Individual Equity.

BAndH020

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).

BAndH013

Right clicking inside the pane, that contains the Equity() plot, and selecting Edit Formula reveals the AmiBroker code that produced the graph.

BAndH022

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.

BAndH004

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).

BAndH005

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Backtesting Example - NewHighs/NewLows

Q. Does anyone know how to buy tomorrow and sell the next day across your entire portfolio?

Basically, I want to:
1) Get the buy signal at the end of Day 1
2) Buy the stock on the opening of Day 2
3) Sell the stock on the opening of Day 3

A. There are multiple ways to do this in Amibroker. Below I give an example (using HHV to signal new 220 bar highs) of how this can be built into a portfolio type system.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//Code by Ed Pottasch 
// if you want to buy and sell, with delay, inside a portfolio type system 
 
SetBarsRequired(10000,10000); 
SetOption("MaxOpenPositions", 10 ); 
SetOption("UsePrevBarEquityForPosSizing",True); 
SetOption("PriceBoundChecking", False); 
PositionSize = -10; 
SetTradeDelays(0,0,0,0); 
 
// delay of exit with respect to entry in bars
sellDelay = Optimize("sellDelay", 1, 1, 50, 1); 
 
// buy signal when H exceeds H of past 220 bars
Buy = H > Ref(HHV(H,220),-1); 
 
// entry at the open of the bar following the signal bar
Buy = Ref(Buy,-1); BuyPrice = O; 
 
// remove excessive signals from initial signal
Buy = ExRemSpan(Buy, sellDelay); 
 
// sell sellDelay bars after entry at the open
Sell = BarsSince(Buy) == sellDelay; SellPrice = O; 
 
SetChartOptions(0, chartShowDates); 
GraphXSpace = 5; 
Plot(C,"C",1,64); 
PlotShapes(IIf(Buy,shapeUpArrow,0),colorWhite, layer = 0, yposition = BuyPrice, offset = 0 ); 
PlotShapes(IIf(Sell,shapeDownArrow,0),colorYellow, layer = 0, yposition = SellPrice, offset = 0 ); 
 
PositionScore = 1/Ref(RSI(sellDelay),-1);

Comments and code by Edward Pottasch.

AmiBrokerYahooGroup message# “How to Buy Tomorrow and Sell the Next Day Using Your Whole Portfolio” http://finance.groups.yahoo.com/group/amibroker/message/116945

ATTACHED FILE:

b_higherhighs.afl

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...