Back to Posts
Listen to Thread

Hello All,

I've been playing with calculating Bollinger Bands but I don't know how to access my calculations in handle_data

import pandas

def process_df(df):  
    df = df.rename(columns={'Close': 'price'})  
    df = df.fillna(method='ffill')  
    #df = df[['price', 'sid']]  
    #log.info(' \n %s ' , df.head())  
    df['MA20']=pandas.stats.moments.rolling_mean(df['price'], 20)  
    df['ABS']=abs(df['price']-df['MA20'])  
    df['STDDEV']=pandas.stats.moments.rolling_std(df['ABS'], 20)  
    df['UPPER']=df['MA20']+2*df['STDDEV']  
    df['LOWER']=df['MA20']-2*df['STDDEV']  
    log.info(df[18:20])  
    log.info(df[37:39])  
    return df  

def initialize(context):  
    fetch_csv('https://raw.github.com/pcawthron/StockData/master/CMG%202011%20Daily%20Close.csv',  
        date_column='Date',  
        symbol='CMG',  
        usecols=['Close'],  
        post_func = process_df,  
        date_format='%d/%m/%Y'  
        )  
    context.stock = sid(28016)

def handle_data(context, data):  
    record(CMG=data['CMG'].price)  
    #print data['CMG'].datetime  
    if str(data['CMG'].datetime) == "2011-03-31 00:00:00+00:00":  
        print data['CMG']  
    # This is what I would like to do!  
    # current_UPPER = data['CMG']['UPPER']  
    # record(LowerBB=data['CMG'].LOWER)  

I can see that my data is available in data_handler but I'm stuck. Is this completely the wrong approach i.e. should I be using a batch transform?

Also, I don't understand the relationship between 'my' dataframe and the Quantopian dataframe of CMG's prices i.e.

data['CMG']  

has my extra fields

but

data[sid(28016)]  

does not. My data came from the Yahoo a few months ago.

Regards,

Peter

Update: this line works but I don't understand why:

if str(data['CMG'].datetime) == "2011-03-31 00:00:00+00:00":  
        print data['CMG']['UPPER']  

But this on its own fails:

print data['CMG']['UPPER']  

with the error:

31  Error   Runtime exception: KeyError: 'UPPER'  

Regards,

Peter

Hi Peter,

I think that what is happening is that your CSV does not have data available for all the days of the backtest. Thus, referring to "data['CMG']['UPPER']" for an event in which Quantopian has data and your CSV dataframe does not will generate a KeyError, as "UPPER" was not generated for that date.

You can check for the existence of a key in a Python array using "in":

if 'UPPER' in data['CMG']:  
    log.info(data['CMG']['UPPER'])

Hello John,

I'm sure you're in the right area but I've moved to a batch_transform now which I still don't fully understand. This code works but could be improved:

import pandas

def initialize(context):  
    context.stocks = [sid(28016)]

@batch_transform(window_length=39)  
def get_bbands(datapanel):  
    prices=datapanel['price']  
    prices['MA20'] = pandas.stats.moments.rolling_mean(prices, 20)  
    prices['ABS'] = prices[28016] - prices['MA20']  
    prices['ABS'] = prices['ABS'].abs()  
    prices['STDDEV']=pandas.stats.moments.rolling_std(prices['ABS'], 20)  
    return prices

def handle_data(context, data):  
    result = get_bbands(data)  
    if result is None:  
        return  
    MA20 = result['MA20'][38]  
    STDDEV = result['STDDEV'][38]  
    record(CMG=data[sid(28016)].price, Upper=MA20 + 2.0 * STDDEV, Lower=MA20 - 2.0 * STDDEV, MA20=MA20)  

With the first price available on Day 0 the first MA20 is available on Day 19 and the first Standard Deviation on Day 38 hence window_length = 39.

Regards,

Peter

Hello Peter,

What don't you understand about the batch transform? Perhaps I have some examples.

Grant

Log in to reply to this thread.
Not a member? Sign up!