Skip to content

Commit 4bf2ccf

Browse files
committed
Added type hints to models folder
1 parent 386c880 commit 4bf2ccf

34 files changed

+1372
-554
lines changed

financepy/models/bachelier.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,24 @@ class Bachelier:
2121

2222
####################################################################################
2323

24-
def __init__(self, volatility):
25-
24+
def __init__(self, volatility: float) -> None:
2625
"""Create FinModel black using parameters."""
26+
27+
if volatility <= 0.0:
28+
raise FinError("Volatility must be positive")
29+
2730
self.volatility = volatility
2831

2932
####################################################################################
3033

3134
def value(
32-
3335
self,
34-
forward_rate, # Forward rate F
35-
strike_rate, # Strike Rate K
36-
time_to_expiry, # Time to Expiry (years)
37-
df, # Discount Factor to expiry date
38-
call_or_put,
39-
): # Call or put
36+
forward_rate: float, # Forward rate F
37+
strike_rate: float, # Strike Rate K
38+
time_to_expiry: float, # Time to Expiry (years)
39+
df: float, # Discount Factor to expiry date
40+
call_or_put: OptionTypes, # Call or put
41+
) -> float:
4042
"""Price a call or put option using Bachelier's model."""
4143
f = forward_rate
4244
t = time_to_expiry
@@ -54,7 +56,7 @@ def value(
5456

5557
####################################################################################
5658

57-
def __repr__(self):
59+
def __repr__(self) -> str:
5860

5961
s = label_to_string("OBJECT TYPE", type(self).__name__)
6062
s += label_to_string("VOLATILITY", self.volatility)

financepy/models/bdt_tree.py

Lines changed: 103 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
########################################################################################
1919

2020

21-
def option_exercise_types_to_int(option_exercise_type):
21+
def option_exercise_types_to_int(option_exercise_type: FinExerciseTypes) -> int:
2222
"""Convert the option exercise type to an integer for use in the tree."""
2323
if option_exercise_type == FinExerciseTypes.EUROPEAN:
2424
return 1
@@ -38,7 +38,15 @@ def option_exercise_types_to_int(option_exercise_type):
3838
fastmath=True,
3939
cache=True,
4040
)
41-
def f(x0, m, q_matrix, rt, df_end, dt, sigma):
41+
def f(
42+
x0: float,
43+
m: int,
44+
q_matrix: np.ndarray,
45+
rt: np.ndarray,
46+
df_end: float,
47+
dt: float,
48+
sigma: float,
49+
) -> float:
4250

4351
# x is the middle value on the short-rate on the tree
4452
midm = int(m / 2)
@@ -69,7 +77,15 @@ def f(x0, m, q_matrix, rt, df_end, dt, sigma):
6977
fastmath=True,
7078
cache=True,
7179
)
72-
def search_root(x0, m, q_matrix, rt, df_end, dt, sigma):
80+
def search_root(
81+
x0: float,
82+
m: int,
83+
q_matrix: np.ndarray,
84+
rt: np.ndarray,
85+
df_end: float,
86+
dt: float,
87+
sigma: float,
88+
) -> float:
7389
"""Search for the root of the function using a numerical method."""
7490
max_iter = 10
7591
max_error = 1e-8
@@ -101,20 +117,20 @@ def search_root(x0, m, q_matrix, rt, df_end, dt, sigma):
101117

102118
@njit(fastmath=True, cache=True)
103119
def bermudan_swaption_tree_fast(
104-
t_exp,
105-
t_mat,
106-
strike_price,
107-
face_amount,
108-
cpn_times,
109-
cpn_flows,
110-
exercise_type_int,
111-
df_times,
112-
df_values,
113-
tree_times,
114-
qq,
115-
rt,
116-
dt,
117-
):
120+
t_exp: float,
121+
t_mat: float,
122+
strike_price: float,
123+
face_amount: float,
124+
cpn_times: np.ndarray,
125+
cpn_flows: np.ndarray,
126+
exercise_type_int: int,
127+
df_times: np.ndarray,
128+
df_values: np.ndarray,
129+
tree_times: np.ndarray,
130+
qq: np.ndarray,
131+
rt: np.ndarray,
132+
dt: float,
133+
) -> tuple[float, float]:
118134
"""Option to enter into a swap that can be exercised on coupon payment
119135
dates after the start of the exercise period. Due to non-analytical bond
120136
price we need to extend tree out to bond maturity and take into account
@@ -249,20 +265,20 @@ def bermudan_swaption_tree_fast(
249265

250266
@njit(fastmath=True, cache=True)
251267
def american_bond_option_tree_fast(
252-
t_exp,
253-
t_mat,
254-
strike_price,
255-
face_amount,
256-
cpn_times,
257-
cpn_flows,
258-
exercise_type_int,
259-
_df_times,
260-
_df_values,
261-
_tree_times,
262-
_qq,
263-
_rt,
264-
_dt,
265-
):
268+
t_exp: float,
269+
t_mat: float,
270+
strike_price: float,
271+
face_amount: float,
272+
cpn_times: np.ndarray,
273+
cpn_flows: np.ndarray,
274+
exercise_type_int: int,
275+
_df_times: np.ndarray,
276+
_df_values: np.ndarray,
277+
_tree_times: np.ndarray,
278+
_qq: np.ndarray,
279+
_rt: np.ndarray,
280+
_dt: float,
281+
) -> tuple[float, float]:
266282
"""Option to buy or sell bond at a specified strike price that can be
267283
exercised over the exercise period depending on choice of exercise type.
268284
Due to non-analytical bond price we need to extend tree out to bond
@@ -435,25 +451,25 @@ def american_bond_option_tree_fast(
435451

436452
@njit(fastmath=True, cache=True)
437453
def callable_puttable_bond_tree_fast(
438-
cpn_times,
439-
cpn_flows,
440-
call_times,
441-
call_prices,
442-
put_times,
443-
put_prices,
444-
face_amount,
445-
_sigma,
446-
_a,
447-
_q_matrix, # IS SIGMA USED ?
448-
_pu,
449-
_pm,
450-
_pd,
451-
_rt,
452-
_dt,
453-
_tree_times,
454-
_df_times,
455-
_df_values,
456-
):
454+
cpn_times: np.ndarray,
455+
cpn_flows: np.ndarray,
456+
call_times: np.ndarray,
457+
call_prices: np.ndarray,
458+
put_times: np.ndarray,
459+
put_prices: np.ndarray,
460+
face_amount: float,
461+
_sigma: float,
462+
_a: float,
463+
_q_matrix: np.ndarray, # IS SIGMA USED ?
464+
_pu: float,
465+
_pm: float,
466+
_pd: float,
467+
_rt: np.ndarray,
468+
_dt: float,
469+
_tree_times: np.ndarray,
470+
_df_times: np.ndarray,
471+
_df_values: np.ndarray,
472+
) -> dict[str, float]:
457473
"""Value a bond with embedded put and call options that can be exercised
458474
at any time over the specified list of put and call dates.
459475
Due to non-analytical bond price we need to extend tree out to bond
@@ -586,7 +602,12 @@ def callable_puttable_bond_tree_fast(
586602

587603

588604
@njit(cache=True, fastmath=True)
589-
def build_tree_fast(sigma, tree_times, num_time_steps, discount_factors):
605+
def build_tree_fast(
606+
sigma: float,
607+
tree_times: np.ndarray,
608+
num_time_steps: int,
609+
discount_factors: np.ndarray,
610+
) -> tuple[np.ndarray, np.ndarray, float]:
590611
"""Unlike the BK and HW Trinomial trees, this Tree is packed into the lower
591612
diagonal of a square matrix because of its binomial nature. This means
592613
that the indexing of the arrays is different."""
@@ -660,7 +681,7 @@ class BDTTree:
660681

661682
####################################################################################
662683

663-
def __init__(self, sigma: float, num_time_steps: int = 100):
684+
def __init__(self, sigma: float, num_time_steps: int = 100) -> None:
664685
"""Constructs the Black-Derman-Toy rate model in the case when the
665686
volatility is assumed to be constant. The short rate process simplifies
666687
and is given by d(log(r)) = theta(t) * dt + sigma * dW. Althopugh"""
@@ -689,7 +710,12 @@ def __init__(self, sigma: float, num_time_steps: int = 100):
689710

690711
####################################################################################
691712

692-
def build_tree(self, tree_mat, df_times, df_values):
713+
def build_tree(
714+
self,
715+
tree_mat: float,
716+
df_times: np.ndarray,
717+
df_values: np.ndarray,
718+
) -> None:
693719

694720
if isinstance(df_times, np.ndarray) is False:
695721
raise FinError("DF TIMES must be a numpy vector")
@@ -723,13 +749,13 @@ def build_tree(self, tree_mat, df_times, df_values):
723749

724750
def bond_option(
725751
self,
726-
t_exp,
727-
strike_price,
728-
face_amount,
729-
cpn_times,
730-
cpn_flows,
731-
exercise_type,
732-
):
752+
t_exp: float,
753+
strike_price: float,
754+
face_amount: float,
755+
cpn_times: np.ndarray,
756+
cpn_flows: np.ndarray,
757+
exercise_type: FinExerciseTypes,
758+
) -> dict[str, float]:
733759
"""Value a bond option that can have European or American exercise
734760
using the Black-Derman-Toy model. The model uses a binomial tree."""
735761

@@ -765,14 +791,14 @@ def bond_option(
765791

766792
def bermudan_swaption(
767793
self,
768-
t_exp,
769-
t_mat,
770-
strike,
771-
face_amount,
772-
cpn_times,
773-
cpn_flows,
774-
exercise_type,
775-
):
794+
t_exp: float,
795+
t_mat: float,
796+
strike: float,
797+
face_amount: float,
798+
cpn_times: np.ndarray,
799+
cpn_flows: np.ndarray,
800+
exercise_type: FinExerciseTypes,
801+
) -> dict[str, float]:
776802
"""Swaption that can be exercised on specific dates over the exercise
777803
period. Due to non-analytical bond price we need to extend tree out to
778804
bond maturity and take into account cash flows through time."""
@@ -809,14 +835,14 @@ def bermudan_swaption(
809835

810836
def callable_puttable_bond_tree(
811837
self,
812-
cpn_times,
813-
cpn_flows,
814-
call_times,
815-
call_prices,
816-
put_times,
817-
put_prices,
818-
face_amount,
819-
):
838+
cpn_times: np.ndarray,
839+
cpn_flows: np.ndarray,
840+
call_times: np.ndarray,
841+
call_prices: np.ndarray,
842+
put_times: np.ndarray,
843+
put_prices: np.ndarray,
844+
face_amount: float,
845+
) -> dict[str, float]:
820846
"""Option that can be exercised at any time over the exercise period.
821847
Due to non-analytical bond price we need to extend tree out to bond
822848
maturity and take into account cash flows through time."""
@@ -851,7 +877,7 @@ def callable_puttable_bond_tree(
851877

852878
####################################################################################
853879

854-
def __repr__(self):
880+
def __repr__(self) -> str:
855881
"""Return string with class details."""
856882

857883
s = "Black-Derman-Toy Model\n"

0 commit comments

Comments
 (0)