Accelerating the pace of engineering and science

# Exotic Options - From Symbolic Modeling to C Code

This example shows how to use Symbolic Math Toolbox, MATLAB Coder, Datafeed Toolbox, and Financial Toolbox to model the exotic Relative Outperformance option in a closed-form manner, symbolically derive option greeks, generate equivalent MATLAB and C/C++ code, and calibrate the model with market data.

This example highlights the following Symbolic Math Toolbox capabilities:

• Using the MuPAD Notebook to define and derive equations of interest
• Controlling the notebook from MATLAB
• Using diff to calculate symbolic derivatives
• Using matlabFunction to convert symbolic results into numeric functions

In addition to Symbolic Math Toolbox, this example requires licenses for MATLAB Coder, Financial Toolbox, and Datafeed Toolbox.

## Define the Parameters of the Model

Financial options can be vanilla or exotic contracts. Vanilla options have standard parameters, and they are often traded on exchanges. Exotic options have nonstandard parameters or underlying assets, and they are traded over the counter.

The values of the input parameters are determined by financial markets data (for example, dividend yield, risk free rate, volatility) and contract specifications (strike price).

Create symbolic variables for vanilla options used by the model.

```syms RiskFree AssetPrice1 AssetPrice2 Strike Sigma1 Sigma2 T
```

In addition, create symbolic variables for exotic options parameters.

```syms Correlation CostOfCarry1 CostOfCarry2
```

The following MuPAD notebook defines the parameters. Create a handle (pointer) nb to this notebook. Then evaluate the notebook using evaluateMuPADNotebook.

```model = 'RelativeOutperformanceOptionModel.mn';
```

After you evaluate the MuPAD notebook, it includes symbolic expressions for call and put prices.

To import these results into the MATLAB workspace, use getVar.

```Call = getVar(nb,'Call');
Put = getVar(nb,'Put');
```

Now, use matlabFunction to convert the symbolic results to numeric MATLAB code.

```Params = [RiskFree AssetPrice1 AssetPrice2 Strike Sigma1 Sigma2 T ...
Correlation CostOfCarry1 CostOfCarry2];
call_ROP = matlabFunction(Call,'vars',Params,'file','call_ROP.m');
put_ROP = matlabFunction(Put,'vars',Params,'file','put_ROP.m');
```

## Derive Greeks

The next step is to compute price sensitivities to changes in different parameters. In the context of financial options, these sensitivities are called option greeks. Among the most important ones are Delta, Gamma, and Vega. Delta and Vega are partial derivatives of the option price with respect to underlying asset price and volatility respectively, while Gamma is a second-order greek that measures the sensitivity of Delta with respect to the underlying asset.

Though greeks have standard forms for vanilla options, computing them for exotic options is not straightforward. However, since you have set up the option models as symbolic closed-form variables, you can symbolically compute greeks, and then derive equivalent MATLAB code.

```delta1_Call = diff(Call,AssetPrice1);
gamma21 = diff(Call,AssetPrice2,AssetPrice1);
vega2 = diff(Call,Sigma2);
```

Convert symbolic greeks to numeric MATLAB functions.

```delta1_Call_ROP = matlabFunction(delta1_Call,'vars',Params,'file','delta1_ROP');
gamma21_ROP = matlabFunction(gamma21,'vars',Params,'file','gamma21_ROP');
vega2_ROP = matlabFunction(vega2,'vars',Params,'file','vega2_ROP');
```

To simplify deployment and integration, options models are often converted to C/C++ code. Convert the numeric versions of the options pricer and greek pricers into MEX code by using MATLAB Coder. MATLAB Coder requires parameter types to be defined. These types can be inferred by passing example parameters as follows.

```codegen call_ROP  -args {0.07,130.00,100.0,1.0,0.3,0.4,0.25,0.5,0.05,0.03}
codegen put_ROP   -args {0.07,130.00,100.0,1.0,0.3,0.4,0.25,0.5,0.05,0.03}
codegen delta1_ROP -args {0.07,130.00,100.0,1.0,0.3,0.4,0.25,0.5,0.05,0.03}
codegen gamma21_ROP -args {0.07,130.00,100.0,1.0,0.3,0.4,0.25,0.5,0.05,0.03}
codegen vega2_ROP  -args {0.07,130.00,100.0,1.0,0.3,0.4,0.25,0.5,0.05,0.03}
```

## Calibrate the Options Model with the Current Data From Financial Market

Suppose you want to price a Relative Outperformance call option on GOOG and AMZN. In other words, you want the payoff to be the ratio of the price of GOOG to the price of AMZN, minus the strike price. Assume that the contract expires in one year, and the risk free rate is 0%.

Now, estimate GOOG and AMZN volatilities as input parameters of the model. First, use Datafeed Toolbox to obtain daily market data for GOOG and AMZN for the last year from Yahoo! Finance.

```conn=yahoo;
toDate=today-1;
fromDate=today-365;
prc_GOOG=trpdata(conn,'GOOG',fromDate,toDate,'d');
last_prc_GOOG = fetch(conn,'GOOG','Last');
prc_AMZN=trpdata(conn,'AMZN',fromDate,toDate,'d');
last_prc_AMZN = fetch(conn,'AMZN','Last');
```

Using Financial Toolbox, convert the obtained market data into a financial time series object for easier manipulation.

```ts_GOOG = fints(prc_GOOG);
ts_AMZN = fints(prc_AMZN);
```

Delay the time-series and generate returns.

```rtn_GOOG = (ts_GOOG - lagts(ts_GOOG))/lagts(ts_GOOG);
rtn_AMZN = (ts_AMZN - lagts(ts_AMZN))/lagts(ts_AMZN);
```

```rtn_GOOG(1)=0;
rtn_AMZN(1)=0;
```

Compute the realized volatility in an annualized form. The realized volatility for GOOG is

```std_GOOG = std(rtn_GOOG);
vol_GOOG = (std_GOOG.series1*sqrt(toDate-fromDate));
```

The realized volatility for AMZN is

```std_AMZN = std(rtn_AMZN);
vol_AMZN = (std_AMZN.series1*sqrt(toDate-fromDate));
```

Define the remaining parameters. Set costs of carry to 0.

```costOfCarry_GOOG = 0;
costOfCarry_AMZN = 0;
```

Set the strike price for the ratio of price of GOOG to price of AMZN to be 20% more than the last value of the ratio.

```Strike_GOOG_by_AMZN = 1.2*last_prc_GOOG.Last/last_prc_AMZN.Last;
```

The asset prices can be defined as follows.

```AssetPrice_GOOG = last_prc_GOOG.Last;
AssetPrice_AMZN = last_prc_AMZN.Last;
```

Finally, compute the relative outperformance call price of the exotic contract. For this, use the MEX version of the option model. Note that the order of parameters in the numeric array, ParamValues, is identical to the order of parameters of the symbolic array, Params, earlier used during the generation of the MATLAB functions.

```ParamValues = [0.0 AssetPrice_GOOG AssetPrice_AMZN Strike_GOOG_by_AMZN ...
vol_GOOG vol_AMZN 1 1 0 0];
inputCell = num2cell(ParamValues);
exotic_price=call_ROP_mex(inputCell{:});
disp('Relative Outperformance option GOOG/AMZN');
fprintf('priced at %.4f for Strike %.2f and Time To Expiry %.2f yrs\n',...
exotic_price,Strike_GOOG_by_AMZN,1);
```
```Relative Outperformance option GOOG/AMZN
priced at 0.0020 for Strike 1.98 and Time To Expiry 1.00 yrs
```