예제 #1
0
def gm2gemrat(data, yearly=256, b=2.5, pc=True):
    '''Compute annualized geometric mean rate and GM(2) parameters.
       Argument pc will present appropriate output in percentage form.
    '''
    #                 k is Pearson kurtosis.
    grate, mu, sigma, k, yearly, N = gemrat(data, yearly, False)
    b = 2 if b <= 1.0 else b
    #   ^sensible correction for violating mathematical assumption.
    try:
        gm2out = gm2_main(k, sigma, b)
    except Exception:
        try:
            b += 0.5
            system.warn("INCREASED b by 0.5 -- attempting resurrection ...")
            gm2out = gm2_main(k, sigma, b)
        except Exception:
            b += 0.5
            system.warn("INCREASED b by 0.5 AGAIN -- final attempt ...")
            gm2out = gm2_main(k, sigma, b)
    [a, b], [p, sigma1], [q, sigma2] = gm2out
    if pc:
        return [
            grate * 100, mu * 100, sigma * 100, k, sigma1 * 100, sigma2 * 100,
            q, b, yearly, N
        ]
    else:
        return [grate, mu, sigma, k, sigma1, sigma2, q, b, yearly, N]
예제 #2
0
def optimize_holt(dataframe, grids=50, alphas=(0.0, 1.0), betas=(0.0, 1.0)):
    '''Optimize Holt-Winters parameters alpha and beta for given data.
       The alphas and betas are boundaries of respective explored regions.
       Function interpolates "grids" from its low bound to its high bound,
       inclusive. Final output: [alpha, beta, losspc, median absolute loss]
       TIP: narrow down alphas and betas using optimize_holt iteratively.
    '''
    if grids > 49:
        system.warn("Optimizing Holt-Winters alphabetaloss may take TIME!")
        #  Exploring loss at all the grids is COMPUTATIONALLY INTENSE
        #  due to holt(), especially if the primary data is very large.
        #  Tip: truncate dataframe to recent data.
    result = op.minBrute(fun=loss_holt,
                         funarg=(dataframe, ),
                         boundpairs=[alphas, betas],
                         grids=grids)
    #  result is a numpy array, so convert to list:
    alpha, beta = list(result)
    #  Compute loss, given optimal parameters:
    loss = loss_holt((alpha, beta), dataframe)
    #  Compute percentage loss relative to absolute tailvalue:
    losspc = (float(loss) / abs(tailvalue(dataframe))) * 100
    #  Since np.round and np.around print ugly, use Python round() to
    #  display alpha and beta. Also include losspc and median absolute loss:
    return [round(alpha, 4), round(beta, 4), round(losspc, 4), loss]
예제 #3
0
def invert(mat, rcond=RCOND):
    '''Compute the inverse, or pseudo-inverse as fallback, of a matrix.'''
    try:
        #  Faster version first, with is_singular() test...
        return invert_caution(mat)
    except Exception:
        #           ... so mat is probably singular:
        system.warn("ILL-CONDITION: invert() may output pseudo-nonsense.")
        #  How did we get here? The problem is most likely collinearity.
        return invert_pseudo(mat, rcond)
예제 #4
0
def index_delta_secs(dataframe):
    '''Find minimum in seconds between index values.'''
    nanosecs_timedelta64 = np.diff(dataframe.index.values).min()
    #  Picked min() over median() to conserve memory;      ^^^^^!
    #  also avoids missing values issue,
    #  e.g. weekend or holidays gaps for daily data.
    secs_timedelta64 = tool.div(nanosecs_timedelta64, 1e9)
    #  To avoid numerical error, we divide before converting type:
    secs = secs_timedelta64.astype(np.float32)
    if secs == 0.0:
        system.warn('Index contains duplicate, min delta was 0.')
        return secs
    else:
        return secs
예제 #5
0
def gmixshow(N=256, mean=SPXmean, sigma=SPXsigma, yearly=256, repeat=1,
             visual=True, inprice=100, b=SPXb):
    '''Statistical and optional visual SUMMARY: repeat simulations of GM(2).'''
    for i in range(repeat):
        istr = str(i)
        prices = gmix2prices(N, mean, sigma, yearly, inprice)
        if visual:
            plotn(prices, title='tmp-gmixshow-'+istr)
        try:
            gm2gem(prices, yearly=yearly, b=b)
        except OverflowError:
            system.warn("Excessive kurtosis: Skipping gm2gem() print.")
        print('---------------------------------------' + istr)
    return
예제 #6
0
def simushow(N=256, mean=0, yearly=256, repeat=1, func=simug_mix, visual=True,
             b=SPXb, inprice=100):
    '''Statistical and optional visual SUMMARY: repeat simulations of func.
       Function func shall use all its default arguments, except for N.
    '''
    for i in range(repeat):
        istr = str(i)
        ratarr = func(N=N)
        prices = zerat2prices(ratarr, mean, yearly, inprice)
        if visual:
            plotn(prices, title='tmp-'+func.__name__+'-'+istr)
        try:
            gm2gem(prices, yearly=yearly, b=b)
        except OverflowError:
            system.warn("Excessive kurtosis: Skipping gm2gem() print.")
        print('---------------------------------------' + istr)
    return
예제 #7
0
def bootshow(N,
             poparr,
             yearly=256,
             repeat=1,
             visual=True,
             b=SPXb,
             inprice=100,
             replace=True):
    '''Statistical and optional visual SUMMARY: repeat bsret2prices().'''
    #  Also nice template for gathering SMALL-SAMPLE statistics...
    #  to be pursued elsewhere for different asset classes.
    for i in range(repeat):
        istr = str(i)
        prices = bsret2prices(N, poparr, inprice=inprice, replace=replace)
        if visual:
            plotn(prices, title='tmp-bootshow-' + istr)
        try:
            gm2gem(prices, yearly=yearly, b=b)
        except OverflowError:
            system.warn("Excessive kurtosis: Skipping gm2gem() print.")
        print('---------------------------------------' + istr)
    return
예제 #8
0
def forecast(data, h=12, grids=0, maxi=0):
    '''h-period ahead forecasts by holtforecast or optimize_holtforecast,
       where "data" may be fredcode, quandlcode, stock slang, or DataFrame.
       Given default grids argument, forecast is very QUICK since we use
       FIXED parameters implicitly: alpha=hw_alpha and beta=hw_beta.
       Recommend grids=50 for reasonable results, but it is TIME-CONSUMING
       for search grids > 49 to find OPTIMAL alpha and beta.
    '''
    if not isinstance(data, pd.DataFrame):
        try:
            data = get(data, maxi)
            #          ^Expecting fredcode, quandlcode, or stock slang.
        except Exception:
            raise ValueError("INVALID data argument.")
    if grids > 0:
        opt = optimize_holtforecast(data, h, grids=grids)
        system.warn(str(opt[1]), stub="OPTIMAL alpha, beta, losspc, loss:")
        return opt[0]
    else:
        holtdf = holt(data)
        system.warn("Holt-Winters parameters have NOT been optimized.")
        return holtforecast(holtdf, h)