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)                 

    
   
  

Tuesday, February 2, 2016

Kelly Strategy rebalancing

From Wiki:
    https://en.wikipedia.org/wiki/Kelly_criterion

Kelly rebalance will enhance the Sharpe ratio and reduce the risk.

def kelly_strategy():

        # Import history, we have to adjust for a bug that causes extra columns
        # to show up in history sometimes.

       # need to get price history
        prices = history(200, '1d', 'price')
     
        # remove empty or None fields, compute the percentage of change
        R = prices.pct_change().dropna()
     
        # Select securities by assuming all returns are statistically independent
        # and calculate their Kelly leverage.
        kelly = R.mean() / R.var()
     
        # Drop any Nan values and sort in ascending order
        kelly = kelly.dropna()
        kelly.sort()
     
        # just select port_size number of stocks
        picks = kelly.tail(context.port_size)
     
        # Limit short exposure if the Kelly score is negative
        kelly = picks.apply(lambda x: max(x, context.short_pct * x))
     
        # Adjust result to keep the account leverage constant
        kelly *= (context.leverage / kelly.abs().sum())

        # Place orders and sell off any securities that were dropped.
        for stock in data:
            if stock in kelly.index:              
                 # adjust the percentage of stocks, either buy or sell
                order_target_percent(stock, kelly[stock])
            else:
                # sell all of them
                order_target(stock, 0)
     

How to find pairs

  • What is cointegration?
  • How to test for cointegration?
  • What is pairs trading?
  • How to find cointegrated pairs?
  • How to generate a tradeable signal?

three major algorithms

1) Mean reversion
2) Momentum trading
3) Pair trading

Monday, February 1, 2016

My trading platform

I will used quantopian as my platform, which is easy to use. You just need know Python programming.

The following post shared some highlighted algorithm in Quantopian.

http://blog.quantopian.com/5-basic-quant-strategies-implemented-by-the-quantopian-community/

It is interesting to  see the following composition about the algorithms:


  1. Mean Reversion, 37%
  2. Sentiment 28%
  3. Momentum 18%
  4. Portfolio Risk 6%
  5. Volatility 5%
  6. Technical 3%
  7. Seansonality 3%

Strategy 1 : mean-reverting

mean-reverting strategies

In finance, mean reversion is the assumption that a stock's price will tend to move to the average price over time.[1][2]
Using mean reversion in stock price analysis involves both identifying the trading range for a stock and computing the average price using analytical techniques taking into account considerations such as earnings, etc.
When the current market price is less than the average price, the stock is considered attractive for purchase, with the expectation that the price will rise. When the current market price is above the average price, the market price is expected to fall. In other words, deviations from the average price are expected to revert to the average.
Stock reporting services commonly offer moving averages for periods such as 50 and 100 days. While reporting services provide the averages, identifying the high and low prices for the study period is still necessary.
Mean reversion has the appearance of a more scientific method of choosing stock buy and sell points than charting, because precise numerical values are derived from historical data to identify the buy/sell values, rather than trying to interpret price movements using charts (charting, also known as technical analysis).
Some asset classes, such as exchange rates, are observed to be mean reverting; however, this process may last for years and thus is not of value to an investor.
Mean reversion should demonstrate a form of symmetry since a stock may be above its historical average approximately as often as below.
A historical mean reversion model will not fully incorporate the actual behavior of a security's price. For example, new information may become available that permanently affects the long-term valuation of an underlying stock. In the case of bankruptcy, it may cease to trade completely and never recover to its former historical average.

Thursday, January 21, 2016

basic terms in stock trading ( sharpe, alpha, beta, volatility)

Sharpe RatioDeveloped by Nobel laureate economist William Sharpe, this ratio measures risk-adjusted performance. It is calculated by subtracting the risk-free rate of return (U.S. Treasury Bond) from the rate of return for an investment and dividing the result by the investment's standard deviation of its return.
The Sharpe ratio tells investors whether an investment's returns are due to smart investment decisions or the result of excess risk. This measurement is very useful because although one portfolio or security can reap higher returns than its peers, it is only a good investment if those higher returns do not come with too much additional risk. The greater an investment's Sharpe ratio, the better its risk-adjusted performance.


AlphaAlpha is a measure of an investment's performance on a risk-adjusted basis. It takes the volatility (price risk) of a security or fund portfolio and compares its risk-adjusted performance to a benchmark index. The excess return of the investment relative to the return of the benchmark index is its "alpha."
Simply stated, alpha is often considered to represent the value that a portfolio manager adds or subtracts from a fund portfolio's return. A positive alpha of 1.0 means the fund has outperformed its benchmark index by 1%. Correspondingly, a similar negative alpha would indicate an underperformance of 1%. For investors, the more positive an alpha is, the better it is.

BetaBeta, also known as the "beta coefficient," is a measure of the volatility, or systematic risk, of a security or a portfolio in comparison to the market as a whole. Beta is calculated using regression analysis, and you can think of it as the tendency of an investment's return to respond to swings in the market. By definition, the market has a beta of 1.0. Individual security and portfolio values are measured according to how they deviate from the market.
A beta of 1.0 indicates that the investment's price will move in lock-step with the market. A beta of less than 1.0 indicates that the investment will be less volatile than the market, and, correspondingly, a beta of more than 1.0 indicates that the investment's price will be more volatile than the market. For example, if a fund portfolio's beta is 1.2, it's theoretically 20% more volatile than the market.
Conservative investors looking to preserve capital should focus on securities and fund portfolios with low betas, whereas those investors willing to take on more risk in search of higher returns should look for high beta investments.