impShortfall: Implementation Shortfall (IS)

View source: R/impShortfall.R

impShortfallR Documentation

Implementation Shortfall (IS)

Description

Calculate Implementation Shortfall (IS) using a variety of methods from the literature.

Usage

impShortfall(Portfolio, Symbol, paQty, priceStart, priceEnd, arrPrice,
  method = c("Complete", "Perold", "Wagner", "Market"))

Arguments

Portfolio

A portfolio name that points to a portfolio object structured with initPortf()

Symbol

A string identifying the symbol to calculate the Shortfall for

paQty

Paper quantity, the total number of units (such as shares or contracts) intended to trade. If missing, total transaction quantity will be used

priceStart

Decision price, the price at the time of the investment decision

priceEnd

Price at the end of the trading period. If missing, last transaction price will be used

arrPrice

The mid-point of bid-ask spread (or alternatively the Last Price) when order first enters the market. If missing, first transaction price will be used

method

String specifying which method to use for The Implementation Shortfall calculation. One of 'Complete' (default), 'Perold', 'Wagner' or 'Market'

Details

Implementation Shortfall is a measure that represents the total cost of executing the investment idea. Implementation Shortfall is calculated as the difference between the paper return of a portfolio where all shares are assumed to have transacted at the manager's decision price and the actual return of the portfolio using actual transaction prices and shares executed.

IS = Paper Return - Actual Return

where

Paper Return = S . P_{n} - S . P_{d}

S is the total number of shares to trade. For Complete Execution where method="Complete", S will equate to the sum of shares actually executed.

P_{d} is the manager's decision price. For Market Activity IS where method="Market", P_{d} is the Arrival Price and is therefore appropriate for analysis in which the decision price is not known.

P_{n} is the price at the end of the trading horizon, period n. This price is only required for IS measures in which there is unexecuted volume, typically a result of the manager's limit price constraint or a shortage of available liquidity. Nevertheless, for the Complete Execution Method whether or not this param is given we still imply it in the calc in order to report a Paper Return and an Actual Return.

Actual portfolio return is the difference between the actual ending portfolio value and the value that was required to acquire the portfolio minus all fees.

Actual Portfolio Return = (∑ s_{j}) . P_{n} - ∑ s_{j}p_{j} - fees

(∑ s_{j}) represents the total number of shares in the portfolio

(∑ s_{j}) . P_{n} is the ending portfolio value

(∑ s_{j} p_{j} is the price paid to acquire the portfolio

Implementation Shortfall can be implemented in 4 ways:

1. Assuming Complete Execution, in which case trading horizon end price for the opportunity cost (relevant for the Paper Return) is not required, but used never- less. Also, sum of shares executed should equal the original targety continue. This is the default method for Implementation Shortfall

The simplest formulation for the Complete Execution IS method is:

IS = S . P_{avg} - S . P_{d} + fees

Note that we add fees, as a positive metric indicates a cost.

2. Using an Opportunity Cost (Perold 1988) component, where not all shares originally allocated for trading are finally executed. Opportunity Cost is the cost of not executing a portion of the originally allocated shares S for execution. This could be due to limit price constraints or a lack of liquidity.

The formulation for Opportunity Cost is:

(S - ∑ s_{j}) . (P_{n} - P_{d})

The Implementation Shortfall formulation of Perold (1988) can be written as:

IS = ∑ s_{j} . (P_{avg} - P_{d}) + (S - ∑ s_{j}) . (P_{n} - P_{d}) + fees

3. Expanded Implementation Shortfall (Wayne Wagner)

Wayne Wagner's implementation categorizes costs into delay, trading and opportunity related costs. Assuming P_{d} is the decision price, P_{0} is the price when trading begins (ideally Arrival Price, defined as the mid-price at order arrival, alternatively Last Price at order arrival or failing that data availability then first transaction price) and P_{n} is the price at the end of trading. Then the Expanded IS can be written as:

(P_{n} - P_{d}) = (P_{n} - P_{0}) + (P_{0} - P_{d})

If you substitute this price into Perold's IS, then IS can be written as:

IS = (∑ s_{j}p_{j} - ∑ s_{j}P_{d}) + (S - ∑ s_{j}) . ((P_{n} - P_{0}) + (P_{0} - P_{d})) + fees

This formula can be re-written into their separate delay, trading and opportunity cost related components as follows:

Expanded IS = S(P_{0} - P_{d}) + (∑ s_{j})(P_{avg} - P_{0}) + (S - ∑ s_{j})(P_{n} - P_{0}) + fees

where each term (excluding fees) reflects the delay, trading and opportunity cost components respectively. Wagner's method allows for an additional decomposition of the "Delay related cost" into the opportunity delay cost component and the trading delay cost component. Our implementation provides this breakdown in the output.

4. Market Activity IS, which assumes the analyst is unaware of the manager's decision price. This method is equivalent to the Wagner formulation except that the first term is excluded in order to assess only market activity IS:

Market Activity IS = (∑ s_{j})(P_{avg} - P_{0}) + (S - ∑ s_{j})(P_{n} - P_{0}) + fees

Value

Return depends on the method used.

'Complete' - default, return is a data.frame containing:

  • Symbol: The traded symbol for which to calculate the IS

  • Method: The method used

  • Paper.Ret: The paper portfolio return

  • Actual.Ret: The actual portfolio return

  • IS: The Implementation Shortfall measure

'Perold' - return is a data.frame containing:

  • Symbol: The traded symbol for which to calculate the IS

  • Method: The method used

  • t.Txn.Qty: The total number of transacted units

  • u.Txn.Qty: The number of untransacted units

  • Exe.Cost: The execution cost component of the IS

  • Opp.Cost: The Perold's opportunity cost component of the IS

  • Fees: The total fees paid on transactions

  • Shortfall: The Implementation Shortfall measure

'Wagner' - return is a data.frame containing:

  • Symbol: The traded symbol for which to calculate the IS

  • Method: The method used

  • t.Txn.Qty: The total number of transacted units

  • u.Txn.Qty: The number of untransacted units

  • Opp.Delay: The opportunity delay component of the Delay cost

  • Trade.Delay: The trading delay component of the Delay cost

  • Delay.Cost: The delay related component of the IS

  • Trade.Cost: The trading related component of the IS

  • Opp.Cost: The Wagner's opportunity cost component of the IS

  • Fees: The total fees paid on transactions

  • Shortfall: The Implementation Shortfall measure

'Market' - return is a data.frame containing:

  • Symbol: The traded symbol for which to calculate the IS

  • Method: The method used

  • t.Txn.Qty: The total number of transacted units

  • u.Txn.Qty: The number of untransacted units

  • Trade.Cost: The trading related component of the Shortafll

  • Opp.Cost: The Wagner's opportunity cost component of the Shortfall

  • Fees: The total fees paid on transactions

  • Shortfall: The Shortfall measure

Author(s)

Vito Lestingi, Jasen Mackie

References

Kissell, R. The Science of Algorithmic Trading and Portfolio Management (ISBN 978-0-12-401689-7)

Perold, A. F. The implementation shortfall: Paper versus reality. The Journal of Portfolio Management, 1988

Examples

## Not run: 

# set up test_txns assuming all 5k shares traded
test_txns <- xts(cbind(rep(10:11,5),rep(500,10),TxnFees = rep(-10,10)), 
                 seq.POSIXt(as.POSIXct("2000-01-01 09:00:00"),
                 as.POSIXct("2000-01-01 18:00:00"),
                 by = "hours"))
colnames(test_txns) <- c("TxnPrice","TxnQty","TxnFees")

stock.str='tca_test' # what are we trying it on
currency('USD')
stock(stock.str,currency='USD',multiplier=1)
suppressWarnings(rm("account.testport","portfolio.testport",pos=.blotter))
initPortf("testport", symbols=stock.str)
initAcct("testport","testport", symbols=stock.str)
addtxns <- addTxns("testport","tca_test",test_txns)
updatePortf("testport")
p = getPortfolio("testport") # make a local copy of the portfolio object
a = getAccount("testport") # make a local copy of the account object
p$symbols$tca_test$txn

### Complete Execution
shortfall("testport", "tca_test",
          paQty=5000,
          priceStart=10,
          priceEnd=11,
          arrPrice=10,
          method='Complete')

### Market
shortfall("testport", "tca_test",
          paQty=5000, 
          priceEnd=11,
          arrPrice = 10,
          method='Market')

# set up test_txns assuming assuming only 4k shares traded
test_txns <- test_txns[-c(2:3),]
suppressWarnings(rm("account.testport","portfolio.testport",pos=.blotter))
initPortf("testport", symbols=stock.str)
initAcct("testport","testport", symbols=stock.str)
addtxns <- addTxns("testport","tca_test",test_txns)
updatePortf("testport")
p = getPortfolio("testport") # make a local copy of the portfolio object
a = getAccount("testport") # make a local copy of the account object
p$symbols$tca_test$txn

### Perold
shortfall("testport", "tca_test",
          paQty=5000,
          priceStart=10,
          priceEnd=11,
          arrPrice=10,
          method='Perold')

### Wagner
shortfall("testport", "tca_test",
          paQty=5000,
          priceStart=10,
          priceEnd=11,
          arrPrice=10.25,
          method='Wagner')


## End(Not run) #end dontrun


braverock/blotter documentation built on Feb. 13, 2023, 1 p.m.