Black-Scholes program for the HP-12C

## Black-Scholes program for the HP-12C

That was a funny challenge: cramming the Black-Scholes equation in an HP-12C.

### Usage

• Fill "i" register with the interest, as usual (e.g. 12 for 12% per year).
• Fill "PV" with the spot value of the underlying asset.
• Fill "PMT" with the volatility, as a percentage (e.g. 25 for 25% per year).
• Fill "n" with the time to expiration. Use the same time unit as interest and volatility. If you enter interest and volatility as % per year, you must supply the time to expiration expressed in years (e.g. 2 months = 0.1666 years).
• Fill "FV" with the strike of the option.
• Press R/S to get the call value. It takes several seconds.
• The value on display is the call value. Press x⇄y to see the put value, and again to go back to the call value.

The option parameters are not changed during calculation, so you can fiddle with them and press R/S as many times as you want.

### The program

Opcode #OperationRemarks
0.196854
STO 3N(x) 1st coefficient
0.115194
STO 4N(x) 2nd coefficient
0.000344
STO 5N(x) 3rd coefficient
0.019527
STO 6N(x) 4th coefficient
f P/RGoes into programming mode
f CLEAR PRGMClears programming memory
06RCL n t
07RCL i 100.r
08% rt
08CHS -rt
08exe-rt
16RCL FV K
13× K.e-rt
02STO EPX √t
15RCL PV S
15÷ K.e-rt/S
151/x S.ert/K
18g LN ln(S/K) + rt
02STO 0 √t
01RCL n t
02g √x √t
03RCL PMT 100.σ
04% √t.σ
17STO ÷ 0 S/K
05STO 2 Let mem2 = √t.σ
102
17÷ S/K
05STO - 0 Let mem2 = √t.σ
05RCL 0 Let mem2 = √t.σ
324 calculate cummulative normal distribution
33Yxd4
34RCL 6 c4
35x⇄y
36× c4.d4
37g LSTx d4
38g √x d2
39RCL 4 c2
40x⇄y
41× c2.d2
42g LSTx d2
43g √x d (guaranteed to be positive)
44RCL 3 c1
45× c1.d
46+ c1.d+c2.d2
47+ c1.d+c2.d2+c4.d4
48RCL 0 d
496
50Yxd6
51g √x d3 (guaranteed to be positive)
52RCL 5 c3
53× c3.d3
54+ c1.d+c2.d2 + c3.d3 + c4.d4
551
56+ 1+c1.d+c2.d2 + c3.d3 + c4.d4
574
58CHS
59Yx(1+c1.d+c2.d2 + c3.d3 + c4.d4) - 4
602
61÷ (1+c1.d+c2.d2 + c3.d3 + c4.d4) - 4/2
620 Current result is 1-N(abs(d))
63RCL 0
64g x≤y d < 0?
65GTO 72 d<0, N(d)=1-N(-d), we are done, jump ahead
66R↓ d>0, need to do 1-(1-(N(d))
67R↓ Restore 1-N(d) into register X
68CHS
691
70+ N(d) corrected, we are done
72R↓ Restore N(d) into register X
73R↓
75RCL 2 mem2 is √t.σ at 1st round, zero otherwise
76g x=0 mem2 is zero?
78RCL + 0 Let mem0 = d2 + √t.σ = d1
79STO - 2 Let mem2 = √t.σ - √t.σ = zero
73R↓ Recalls N(d2)
74STO 1 Let mem1 = N(d2)
80GTO 26 Go back to calculate N(d1)
81R↓ Recalls N(d1)
81RCL PV S
36× S.N(d1)
82STO 0 Let mem0 = S.N(d1)
89RCL EPX K.e-rt
90STO × 1 Let mem1 = K.e-rt.N(d2)
91RCL PV S
92- K.e-rt - S
93RCL 0 S.N(d1)
94RCL 1 K.e-rt . N(d2)
95- S.N(d1) - K.e-rt . N(d2) = Call
96+ Call + K.e-rt - S = Put
97g LSTx Call at X, put at Y
f P/RBack to normal mode

### Implementation remarks

It was difficult to fit the equation in 99 programming steps, and using all steps reduces the available memory, which in turn makes the program more complicated.

The most critical function is the cummulative normal distribution, that we implement using a rational approximation with precision of 4 decimal digits. The coefficients are entered as part of the program but they are stored on memory positions (the STO 3, STO 4... at the beginning of the table). There are better approximations but they could not be fitted in such a small "computer".