Beispiel #1
0
    def __init__(self, r, fee=0., fee_freq='Q', start=None, end=None,
                 lookback={}, strict=False, dist_amt=None, dist_pct=None,
                 dist_freq=None, v0=float(1e6), include_start=True, freq='M',
                 name=None,  in_format='num'):

        self.gross = returns.prep(r=r, freq=freq, name=name,
                                  in_format=in_format)

        # fee_freq: if str -> frequency; if int/float -> periods/yr
        # Get `fee` to a per-period float
        if isinstance(fee_freq, (int, float)):
            self.fee_freq = fee_freq
            self.fee = fee / self.fee_freq
        elif isinstance(fee_freq, str):
            self.fee_freq = utils.convertfreq(fee_freq)
            self.fee = fee / self.fee_freq

        # Logic for interaction of `start`, `end`, and `lookback`
        # TODO: how should lookback be passed? Consider params to
        # `constrain_horizon`
        if any((start, end)) and not lookback:
            self.gross = self.gross[start:end]
        elif lookback:
            # TODO: cleanup
            self.gross = utils.constrain_horizon(self.gross, **lookback)
        elif all((any((start, end)), lookback)):
            raise ValueError('if `lookback` is specified, both `start` and'
                             ' `end` should be None')

        self.index = self.gross.index
        self.columns = self.gross.columns

        masktypes = {12. : 'is_month_end',
                     4. : 'is_quarter_end',
                     1. : 'is_quarter_end'}

        mask = getattr(self.index, masktypes[self.fee_freq])
        self.feesched = np.where(mask, self.fee, 0.)

        # Net of fees (not yet of distributions)
        self.net = (1. + self.gross.values) \
                 * (1. - self.feesched.reshape(-1,1)) - 1.
        self.net = DataFrame(self.net, index=self.index, columns=self.columns)

        self.dist_amt = dist_amt
        self.dist_pct = dist_pct
        self.dist_freq = dist_freq
        self.v0 = v0
        self.include_start = include_start
Beispiel #2
0
def amortize(rate, nper, pv, freq='M'):
    """Construct an amortization schedule for a fixed-rate loan.

    Rate -> annualized input

    Example
    =======
    # a 6.75% $200,000 loan, 30-year tenor, payments due monthly
    # view the 5 final months
    print(amortize(rate=.0675, nper=30, pv=200000).round(2).tail())
         beg_bal     prin  interest  end_bal
    356  6377.95 -1261.32    -35.88  5116.63
    357  5116.63 -1268.42    -28.78  3848.22
    358  3848.22 -1275.55    -21.65  2572.67
    359  2572.67 -1282.72    -14.47  1289.94
    360  1289.94 -1289.94     -7.26    -0.00
    """

    freq = utils.convertfreq(freq)
    rate = rate / freq
    nper = nper * freq

    periods = np.arange(1, nper + 1, dtype=int)

    principal = np.ppmt(rate, periods, nper, pv)
    interest = np.ipmt(rate, periods, nper, pv)
    pmt = np.pmt(rate, nper, pv)

    def balance(pv, rate, nper, pmt):
        dfac = (1 + rate)**nper
        return pv * dfac - pmt * (dfac - 1) / rate

    res = DataFrame(
        {
            'beg_bal': balance(pv, rate, periods - 1, -pmt),
            'prin': principal,
            'interest': interest,
            'end_bal': balance(pv, rate, periods, -pmt)
        },
        index=periods)['beg_bal', 'prin', 'interest', 'end_bal']

    return res