Back to Community
Solid Mean Reversion

Uses 100 day sma to 2 day sma %change then sort by worst 2 day return. Buys 4 stocks with the best ROI. Hold for a week. Sell and repeat. Essentially, just screening for negative momentum and picking the best companies through ROI.

Let me know where I went wrong

Clone Algorithm
139
Loading...
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
Returns 1 Month 3 Month 6 Month 12 Month
Alpha 1 Month 3 Month 6 Month 12 Month
Beta 1 Month 3 Month 6 Month 12 Month
Sharpe 1 Month 3 Month 6 Month 12 Month
Sortino 1 Month 3 Month 6 Month 12 Month
Volatility 1 Month 3 Month 6 Month 12 Month
Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Import the libraries we will use here.
from quantopian.pipeline.data import Fundamentals
import quantopian.algorithm as algo
import quantopian.optimize as opt
from quantopian.pipeline import Pipeline
from quantopian.pipeline.data.builtin import USEquityPricing
from quantopian.pipeline.factors import Returns, SimpleMovingAverage, DailyReturns, AverageDollarVolume
from quantopian.pipeline.filters import QTradableStocksUS
from quantopian.pipeline.filters.morningstar import Q1500US, Q500US, Q3000US 
def initialize(context):
    #context.tvix= sid(40515)#1.5x leveraged VIX ETF
    #context.vix=sid(41969)#2x leveraged VIX
    #context.sjb=sid(41114)
    set_benchmark(symbol('spy'))
    #schedule_function(ma_crossover_handling, date_rules.every_day(),time_rules.market_open(hours=1 ,minutes=0))    #Buys five minutes before market close
    algo.schedule_function(
        rebalance,
        algo.date_rules.week_start(),
        algo.time_rules.market_open(minutes=59))
    
    #Sells all positions at open to secure overnight gains
    #schedule_function(sell_all, date_rules.every_day(),  
                      #time_rules.market_open(minutes=59))
    
    algo.attach_pipeline(make_pipeline(context), 'mean_reversion_example')
def sell_all(context,data):
    order_optimal_portfolio(
    objective=opt.TargetWeights({sid(8554): 0.0}) ,
    constraints=[],)
 
def make_pipeline(context):    
    universe =QTradableStocksUS()
    sma_1 = SimpleMovingAverage(inputs=[USEquityPricing.close],window_length=200, mask=universe)   
    sma_2=SimpleMovingAverage(inputs=[USEquityPricing.close],window_length=2,mask=universe)
    sma_change=(sma_2-sma_1)/sma_1
    #primary factor is by volume
    volume4=AverageDollarVolume(window_length=2,mask=universe)  
    volume1=AverageDollarVolume(window_length=100,mask=universe)  
    volume2=AverageDollarVolume(window_length=21,mask=universe)  
    volume3=AverageDollarVolume(window_length=34,mask=universe)  
    #volume=((volume1+volume2+volume3)/3)
    volume=(volume4-volume1)/volume1
    #returns=volume for labling purposes 
    recent_volume_zscore = sma_change.zscore()    
    #selects a handful of the most liquid stocks
    high_returns = recent_volume_zscore.percentile_between(0,5)
    #low_returns = recent_returns_zscore.percentile_between(0,.5)
    recent_returns = Returns(
        window_length=2, 
        mask=high_returns
    )
    recent_returns_zscore = recent_returns.zscore()
    low_returns =recent_returns_zscore.percentile_between(0
                                                          ,10)
    roe = Fundamentals.roe.latest
    securities_to_trade = (low_returns)
    pipe = Pipeline(columns={'roe': roe},screen=securities_to_trade)
 
    return pipe
 
def before_trading_start(context, data):
    context.output = algo.pipeline_output('mean_reversion_example')  
    context.recent_returns_zscore = context.output['roe']
def rebalance(context, data):
    context.top_n_roe_to_buy = 4
    #put stocks on a list to run analysis on
    df=context.output
    top_n_roe = df['roe'].nlargest(context.top_n_roe_to_buy)
    bot_roe=df['roe'].nsmallest(context.top_n_roe_to_buy)
    longs=top_n_roe.index
    shorts=bot_roe.index
    #need quantity of stocks in pipeline to equally weigh portfolio
    for stock in context.portfolio.positions:
        order_target_percent(stock,0)
    for symb in longs:
        num=len(longs)
        print(num)
        order_target_percent(symb,1/num)#portfolio is equal weighted by dividing by number of stocks in pipeline
    for symb in shorts:
        num=len(shorts)
       # order_target_percent(symb,-1/num)
    record(lever=context.account.leverage)

def ma_crossover_handling(context, data):
    hist=data.history(context.tvix, 'price', 6, '1d')
    hist2=data.history(context.tvix, 'price', 7, '1d')
    sma_10=hist2.mean()
    sma_5 =hist.mean()
    sma_3 =hist[3:].mean()
    cur=hist[-1]
    old=hist2[0]
    sma_hedge=(((cur-sma_3)/sma_3)*((cur-sma_5)/sma_5))
    open_orders = get_open_orders()
    sma_average_diff=(sma_3-sma_5)
    ma_diff=(cur-sma_hedge)/sma_hedge
    dollar_diff=abs((cur-old)/old)*100

#weights 5 
    hedge_factor=abs(9*sma_hedge)
    print(dollar_diff,sma_hedge)
    while hedge_factor>1:
        hedge_factor=hedge_factor/4
    vix1=1-hedge_factor
    hedge1=hedge_factor
#crossover logic
#longs if momentum is positive
    if sma_average_diff > 0:
       if context.vix not in open_orders:
           order_target_percent(context.tvix,.1*vix1)
           order_target_percent(context.vix,-.2*hedge1)
#shorts if momentum is negative
    elif sma_average_diff <0:
       if context.vix not in open_orders:
         order_target_percent(context.tvix, -.1*vix1)
         order_target_percent(context.vix,.2*hedge1)
    record(hedge=hedge_factor)
    record(lever=context.account.leverage)
    
    hist=data.history(context.sjb, 'price', 4, '1d')
    cur=hist[-1]
    log.info(hist.head())
    sma_10 =hist.mean()
    leverage=.3
    open_orders = get_open_orders()
    if cur < sma_10:
        if context.sjb not in open_orders:
            order_target_percent(context.sjb,-leverage)
    elif cur>sma_10:
         if context.sjb not in open_orders:
              order_target_percent(context.sjb,leverage)
There was a runtime error.