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```