from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.data import morningstar
from quantopian.pipeline.factors import SimpleMovingAverage, AverageDollarVolume, CustomFactor, Returns
from quantopian.pipeline.data.psychsignal import stocktwits
from quantopian.pipeline.data.estimize import (
consensus_estimize_eps,
consensus_wallstreet_eps,
consensus_estimize_revenue,
consensus_wallstreet_revenue,
ConsensusEstimizeEPS,
ConsensusWallstreetEPS,
ConsensusEstimizeRevenue,
ConsensusWallstreetRevenue
)
class Surprise(CustomFactor):
window_length = 20
inputs = [ConsensusEstimizeEPS.previous_actual_value,
ConsensusEstimizeEPS.previous_mean]
def compute(self, today, assets, out, actual_eps, estimize_eps):
out[:] = (actual_eps[-1] - estimize_eps[-1])/(estimize_eps[-1] + 0)
def initialize(context):
attach_pipeline(my_pipeline(context), 'my_pipeline')
schedule_function(rebalance,
date_rules.month_end(days_offset=0),
time_rules.market_open(hours = 1, minutes = 30))
set_slippage(slippage.FixedSlippage(spread=0.00))
set_commission(commission.PerTrade(cost=1.00))
#context.my_leverage = 0.99
def my_pipeline(context):
recent_returns = Returns(window_length=20)
return Pipeline(
columns={
'close': USEquityPricing.close.latest,
'dollar_volume': AverageDollarVolume(window_length=20),
'rec_returns' : recent_returns,
'pct_surp': Surprise (),
'rev_growth': morningstar.operation_ratios.revenue_growth.latest,
'eps_growth' : morningstar.earnings_ratios.diluted_eps_growth.latest,
'total_bullish' : stocktwits.bull_scored_messages .latest,
'eps_est': consensus_estimize_eps.estimize_eps_final.latest,
'actual_eps': ConsensusEstimizeEPS.previous_actual_value.latest,
'num_est': consensus_estimize_eps.count.latest,
'roe' : morningstar.operation_ratios.roe.latest,
'pe' : morningstar.valuation_ratios.pe_ratio.latest,
'mkt_cap' : morningstar.valuation.market_cap.latest,
'50d' : SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=50),
'roe_pe' : ((morningstar.operation_ratios.roe.latest / morningstar.valuation_ratios.pe_ratio.latest)*100)*4,
'ws_eps' : consensus_wallstreet_eps.wallstreet_eps_final.latest,
'ws_rev' : consensus_wallstreet_revenue.wallstreet_revenue_final.latest,
'es_rev' : consensus_estimize_revenue.estimize_revenue_final.latest,
'rev_rank' : ((consensus_estimize_revenue.estimize_revenue_final.latest- consensus_wallstreet_revenue.wallstreet_revenue_final.latest)/
consensus_wallstreet_revenue.wallstreet_revenue_final.latest)*100
},
screen= ((morningstar.valuation.market_cap.latest > 1000000000) & (USEquityPricing.close.latest > 5) & (ConsensusEstimizeEPS.previous_actual_value.latest > 0) & (consensus_estimize_eps.estimize_eps_final.latest > 0) & (consensus_estimize_eps.estimize_eps_final.latest > ConsensusEstimizeEPS.previous_actual_value.latest) & ((((morningstar.operation_ratios.roe.latest / morningstar.valuation_ratios.pe_ratio.latest)*100)*4) > 1) & (USEquityPricing.close.latest > SimpleMovingAverage(inputs= [USEquityPricing.close], window_length=50)))
#screen= ((morningstar.valuation.market_cap.latest > 1000000000) & (USEquityPricing.close.latest > 5) & (consensus_estimize_eps.estimize_eps_final.latest > ConsensusEstimizeEPS.previous_actual_value.latest) & (consensus_estimize_eps.estimize_eps_final.latest > 0.01) & ((AverageDollarVolume(window_length=20)) > 10**7) & (morningstar.earnings_ratios.diluted_eps_growth.latest > 0.1) & (morningstar.operation_ratios.revenue_growth.latest > 0.01) &(USEquityPricing.close.latest > SimpleMovingAverage(inputs= [USEquityPricing.close], window_length=50)) & ((((morningstar.operation_ratios.roe.latest / morningstar.valuation_ratios.pe_ratio.latest)*100)*4)>1.5))
)
#& (recent_returns > 0)
def before_trading_start(context, data):
context.data = pipeline_output('my_pipeline').dropna()
context.data_sort = context.data.sort(['eps_growth'], ascending=False).iloc[:100]
#context.data_sort = context.data.sort(['eps_growth'], ascending=False).iloc[:100]
#I can modify the above to rank securities based on any column in my
#pipeline. I must first create the column with the criteria im
#looking for and then apply the sort criteria.
#context.long_secs = context.data_sort
context.final_longs_sort = context.data_sort.sort(['dollar_volume'], ascending=False).iloc[:10]
#15 sec 2015 to 0629 returned 8%
#20 sec 2015 to 0629 returned 10%
context.long_final = context.final_longs_sort
context.security_list = context.long_final.index
context.hedge = symbol('TLT')
log.info(context.long_final)
def compute_weights(context):
long_weight = 1.0/ len(context.long_final)
return long_weight
def rebalance(context, data):
long_weight = compute_weights(context)
stock = context.security_list
bond = context.hedge
period = 70
target_lev = 1
pw = 0.5
price_hedge = data.history(context.hedge, 'price', period+1, '1d')[0:-1]
ret_sum1 = price_hedge.pct_change().sum()
prices = data.history(context.long_final.index, 'price', period+1, '1d')[0:-1]
ret_sum2 = prices.pct_change().sum()
r_diff = ret_sum2[stock].sum() - ret_sum1
print(r_diff)
#record(r_diff = r_diff)
if r_diff>0.0:
adpt = (1+r_diff)**pw-1.0
elif r_diff<0.0:
adpt =-((1+abs(r_diff))**pw-1.0)
else:
adpt =0.0
wt_stock = target_lev*(0.50+adpt)
wt_each_stock = wt_stock / len(context.long_final)
wt_bond = target_lev*(0.50-adpt)
for stock in context.security_list:
if data.can_trade(stock):
if stock in context.long_final.index:
order_target_percent(stock, wt_each_stock)
for stock in context.portfolio.positions:
if stock not in context.security_list and data.can_trade(stock):
order_target_percent(stock, 0)
order_target_percent(context.hedge, wt_bond)
log.info("This months's longs: "+", ".join([long_.symbol for long_ in context.long_final.index]))
record(wt_stock = wt_stock, wt_bond = wt_bond)
record(Leverage = context.account.leverage)
def record_vars(context, data):
"""
This function is called at the end of each day and plots certain variables.
"""
# Check how many long and short positions we have.
longs = shorts = 0
for position in context.portfolio.positions.itervalues():
if position.amount > 0:
longs += 1
if position.amount < 0:
shorts += 1
#def compute_weights(context):
#long_weight = 0.95/ len(context.long_final)
#return long_weight
#def rebalance(context, data):
# long_weight = compute_weights(context)
#for stock in context.security_list:
# if data.can_trade(stock):
# if stock in context.long_final.index:
# order_target_percent(stock, long_weight)
# Sell all previously held positions not in our new context.security_list.
#for stock in context.portfolio.positions:
# if stock not in context.security_list and data.can_trade(stock):
# order_target_percent(stock, 0)
#log.info("This months's longs: "+", ".join([long_.symbol for long_ in context.long_final.index]))
#def record_vars(context, data):
"""
This function is called at the end of each day and plots certain variables.
"""
# Check how many long and short positions we have.
# longs = shorts = 0
# for position in context.portfolio.positions.itervalues():
# if position.amount > 0:
# longs += 1
# if position.amount < 0:
# shorts += 1
# Record and plot the leverage of our portfolio over time as well as the
# number of long and short positions. Even in minute mode, only the end-of-day
# leverage is plotted.
#record(leverage = context.account.leverage, long_count=longs, short_count=shorts)
#062816 need to implement filter to remove N/As
#063016 see sample algo of weight for 50 day to view trading thesis
#criteria. Particularly the thoery that the worst performing stocks #over the past 5days will be the best performing stocks over the #next 5 days.
#too tired to continue. having problems at line 50. I was copying the algo portion from Weights Factor for 50 day MAVG.
#063016 Resumed in the morning and was able to get first algo trading by itself. returns not great and must continue to add relevant parameters to develop strategy. Good base to continue to build on. Will now proceed to change earning growth metrics to something more relevant to our IFG strategies.
#successfully implemented ranking system by roe/pe ratio. Ranking system grabbing only top 40 securities by roe/pe
#made plenty of progres thie evening. got a ranking system going
#implemented eps
#07/05/16 algorithm is working pretty good. I have got everything working the way I wanted and I think that the only thing missing is to tweak it to reduce down side.