1.3 Portfolios and Portfolio Returns

Consider an investment in two assets named asset A and asset B (e.g. Amazon and Boeing stock). Let VA and VB denote the dollar amounts invested in assets A and B, respectively. We call such an investment in multiple assets a portfolio. The total dollar amount invested in the portfolio is Vp=VA+VB. The shares of dollars invested in assets A and B are: xA=VAVp, xB=VBVp. Notice that xA+xB=1 by construction (100% of all wealth is invested in the two assets).

In this book, the collection of investment shares (xA,xB) and initial wealth invested Vp defines a portfolio. If Vp is not specified then assume that Vp=$1. For example, one portfolio may be (xA=0.5,xB=0.5) (equally weighted portfolio) and another may be (xA=0,xB=1) (everything invested in asset B). Negative values for xA or xB are possible and represent short sales (to be discussed in later chapters). Given xA, xB, and Vp, the dollar amounts invested in assets A and B are: VA=xA×Vp,VB=xB×Vp.

The rate of return on a portfolio can be represented as a share weighted average of the rates of returns on the assets in the portfolio. To see this, let RA and RB denote the simple one-period returns on assets A and B. We wish to determine the simple one-period return on the portfolio defined by (xA,xB) and initial wealth Vp. To do this, note that at the end of the holding period, the investments in assets A and B are worth Vp×xA(1+RA) and Vp×xB(1+RB), respectively. Hence, at the end of the holding period the portfolio is worth: Vp×[xA(1+RA)+xB(1+RB)]=Vp×(1+Rp). Hence, xA(1+RA)+xB(1+RB)=1+Rp defines the portfolio gross return. The portfolio gross return is equal to a weighted average of the gross returns on assets A and B, where the weights are the portfolio shares xA and xB.

To determine the portfolio rate of return, re-write the portfolio gross return as: 1+Rp=xA+xB+xARA+xBRB=1+xARA+xBRB, since xA+xB=1 by construction. Then the portfolio rate of return is: Rp=xARA+xBRB, which is equal to a weighted average of the simple returns on assets A and B, where the weights are the portfolio shares xA and xB.

In the portfolio rate of return, the components xARA and xBRB are the contributions of assets A and B to the portfolio return, respectively. These contributions add up to the total portfolio return Rp.

Example 1.19 (Compute portfolio return)

Consider a portfolio of Microsoft and Starbucks stock in which you initially purchase ten shares of each stock at the end of month t1 at the prices Pmsft,t1=$85 and Psbux,t1=$30, respectively. The initial value of the portfolio is Vt1=10×$85+10×30=$1,150. The portfolio shares are xmsft=850/1150=0.7391 and xsbux=30/1150=0.2609. Suppose at the end of month t, Pmsft,t=$90 and Psbux,t=$28. Assuming that Microsoft and Starbucks do not pay a dividend between periods t1 and t, the one-period returns on the two stocks are: Rmsft,t=$90$85$85=0.0588,Rsbux,t=$28$30$30=0.0667. The one-month rate of return on the portfolio is then: Rp,t=(0.7391)(0.0588)+(0.2609)(0.0667)=0.02609, The contributions of assets A and B to the portfolio return are: xARA=(0.7391)(0.0588)=0.0435, xBRB=0.0174. Asset A contributes positively and asset B contributes negatively to the portfolio return. The portfolio value at the end of month t is: Vt=Vt1(1+Rp,t)=$1,150×(1.02609)=$1,180

In R, the portfolio calculations are:
P.msft = c(85, 90) 
P.sbux = c(30, 28) 
V = P.msft[1]*10 + P.sbux[1]*10
x.msft = 10*P.msft[1]/V 
x.sbux = 10*P.sbux[1]/V 
R.msft = (P.msft[2] - P.msft[1])/P.msft[1] 
R.sbux = (P.sbux[2] - P.sbux[1])/P.sbux[1] 
R.p = x.msft*R.msft + x.sbux*R.sbux 
V1 = V*(1 + R.p) 
c(R.p, x.msft*R.msft, x.sbux*R.sbux, V1)
## [1]    0.02608696    0.04347826   -0.01739130 1180.00000000

In general, for a portfolio of n assets with investment shares xi such that x1++xn=1, the one-period portfolio gross and simple returns are defined as: 1+Rp,t=ni=1xi(1+Ri,t)Rp,t=ni=1xiRi,t. where Ri,t is the one-period simple return on asset i. Asset i’s contribution to the portfolio return is ctri,p=xiRt. and ni=ictri,p=ni=ixiRi,t=Rp,t.

1.3.1 Multiperiod portfolio returns and rebalancing

How to compute multiperiod portfolio returns depends on the assumptions made about the portfolio weights each period. Several scenarios exist:

  1. Portfolio weights from the initial portfolio are allowed to change over time as prices of the underlying assets change over time. In this case no rebalancing of the portfolio is done. This is called a buy-and-hold portfolio.
  2. Portfolio weights remain constant over time, which implies that the portfolio is rebalanced at every time period (associated with holding period) to maintain constant weights.
  3. Portfolio weights from the initial portfolio are rebalanced at specific time intervals that are different than the holding period (e.g. rebalance quarterly for monthly holding periods). This is a hybrid of scenarios 1 and 2.
  4. Portfolio weights are actively changed at each time period associated with the holding period. This is called an actively managed portfolio.

How to deal with the above scenarios is best illustrated through examples.

1.3.1.1 No rebalancing of portolio weights

Prices and shares framework

We illustrate the buy-and-hold scenario 1 using a simple portfolio consisting of two assets A and B invested for three time months starting at time t3 in a framework where we know the asset prices each period and the initial amounts invested in each asset4. In particular, we assume that the initial portfolio consists of sA=100 shares of asset A and sB=50 shares of asset B. The end-of-month prices and values (Vi,t=si×Pi,t,i=A,B) of the assets as well as the end-of-month values of the portfolio are given by

P.A = c(5,7,6,7)
V.A = c(500, 700, 600, 700)
P.B = c(10, 11, 12, 8)
V.B = c(500, 550, 600, 400)
V.p = V.A + V.B
table.vals = cbind(P.A, V.A, P.B, V.B, V.p)
rownames(table.vals) = c("t-3", "t-2", "t-1", "t")
table.vals
##     P.A V.A P.B V.B  V.p
## t-3   5 500  10 500 1000
## t-2   7 700  11 550 1250
## t-1   6 600  12 600 1200
## t     7 700   8 400 1100

In the above table the time index t represents the end of month t. Slightly abusing notation, we can also say that the time index t1 represents the beginning of month t. This is important because for the portfolio calculations the end-of-month values VA,t1, VB,t1 and Vp,t1 are used to calculate the portfolio weights to be applied in month t. That is, xA,t1=VA,t1Vp,t1, xB,t1=VB,t1Vp,t1 represent the portfolio weights for assets A and B at the beginning of month t. Then, the portfolio return over month t is computed as Rp,t=%ΔVp,t=Vp,tVp,t1Vp,t1=xA,t1RA,t+xB,t1RB,t, where RA,t=%ΔVA,t=VA,tVA,t1VA,t1=%ΔPA,t=PA,tPA,t1PA,t1RB,t=%ΔVB,t=VB,tVB,t1VB,t1=%ΔPB,t=PB,tPB,t1PB,t1.

The portfolio return, Rp,t, is still a share weighted average of the individual asset returns but with time varying portfolio weights xA,t1 and xB,t1.

The R calculations for returns are:

R.A = (V.A[2:4] - V.A[1:3])/V.A[1:3]
R.B = (V.B[2:4] - V.B[1:3])/V.B[1:3]
R.p = (V.p[2:4] - V.p[1:3])/V.p[1:3]
table.returns = cbind(R.A, R.B, R.p)
rownames(table.returns) =  c("t-2", "t-1", "t")
table.returns
##            R.A         R.B         R.p
## t-2  0.4000000  0.10000000  0.25000000
## t-1 -0.1428571  0.09090909 -0.04000000
## t    0.1666667 -0.33333333 -0.08333333

The R calculations for the weights are:

x.A = V.A/V.p
x.B = V.B/V.p
table.weights = cbind(x.A, x.B)
rownames(table.weights) = c("t-3", "t-2", "t-1", "t")
table.weights
##           x.A       x.B
## t-3 0.5000000 0.5000000
## t-2 0.5600000 0.4400000
## t-1 0.5000000 0.5000000
## t   0.6363636 0.3636364

Here, the initial portfolio formed at the end of month t3 is an equally weighted portfolio of assets A and B. However, the portfolio weights at the end of month t2 are not 0.5 and 0.5 as the prices of assets A and B have changed over the month. Asset A’s price has gone up more in percentage terms (RA,t2=40%) than asset B’s price (RB,t2=10%) so the portfolio weight in asset A at the beginning of t1 (xA,t2=0.56), has become bigger than the portfolio weight in asset B (xB,t2=0.44).

For the calculation of the portfolio returns, the asset weights at time t3 apply to the asset returns at time t2, the weights at time t2 apply to the returns at time t1, and the weights at time t1 apply to the returns at time t:

R.p = x.A[1:3]*R.A + x.B[1:3]*R.B
R.p
## [1]  0.25000000 -0.04000000 -0.08333333

The asset contributions to the portfolio return at time t are ctrA,t=%ΔVA,tVp,t1=xA,t1×RA,tctrB,t=%ΔVB,tVp,t1=xB,t1×RB,t The R calculations for the contributions derived from values are:

ctr.A = (V.A[2:4] - V.A[1:3])/V.p[1:3]
ctr.B = (V.B[2:4] - V.B[1:3])/V.p[1:3]
table.ctr = cbind(ctr.A, ctr.B, ctr.A+ctr.B)
colnames(table.ctr)[3] = "R.p"
rownames(table.ctr) = c("t-2", "t-1", "t")
table.ctr
##           ctr.A      ctr.B         R.p
## t-2  0.20000000  0.0500000  0.25000000
## t-1 -0.08000000  0.0400000 -0.04000000
## t    0.08333333 -0.1666667 -0.08333333

The R calculations for the contributions derived from returns are:

ctr.A = x.A[1:3]*R.A
ctr.B = x.B[1:3]*R.B
table.ctr = cbind(ctr.A, ctr.B, R.p)
rownames(table.ctr) = c("t-2", "t-1", "t")
table.ctr
##           ctr.A      ctr.B         R.p
## t-2  0.20000000  0.0500000  0.25000000
## t-1 -0.08000000  0.0400000 -0.04000000
## t    0.08333333 -0.1666667 -0.08333333

Returns and weights framework

The above calculations are based on knowing asset prices and initial shares purchased for each asset. In many situations, we only have return information and initial portfolio weights on each asset and the initial value of the portfolio. Using the above example, the initial portfolio weights are xA,t3=xB,t3=0.5 and the initial value of the portfolio is Vp,t3=1000. We also know the returns, Ri,t, each period for the two assets:

table.returns[, c("R.A", "R.B")]
##            R.A         R.B
## t-2  0.4000000  0.10000000
## t-1 -0.1428571  0.09090909
## t    0.1666667 -0.33333333

We deduce the initial asset values using VA,t3=xA,t3×Vp,t3=0.5×1000=500,VB,t3=xB,t3×Vp,t3=0.5×1000=500.

The end-of-month asset values for i=A,B are computed using Vi,t2=Vi,t3×(1+Ri,t2),Vi,t1=Vi,t2×(1+Ri,t1)=Vi,t3×(1+Ri,t2)(1+Ri,t1),Vi,t=Vi,t1×(1+Ri,t)=Vi,t3×(1+Ri,t2)(1+Ri,t1)(1+Ri,t).

The end-of-month portfolio values are the sum of the end of month asset values. The R calculations are:

V.A = V.B = V.p = rep(0, 4)
V.p[1] = 1000
V.A[1] = V.B[1] = 0.5*V.p[1]
V.A[2:4] = cumprod(1+R.A)*V.A[1]
V.B[2:4] = cumprod(1+R.B)*V.B[1]
V.p[2:4] = V.A[2:4] + V.B[2:4]
table.vals = cbind(V.A, V.B, V.p)
rownames(table.vals) = c("t-3", "t-2", "t-1", "t")
table.vals
##     V.A V.B  V.p
## t-3 500 500 1000
## t-2 700 550 1250
## t-1 600 600 1200
## t   700 400 1100

The portfolio weights at the end-of-month t are computed as xi,t=Vi,tVp,t1, and the R calculations are:

x.A = V.A/V.p
x.B = V.B/V.p
table.weights = cbind(x.A, x.B)
rownames(table.weights) = c("t-3", "t-2", "t-1", "t")
table.weights
##           x.A       x.B
## t-3 0.5000000 0.5000000
## t-2 0.5600000 0.4400000
## t-1 0.5000000 0.5000000
## t   0.6363636 0.3636364

The portfolio return over month t can be computed using Rp,t=%ΔVp,t=Vp,tVp,t1Vp,t1=xA,t1×RA,t+xB,t1×RB,t

The R calculations for returns based on values are:

diff(table.vals[, "V.p"])/table.vals[1:3, "V.p"]
##         t-2         t-1           t 
##  0.25000000 -0.04000000 -0.08333333

The calculation for returns based on weights is

x.A[1:3]*R.A + x.B[1:3]*R.B
## [1]  0.25000000 -0.04000000 -0.08333333

1.3.1.2 Constant portfolio weights

If the initial portfolio weights are to be held constant over time then the portfolio typically needs to be rebalanced at each time period to adjust the portfolio weights back to the initial weights. Given the constant portfolio weights xA and xB the return on the portfolio at every time period is given by Rp,t=xARA,t+xBRB,t.

The rebalancing of portfolio weights can be illustrated with the example from the previous sub-section. The initial portfolio is an equally weighted portfolio, xA,t3=xB,t3=0.5. To have constant portfolio weights the portfolio will need to be rebalanced each period so that xA,t2=xA,t1=xA,t=0.5 and xB,t2=xB,t1=xB,t=0.5. Consider the portfolio at the end-of-month t2 where VA,t2=VA,t3×(1+RA,t2)=500×(1+0.40)=700VB,t2=VB,t3×(1+RB,t2)=500×(1+0.10)=550Vp,t2=VA,t2+VB,t2=700+550=1250xA,t2=VA,t2Vp,t2=7001250=0.56xB,t2=VB,t2Vp,t2=5501250=0.44 The end-of-month portfolio weights are xA,t2=0.56 and xB,t2=0.44, which are not equal to 0.5. Since Vp,t2=1250, to rebalance the portfolio so that xA,t2=xB,t2=0.5 we need VA,t2=VB,t2=Vp,t2/2=625. This requires selling 700625=75 of asset A and purchasing 75 of asset B and the end-of-month t-2. Then, at the beginning of month t1 we have VA,t2=VB,t2=625 and xA,t2=xB,t2=0.5.

At the end-of-month t1, for the rebalanced portfolio we have VA,t1=VA,t2×(1+RA,t1)=625×(10.1429)=535.69VB,t1=VB,t2×(1+RB,t1)=625×(1+0.0909)=681.81Vp,t1=VA,t2+VB,t2=535.69+681.81=1217.50xA,t1=VA,t1Vp,t1=535.691217.50=0.44xB,t1=VB,t1Vp,t1=681.811217.50=0.56 The end-of-month portfolio weights are xA,t1=0.44 and xB,t1=0.56. Since Vp,t1=1217.50, to rebalance the portfolio we need VA,t1=VB,t1=608.75. This requires selling 73.06 of asset B and purchasing 73.06 of asset A and the end-of-month t-1. Then, at the beginning of month t we have VA,t1=VB,t1=608.75 and xA,t1=xB,t1=0.5.

Finally, at the end-of-month t, for the rebalanced portfolio we have VA,t=VA,t1×(1+RA,t)=608.75×(1+0.1667)=710.23VB,t=VB,t1×(1+RB,t)=608.75×(10.3333)=405.85Vp,t=VA,t1+VB,t1=710.23+405.85=1116.08xA,t=VA,tVp,t=710.231116.08=0.64xB,t=VB,tVp,t=405.851116.08=0.36 The end-of-month portfolio weights are xA,t=0.64 and xB,t=0.36. Since Vp,t=1116.08, to rebalance the portfolio we need VA,t=VB,t=558.04. This requires selling 152.19 of asset A and purchasing 152.19 of asset B and the end-of-month t. Then, at the beginning of month t+1 we have VA,t=VB,t=558.04 and xA,t=xB,t=0.5.

The above calculations in R are:

value.table = matrix(0, 4, 3)
rownames(value.table) = c("t-3", "t-2", "t-1", "t")
colnames(value.table) = c("V.A", "V.B", "V.p")
value.table["t-3", ] = c(V.A[1], V.B[1], V.p[1])
for (t in 2:4) {
  value.table[t, "V.A"] = value.table[t-1, "V.A"]*(1 + R.A[t-1])
  value.table[t, "V.B"] = value.table[t-1, "V.B"]*(1 + R.B[t-1])
  value.table[t, "V.p"] = value.table[t, "V.A"] + value.table[t, "V.B"]
  RB = max(value.table[t, "V.A"], value.table[t, "V.B"]) - value.table[t, "V.p"]/2
  if (value.table[t, "V.A"] > value.table[t, "V.B"]) {
    value.table[t, "V.A"] = value.table[t, "V.A"] - RB
    value.table[t, "V.B"] = value.table[t, "V.B"] + RB
    }
  else{
    value.table[t, "V.A"] = value.table[t, "V.A"] + RB
    value.table[t, "V.B"] = value.table[t, "V.B"] - RB
  }
  value.table[t, "V.p"] = value.table[t, "V.A"] + value.table[t, "V.B"]
}
value.table
##          V.A      V.B      V.p
## t-3 500.0000 500.0000 1000.000
## t-2 625.0000 625.0000 1250.000
## t-1 608.7662 608.7662 1217.532
## t   558.0357 558.0357 1116.071

Notice that the rebalanced portfolio slightly outperforms the buy-and-hold portfolio.

The portfolio return each period can be computed using Rp,t=%ΔVp,t:

diff(value.table[, "V.p"])/value.table[1:3, "V.p"]
##         t-2         t-1           t 
##  0.25000000 -0.02597403 -0.08333333

It can also be computed using Rp,t=0.5×RA,t+0.5×RB,t:

0.5*R.A + 0.5*R.B
## [1]  0.25000000 -0.02597403 -0.08333333

Here, we see that the rebalanced portfolio loses less money over month t1 than the buy-and-hold portfolio.

1.3.1.3 Rebalance portfolio at specified dates

When the portfolio is rebalanced to a fixed initial portfolio, such as an equaly weighted portfolio, on specific dates the portfolio return calculations become a hybrid of those used for scenarios 1 and 2. The portfolio return is computed as Rp,t=xA,t1×RA,t+xB,t1×RB,t, where xi,t1(i=A,B) are equal to the initial portfolio weights on the rebalancing dates and is computed like the buy-and-hold weights in between the rebalancing dates.

1.3.1.4 Actively managed portfolio

In an actively managed portfolio, the portfolio weights are chosen by the portfolio manager at each time period. Many mutual funds are managed in this way. The return on the actively managed portfolio is computed as Rp,t=xA,t1×RA,t+xB,t1×RB,t where xA,t1 and xB,t1 are the portolio weights chosen by the portfolio manager at the beginning of time t.

1.3.2 Continuously Compounded Portfolio Returns

The continuously compounded portfolio return is defined by (1.18), where Rt is computed using the portfolio return (1.24). However, notice that: rp,t=ln(1+Rp,t)=ln(1+ni=1xiRi,t)ni=1xiri,t, where ri,t denotes the continuously compounded one-period return on asset i. Hence, the continuously compounded portfolio return is not a share weighted average of the individual asset continuously compounded returns. However, if the portfolio return Rp,t=ni=1xiRi,t is not too large then rp,tRp,t otherwise, Rp,t>rp,t.

Example 1.20 (Compute continuously compounded portfolio returns)

Consider a portfolio of Microsoft and Starbucks stock with xmsft=0.25, xsbux=0.75, Rmsft,t=0.0588, Rsbux,t=0.0503 and Rp,t=0.02302. Using ((1.26)), the continuously compounded portfolio return is: rp,t=ln(10.02302)=ln(0.977)=0.02329. Using rmsft,t=ln(1+0.0588)=0.0572 and rsbux,t=ln(10.0503)=0.05161, notice that: xmsftrmsft+xsbuxrsbux=0.02442rp,t

Because the continuously compounded portfolio return is not a share weighted average of the individual asset continuously compounded returns, the analysis of portfolios is typically performed using simple returns and not continuously compounded returns.


  1. This example is inspired by the return.portfolio vignette in PerformanceAnalytics).↩︎