예제 #1
0
def randTSGen(F0, Sigma, Kappa, StartDate, EndDate):

    ts = curve.Curve()
    factors = len(Sigma)

    date = StartDate
    ts[date] = F0

    F = F0
    while tenor.RDateAdd('1d', date, Holidays=[]) <= EndDate:
        lastDate = date
        date = tenor.RDateAdd('1d', date, Holidays=[])

        dt = (date - lastDate).days / 365.0
        tau = (EndDate - date).days / 365.0

        x = 0.0
        for sig, kap in zip(Sigma, Kappa):
            x = x - 0.5 * sig**2 * math.exp(
                -2 * kap * tau) * dt + sig * math.exp(
                    -kap * tau) * math.sqrt(dt) * random.gauss(0, 1)

        F = F * math.exp(x)
        ts[date] = F

    return ts
예제 #2
0
def CF_DeltaHedge(IsCall,
                  ts,
                  strike,
                  vol,
                  expiryT,
                  rd=0.0,
                  rf=0.0,
                  rehedgingTenor="1d",
                  exceptionDateList=[]):

    Dates = ts.Dates()
    Prices = ts.Values()

    # annualized days
    startD = Dates[0]
    endD = Dates[-1]
    lastPrice = ts[startD]
    lastTau = (expiryT - startD).days / YEARLY_DAYS

    date = tenor.RDateAdd(rehedgingTenor, startD, exceptionDateList)
    CF = 0.0
    while date < endD:
        if date in ts.Dates():
            CF = CF + bsopt.BSDelta(IsCall, lastPrice, strike, vol, lastTau,
                                    rd, rf) * (ts[date] - lastPrice)
            lastPrice = ts[date]
            lastTau = (expiryT - date).days / YEARLY_DAYS

        date = tenor.RDateAdd(rehedgingTenor, date, exceptionDateList)

    CF = CF + bsopt.BSDelta(IsCall, lastPrice, strike, vol, lastTau, rd,
                            rf) * (ts[endD] - lastPrice)
    return CF
예제 #3
0
def BS_ConstDelta_VolSurf(tsFwd,
                          moneynessList,
                          expiryT,
                          rd=0.0,
                          rf=0.0,
                          exceptionDateList=[]):
    ts = curve.Curve()
    rptTenor = '-1m'
    rehedgingTenor = '1d'
    IsCall = 1

    for d in tsFwd.Dates():
        if d not in exceptionDateList:
            ts[d] = tsFwd[d]

    DateList = [x for x in ts.Dates() if x not in exceptionDateList]
    TSstart = DateList[0]
    TSend = DateList[-1]

    date = copy.copy(TSend)
    endDate = tenor.RDateAdd('1d', date)
    startDate = tenor.RDateAdd(rptTenor, date, exceptionDateList)

    volTS = curve.GRCurve()
    while startDate >= TSstart:
        subTS = ts.Slice(startDate, endDate)
        vol = []
        if len(subTS) < 2:
            print 'No data in time series further than ', startDate
            break

        if 0.0 in subTS.Values():
            print 'Price is zero at some date from ', startDate, ' to ', endDate
            break

        # for the moment, consider ATM vol
        for m in moneynessList:
            strike = subTS.Values()[0] * m
            if IsCall:
                finalValue = max((subTS.Values()[-1] - strike), 0)
            else:
                finalValue = max((strike - subTS.Values()[-1]), 0)

        vol += [
            BSrealizedVol(IsCall, subTS, strike, expiryT, rd, rf, finalValue,
                          rehedgingTenor, exceptionDateList)
        ]
        if None in vol:
            print 'no vol is found to match PnL- strike:' + str(
                m) + ' expiry:' + expiryT

        volTS[startDate] = vol
        startDate = tenor.RDateAdd(rptTenor, startDate, exceptionDateList)

    return volTS
예제 #4
0
def BSrealizedVol(IsCall,
                  ts,
                  strike,
                  expiryT,
                  rd=0.0,
                  rf=0.0,
                  optPayoff=0.0,
                  rehedgingTenor="1d",
                  exceptionDateList=[],
                  refVol=0.5):
    startD = ts.Dates()[0]
    endD = ts.Dates()[-1]

    if tenor.RDateAdd(rehedgingTenor, startD, exceptionDateList) > endD:
        raise ValueError, 'the difference between the start and the end is smaller than the hedging step'

    if expiryT < endD:
        raise ValueError, 'Expiry time must be later than the end of the time series'

    F0 = ts.Values()[0]

    numTries = 0
    diff = 1000.0
    tau = (expiryT - startD).days / YEARLY_DAYS
    vol = refVol

    def func(x):
        return bsopt.BSOpt(IsCall, F0, strike, x, tau, rd, rf) + CF_DeltaHedge(
            IsCall, ts, strike, x, expiryT, rd, rf, rehedgingTenor,
            exceptionDateList) - optPayoff

    while diff >= SOLVER_ERROR_EPSILON and numTries <= ITERATION_NUM:
        current = func(vol)
        high = func(vol + ITERATION_STEP)
        low = func(vol - ITERATION_STEP)
        if high == low:
            volnext = max(vol - ITERATION_STEP, 1e-2)
        else:
            volnext = vol - 2 * ITERATION_STEP * current / (high - low)
            if volnext < 1e-2:
                volnext = vol / 2.0

        diff = abs(volnext - vol)
        vol = volnext
        numTries += 1

    if diff >= SOLVER_ERROR_EPSILON or numTries > ITERATION_NUM:
        return None
    else:
        return vol
예제 #5
0
def rand2DTSGen(F0, Sigma, Kappa, rho, StartDate, EndDate):

    ts1 = curve.Curve()
    ts2 = curve.Curve()

    date = StartDate
    ts1[date] = F0[0]
    ts2[date] = F0[1]

    P = F0[0]
    G = F0[1]

    while tenor.RDateAdd('1d', date, Holidays=[]) <= EndDate:
        lastDate = date
        date = tenor.RDateAdd('1d', date, Holidays=[])

        dt = (date - lastDate).days / 365.0
        tau = (EndDate - date).days / 365.0

        y1 = random.gauss(0, 1)
        y2 = y1 * rho + math.sqrt(1 - rho**2) * random.gauss(0, 1)

        x1 = -0.5 * Sigma[0]**2 * math.exp(
            -2 * Kappa[0] * tau) * dt + Sigma[0] * math.exp(
                -Kappa[0] * tau) * math.sqrt(dt) * y1
        x2 = -0.5 * Sigma[1]**2 * math.exp(
            -2 * Kappa[1] * tau) * dt + Sigma[1] * math.exp(
                -Kappa[1] * tau) * math.sqrt(dt) * y2

        P = P * math.exp(x1)
        G = G * math.exp(x2)

        ts1[date] = P
        ts2[date] = G

    return ts1, ts2
예제 #6
0
def BS_ATMVol_TermStr(IsCall,
                      tsFwd,
                      expiryT,
                      rd=0.0,
                      rf=0.0,
                      endVol=0.0,
                      termTenor="1m",
                      rehedgingTenor="1d",
                      exceptionDateList=[]):

    ts = curve.Curve()
    for d in tsFwd.Dates():
        if d not in exceptionDateList and d <= expiryT:
            ts[d] = tsFwd[d]

    rptTenor = '-' + termTenor
    DateList = [x for x in ts.Dates() if x not in exceptionDateList]
    TSstart = DateList[0]
    TSend = DateList[-1]

    date = copy.copy(TSend)
    endDate = tenor.RDateAdd('1d', date)
    startDate = tenor.RDateAdd(rptTenor, date, exceptionDateList)
    finalValue = 0.0

    volTS = curve.Curve()
    while startDate >= TSstart:
        subTS = ts.Slice(startDate, endDate)

        if len(subTS) < 2:
            print 'No data in time series further than ', startDate
            break

        if 0.0 in subTS.Values():
            print 'Price is zero at some date from ', startDate, ' to ', endDate
            break

        # for the moment, consider ATM vol
        strike = subTS.Values()[0]

        if endVol > 0:
            tau = (expiryT - subTS.Dates()[-1]).days / YEARLY_DAYS
            finalValue = bsopt.BSOpt(IsCall,
                                     subTS.Values()[-1], strike, endVol, tau,
                                     rd, rf)
            refVol = endVol
        elif endVol == 0:
            if IsCall:
                finalValue = max((subTS.Values()[-1] - strike), 0)
            else:
                finalValue = max((strike - subTS.Values()[-1]), 0)
            refVol = 0.5
        elif endVol == None:
            raise ValueError, 'no vol is found to match PnL'

        vol = BSrealizedVol(IsCall,
                            subTS,
                            strike,
                            expiryT,
                            rd,
                            rf,
                            finalValue,
                            rehedgingTenor,
                            exceptionDateList,
                            refVol=refVol)
        volTS[startDate] = vol
        endVol = vol

        date = startDate
        endDate = tenor.RDateAdd('1d', date)
        startDate = tenor.RDateAdd(rptTenor, date, exceptionDateList)

    return volTS