Exemple #1
0
    def calc_futures_payoff(self, maturity=None):
        ''' calculate futures payoff given updated maturity as year fraction '''

        if maturity and isinstance(
                maturity, (str, intdate.bdte.BusinessDate, intdate.dt.date)):
            mat = intdate.convert_date_bdte(maturity, self.options)
        else:
            mat = self.maturity

        mult = 0.01 * intdate.calc_bdte_diff(mat, self.options, self.reset)

        if mat != max(self.cash_flow_df.index):
            print("Warning -- mismatch %s %s  shape %d" %
                  (mat.to_date(), max(
                      self.cash_flow_df.index), self.cash_flow_df.shape[0]))
            if self.cash_flow_df.shape[0] == 1:
                self.cash_flow_df.loc[mat.to_date(), 'maturity'] =\
                    intdate.calc_bdte_diff(mat, self.options)
            elif self.cash_flow_df.shape[0] == 2:
                self.cash_flow_df.index = [self.reset.to_date(), mat.to_date()]
                self.cash_flow_df.loc[mat.to_date(), 'maturity'] =\
                    intdate.calc_bdte_diff(mat, self.options)

            else:
                raise ValueError("Faulty dimansions for futures contract")

            self.cash_flow_df.loc[mat.to_date(), 'time_diff'] =\
                self.cash_flow_df.loc[mat.to_date(), 'maturity'] -\
                    self.cash_flow_df.loc[self.reset.to_date(), 'maturity']

        self.cash_flow_df.loc[mat.to_date(), 'CF'] = self.princ +\
            mult*self.princ*self.spot
Exemple #2
0
    def init_prices(self, prices):
        ''' results in the case of yields '''
        mult = 100.0

        for i in np.arange(0, self.matrix.shape[0]):
            sched = self.schedule[i]
            if i == 0:
                self.matrix.loc[sched, 'zero'] = 1.0
                schedprev = 0
            else:
                mat = intdate.calc_bdte_diff(self.schedule[i], self.date_spec,
                                             self.schedule[0])

                self.matrix.loc[sched, 'yield'] = -mult * np.log(
                    prices[i - 1] / mult) / mat

                self.matrix.loc[sched, 'maturity'] = mat

                self.matrix.loc[sched, 'date_diff'] = intdate.calc_bdte_diff(
                    self.schedule[i], self.date_spec, self.schedule[i - 1])

                if i > 1:
                    self.matrix.loc[sched,
                                    ['forward', 'yield_hat']] = self.forward(
                                        sched, schedprev)
                else:
                    self.matrix.loc[sched, 'yield_hat'] = self.f0(mat)
                    self.matrix.loc[sched,
                                    'forward'] = self.matrix.loc[sched,
                                                                 'yield_hat']

                self.matrix.loc[sched, 'zero'] = np.exp(
                    -self.matrix.loc[sched, 'yield_hat'] * mat / mult)

                schedprev = sched
def load_data_row(options,
                  df=None,
                  dates=None,
                  position=0,
                  rate=0.15,
                  date='2012-10-02',
                  typ='LIBOR',
                  ref_position=-1,
                  dbg=True):
    ''' DEPRECATED -- see curve constructor
    Loader -- operates based on typ
    '''
    if df is not None and isinstance(df, np.ndarray) and\
            int(df.size / len(df)) == len(options['control']["columns"]):
        if dbg:
            print("Fine Dimensions")
    else:
        df, dates = build_arrays(options, dbg=dbg)

    dates[position] = dt.datetime.strptime(date,
                                           options['control']["date_format"])
    if "origin" in options['control']["columns"]:
        df[position][4] = intbase.load_types.MARKET.value

    if typ.upper().startswith('LIBOR'):
        df[position][0] = intdate.calc_bdte_diff(dates[position], options)
        df[position][1] = rate
        df[position][2] = intbase.calc_libor_zero_coupon(rate, df[position][0])
        df[position][3] = intbase.rate_instruments.LIBOR.value
    elif typ.upper().startswith("FUTUR"):
        df[position][0] = intdate.calc_bdte_diff(dates[position], options)
        df[position][1] = intbase.futures_rate(rate)

        if 0 <= ref_position < position:
            df[position][2] = intbase.calc_forward_zero_coupon(
                df[position][1], (df[position][0] - df[ref_position][0]),
                df[ref_position][2])

        df[position][3] = intbase.rate_instruments.FUTURE.value
    elif typ.upper().startswith("SWAP"):
        df[position][0] = intdate.calc_bdte_diff(dates[position], options)
        df[position][1] = rate

        if 0 <= ref_position < position:
            df[position][2] = intbase.calc_swap_zero_coupon(
                rate, df, position, ref_position)

        df[position][3] = intbase.rate_instruments.SWAP.value
    else:
        raise ValueError("Type not supported")

    return df, dates
Exemple #4
0
    def determine_reference_date(self, instrument):
        ''' deterimines reference date and maturity '''
        refereposition = None
        maturity = np.nan

        if instrument in self.options['instruments'].keys():
            reference_date = self.options['instruments'][instrument]['ref_date']
        elif int(self.results.loc[instrument]['origin']) == 2:
            x0_nme = self.options['interpolated_instruments'][instrument]['reference_positions'][0]
            x1_nme = self.options['interpolated_instruments'][instrument]['reference_positions'][1]

            if self.options['instruments'][x0_nme]['date'] <=\
                    self.options['instruments'][x1_nme]['date']:
                x1_nme = x0_nme

            reference_date = self.options['instruments'][x1_nme]['ref_date']
        else:
            raise ValueError("Faulty FUTURES")

        refereposition = self.determine_instrument_name(reference_date)
        # print(refereposition, inst, "\n")
        # print(self.results.loc[inst], self.results.loc[refereposition])
        if not isinstance(refereposition, bool) and refereposition in self.results.index:
            maturity = self.results.loc[refereposition, 'maturity']
        else:
            maturity = intdate.calc_bdte_diff(reference_date, self.options)

        return reference_date, maturity
Exemple #5
0
    def append_swaps(self):
        ''' Appends SWAPs interpolated SWAPs '''
        self.next_swap_key = self.next_swap_key - 1

        for _, item in self.options['interpolated_swaps'].items():
            strt = intdate.convert_date_bdte(item['lower_date'], self.options)
            end = intdate.convert_date_bdte(item['upper']['date'], self.options)

            per = intdate.convert_period(item['upper']['frequency'])

            sched = bdte.BusinessSchedule(strt, end, per)
            if 'control' in self.options.keys() and\
                    'date_adjust' in self.options['control'].keys() and\
                    self.options['control']['date_adjust'] in ['follow', 'flw', 'modified']:
                # key adjusts sched for business date -- print("Here")
                sched.adjust(self.options['control']['date_adjust'])


            date_diff_final = intdate.calc_bdte_diff_int(
                end, strt, self.options, dbg=False)

            if self.dbg:
                print("## ", self.next_swap_key, strt, end, date_diff_final)

            self.next_swap_key = (self.next_swap_key + date_diff_final)
            if 'control' in self.options.keys() and 'date_adjust' in\
                    self.options['control'].keys():
                if not strt.is_business_day():
                    strt.adjust(self.options['control']['date_adjust'])
                if not end.is_business_day():
                    end.adjust(self.options['control']['date_adjust'])

            date_diff_dbl = intdate.calc_bdte_diff(end, self.options, strt)
            key = "".join(["SWAP", str(self.next_swap_key)])
            # self.calc_next_swap_key(key)
            self.instruments[key] = swapconv.build_swap(key, item['upper'], self.options, dbg=False)
            self.append_instrument_dates_swap(key)
            swap_key = self.find_swap(min(sched))
            swap_strt = int(swap_key.upper().split("AP")[1])

            for loc, dte in zip(np.arange(0, len(sched)), sched):
                if  min(sched) < dte < max(sched):
                    new_swap_dict, new_swap_name = swapconv.generate_swap_dictionary(
                        self.options, maturity=dte, swap_start=strt,
                        swapid=(swap_strt + loc), reference="SWAP1",
                        rates=[[0.0, date_diff_dbl],
                               [self.instruments[swap_key].r_swap, self.instruments[key].r_swap]],
                        dbg=False)

                    self.instruments[new_swap_name] = swapconv.build_swap(
                        new_swap_name, new_swap_dict, self.options, dbg=False)

                    self.append_instrument_dates_swap(new_swap_name)
Exemple #6
0
    def init_forward(self, rates):
        ''' inittializes structure in the case of forwards '''
        mult = 100.0  # calculate results in percents

        for i in np.arange(0, self.matrix.shape[0]):
            if i == 0:
                self.matrix.loc[i, 'zero'] = 1.0
            else:
                self.matrix.loc[i, 'forward'] = rates[i - 1]
                self.matrix.loc[i, 'maturity'] = intdate.calc_bdte_diff(
                    self.schedule[i], self.date_spec, self.schedule[0])

                self.matrix.loc[i, 'date_diff'] = intdate.calc_bdte_diff(
                    self.schedule[i], self.date_spec, self.schedule[i - 1])
                self.matrix.loc[i, 'zero'] = intbase.calc_forward_zero_coupon(
                    self.matrix.loc[i, 'forward'],
                    self.matrix.loc[i, 'date_diff'], self.matrix.loc[(i - 1),
                                                                     'zero'])

                self.matrix.loc[i, 'yield'] = mult*(-1)*np.log(self.matrix.loc[i, 'zero'])/\
                    self.matrix.loc[i, 'maturity']
 def __init__(self, name, strike, swap, options, dbg=False):
     self.options = options
     self.debug = dbg
     if isinstance(swap, intrate.swap):
         self.reference_instrument = swap
         self.maturity = swap.reset
     elif isinstance(swap, json):
         self.maturity = intdate.convert_date_bdte(swap['reset_date'],
                                                   options)
         self.reference_instrument = build_swap("SWAP",
                                                swap,
                                                options,
                                                dbg=self.debug)
     else:
         raise ValueError("Must be type JSON or swap")
     self.maturity_dbl = intdate.calc_bdte_diff(self.maturity, self.options)
     self.strike = strike
     self.name = name
     self.notional = self.reference_instrument.princ
Exemple #8
0
    def load_data_row(self, position='LIBOR1', rate=0.15, date='2012-10-02',
                      typ='LIBOR', origin=None):
        ''' Loader -- operates based on typ '''

        if "origin" in self.options['control']["columns"] and origin is None:
            self.results.loc[position]['origin'] = intbase.load_types.MARKET.value
        elif "origin" in self.options['control']["columns"] and\
                isinstance(origin, (int, float)):
            self.results.loc[position]['origin'] = origin

        if isinstance(date, float):
            mat = date
        else:
            mat = intdate.calc_bdte_diff(date, self.options)
        # print(position, date, mat)

        if typ.upper().startswith('LIBOR'):
            self.results.loc[position]['maturity'] = mat
            self.results.loc[position]['rate'] = rate
            self.results.loc[position]['type'] = intbase.rate_instruments.LIBOR.value

        elif typ.upper().startswith("FUTUR"):
            self.results.loc[position]['maturity'] = mat
            self.results.loc[position]['rate'] = intbase.futures_rate(rate)
            self.results.loc[position]['type'] = intbase.rate_instruments.FUTURE.value
        elif typ.upper().startswith("SWAP"):
            self.results.loc[position]['maturity'] = mat
            self.results.loc[position]['rate'] = rate
            self.results.loc[position]['type'] = intbase.rate_instruments.SWAP.value
        elif typ.upper().startswith("FIXEDCOUPONBO") or typ.upper().startswith("ZERO"):
            self.results.loc[position]['maturity'] = mat
            self.results.loc[position]['rate'] = rate
            self.results.loc[position]['type'] = intbase.rate_instruments.ZERO_COUPON.value if\
                typ.upper().startswith("ZERO") else intbase.rate_instruments.FIXED_RATE_BOND.value
        else:
            raise ValueError("Type not supported")

        self.results.loc[position, 'loaded'] = 1
Exemple #9
0
    def interpolate_instruments(self, result_position, item_dict):
        ''' Simple linear interpolator that constructs interpolated instrument of same time
        result_position: location (numpy -- row) where results stored, determines location of date
        result_date: maturity date of instrument / rate -- determines weightings
        position1: location in df of left value used in interpolation
        position2: location in df of right valued used in interpolation
        '''
        if self.results.loc[item_dict['reference_positions'][0]]['maturity'] <=\
                self.results.loc[item_dict['reference_positions'][1]]['maturity']:
            position1 = item_dict['reference_positions'][0]
            position2 = item_dict['reference_positions'][1]
        else:
            position2 = item_dict['reference_positions'][0]
            position1 = item_dict['reference_positions'][1]

        if int(self.results.loc[position1]['type']) == int(self.results.loc[position2]['type']):
            if 'type' in item_dict.keys():
                typ = item_dict['type']
            else:
                typ = self.options['instruments'][position1]['type']

            mat = intdate.calc_bdte_diff(item_dict['date'], self.options)

            dist = self.results.loc[position2]['maturity'] - self.results.loc[position1]['maturity']
            q = (mat - self.results.loc[position1]['maturity']) / dist

            rate = (1- q)*self.results.loc[position1]['rate'] +\
                    q*self.results.loc[position2]['rate']

            if result_position.upper().startswith('LIBOR'):
                self.load_data_row(position=result_position, rate=rate, date=item_dict['date'],
                                   typ='LIBOR', origin=intbase.load_types.INTERPOLATED.value)
            else:
                if position1 in self.options['instruments'].keys():
                    if typ.upper().startswith("FUTUR"):
                        self.instruments[result_position] = intrate.interest_rate_future(
                            result_position, rate, maturity=item_dict['date'],
                            reset=self.instruments[position1].reset,
                            frequency=self.instruments[position1].frequency,
                            options=self.options, dbg=False)


                        self.load_data_row(
                            position=result_position,
                            rate=self.instruments[result_position].rate,
                            date=self.instruments[result_position].maturity,
                            typ='FUTURE', origin=intbase.load_types.INTERPOLATED.value)
                    else:
                        self.load_data_row(position=result_position, rate=rate,
                                           date=item_dict['date'],
                                           typ=typ, origin=intbase.load_types.INTERPOLATED.value)
                else:
                    print("Warning no item %s loaded" % (result_position))

            if self.dbg:
                print("Interpolate Results: %f %f  %d  %d" % (
                    self.results.loc[result_position]['maturity'],
                    self.results.loc[result_position]['rate'],
                    int(self.results.loc[result_position]['type']),
                    int(self.results.loc[result_position]['origin'])))

        else:
            raise ValueError("(interpolate_instruments): Instrument Types MUST MATCH")
def generate_swap_dictionary(options,
                             maturity,
                             swap_start=None,
                             swapid=0,
                             reference="SWAP1",
                             rates=None,
                             princ=1.0,
                             frequency='Y',
                             reset_date=None,
                             to_equal_T0=False,
                             dbg=False):
    ''' constructs dictionary of swap assumptions necessary to construction of swap instrument
    options: python dict including control and instruments dictionaries
    maturity: maturity of constructed swap
    swap_start: aplies in case interpolating between two swap rates
    swapid: string applied to identify SWAP
    reference: refers to swap of same name in options['instruments']
    rates: asscepts (1) single float or (2) 2x2 conformable matrix object
    NOTE: items procede by asterisk are applied only in case not reference object provided
    princ (*): principal
    frquency (*): frequency of swap payments
    reset_date (*) date (date conformable object) of reset
    to_equal_T0 (*) bool indicating whether valuation time equals reset date
    dbg: debugging indicator
    returns: (1) swap specfication dict (2) swap_name
    '''
    if reference and isinstance(reference, str):
        if 'instruments' in options.keys(
        ) and reference in options['instruments'].keys():
            new_swap_dict = options['instruments'][reference].copy()
        else:
            raise ValueError(
                "genrate_swap_dictionary: missing instruments + reference")
    else:
        if dbg:
            print("Warning -- applying default SWAP definition ")
        new_swap_dict = {
            'type': 'SWAP',
            'princ': princ,
            'frequency': frequency,
            'reference_rate': 'LIBOR',
            'to_equal_T0': to_equal_T0
        }
        new_swap_dict['reset_date'] = reset_date

    new_swap_dict['date'] = maturity

    if rates and isinstance(rates, float) and np.isfinite(rates):
        new_swap_dict['rate'] = rates
        new_swap_dict['is_market'] = 1
    elif rates and isinstance(rates,
                              (list, np.ndarray)) and np.size(rates) > 3:
        new_swap_dict['is_market'] = 0
        if isinstance(rates, list) and len(rates) == 2:
            np_rates = np.array(rates, ndmin=2)
        elif isinstance(rates, np.ndarray):
            np_rates = rates.copy()
        else:
            raise ValueError("genrate_swap_dictionary: faulty rates spec")

        date_diff_dbl2 = intdate.calc_bdte_diff(maturity, options, swap_start)
        new_swap_dict['rate'] = sci.interp(date_diff_dbl2,
                                           xp=np_rates[0],
                                           fp=np_rates[1])
    else:
        new_swap_dict['rate'] = np.nan
        new_swap_dict['is_market'] = 0
        print("Warning (genrate_swap_dictionary): faulty rates specifcation")

    if swapid > 0:
        new_swap_name = "".join(["SWAP", str(swapid)])
    else:
        new_swap_name = "SWAP"

    return new_swap_dict, new_swap_name
def interpolate_instruments(result_position,
                            result_date,
                            position1,
                            position2,
                            options,
                            df,
                            dates,
                            dbg=False):
    ''' Simple linear interpolator that constructs interpolated instrument of same time
    result_position: location (numpy -- row) where results stored, determines location of date
    result_date: maturity date of instrument / rate -- determines weightings
    position1: location in df of left value used in interpolation
    position2: location in df of right valued used in interpolation
    options: controls dictionary
    df:     numpy containing interpolation inputs and result interpolation
    dates: date numpy 9.96400000e+01array containing dates (in dt.datetime)
    dbg: determines whether to output intermediate results from interpolation
    '''
    if int(df[position1][3]) == int(df[position2][3]):
        if "origin" in options['control']["columns"]:
            df[result_position][4] = intbase.load_types.INTERPOLATED.value

        if isinstance(result_date, str):
            dates[result_position] = dt.datetime.strptime(
                result_date, options['control']["date_format"])
        elif isinstance(result_date, bdte.BusinessDate):
            init_date = result_date.to_date()
            dates[result_position] = dt.datetime(init_date.year,
                                                 init_date.month,
                                                 init_date.day, 0, 0)
        else:
            dates[result_position] = result_date

        df[result_position][0] = intdate.calc_bdte_diff(
            dates[result_position], options)

        dist = df[position2][0] - df[position1][0]
        q = (df[result_position][0] - df[position1][0]) / dist
        df[result_position][1] = (1 -
                                  q) * df[position1][1] + q * df[position2][1]

        df[result_position][3] = df[position1][3]

        if int(df[position1][3]) == 1:
            df[result_position][2] = intbase.calc_libor_zero_coupon(
                df[result_position][1], df[result_position][0])

        elif int(df[position1][3]) == 2 or int(df[position1][3]) == 3:
            df[result_position][2] = intbase.calc_forward_zero_coupon(
                df[result_position][1],
                (df[result_position][0] - df[position1][0]), df[position1][2])

        if dbg:
            print("Interpolate Results: %d %f (%f) %f  %d" %
                  (df[result_position][0], df[result_position][1],
                   (df[result_position][0] - df[position1][0]),
                   df[result_position][2], int(df[result_position][3])))

    else:
        raise ValueError(
            "(interpolate_instruments): Instrument Types MUST MATCH")

    return df, dates