-
-
Notifications
You must be signed in to change notification settings - Fork 322
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed pandas issue with append and lots of small bugs
- Loading branch information
Showing
17 changed files
with
553 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import pandas as pd | ||
from os.path import dirname, join | ||
|
||
import sys | ||
sys.path.append("..") | ||
|
||
|
||
from financepy.utils.date import Date | ||
from financepy.utils.math import ONE_MILLION | ||
from financepy.utils.global_types import SwapTypes | ||
from financepy.utils.frequency import FrequencyTypes | ||
from financepy.utils.day_count import DayCountTypes | ||
from financepy.utils.calendar import Calendar, CalendarTypes | ||
from financepy.market.curves.interpolator import InterpTypes | ||
from financepy.products.rates.ibor_swap import IborSwap | ||
from financepy.products.rates.ibor_fra import IborFRA | ||
from financepy.products.rates.ibor_deposit import IborDeposit | ||
from financepy.products.rates.ibor_future import IborFuture | ||
from financepy.products.rates.ibor_single_curve import IborSingleCurve | ||
|
||
from financepy.products.rates.ibor_benchmarks_report import ibor_benchmarks_report, dataframe_to_benchmarks | ||
|
||
|
||
def test_ibor_benchmarks_report(): | ||
valuation_date = Date(6, 10, 2001) | ||
cal = CalendarTypes.UNITED_KINGDOM | ||
interp_type = InterpTypes.FLAT_FWD_RATES | ||
|
||
depoDCCType = DayCountTypes.ACT_360 | ||
depos = [] | ||
spot_days = 2 | ||
settlement_date = valuation_date.add_weekdays(spot_days) | ||
depo = IborDeposit(settlement_date, "3M", 4.2/100.0, depoDCCType, cal_type=cal) | ||
depos.append(depo) | ||
|
||
fraDCCType = DayCountTypes.ACT_360 | ||
fras = [] | ||
fra = IborFRA(settlement_date.add_tenor("3M"), "3M", 4.20/100.0, fraDCCType, cal_type=cal) | ||
fras.append(fra) | ||
|
||
swaps = [] | ||
swapType = SwapTypes.PAY | ||
fixedDCCType = DayCountTypes.THIRTY_E_360_ISDA | ||
fixedFreqType = FrequencyTypes.SEMI_ANNUAL | ||
|
||
swap = IborSwap(settlement_date, "1Y", swapType, 4.20/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "2Y", swapType, 4.30/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "3Y", swapType, 4.70/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "5Y", swapType, 5.40/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "7Y", swapType, 5.70/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "10Y", swapType, 6.00/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "12Y", swapType, 6.10/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "15Y", swapType, 5.90/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "20Y", swapType, 5.60/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "25Y", swapType, 5.55/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
|
||
# Create but do not build the initial curve | ||
do_build = True | ||
curve = IborSingleCurve(valuation_date, depos, fras, swaps, | ||
interp_type, check_refit=False, do_build=do_build) | ||
|
||
bechmarks_report = ibor_benchmarks_report(curve) | ||
|
||
# print(bechmarks_report) | ||
|
||
# Confirm that there are no NaNs. In particular this means that different types of benchmarks | ||
# return exactly the same keys, just like we want it, with a couple of exceptions | ||
assert (bechmarks_report | ||
.drop(columns=['fixed_freq_type', 'fixed_leg_type']) | ||
.isnull().values.any() | ||
) == False | ||
|
||
|
||
def test_dataframe_to_benchmarks(): | ||
path = dirname(__file__) | ||
filename = "ibor_benchmarks_example.csv" | ||
full_filename_path = join(path, "data", filename) | ||
|
||
asof = Date(6, 10, 2001) | ||
|
||
df = pd.read_csv(full_filename_path, index_col=0) | ||
df['start_date'] = pd.to_datetime(df['start_date'], errors='ignore') # allow tenors | ||
df['maturity_date'] = pd.to_datetime(df['maturity_date'], errors='ignore') # allow tenors | ||
|
||
benchmarks = dataframe_to_benchmarks( | ||
df, asof_date=asof, calendar_type=CalendarTypes.UNITED_KINGDOM) | ||
|
||
assert len(benchmarks['IborDeposit']) == 2 | ||
assert len(benchmarks['IborFRA']) == 1 | ||
assert len(benchmarks['IborSwap']) == 10 | ||
|
||
|
||
if __name__ == '__main__': | ||
test_ibor_benchmarks_report() | ||
test_dataframe_to_benchmarks() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import pytest | ||
import pandas as pd | ||
|
||
from financepy.utils.global_types import SwapTypes | ||
from financepy.utils.math import ONE_MILLION | ||
from financepy.utils.global_vars import gBasisPoint | ||
from financepy.market.curves.interpolator import InterpTypes | ||
from financepy.products.rates.ibor_swap import IborSwap | ||
from financepy.products.rates.ibor_fra import IborFRA | ||
from financepy.products.rates.ibor_deposit import IborDeposit | ||
from financepy.products.rates.ibor_future import IborFuture | ||
from financepy.products.rates.ibor_single_curve import IborSingleCurve | ||
from financepy.products.rates.ibor_single_curve_par_shocker import IborSingleCurveParShocker | ||
from financepy.utils.frequency import FrequencyTypes | ||
from financepy.utils.day_count import DayCountTypes | ||
from financepy.utils.date import Date | ||
from financepy.utils.calendar import Calendar, CalendarTypes | ||
|
||
|
||
def test_ibor_curve_par_rate_shocker(): | ||
valuation_date = Date(6, 10, 2001) | ||
cal = CalendarTypes.UNITED_KINGDOM | ||
interp_type = InterpTypes.FLAT_FWD_RATES | ||
|
||
depoDCCType = DayCountTypes.ACT_360 | ||
depos = [] | ||
spot_days = 2 | ||
settlement_date = valuation_date.add_weekdays(spot_days) | ||
depo = IborDeposit(settlement_date, "3M", 4.2/100.0, depoDCCType, cal_type=cal) | ||
depos.append(depo) | ||
|
||
fraDCCType = DayCountTypes.ACT_360 | ||
fras = [] | ||
fra = IborFRA(settlement_date.add_tenor("3M"), "3M", 4.20/100.0, fraDCCType, cal_type=cal) | ||
fras.append(fra) | ||
|
||
swaps = [] | ||
swapType = SwapTypes.PAY | ||
fixedDCCType = DayCountTypes.THIRTY_E_360_ISDA | ||
fixedFreqType = FrequencyTypes.SEMI_ANNUAL | ||
|
||
swap = IborSwap(settlement_date, "1Y", swapType, 4.20/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "2Y", swapType, 4.30/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
swap = IborSwap(settlement_date, "3Y", swapType, 4.70/100.0, fixedFreqType, fixedDCCType, cal_type=cal) | ||
swaps.append(swap) | ||
|
||
base_curve = IborSingleCurve(valuation_date, depos, fras, swaps, InterpTypes.FLAT_FWD_RATES, ) | ||
curve_shocker = IborSingleCurveParShocker(base_curve) | ||
mat_dates = curve_shocker.benchmarks_report()['maturity_date'].values | ||
|
||
# size of bump | ||
par_rate_bump = 1*gBasisPoint | ||
|
||
# expected forward rate changes in the periods before and after the maturity date of the bumped benchmark | ||
# in basis points | ||
expected_fwd_rate_changes = {1: (1.00000, 0.0), | ||
2: (1.00000, -0.50715), | ||
4: (2.06214, -2.16773)} | ||
|
||
# Which benchmarks we test-bump. They are | ||
# - The first (and only) depo we used in construction. Here index = 1 (not 0) because | ||
# ibor_single_curve creates a synthetic deposit for the stub implictly | ||
# - The only FRA | ||
# - the 2Y swap | ||
benchmark_idxs = [1, 2, 4] | ||
for benchmark_idx in benchmark_idxs: | ||
bumped_curve = curve_shocker.apply_bump_to_benchmark(benchmark_idx, par_rate_bump) | ||
|
||
d1 = mat_dates[benchmark_idx-1] | ||
d2 = mat_dates[benchmark_idx] | ||
d3 = mat_dates[benchmark_idx+1] | ||
|
||
base_fwd_before = base_curve.fwd_rate(d1, d2) | ||
base_fwd_after = base_curve.fwd_rate(d2, d3) | ||
bumped_fwd_before = bumped_curve.fwd_rate(d1, d2) | ||
bumped_fwd_after = bumped_curve.fwd_rate(d2, d3) | ||
|
||
actual_fwd_rate_changes = ((bumped_fwd_before-base_fwd_before)/gBasisPoint, | ||
(bumped_fwd_after-base_fwd_after)/gBasisPoint) | ||
|
||
assert round(actual_fwd_rate_changes[0], 3) == round(expected_fwd_rate_changes[benchmark_idx][0], 3) | ||
assert round(actual_fwd_rate_changes[1], 3) == round(expected_fwd_rate_changes[benchmark_idx][1], 3) | ||
|
||
|
||
if __name__ == '__main__': | ||
test_ibor_curve_par_rate_shocker(); | ||
|
Oops, something went wrong.