コード例 #1
0
def iter_minimizer(Loss, beta_init, loss_args, bounds, max_deal_span,
                   **kwargs):
    i = 0.1

    def callback_print(xk):
        loss = Loss(xk,
                    df=loss_args[0],
                    coupons_cf=loss_args[1],
                    streak_data=loss_args[2],
                    weight_scheme=loss_args[4])
        print(xk, loss)

    #optimization goes in loop until spot rate function will not be bigger
    #than 0 at each point;
    #Z constructs from 0.001 year to 30 year (no bonds with tenor > 30 year)
    while (Z(np.linspace(0.001, 30, 1000), beta_init)).min() < 0 or i == 0.1:
        res = minimize(fun=Loss,
                       x0=beta_init,
                       args=loss_args,
                       bounds=bounds,
                       callback=callback_print,
                       **kwargs)
        beta_init = res.x
        #bounds of teta increases at every iteration by i which itself increases
        #also, as we want to exit negative zone as fast as we can
        bounds = ((0, 1), (None, None), (None, None), (beta_init[-1] + i,
                                                       0.05 * max_deal_span))
        i += 0.1
    return res
コード例 #2
0
def naive_yield_Loss(beta, df, coupons_cf, streak_data, rho=0.2,
                     weight_scheme='no_weight', tau=None):
    '''
    Parameters
    ---------------
    beta: array-like
        Nelson-Siegel's vector of parameters
    df: Pandas Dataframe
        Dataframe of bonds' data
    coupons_cf: Pandas Dataframe
        Dataframe containing bonds' payment cash flows
    streak_data: Pandas Dataframe
        Dataframe containing bonds' payment calendar
    rho: float from 0 to 1, default 0.2
        Weight of oldest deal - only used in
        'vol_time', 'full_vol_time', 'volume_kzt', 'complex_volume' weight schemes
    weight_scheme: str, default 'no_weight'
        weight function used to weight deals
    tau: float, default None
        Use this parameter if only you do 3-variablie minimization.
        Parameter is only used in grid search optimization
    '''
    #if tau is given, then beta is array
    if tau is not None:
        assert beta.shape[0] == 3
        beta = np.append(beta, [tau])
    #estimating price
    #calculatting Loss
    W = weight(beta, df=df, rho=rho, weight_scheme=weight_scheme)
    Loss = (W * np.square(df.ytm.values - Z(df.span / 365, beta))).sum()
    return Loss
コード例 #3
0
ファイル: Loss.py プロジェクト: olkuba/FinancialStability_Lab
def grad(beta,
         data,
         coupons_cf,
         streak_data,
         rho=0.2,
         weight_scheme='no_weight'):
    m = data['span']
    grad_z = []
    teta_m = m / beta[3]
    grad_z.append(1)
    grad_z.append((1 / teta_m) * (1 - np.exp(-teta_m)))
    grad_z.append((1 / teta_m) * (1 - np.exp(-teta_m)) - np.exp(-teta_m))

    teta_m_der = m / (beta[3]**2)
    grad_z.append(
        ((beta[1] + beta[2]) *
         ((1 / m) * (1 - np.exp(-teta_m)) - np.exp(-teta_m) / beta[3]) -
         beta[2] * np.exp(-teta_m) * teta_m_der))
    #calculatting Loss
    W = weight(beta, df=data, rho=rho, weight_scheme=weight_scheme)

    non_grad = W * (data['ytm'] / 100 - Z(m, beta))
    loss_grad = np.zeros_like(beta)
    for i in range(beta.shape[0]):
        loss_grad[i] = -2 * (non_grad * grad_z[i]).sum()
    return loss_grad
コード例 #4
0
def fixed_tau_minimizer(Loss, beta_init, loss_args, bounds, max_deal_span, **kwargs):
    i = 0.1
    beta = beta_init.copy()
    beta.append(loss_args[5])
    def callback_print(xk):
        loss = Loss(xk, df=loss_args[0], coupons_cf=loss_args[1],
                    streak_data=loss_args[2], weight_scheme=loss_args[4],
                    tau=loss_args[5])
        print(xk, loss)
    #optimization goes in loop until spot rate function will not be bigger
    #than 0 at each point;
    #Z constructs from 0.001 year to 30 year (no bonds with tenor > 30 year)

    while (Z(np.linspace(0.001, 30, 1000), beta)).min() < 0 or i == 0.1:
        res = minimize(fun=Loss, x0=beta_init, args=loss_args, bounds=bounds,
                       callback=callback_print, **kwargs)
        beta_init = res.x
        #if Z < 0 than tau will incremeantly increase until Z >= 0
        #from tuple to list and back
        i += 1
        loss_args = list(loss_args)
        loss_args[5] += i
        loss_args = tuple(loss_args)
        #beta change in order to asses new curve
        beta = beta_init.copy()
        beta = np.append(beta, loss_args[5])
    return res
コード例 #5
0
def area_boot(betas_array, tenors):
    spots_boot = pd.DataFrame()
    for i, beta_ in enumerate(betas_array):
        spots_boot[i] = Z(tenors, beta_)
    diff_curve = spots_boot.max(1) - spots_boot.min(1)
    area = np.trapz(diff_curve * 100, tenors)
    av_area = round(area / max(tenors), 3)
    return area, av_area
コード例 #6
0
 def filter_frame(self, loss_frame):
     accepted_ind = []
     for ind in loss_frame.index:
         beta = loss_frame.loc[ind, loss_frame.columns[:-1]]
         spot_rate_curve = Z(self.maturities, beta)
         if (spot_rate_curve >= 0).all():
             accepted_ind.append(ind)
     loss_frame_filtered = loss_frame.loc[accepted_ind, :]
     n_rows = loss_frame.shape[0]
     n_dropped_rows = n_rows - loss_frame_filtered.shape[0]
     print('{0} out of {1} of rows were dropped'.format(
         n_dropped_rows, n_rows))
     return loss_frame_filtered
コード例 #7
0
 def filter_frame(self, loss_frame):
     accepted_ind = []
     for ind in loss_frame.index:
         beta = loss_frame.loc[ind, loss_frame.columns[:-1]]
         spot_rate_curve = Z(self.maturities, beta)
         if (spot_rate_curve >= 0).all():
             accepted_ind.append(ind)
     loss_frame_filtered = loss_frame.loc[accepted_ind, :]
     #printing info about № of dropped rows
     n_rows = loss_frame.shape[0]
     n_dropped_rows = n_rows - loss_frame_filtered.shape[0]
     self.logger.debug(
         f'{n_dropped_rows} out of {n_rows} of rows were dropped')
     return loss_frame_filtered
コード例 #8
0
def iter_minimizer(Loss, beta_init, loss_args, bounds, max_deal_span,
                   **kwargs):
    i = 0.1

    def callback_print(xk):
        loss = Loss(xk,
                    df=loss_args[0],
                    coupons_cf=loss_args[1],
                    streak_data=loss_args[2],
                    weight_scheme=loss_args[4])
        print(xk, loss)

    while (Z(np.linspace(0.001, 30, 1000), beta_init)).min() < 0 or i == 0.1:
        res = minimize(fun=Loss,
                       x0=beta_init,
                       args=loss_args,
                       bounds=bounds,
                       callback=callback_print,
                       **kwargs)
        beta_init = res.x
        bounds = ((0, 1), (None, None), (None, None), (beta_init[-1] + i,
                                                       0.05 * max_deal_span))
        i += 0.1
    return res
コード例 #9
0
    def is_outlier(self, points, thresh=3.5, score_type='mzscore'):
        '''
        Returns a boolean array with True if points are outliers and False
        otherwise.
    
        Parameters:
        -----------
            points : An numobservations by numdimensions array of observations
            thresh : The modified z-score to use as a threshold. Observations with
                a modified z-score (based on the median absolute deviation) greater
                than this value will be classified as outliers.
    
        Returns:
        --------
            mask : A numobservations-length boolean array.
    
        References:
        ----------
            Boris Iglewicz and David Hoaglin (1993), 'Volume 16: How to Detect and
            Handle Outliers', The ASQC Basic References in Quality Control:
            Statistical Techniques, Edward F. Mykytka, Ph.D., Editor.
        '''
        if score_type == 'zscore':
            thresh = 2

            #            if len(points.shape) >= 1:
            #                points = points.loc[:,'ytm'][:,None]

            if (self.inertia) & (len(self.previous_curve) != 0):
                self.logger.debug(
                    f'diff to previous curve, Z-score threshold: {thresh}')
                diff = (
                    points.loc[:, 'ytm'] * 100 -
                    (np.exp(Z(points.loc[:, 'span'] / 365,
                              self.previous_curve)) - 1) * 100)
            else:
                #            self.logger.debug(points)
                self.logger.debug('first filtering')
                mean = np.mean(points.loc[:, 'ytm'])
                diff = (points.loc[:, 'ytm'] - mean)

            sstd = np.std(diff)

            z_score = np.abs(diff / sstd)

        elif score_type == 'mzscore':
            #            if len(points.shape) >= 1:
            #                points = points.loc[:,'ytm'][:,None]

            if (self.inertia) & (len(self.previous_curve) != 0):
                self.logger.debug(
                    f'diff to previous curve, modified Z-score threshold: {thresh}'
                )
                diff = np.abs(points.loc[:, 'ytm'] - (np.exp(
                    par_yield(points.loc[:, 'span'].values /
                              365, self.previous_curve)) - 1)) * 100
            else:
                self.logger.debug('first filtering')
                median = np.median(points.loc[:, 'ytm'])
                #                diff = (points.loc[:,'ytm']*100- median*100)**2
                diff = np.abs(points.loc[:, 'ytm'] - median) * 100

#            sstd = np.sqrt(diff)
            sstd = np.median(diff)  #med_abs_deviation

            z_score = 0.6745 * diff / sstd

        return (z_score, (z_score > thresh), sstd)