Example #1
0
def bollinger_mean_revert(x, y, model=None):
    if model is None:
        model = bollinger_mean_revert_fit(x, y)
        
    lookback = model['lookback']
    hedge_lookback = model['hedge_lookback']
    entry_z_score = model['entry_z_score']
    exit_z_score = model['exit_z_score']
    static_hedges = model.get('static_hedges') or False
    
    # Setup mean reversion portfolio to use for tradable zScore
    strategy = rolling_hedge_mean_revert_strategy
    (prices, weights, units) = strategy(x, y, lookback, hedge_lookback)
    port = portfolio.portfolio_price(prices, weights)
    
    # Ok, now let's look at the half-life of this portfolio, this needs to be low (under 30)
    # TODO: Test this? Throw it out if it doesn't meet standard?
    halflife = mr.halflife(port)
    cadf = sms.adfuller(port, maxlag=1, regression='c')[0]
    hurst = mr.hurst_exponent(port.pct_change().fillna(0))[0]
    
    # Collect zScore and theoretical results in the form of a sharpe ratio
    zScore = util.rolling_z_score(port, lookback)
    rets = portfolio.portfolio_returns(prices, weights, -zScore)['returns']
    theoretical_sharpe = returns.annual_sharpe(rets)
    
    # Collect units of this portfolio according to bollinger band strategy (buying and selling
    # against the given zScore)    
    units = bollinger_band_units(zScore, entryZScore=entry_z_score, exitZScore=exit_z_score)
    
    # Random experiment - static weights. Basically, force hedge weights to be static for the duration
    # of any particular trade.
    if static_hedges == True:
        unit_changes = units != units.shift().fillna(0)
        weights[~unit_changes] = np.nan
        weights['x'][0] = 0
        weights['y'][0] = 0
        weights = weights.fillna(method='ffill')

    # Finally, collect the results        
    results = {
        'lookback': lookback,
        'hedge_lookback': hedge_lookback,
        'static_hedges': static_hedges,
        'halflife': halflife,
        'cadf': cadf,
        'hurst': hurst,
        'theoretical_sharpe': theoretical_sharpe,
        'prices': prices,
        'weights': weights,
        'units': units
    }
        
    port_rets = portfolio.portfolio_returns(prices, weights, units)
    results.update(port_rets)
    
    rets = port_rets['returns']
    results.update(
        returns.report(rets))
    
    results.update(
        report(units))
    
    return results
Example #2
0
def portfolio_price_test():
    port = portfolio.portfolio_price(prices, [1, -0.4])
    assert_almost_equals(port.iloc[0], 5.6539, places=4)
    assert_almost_equals(port.iloc[1], 5.6344, places=4)
    assert_almost_equals(port.iloc[-2], 9.1112, places=4)
    assert_almost_equals(port.iloc[-1], 9.0446, places=4)