Notebook
In [ ]:
"""
This is an algorithm.... copy past the code to a new algorithm to test it....
"""
import quantopian.algorithm as algo
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline import factors, filters, classifiers
import pandas as pd

def Q5US():
    return filters.make_us_equity_universe(
        target_size=5,
        rankby=factors.AverageDollarVolume(window_length=200),
        mask=filters.default_us_equity_universe_mask(),
        groupby=classifiers.fundamentals.Sector(),
        max_group_weight=0.3,
        smoothing_func=lambda f: f.downsample('month_start'),
    )


UNIVERS = Q5US()

BARS_VOLUME_PER_DAY = 10
BARS_DOLLAR_PER_DAY = 10
BACKWARD_MINUTES_CREATE = 4500
BACKWARD_MINUTES_DAY = 450





def initialize(context):
    """
    Called once at the start of the algorithm.
    """
    
    context.FTD = True
    context.bars_list = []
    context.bars_created = {}
    
    # Rebalance every day, 1 hour after market open.
    algo.schedule_function(
        rebalance,
        algo.date_rules.every_day(),
        algo.time_rules.market_open(hours=1),
    )

    # Record tracking variables at the end of each day.
    algo.schedule_function(
        record_vars,
        algo.date_rules.every_day(),
        algo.time_rules.market_close(),
    )
    

    # Create our dynamic stock selector.
    algo.attach_pipeline(make_pipeline(), 'pipeline')
    
def make_pipeline():
    """
    A function to create our dynamic stock selector (pipeline). Documentation
    on pipeline can be found here:
    https://www.quantopian.com/help#pipeline-title
    """

    # Base universe set to the QTradableStocksUS
    base_universe = UNIVERS


    # Factor of yesterday's close price.
    yesterday_close = USEquityPricing.close.latest

    pipe = Pipeline(
        columns={
            'close': yesterday_close,
        },
        screen=base_universe
    )
    return pipe


def before_trading_start(context, data):
    """
    Called every day before market open.
    """
    
    context.output = algo.pipeline_output('pipeline')

    # These are the securities that we are interested in trading each day.
    context.security_list = context.output.index
   
    
    if context.FTD:
        print "first trading day, creating bars dataframes and thresholds"
        context.FTD = False
        print type(context.security_list.values)
        
        idx = pd.MultiIndex.from_product([[],[]],
                                 names=['Equities', 'Dates'])
        col = ['open','high','low','close','volume','dollar','last_date']
        context.dollar_bars = pd.DataFrame( object, idx, col)
        col = ['open','high','low','close','volume','last_date']
        context.volume_bars = pd.DataFrame( object, idx, col)
        
        ### compute the volume and price average of last 100 days
        context.volume_bars_threshold = {}
        context.dollar_bars_threshold = {}
        
        for equity in context.security_list.values:
            vol = data.history(equity, 'volume', 100, '1d')
            price = data.history(equity, 'high', 100, '1d')
            context.volume_bars_threshold[equity] = vol.min() / BARS_VOLUME_PER_DAY
            context.dollar_bars_threshold[equity] = (vol.values * price.values).min() / BARS_DOLLAR_PER_DAY
            context.bars_created[equity] = False
            context.bars_list.append(equity)
            #print(equity,context.volume_bars_threshold[equity])
            
    ##### TODO : if a new equity popup.... one need to add it.....
    
    print context.bars_list
    ###Create the bars for equities which bars have not been created yet
    for equity in context.bars_list:
        if context.bars_created[equity]==False:
            print("creating bars:",equity)
            open_price = data.history(equity, 'open', BACKWARD_MINUTES_CREATE, '1m')
            high = data.history(equity, 'high', BACKWARD_MINUTES_CREATE, '1m')
            low = data.history(equity, 'low', BACKWARD_MINUTES_CREATE, '1m')
            close_price = data.history(equity, 'close',BACKWARD_MINUTES_CREATE, '1m')
            volume = data.history(equity, 'volume', BACKWARD_MINUTES_CREATE, '1m')
            dollar = volume.values*(high.values+low.values)/2
            
            idx = 0
            while context.bars_created[equity]==False and idx < BACKWARD_MINUTES_CREATE:
                if open_price.values[idx]==open_price.values[idx]:
                    create_new_volume_bar(context.volume_bars,
                                          equity,
                                          volume.index[idx],
                                          open_price.values[idx],
                                          close_price.values[idx],
                                          low.values[idx],
                                          high.values[idx],
                                          volume.values[idx])
                    create_new_dollar_bar(context.dollar_bars,
                                          equity,
                                          volume.index[idx],
                                          open_price.values[idx],
                                          close_price.values[idx],
                                          low.values[idx],
                                          high.values[idx],
                                          volume.values[idx],
                                          dollar[idx])
                    context.bars_created[equity] = True
                idx += 1
                
            if context.bars_created[equity] == True:
                update_volume_bar(context.volume_bars,
                                  equity,
                                  volume.index[idx-1],
                                  volume.index,
                                  open_price.values,
                                  close_price.values,
                                  low.values,
                                  high.values,
                                  volume.values,
                                  idx,
                                  BACKWARD_MINUTES_CREATE,
                                  context.volume_bars_threshold[equity])
                
                update_dollar_bar(context.dollar_bars,
                                  equity,
                                  volume.index[idx-1],
                                  volume.index,
                                  open_price.values,
                                  close_price.values,
                                  low.values,
                                  high.values,
                                  volume.values,
                                  dollar,
                                  idx,
                                  BACKWARD_MINUTES_CREATE,
                                  context.dollar_bars_threshold[equity])
                
            print(equity,"bar constructed") 
            
                    
                    
            
        ### if an equity bar exist update the bars with previous day data
        else:
            print(equity,"bar exist, updating") 
            open_price = data.history(equity, 'open', BACKWARD_MINUTES_DAY, '1m')
            high = data.history(equity, 'high', BACKWARD_MINUTES_DAY, '1m')
            low = data.history(equity, 'low', BACKWARD_MINUTES_DAY, '1m')
            close_price = data.history(equity, 'close',BACKWARD_MINUTES_DAY, '1m')
            volume = data.history(equity, 'volume', BACKWARD_MINUTES_DAY, '1m')
            dollar = volume.values*(high.values+low.values)/2
            
            volume_date_index = context.volume_bars.loc[equity].index[-1]
            dollar_date_index = context.dollar_bars.loc[equity].index[-1]
            
            idx_volume = 0
            idx_dollar = 0
            
            while idx_volume < BACKWARD_MINUTES_DAY:
                ##print(volume_date_index,open_price.index[idx_volume])
                if context.volume_bars.loc[equity].values[-1][5] == open_price.index[idx_volume]:
                    idx_volume += 1
                    break
                idx_volume += 1
                
            while idx_dollar < BACKWARD_MINUTES_DAY:
                if context.dollar_bars.loc[equity].values[-1][6] == open_price.index[idx_dollar]:
                    idx_dollar += 1
                    break
                idx_dollar += 1
                
            update_volume_bar(context.volume_bars,
                                  equity,
                                  volume_date_index,
                                  volume.index,
                                  open_price.values,
                                  close_price.values,
                                  low.values,
                                  high.values,
                                  volume.values,
                                  idx_volume,
                                  BACKWARD_MINUTES_DAY,
                                  context.volume_bars_threshold[equity])
                
            update_dollar_bar(context.dollar_bars,
                                  equity,
                                  dollar_date_index,
                                  volume.index,
                                  open_price.values,
                                  close_price.values,
                                  low.values,
                                  high.values,
                                  volume.values,
                                  dollar,
                                  idx_dollar,
                                  BACKWARD_MINUTES_DAY,
                                  context.dollar_bars_threshold[equity])
            
            
    print "done"    
    

    
    ### here one should remove "too old bars" and "equitity not anymore tradable" to decrease memory usage.
    
def update_volume_bar(volume_bars,
                      equity,
                      start_bar_index,
                      dates_arr,
                      open_price_arr,
                      close_price_arr,
                      low_arr,
                      high_arr,
                      volume_arr,
                      start_idx,
                      end_idx,
                      threshold):
    
    idx = start_idx
    bar_index = start_bar_index
    tot = volume_bars.loc[(equity,bar_index),'volume']
    
    while idx < end_idx:
        if open_price_arr[idx]==open_price_arr[idx]:
            tot += volume_arr[idx]
            if tot>threshold and abs(tot-volume_arr[idx]-threshold)<abs(tot-threshold):
                #creat a new bar
                bar_index = dates_arr[idx]
                tot = volume_arr[idx]
                
                create_new_volume_bar(volume_bars,
                                      equity,
                                      bar_index,
                                      open_price_arr[idx],
                                      close_price_arr[idx],
                                      low_arr[idx],
                                      high_arr[idx],
                                      volume_arr[idx])
            else:
                #add to this bar
                add_minute_to_volume_bar(volume_bars,
                                         equity,
                                         bar_index,
                                         close_price_arr[idx],
                                         low_arr[idx],
                                         high_arr[idx],
                                         volume_arr[idx],
                                         dates_arr[idx])
        else:
            volume_bars[(equity,bar_index),'last_date'] = dates_arr[idx]
        idx+=1
        
def update_dollar_bar(dollar_bars,
                      equity,
                      start_bar_index,
                      dates_arr,
                      open_price_arr,
                      close_price_arr,
                      low_arr,
                      high_arr,
                      volume_arr,
                      dollar_arr,
                      start_idx,
                      end_idx,
                      threshold):
    
    
    idx = start_idx
    bar_index = start_bar_index
    tot = dollar_bars.loc[(equity,bar_index),'volume']
    
    while idx < end_idx:
        if open_price_arr[idx]==open_price_arr[idx]:
            tot += dollar_arr[idx]
            if tot>threshold and abs(tot-volume_arr[idx]-threshold)<abs(tot-threshold):
                #creat a new bar
                bar_index = dates_arr[idx]
                tot = volume_arr[idx]
                
                create_new_dollar_bar(dollar_bars,
                                      equity,
                                      bar_index,
                                      open_price_arr[idx],
                                      close_price_arr[idx],
                                      low_arr[idx],
                                      high_arr[idx],
                                      volume_arr[idx],
                                      dollar_arr[idx])
                
            else:
                #add to this bar
                add_minute_to_dollar_bar(dollar_bars,
                                         equity,
                                         bar_index,
                                         close_price_arr[idx],
                                         low_arr[idx],
                                         high_arr[idx],
                                         volume_arr[idx],
                                         dollar_arr[idx],
                                         dates_arr[idx])
        else:
            dollar_bars[(equity,bar_index),'last_date'] = dates_arr[idx]
        idx+=1
    
def create_new_volume_bar(volume_bars,equity,date,open_price,close_price,
                          low,high,volume):
    volume_bars.loc[(equity, date),'open'] = open_price
    volume_bars.loc[(equity, date),'close'] = close_price
    volume_bars.loc[(equity, date),'high'] = high
    volume_bars.loc[(equity, date),'low'] = low
    volume_bars.loc[(equity, date),'volume'] = volume
    volume_bars.loc[(equity, date),'last_date'] = date
    
def add_minute_to_volume_bar(volume_bars,equity,date,close_price,
                              low,high,volume,last_date):
    volume_bars.loc[(equity, date),'close'] = close_price
    if volume_bars.loc[(equity, date),'high'] < high:
        volume_bars.loc[(equity, date),'high'] = high
    if volume_bars.loc[(equity, date),'low'] > low:
        volume_bars.loc[(equity, date),'low'] = low
    volume_bars.loc[(equity, date),'volume'] += volume
    volume_bars.loc[(equity, date),'last_date'] = last_date

def create_new_dollar_bar(dollar_bars,equity,date,open_price,close_price,
                          low,high,volume,dollar):
    dollar_bars.loc[(equity, date),'open'] = open_price
    dollar_bars.loc[(equity, date),'close'] = close_price
    dollar_bars.loc[(equity, date),'high'] = high
    dollar_bars.loc[(equity, date),'low'] = low
    dollar_bars.loc[(equity, date),'volume'] = volume
    dollar_bars.loc[(equity, date),'dollar'] = dollar
    dollar_bars.loc[(equity, date),'last_date'] = date
    
def add_minute_to_dollar_bar(dollar_bars,equity,date,close_price,
                              low,high,volume,dollar,last_date):
    
    dollar_bars.loc[(equity, date),'close'] = close_price
    if dollar_bars.loc[(equity, date),'high'] < high:
        dollar_bars.loc[(equity, date),'high'] = high
    if dollar_bars.loc[(equity, date),'low'] > low:
        dollar_bars.loc[(equity, date),'low'] = low
    dollar_bars.loc[(equity, date),'volume'] += volume
    dollar_bars.loc[(equity, date),'dollar'] += dollar
    dollar_bars.loc[(equity, date),'last_date'] = last_date
    
def rebalance(context, data):
    """
    Execute orders according to our schedule_function() timing.
    """
    pass


def record_vars(context, data):
    """
    Plot variables at the end of each day.
    """
    
def handle_data(context, data):
    """
    Called every minute.
    """
    pass