Columbia Trading

Friday, March 18, 2016

moment rotation system

from quantopian.algorithm import attach_pipeline, pipeline_output 
from quantopian.pipeline import Pipeline 
from quantopian.pipeline import CustomFactor 
from quantopian.pipeline.data.builtin import USEquityPricing 
from quantopian.pipeline.data import morningstar
import numpy as np
from collections import defaultdict
     
class momentum_factor_1(CustomFactor):   
   inputs = [USEquityPricing.close]  
   window_length = 20 
    
   def compute(self, today, assets, out, close):     
     out[:] = close[-1]/close[0]     
  
class momentum_factor_2(CustomFactor):   
   inputs = [USEquityPricing.close]  
   window_length = 60 
    
   def compute(self, today, assets, out, close):     
     out[:] = close[-1]/close[0]  
  
class momentum_factor_3(CustomFactor):   
   inputs = [USEquityPricing.close]  
   window_length = 125 
    
   def compute(self, today, assets, out, close):     
     out[:] = close[-1]/close[0] 
  
class momentum_factor_4(CustomFactor):   
   inputs = [USEquityPricing.close]  
   window_length = 252 
    
   def compute(self, today, assets, out, close):     
     out[:] = close[-1]/close[0] 
  
class market_cap(CustomFactor):   
   inputs = [USEquityPricing.close, morningstar.valuation.shares_outstanding]  
   window_length = 1 
    
   def compute(self, today, assets, out, close, shares):     
     out[:] = close[-1] * shares[-1]       
       
class efficiency_ratio(CustomFactor):   
   inputs = [USEquityPricing.close, USEquityPricing.high, USEquityPricing.low]  
   window_length = 252
    
   def compute(self, today, assets, out, close, high, low):
       lb = self.window_length
       e_r = np.zeros(len(assets), dtype=np.float64)
       a=np.array(([high[1:(lb):1]-low[1:(lb):1],abs(high[1:(lb):1]-close[0:(lb-1):1]),abs(low[1:(lb):1]-close[0:(lb-1):1])]))     
       b=a.T.max(axis=1)
       c=b.sum(axis=1)
       e_r=abs(close[-1]-close[0]) /c 
       out[:] = e_r
       
def initialize(context): 
    set_commission(commission.PerShare(cost=0.005, min_trade_cost=1.00))
    schedule_function(func=rebalance, date_rule=date_rules.month_start(days_offset=5), time_rule=time_rules.market_open(), half_days=True) 
    schedule_function(close_orders,date_rule=date_rules.week_end(),time_rule=time_rules.market_close())
    set_do_not_order_list(security_lists.leveraged_etf_list)
    context.acc_leverage = 1.00
    context.holdings =10
    context.profit_taking_factor = 0.01
    context.profit_target={}
    context.profit_taken={}
    context.entry_date={}
    context.stop_pct = 0.75
    context.stop_price = defaultdict(lambda:0)
      
    pipe = Pipeline() 
    attach_pipeline(pipe, 'ranked_stocks') 
    
    factor1 = momentum_factor_1() 
    pipe.add(factor1, 'factor_1')  
    factor2 = momentum_factor_2() 
    pipe.add(factor2, 'factor_2') 
    factor3 = momentum_factor_3() 
    pipe.add(factor3, 'factor_3') 
    factor4 = momentum_factor_4() 
    pipe.add(factor4, 'factor_4')
    factor5=efficiency_ratio()
    pipe.add(factor5, 'factor_5')
       
       
    mkt_screen = market_cap()   
    stocks = mkt_screen.top(3000)
    factor_5_filter = factor5 > 0.031
    total_filter = (stocks& factor_5_filter)
    pipe.set_screen(total_filter) 
    
       
    factor1_rank = factor1.rank(mask=total_filter, ascending=False) 
    pipe.add(factor1_rank, 'f1_rank') 
    factor2_rank = factor2.rank(mask=total_filter, ascending=False) 
    pipe.add(factor2_rank, 'f2_rank') 
    factor3_rank = factor3.rank(mask=total_filter, ascending=False)  
    pipe.add(factor3_rank, 'f3_rank') 
    factor4_rank = factor4.rank(mask=total_filter, ascending=False) 
    pipe.add(factor4_rank, 'f4_rank') 
  
    combo_raw = (factor1_rank+factor2_rank+factor3_rank+factor4_rank)/4 
    pipe.add(combo_raw, 'combo_raw')  
    pipe.add(combo_raw.rank(mask=total_filter), 'combo_rank')      
        
def before_trading_start(context, data): 
    context.output = pipeline_output('ranked_stocks') 
  
    ranked_stocks = context.output.fillna(0) 
    ranked_stocks = context.output[context.output.factor_1 > 0] 
    ranked_stocks = context.output[context.output.factor_2 > 0] 
    ranked_stocks = context.output[context.output.factor_3 > 0] 
    ranked_stocks = context.output[context.output.factor_4 > 0]
    ranked_stocks = context.output[context.output.factor_5 > 0]
       
    context.stock_list = ranked_stocks.sort(['combo_rank'], ascending=True).iloc[:context.holdings] 
    
    update_universe(context.stock_list.index)  
           
def handle_data(context, data):  
    for stock in context.portfolio.positions:      
           price = data[stock].price
           context.stop_price[stock] = max(context.stop_price[stock], context.stop_pct * price)
    for stock in context.portfolio.positions:
       if data[stock].price < context.stop_price[stock]:
           order_target(stock, 0)
           context.stop_price[stock] = 0
       
    current_date = get_datetime()
    record(leverage=context.account.leverage, positions=len(context.portfolio.positions))   
    for stock in context.portfolio.positions: 
       if (stock.end_date - current_date).days < 2: 
        order_target_percent(stock, 0.0)      
        print "Long List" 
        log.info("\n" + str(context.stock_list.sort(['combo_rank'], ascending=True).head(context.holdings)))
      
       if data[stock].close_price > context.profit_target[stock]:
        context.profit_target[stock] = data[stock].close_price*1.25
        profit_taking_amount = context.portfolio.positions[stock].amount * context.profit_taking_factor
        order_target(stock, profit_taking_amount)
          
def rebalance(context,data):   
   weight = context.acc_leverage / len(context.stock_list)   
   for stock in context.stock_list.index: 
     if stock in data:
      if context.stock_list.factor_1[stock]>1:
        if (stock.end_date - get_datetime()).days > 35:
            if stock not in security_lists.leveraged_etf_list:
              order_target_percent(stock, weight) 
              context.profit_target[stock] = data[stock].close_price*1.25
    
   for stock in context.portfolio.positions.iterkeys(): 
     if stock not in context.stock_list.index or context.stock_list.factor_1[stock]<=1: 
       order_target(stock, 0) 
        
def close_orders(context, data): 
    orders = get_open_orders() 
    if orders:  
     for o in orders: 
       cancel_order(o)                 

    
   
  

No comments:

Post a Comment