import math


def bollinger(strategy, instrument, period=20, matype=None, field=None):
    """
    The Bollinger band width kernel
    :param Strategy strategy: the instance of the Strategy class
    :param Instrument instrument: the instrument object
    :param int period: the window of rolling average
    :param str matype: type of moving average, either simple, 'sma' or exponensial, 'ema'
    :param str field: which field to use for the moving average. default is 'Close'
    :return double: the score
    """
    matype = matype or 'ema'
    field = field or 'Close'
    profile = instrument.snapshot(strategy.rule)[field].tail()
    profile['nu'] = strategy.moving_average(instrument, period, matype=matype, field=field).tail()
    profile['Sigma'] = strategy.moving_standard_deviation(instrument, period, matype=matype, field=field).tail()
    profile[['d' + col for col in profile.columns]] = profile.diff()

    def _score1(x):
        return (-1.25 * x * x * x * x + 22.25 * x * x + 1.) / 100.

    def _score2(x):
        return -math.atan(x) / 3 + .5

    price = profile.get('Price')[-1]
    sigma = profile.get('Sigma')[-1]
    nu = profile.get('nu')[-1]
    n = (price - nu) / sigma
    s1 = _score1(n)
    d_price = profile.get('dPrice')[-1]
    d_sigma = profile.get('dSigma')[-1]
    m = d_price / d_sigma
    s2 = _score2(m)
    return s1 * s2