**Welcome to THETAWIKI**. If you like to create or edit a page please make sure to login or register an account. All registered users please make sure to provide a valid email address.

# Tips and Tricks

## ThetaML Tips and Tricks

When working with ThetaML, there are various techniques which can be used to improve the speed and accuracy of Monte-Carlo simulations with ThetaML models. This section explains the most important ones.

### Nested ifs improve speed

- Avoid evaluating conditional functions that returns zero

The most costly operation in pricing options is the evaluation of conditional stochastic functions such as `E`

and `Beta`

. The time complexity of such an operation is at least of order O(n2) with n as the number of Monte-Carlo paths. In many cases, we can selectively reduce the simulated paths to the most relevant ones before doing any computations with the conditional functions `E`

and `Beta`

.

As an example, consider the following `if … end`

block:

if E(V_CUR!) < (K – S)*CUR V_CUR = (K – S)*CUR end

Since we know in advance that `E(V_CUR!)`

must be greater than zero, we restrict the whole computations to those simulation paths where `(K – S)*CUR`

is greater than zero.

if 0 < (K – S)*CUR if E(V_CUR!)< (K – S)*CUR V_CUR = (K – S)*CUR end end

As an example, a selected part of the American Option is shown below.

if E(V)< K*EUR-S V= K*EUR-S end

Since we know in advance that `E(V)`

must be greater than zero, we restrict the whole computation to those simulation paths where `K*EUR-S`

is also greater than zero.

if 0 < K*EUR-S if E(V)< K*EUR-S V= K*EUR-S end end

### Reducing variance by hedging improves convergence

- The
`Beta`

function reduces the variance of simulated option prices thus increases the accuracy of price estimates.

The following two models "American" and "American_hedged" have similar runtimes but the model "American_hedged" returns option values of higher precision as a result of using the `Beta`

function.

model American % Model American simulates prices for an American put option import S "Stock prices" import CUR "Discount factors" import sigma "Volatility" import r "Interest rate" import K "Strike price" export P "Option value" % current option value P = E(V_CUR!) % time to maturity of the option T = 1 % n loops, assuming daily exercise interval and % 252 trading days in a year n = 252*T loop n % evaluate optimal exercise conditions, compare estimated % discounted hold values E(V_CUR!) with discounted % intrinsic values, for all Monte-Carlo paths if E(V_CUR!) < (K - S)*CUR V_CUR = (K - S)*CUR end % time passing of T/n theta T/n end % at maturity, option payoffs are discounted to time 0 V_CUR = max(K - S,0)*CUR end

model American_hedged % Model American_hedged simulates the optimal hedge of an % American put option; note that this hedge is variance % optimal for any underlying process S import S "Stock prices" import CUR "Discount factors" import sigma "Volatility" import r "Interest rate" import K "Strike price" export P "Option value" % current option value P = E(Pi_CUR!) % time to maturity T = 1 %n loops n = 250*T loop n % hedge the discounted portfolio Pi_CUR using Beta function Pi_CUR = Pi_CUR! – Beta(S!*CUR!,Pi_CUR)*(S!*CUR! - S*CUR) % evaluate optimal exercise conditions, compare estimated % discounted hold values E(Pi_CUR!) with discounted % intrinsic values, for all Monte-Carlo paths if E(Pi_CUR!) < (K – S)*CUR Pi_CUR = (K – S)*CUR end % time passing of T/n theta T/n end % at option maturity, the hedged portfolio has the same value % distribution as the discounted option payoffs Pi_CUR = V_CUR! % at maturity, the option payoff is discounted to time 0 V_CUR = max(K - S,0)*CUR end

### Adding control variables can improve accuracy

- using additional information available, we can significantly improve the numerical accuracies of conditional expected values such as
`E`

and`Beta`

In the model "European_S_control", the underlying `S` is simulated with no drift, as such we can use its price at time 0 as an estimate of its expected value at time 1. We can then use this knowledge to compute a better estimate `P` for the expected value of `V_CUR` as follows:

model European_S_control % Pricing a European put option with S as control variable import S "Stock prices" import CUR "Discount factors" import K "Option strike price" export P "Option price" % use S as control variable for better price estimates P P = V_CUR! -Beta(S_control!,V_CUR!) * (S_control! - S) % 1 time unit passes theta 1 % S_control has expected value S S_control = S % at maturity, the option payoff is discounted to time 0 % S is already discounted since it is simulated with no drift V_CUR = max(K*CUR - S,0) end

We can even go a little further and include other knowledge like the closed-form solution of a European option price (`'myBlsprice'`) and use it to estimate an American option price:

% Pricing an American put option with a European put option as % control variable model American_Vcontrol import S "Stock prices" import CUR "Discount factors" import K "Option strike price" import sigma "Volatility" import r "Risk-free rate" export P "Option price" % use European option V_control as control variable % V_control has expected value V_ref P = V_CUR! -Beta(V_control,V_CUR) * (V_control! - V_ref!) % V_ref is computed using the closed form formula for the % European put option; the function arguments for myBlsprice % are respectively: stock price, strike price, volatility, % interest rate, option maturity, and option type ‘call’; % the option price V_ref is discounted to time 0 by CUR, this % is to be consistent with its simulated counterpart V_control V_ref = myBlsprice(S, K, sigma, r, 1, 0)*CUR %loop 52 times loop 52 % time passing of one week theta 1/52 % early exercise evaluation: compare the expected discounted % hold values E(V_CUR!) with discounted option intrinsic % values, for all the Monte-Carlo simulation paths if E(V_CUR!) < (K - S)*CUR V_CUR = (K - S)*CUR end end % at maturity 1, the control variable V_control has the same % discounted payoffs as the American put option V_CUR V_control = V_CUR! % at maturity 1, the payoff is discounted to time 0 V_CUR = max(K - S,0)*CUR end

Hint: `myBlsprice()` can be found at Black-Scholes Option Pricing

### Avoiding direct assignment of expected values improves accuracy

- We can improve the accuracy of option price estimates by avoiding direct assignments of the expected values from functions
`E`

and`Beta`

The expected value function `E`

generates approximation errors and should only be used when a (statistical) expected value is required. For example, in a compound option, it advisable not to use the `E`

function for both decisional and computational steps:

model compound ... theta 1 %time 1 outer option payoffs, E(V_inner) is the expected value %of the inner option conditional on time 1 information V = max( E(V_inner!)- K, 0 ) theta 1 %time 2 inner option payoffs V_inner = max(S - K_inner,0) end

Instead, the decisional and computational parts should be separated as follows:

model compound ... theta 1 % at time 1, evaluate the outer option payoffs % E(V_inner!) is the expected value of the inner option, % conditional on time 1 information if E(V_inner!) - K > 0 V = V_inner! - K else V = 0 end theta 1 % at time 2, inner option payoffs V_inner = max(S - K_inner,0) end

### Keep export variables unique

- Export variables serve to report (return) results of a model. If they are also used to store temporary results, the exported results will get clogged. This situation can be avoided by keeping assignments to export variables unique.

In the following code, the first instance of `x`

is a temporary result that gets incorrectly reported:

model test export x % results of x get clogged ... x = x/(n-1) % x has the temporary results x = x + S/n ... end

Storing the intermediate results in a temporary variable keeps the reporting of `x`

unique:

x_tmp = x % store x in a temporary variable x_tmp x_tmp = x_tmp/(n-1) % doing computations with x_tmp x_tmp = x_tmp + S/n % doing computations with x_tmp x = x_tmp % assign x_tmp to x and report x

## Stochastic Processes

### Increase accuracy by using sub-steps in an Euler discretization

The Euler discretization scheme of a stochastic process usually requires small time steps in order to achieve accurate numerical results. Using ThetaSuite Analyzer with simple time-stepping might be too coarse. However, this can be avoided by using sub-steps similar to the following ones shown in Theta.m:

function state = Theta(dt, state) if nargin == 0 : state.r.comment = "Stochastic variable"; : else : max_dt = 0.1; % Sample Euler steps with higher frequency if "dt" is too big for i = 1 : floor(dt/max_dt) state.r= ... end % compute remaining time for last step dt_rest = max(0, dt-max_dt*floor(dt/max_dt)); state.r= ... : end end