The easy way to price these is of course via Monte Carlo simulation; it is simple to implement and straightforward to accommodate any added contract bells and whistles. But MC is slow and it's tough to get good Greeks out of it. There is of course another way.
Pricing TARF's the PDE way
So the structure is knocked out when/if the accrued amount A reaches the target. This is a strong path dependency feature; but unlike accumulators where the knock out depends on the path of the spot itself (which is already part of the numerical solution), here we need to somehow involve A in the solution. We do that by adding A as an extra pseudo-dimension, discretized by a number of individual 1-D PDE solvers (for Black Scholes, local volatility (LV) model, or local regime switching). Each of these solvers corresponds to an A-level within the range of possible values (from zero to the target).
Solving backwards from maturity, we march the option value in time separately for each solver until we reach a fixing/settlement date (for simplicity here I assume that fixing and settlement dates coincide). There we have a jump condition that must be applied in order to continue solving. More specifically, for each S-grid point on each solver we determine the payment to be made based on the S value and the solver's A level. Adding positive payments to the solver's A, gives us the implied A level that corresponds to each S grid point of the solver just after (in normal time direction) the payment has been made. Given the implied A level we can find the option value there by interpolating from the solutions of the solvers whose A levels are nearest (which we have all marched up to that time point). We do that with say cubic interpolation. The (initial, or rather final) values with which we start solving again towards the next fixing date are then found by adding the payout to the interpolated continuation value.
That is the outline (by the way, this "auxiliary state variable" method can be seen in action when pricing Asian options within the old option pricer in this site). I will stick with the basics here (no volatility model) in order to show that even in this simple setting the implementation leaves enough room for one to come up with a great, or not so great pricing engine.
So each individual solver is solving the Black Scholes pricing PDE using the Crank Nicolson method with Rannacher time-stepping on a non-uniform S-grid that places more points near the strike. This standard building block is well-optimized and one can use it as per above to put together a basic implementation of the TARF pricing engine. I did this and the results while still better than MC, left a lot to be desired in my view. Let's just say that a basic implementation results in a solution that does not behave optimally (and a lot worse than it does for Asian options by the way). So I tried to find ways to improve things. And here I will just give an indication of how much one can improve. The details that make this possible will not be the subject of this short post, but if one really wants to know you can contact me (using the contact form or the email in this paper).
Test cases
The plots below show the numerical (spatial discretization) error for the part of the solution that is of interest (the actual solver S-grid extends further) and assuming the accrued amount today is zero, i.e. A = 0. This may mean we are pricing at the time of issue, or at some time during the lifetime of the contract (in which case target stands for "remaining target"). The error profile is obtained by comparing the solution to that from an optimized engine using NS = 6000 and NT = 500 (this has really, really low spatial discretization error, < $10^{-8}$ to be precise). One CPU (Ryzen 5900X) core was used for the timings shown, though if need be the method is easily parallelized. Code is written in C++ and compiled with gcc on Linux. Interest rates are zero.
First we look at a one year contract with weekly fixings/payments and volatility typical of many FX rates. The knockout type is no pay and the leverage factor is two. The optimized version achieves the desired accuracy in 0.09 seconds, while the basic version needs a lot higher spatial resolution and 5 seconds to come close to that.
By the way, if the aim is a single spot valuation, it is often (but not always) preferable to cluster the grid points around the current spot (typical for example when one solves the PDE in log space). In this case one can get higher efficiency still, i.e. same discretization error in even less CPU time.
Some benchmark valuations
Case | T (yrs) | num. fixings | target | lev. factor | KO type | spot | BS vol | TARF value |
1 | 1 | 52 | 0.3 | 2 | No Pay | 1.06 | 10% | -0.02096094 |
2 | 1 | 52 | 0.5 | 2 | No Pay | 1.06 | 10% | -0.017514630 |
3 | 1 | 52 | 0.7 | 2 | No Pay | 1.06 | 10% | 0.035902523 |
4 | 1 | 52 | 0.3 | 2 | No Pay | 1.1 | 10% | 0.235120763 |
5 | 1 | 52 | 0.3 | 2 | Capped pay | 1.1 | 10% | 0.286424762 |
6 | 1 | 52 | 0.3 | 2 | Full pay | 1.1 | 10% | 0.335294058 |
7 | 1 | 52 | 0.3 | 1 | No Pay | 1.03 | 10% | -0.29368756 |
8 | 1 | 52 | 0.3 | 1 | No pay | 1.1 | 20% | -0.01224772 |
9 | 1 | 52 | 0.7 | 1 | No pay | 1.1 | 20% | 0.037345388 |
10 | 1 | 52 | 0.7 | 1 | Full pay | 1.1 | 20% | 0.152792822 |
11 | 2 | 104 | 0.3 | 1 | No pay | 1.35 | 40% | 0.059232579 |
12 | 2 | 104 | 0.5 | 1 | No pay | 1.35 | 40% | 0.315294774 |
13 | 2 | 104 | 0.5 | 1 | Full pay | 1.1 | 40% | -3.81704655 |