# Accumulator option pricing

An accumulator is a financial derivative that is sometimes known as "I kill you later". This post attempts to explain how it is structured and price it via Monte Carlo simulations in Python.

## 1. Overview of Accumulator¶

Like all derivatives, there are two parties invovled in an accumulator, the buyer and the seller, both agree on a strike price that is usually at a discount to the prevailing market price of the underlying security at the time of contract origination.

• The buyer has the obligation to buy certain amount of the underlying security at the predetermined strike price.
• The seller has the obligation to sell the specified amount of the underlying security at the strike price to the buyer.

The accumulator is settled periodically throughout its term. At each settlement:

• If the market price of the underlying security is above the predetermined knock-out price, the contract is terminated.
• If the market price of the underlying security is between the knock-out price and the strike price, the buyer "accumulates" the underlying security at the strike price.
• If the market price of the underlying security is below the strike price, the buyer is obligated to buy the underlying security at the strike price at 2 (or more) times of the predetermined amount.

## 2. An Example 6-month Accumulator¶

Let's make up an example so as to illustrate how it works.

## 3. Some Observations¶

In the example above:

• I've accumulated in total of 6,000 shares of TSC at a cost of $90 per share. This implies that an accumulator is like a forward contract and helps the buyer lock in the cost of acquiring the underlying security (why it's also known as share forward accumulator). • As long as the share price is between the strike price and knock-out price, the buyer can accumulate shares at a discount. • The 6-month accumulator terminates in 5 months because of the knock out and so the seller's loss is limited. • When the share price is below the strike price, the buyer accumulates more shares but at a loss. All these taken together, we can find that the buyer has: 1. a limited upside potential because the potential gain is capped by the knock-out price and zero when knocked out, and 2. a disproportional (limited) downside in that any loss is amplified by the doubled amount of shares he or she has to purchase from the seller when share price is below the strike. But this is not the full story. Another hidden feature is that while the accumulator is terminated when the share price is above the knock-out price, the contract does not terminate when the buyer is at a loss untill it matures. So, even though the maximum losses of both the buyer and the seller are fixed, but they differ significantly and disproportionately. If so, why would anyone become interested in buying the contract? Potentially it's because the strike is set to be lower at market price, therefore at the beginning the buyers always feel like they are taking advantages. They may also think that once the price increases to above the knock-out level, which might be set to slightly higher than market price, the contract is terminated so they are free of any loss. However, the buyers often underestimate the probability of a price decline and how big the impact it will have on accumulator buyers. The "I kill you later" earns its name for a reason. ## 4. Some Math ...¶ Let's make some notations. • Strike price is $K$ • Share price at time $t$ is $S_t$ • Knock-out price is $K^+$ • The amount of shares to buy is: • $A$ when $K, and • $cA$ when $S_t>K^+$, where $c>1$ • There are $N$ settlements So at each settlement, the payoff matrix conditional on the contract not terminated in the previous settlement is: Share Price Buyer's Payoff Seller's Payoff $S_t>K^+$ 0 0 $K\le S_t\le K^+$ $A(S_t-K)\ge0$ $-A(S_t-K)\le0$ $S_t $c A(S_t-K)<0$ $-cA(S_t-K)>0$ However, deriving a closed-end analytical solution is not easy since there are many settlements in the contract and the total payoff is path-dependent (the knock out). There is a conference paper in 2009 discussing the issue and the PDF version is available here. ## 5. ... A Simulation Approach¶ I am to going to use Monte Carlo simulations to find out the distribution of buyer's payoff. ### 5.1. Assumptions¶ For simplicity, I'm going to make the following assumptions: • the share price when the contract is signed $S_t=\100$. • the strike price and the knock-out price are symmetric around$100.
• the strike price $K=100-k$
• the knock-out price $K^+=100+k$
• the contract lasts for a year with 12 settlements and each month end.
• the amount of shares to buy in each settlement:
• $A=1,000$ if the share price at settlement is between the strike price and the knock-out price.
• $A=2,000$ if the share prices settlement is below the strike price.
• the monthly stock returns follow a normal distribution with mean zero and a standard deviation of $\sigma$.

Then, there are only two variables: $k$ and $\sigma$ that I will need to vary!

### 5.2. Core Code¶

The simulation code I write below leverages Numba to speed up the calculation.

For 1 million simulations per pair of $(k, \sigma)$, it takes about 2 seconds on my laptop with JIT and almost 1 minute without it.

  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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import random import numpy as np from collections import OrderedDict from numba import jitclass, int32, float32 @jitclass(OrderedDict({ 'times': int32, 'strike_price': float32, 'knock_out_price': float32, 'volatility': float32 })) class FastSimulation: def __init__(self, times, strike_price, knock_out_price, volatility): self.times = times self.strike_price = strike_price self.knock_out_price = knock_out_price self.volatility = volatility def run(self): np.random.seed(1) buyer_payoffs = [] for i in range(self.times): # generate 12 monthly returns from a normal distribution # written this way as size parameter is not supported by numba returns = [np.random.normal( loc=0, scale=self.volatility)/100 + 1 for _ in range(12)] # convert returns to a price array prices = np.asarray(returns).cumprod() * 100 payoff = 0 for price in prices: # the accumulator is terminated immediately if price > self.knock_out_price: break payoff += self.buyer_payoff(price) buyer_payoffs.append(payoff) return buyer_payoffs def buyer_payoff(self, share_price): "Buyer payoff conditional on the accumulator not terminated" if share_price > self.knock_out_price: return 0 payoff = 1000 * (share_price - self.strike_price) if self.strike_price <= share_price <= self.knock_out_price: return payoff else: return payoff * 2 

### 5.3. Results¶

Numbers are boring. So here I put two plots showing the distribution of the buyer's payoffs.

### 6. Discussion¶

Apparently, the accumulator is a very interesting and sometimes evil derivative. From the plots above we can notice several things:

1. When volatility is low, an accumulator gives the buyer an opportunity to accumulate shares at a discount and therefore positive payoffs.
2. When volatility is high, the buyer's payoff distribution becomes increasingly negatively skewed.
3. The maximum potential payoff is capped and decreasing in volatility but VaR is increasing in the volatility.
4. ......

Hence, as a buyer of an accumulator, you win small with low volatility but lose big and huge with high volatility. I don't think any rational investor would like to take the long position. However, we do find exceptions, like CITIC Limited lost HK\$15 billion in accumulators back in 2008.

Last update: May 22, 2020