Back to Community
Any help with why this is not trading?

Hi - can someone please take a look at this and let me know why its not trading anything? Seriously spent over 4 hrs trying a whole bunch of different things before resorting to asking Q Crowd to assist this newbie. Took code from a few different places and somehow lost track along the way (wish some version control functionalities can be introduced at some point ... or I should just be a bit more careful)...

Summary of what I am trying:
- take predefined universe
- get 2 /30 EMA
- get delta between EMA's
- sort to get the top 5 delta's
- calculate a weight for the top 5
- purchase those 5 positions based on the calculated weight

Currently just want to try it long only, but tried to build framework around in case wanted to start testing shorts also ... any assistance would be much appreciated

Clone Algorithm
55
Loading...
Backtest from to with initial capital
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
#https://www.quantopian.com/posts/meb-fabers-3-way-system
# Meb Faber 3 ways system

#TO DOOO!!!
#consider stock screens on medium volatility stocks/indexs to use
#still far too correlated to SPY ... figure out why
#check out research portfolio that allow different backstests based on chaning a parameter and see how results look
# order the measures to limit to only buy top 6-8 stocks

# Three asset classes: Stocks, bonds, gold.
# Invest equally in whatever is going up (defined as 3 month SMA > 10 month SMA).
# - See more at: http://mebfaber.com/2015/06/16/three-way-model/#sthash.nUERh7tS.dpuf
import pandas as pd
import talib as ta
import numpy as np
from numpy import array

def initialize(context):
    set_symbol_lookup_date('2015-04-11')    
    context.stocks = symbols( 'IVV','IWF','IWM','IJH','IWD','IJR','IBB','IYR','ICF','IYW','IYH','ITB','IYF','IHE','IYC','EFA','EEM','EWJ','EZU','IEMG','EWG','IEFA','FXI','INDA','IDV','IGE','IXJ','IGF','IXN','KXI','FLWS','SRCE','TWOU','SIXD','EGHT','AVHI','ATEN','AAC','AAON','AIR','ABAX','ABY','ABEO','ANF','ABMD','ABM','AXAS','ACTG','ACAD','AKR','AXDX','XLRN','ANCX','ACCO','ARAY','ACW','ACET','ACHN','ACIW','ACOR','ACTA','ATU','ACXM','ADMS','AE','ADUS','ADPT','ADTN','WMS','AEIS','AMD','ADXS','ADVS','ABCO','AEGR','AEGN','AEPI','AERI','HIVE','AJRD','AVAV','AFMD','AFFX','MITT','AGEN','AGRX','AGYS','ADC','AIRM','ATSG','AYR','AKS','AKBA','ALG','AIN','AMRI','ALDR','ALEX','ALX','ALCO','ALIM','ALGT','ALE','AFOP','AIQ','AMOT','AFAM','ALJ','AOSL','AAMC','ASPS','RESI','AIMC','AMAG','AMBC','AMBA','AMBR','AMC','AMED','APEI','AMRC','AAT','AXL','MTGE','AEO','AEL','AMNB','ARII','ARPI','ASEI','AMSW_A','AWR','AVD','AMWD','CRMT','ABCB','AMSF','ATLO','FOLD','AMKR','AHS','AMPH','AMSG','ANAC','ALOG','ABCW','ANDE','ANGI','ANGO','ANIP','ANIK','AXE','ANN','ATRS','ANTH','ANH','APOG','ARI','APOL','AMTG','AGTC','AIT','AMCC','AAOI','AREX','PETX','ARC','ARCB','ACAT','ARDX','ASC','ARNA','ACRE','AGX','AGII','ARIA','AI','AHH','ARR','ARRY','AROW','ARWR','ARTN_A','ABG','ASNA','ASCM_A','AHP','AHT','AINC','AZPN','ASMB','AEC','ASTE','AST','AF','ATRO','ATRA','AT','ATNI','AAWW','AFH','ATRC','ATRI','ATW','LIFE','AAVL','AVG','AVID','AVA','AVX','ACLS','AXLL','AZZ','BGS','BMI','BCPC','BWIN_B','BANC','BANF','BLX','TBBK','BXS','BKMU','BMRC','OZRK','BFIN','RATE','BANR','BHB','BKS','B','CUDA','BBSI','BAS','BSET','BV','BBCN')
    context.stocks1 = symbols( 'BBX','BECN','BSF','BZH','BEBE','BELF_B','BDC','BLCM','BEL','BHE','BNCL','BNFT','BHLB','BERY','BGCP','BGFV','BIG','BH','BBG','BCRX','BDSI','BRLI','BIOS','BSTC','BEAT','BTX','BJRI','BBOX','BDE','BKH','BLKB','HAWK','BLMN','BLT','BCOR','BLBD','BHBK','NILE','BRG','BNCN','BOBE','BOFI','WIFI','BCC','BCEI','BOOT','SAM','BPFH','EPAY','BDBD','BOX','BYD','BRC','BBRG','BDGE','BBNK','BPI','BGG','BFAM','BCOV','BCO','BRS','BSFT','BRKL','BRKS','BMTC','BLMT','BKE','BWLD','BBW','BLDR','BURL','CJES','BNK','CCMP','CACI','CACQ','CZR','CALM','CLMS','CAMP','CVGW','CAL','CCC','CWT','CALA','CALX','ELY','CALD','CPE','ABCD','CBM','CAC','CCG','CMN','CPLA','CBF','CCBG','CSU','CFFN','CMO','CARA','CRR','CARB','CBYL','CFNL','CSII','CATM','CRCM','CECO','CTRE','CKEC','CRS','CSV','CRZO','TAST','CACB','CSCD','CWST','CASY','CSH','CASS','ROX','CSLT','CTLT','CPRX','CTT','CATY','CATO','CVCO','CAVM','CBZ','CDI','CEB','CECE','CDR','CGI','CLDX','CBMG','CEMP','CSFL','CETV','CENT_A','CPF','CENX','CNBK_A','CCS','CPHD','CERS','CEVA','CSG','ECOM','GTLS','CHFN','CCF','CLDT','CKP','CAKE','CHEF','CHGG','CHE','CHFC','CCXI','CHMT','CHKE','CHSP','CPK','CHS','PLCE','CMRX','CBK','CHDN','CHUY','CBR','CIEN','CIFC','CMPR','CBB','CIR','CRUS','CTRN','CZNC','CIA','CHCO','CVEO','CIVI','CLC','CLNE','CLFD','CLW','CNL','CLF','CSBK','CLD','CLVS','MYCC','CCNE','CNO','COBZ','COKE','CDE','CUZ','CVTI','COWN','CRAI','CBRL','BREW','CRD_B','CRAY','CROX','CCRN','CRWN','CRY','CSGS','CSS','CTIC','CTS','CUNB','CUBE','CUB','CFI','CMLS','CRIS','CW','CUBI','CUTR','CVBF','CVT','TLT', 'agg', 'LQD', 'TIP', 'hyg', 'shy', 'emb','lEmb','igov', 'GOVT', 'CRED','GLD', 'uso','fxe','slv','IAU','GSG','COMT','PICK','VEGI') # from 2005
    context.longterm  = 30
    context.shortterm = 2
    context.N = (context.longterm)*20
    
    context.bet_amount = context.portfolio.cash / 5 
    context.count = 5    
    #schedule_function(handle_data_daily,
     #                 date_rule=date_rules.every_day(),
      #               time_rule=time_rules.market_open(minutes=30))
    
# Will be called on every trade event for the securities you specify. 
def handle_data(context, data):
    prices =  history(context.N, frequency="1d", field='price')
    
    ranking = sort_returns(prices)
    
    if ranking is not None:
        column_name = ranking.columns[0]  
        # bottom quantile to go long
        bottom = ranking[-1*context.count:] 
        longs = bottom[bottom[column_name] < 0]
        
        # top quantile to go short
        top = ranking[:context.count]
        shorts = top[top[column_name] > 0]
        
        for stock in data.keys():
            if stock in longs.index:
                amount = calculate_order_amount(context, stock, 1, data[stock].price)
            elif stock in shorts.index:
                amount = calculate_order_amount(context, stock, -1, data[stock].price)
            else:
                amount = calculate_order_amount(context, stock, 0, data[stock].price)
                
            order(stock, amount)    
   
# This method is purely for order managment. It calculates and returns an 
# order amount to place binary bets.
# If signal_val is -1, get to a short position of -1 * context.bet_size
# If signal_val is 1, get to a long position of context.bet_size
def calculate_order_amount(context, stock, signal_val, cur_price):
    current_amount = context.portfolio.positions[stock].amount
    prices =  history(context.N, frequency="1d", field='price')
    prices = prices.dropna(axis=1)
    prices = prices.resample('BM', how='last',closed ='left', label='left')
    pricesshort  =  prices.apply(ta.EMA, timeperiod=context.shortterm)
    
    priceslong  =  prices.apply(ta.EMA, timeperiod=context.longterm)
    
    updown = pricesshort.iloc[-1] > priceslong.iloc[-1] 
    weight = 1.0/len(updown[updown==True]) if len(updown[updown==True])!=0 else 0.0   
    abs_order_amount = int(context.bet_amount / weight) 
    
    if signal_val == -1:
        return (1 * abs_order_amount) - current_amount
    elif signal_val == 1:
        return 0 * current_amount
    elif signal_val == 0:
        return 0 * current_amount
    else:
        return 0        
    
def sort_returns(prices):
    longterm  = 30
    shortterm = 2
    N = (longterm)*20   
    prices = prices.dropna(axis=1)
    prices = prices.resample('BM', how='last',closed ='left', label='left')
    pricesshort  =  prices.apply(ta.EMA, timeperiod=shortterm)
    
    priceslong  =  prices.apply(ta.EMA, timeperiod=longterm)
    
    updown = pricesshort.iloc[-1] > priceslong.iloc[-1] 
    updowndelta = pricesshort.iloc[-1] - priceslong.iloc[-1] 
    # use a slice operator to get the most recent returns
    last_delta = updowndelta[-1:]
    last_date = last_delta.index[-1]
    sorted_delta = last_delta.T.sort()
    log.info (sorted_delta)
    log.info (last_delta)
    return sorted_delta    
  
There was a runtime error.
5 responses

Hi Umar,

Welcome to Quantopian. Some advice on debugging:

When something is going wrong, cut everything out to make it as simple as possible. Cut down the number of stocks. print everything you can think of. Have it backtest over just one or two days, and of course, use the debugger and step through every line of code.

Of course, you may have tried some of that ;)

In def sort_returns(prices) you have updowndelta which is a pandas series, the index is stocks and the value is short EMA - long EMA (It's already the 'most recent returns' because you've used .iloc[-1]) last_delta will contain the 'last' stock in that series, which could be anything, but in this case was just 'CARB'. I think what you actually need here is just updowndelta.sort() (which returns None because it sorts inplace, if you want to return a sorted copy you need updowndelta.order()) and return.

I didn't look closely at the other functions, but I think that gives you some food for thought. Let us know how it goes :)

James

Thanks James - was able to piece together a few things and get it work - attached is the daily back test for a short time period.

Two Issues I am having now is:
1) that I am trying to stop it trading when the SPY moves 2% - I tried this on line 64 but it does not appear to be kicking in for some reason - you can see the impact from Aug 18/15 onwards

2) backtests in minute mode are taking me over 45 minutes and some even longer - not sure how I can 'clean' the code to avoid this.

Thanks again for your help - would it be inappropriate (Q rules or just bad taste) if I offered a token gesture of $25 to your favorite charity for helping me out? Either way, appreciate the help

Clone Algorithm
55
Loading...
Backtest from to with initial capital
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
#https://www.quantopian.com/posts/meb-fabers-3-way-system
# Meb Faber 3 ways system

#TO DOOO!!!
#consider stock screens on medium volatility stocks/indexs to use
#still far too correlated to SPY ... figure out why
#check out research portfolio that allow different backstests based on chaning a parameter and see how results look
# order the measures to limit to only buy top 6-8 stocks

# Three asset classes: Stocks, bonds, gold.
# Invest equally in whatever is going up (defined as 3 month SMA > 10 month SMA).
# - See more at: http://mebfaber.com/2015/06/16/three-way-model/#sthash.nUERh7tS.dpuf
import pandas as pd
import talib as ta
import numpy as np
from numpy import array


def initialize(context):
    #context.stocks = symbol('IVV')
    #context.bonds = symbol('TLT')
    #context.gold = symbol('GLD') # from 2005
    context.longterm  = 30
    context.shortterm = 2
    context.N = (context.longterm)*30
    set_universe(universe.DollarVolumeUniverse(90, 95.0))
    
    #set what fraction of this universe we want to invest in
    context.pct_universe_to_buy = 5     
#    schedule_function(handle_data_daily,
#                      date_rule=date_rules.every_day(),
#                      time_rule=time_rules.market_open(minutes=30))
    
# Will be called on every trade event for the securities you specify. 
def handle_data(context, data):
#    pass
    record(cash = context.portfolio.cash)
#def handle_data_daily(context, data):
    context.sids = data.keys()
    prices =  history(context.N, frequency="1d", field='price')
    prices = prices.dropna(axis=1)    
    prices = prices.resample('BM', how='last',closed ='left', label='left')
    pricesshort =  prices.apply(ta.SMA, timeperiod=context.shortterm)
    priceslong  =  prices.apply(ta.SMA, timeperiod=context.longterm)
    
    ranges = pricesshort.iloc[-1] - priceslong.iloc[-1]
    ranges.sort(ascending=False)
    num_stocks = round(int(min(len(ranges), context.pct_universe_to_buy)))
    top = ranges.keys()[0:num_stocks-1]
    
    rangesD = priceslong.iloc[-1] - pricesshort.iloc[-1]
    rangesD.sort(ascending=False)
    num_stocksD = round(int(min(len(rangesD), context.pct_universe_to_buy)))
    bottom = rangesD.keys()[0:num_stocksD-1]    
    
    #updown = pricesshort.iloc[-1] > priceslong.iloc[-1]
    #downup = pricesshort.iloc[-1] < priceslong.iloc[-1]
    #weight = 1.0/len(updown[updown==True])
    #weightdown = -1.0/len(downup[downup==True])
    mkt = data[symbol('SPY')].returns()*100
    record(Spy=mkt)
        
    for sid in context.sids:
        if abs(mkt)<2:
            if sid in top:
                if mkt >0:
                    weight = 1.6/len(top)
                    order_target_percent(sid,weight)
            if sid in bottom:
                if mkt<0:
                    weight = 1.6/len(bottom)
                    order_target_percent(sid,-weight)            
            elif sid not in top and sid not in bottom:
                    order_target_value(sid,0)
        pass                    
There was a runtime error.

ok looking quite a bit better - got it to 'almost' stop based on SPY movement and also backtesting much faster ... stats looking ok at 2015 YTD 129% with 17.6% DD but need to do realism test on them at some point (cash/leverage/commission etc. etc.) but more interested in just figuring out logic of coding right now

but still need to figure out:
1) how to run two different history pulls - one will be used for trading on a day period interval, and the other is on the previous 3 hrs on a minute interval which tracks the SPY movement that I can use as a gauge to turn off trading/alter trading parameters... cannot figure out how to calculate the minute SPY movement in one def and call it in a another def (like I can calculate it one def that loops on X minutes but do not know how to pull it another def that runs once a day)
2) how can I put some sort of trading guard to avoid volatility ETF's - not all ETFs, just the volatility one - is there a way without manually listing them all out?

Clone Algorithm
55
Loading...
Backtest from to with initial capital
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
#https://www.quantopian.com/posts/meb-fabers-3-way-system
# Meb Faber 3 ways system

#TO DOOO!!!
#consider stock screens on medium volatility stocks/indexs to use
#still far too correlated to SPY ... figure out why
#check out research portfolio that allow different backstests based on chaning a parameter and see how results look
# order the measures to limit to only buy top 6-8 stocks

# Three asset classes: Stocks, bonds, gold.
# Invest equally in whatever is going up (defined as 3 month SMA > 10 month SMA).
# - See more at: http://mebfaber.com/2015/06/16/three-way-model/#sthash.nUERh7tS.dpuf
import pandas as pd
import talib as ta
import numpy as np
from numpy import array


def initialize(context):
    #context.stocks = symbol('IVV')
    #context.bonds = symbol('TLT')
    #context.gold = symbol('GLD') # from 2005
    context.longterm  = 30
    context.shortterm = 2
    context.N = (context.longterm)*30
    set_universe(universe.DollarVolumeUniverse(97.5, 99.9))
    
    #set what fraction of this universe we want to invest in
    context.pct_universe_to_buy = 5     
    schedule_function(handle_data_daily,
                      date_rule=date_rules.every_day(),
                      time_rule=time_rules.market_open(minutes=30))
    
# Will be called on every trade event for the securities you specify. 
def handle_data(context, data):
#    pass
    record(cash = context.portfolio.cash)
def handle_data_daily(context, data):
    context.sids = data.keys()
    prices =  history(context.N, frequency="1d", field='price')
    prices = prices.dropna(axis=1)    
    prices = prices.resample('BM', how='last',closed ='left', label='left')
    pricesshort =  prices.apply(ta.SMA, timeperiod=context.shortterm)
    priceslong  =  prices.apply(ta.SMA, timeperiod=context.longterm)
    
    ranges = pricesshort.iloc[-1] - priceslong.iloc[-1]
    ranges.sort(ascending=False)
    num_stocks = round(int(min(len(ranges), context.pct_universe_to_buy)))
    top = ranges.keys()[0:num_stocks-1]
    
    rangesD = priceslong.iloc[-1] - pricesshort.iloc[-1]
    rangesD.sort(ascending=False)
    num_stocksD = round(int(min(len(rangesD), context.pct_universe_to_buy)))
    bottom = rangesD.keys()[0:num_stocksD-1]    
    
    #updown = pricesshort.iloc[-1] > priceslong.iloc[-1]
    #downup = pricesshort.iloc[-1] < priceslong.iloc[-1]
    #weight = 1.0/len(updown[updown==True])
    #weightdown = -1.0/len(downup[downup==True])
    hist = history(60, '1m', 'price')
    simple_returns = hist.pct_change()
    avg_simple_return = simple_returns.mean()
    mkt=avg_simple_return[symbol('SPY')]*10000
    mkt1 = data[symbol('SPY')].returns()*100
    record(Spy=mkt)
    record(Spy1=mkt1)    
    
    if abs(mkt)>2:
        for stock in context.portfolio.positions:
            order_target_percent(stock,0)
    
    for sid in context.sids:
        if abs(mkt)<2:
            if sid in top:
                if mkt >0:
                    weight = 1.6/len(top)
                    order_target_percent(sid,weight)
            if sid in bottom:
                if mkt<0:
                    weight = 1.6/len(bottom)
                    order_target_percent(sid,-weight)            
            elif sid not in top and sid not in bottom:
                    order_target_value(sid,0)
        pass                    
There was a runtime error.

one more just from 1July15 to date backtest @ 55% in just two months with 10% DD

Clone Algorithm
55
Loading...
Backtest from to with initial capital
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
#https://www.quantopian.com/posts/meb-fabers-3-way-system
# Meb Faber 3 ways system

#TO DOOO!!!
#consider stock screens on medium volatility stocks/indexs to use
#still far too correlated to SPY ... figure out why
#check out research portfolio that allow different backstests based on chaning a parameter and see how results look
# order the measures to limit to only buy top 6-8 stocks

# Three asset classes: Stocks, bonds, gold.
# Invest equally in whatever is going up (defined as 3 month SMA > 10 month SMA).
# - See more at: http://mebfaber.com/2015/06/16/three-way-model/#sthash.nUERh7tS.dpuf
import pandas as pd
import talib as ta
import numpy as np
from numpy import array


def initialize(context):
    #context.stocks = symbol('IVV')
    #context.bonds = symbol('TLT')
    #context.gold = symbol('GLD') # from 2005
    context.longterm  = 30
    context.shortterm = 2
    context.N = (context.longterm)*30
    set_universe(universe.DollarVolumeUniverse(97.5, 99.9))
    
    #set what fraction of this universe we want to invest in
    context.pct_universe_to_buy = 5     
    schedule_function(handle_data_daily,
                      date_rule=date_rules.every_day(),
                      time_rule=time_rules.market_open(minutes=30))
    
# Will be called on every trade event for the securities you specify. 
def handle_data(context, data):
#    pass
    record(cash = context.portfolio.cash)
def handle_data_daily(context, data):
    context.sids = data.keys()
    prices =  history(context.N, frequency="1d", field='price')
    prices = prices.dropna(axis=1)    
    prices = prices.resample('BM', how='last',closed ='left', label='left')
    pricesshort =  prices.apply(ta.SMA, timeperiod=context.shortterm)
    priceslong  =  prices.apply(ta.SMA, timeperiod=context.longterm)
    
    ranges = pricesshort.iloc[-1] - priceslong.iloc[-1]
    ranges.sort(ascending=False)
    num_stocks = round(int(min(len(ranges), context.pct_universe_to_buy)))
    top = ranges.keys()[0:num_stocks-1]
    
    rangesD = priceslong.iloc[-1] - pricesshort.iloc[-1]
    rangesD.sort(ascending=False)
    num_stocksD = round(int(min(len(rangesD), context.pct_universe_to_buy)))
    bottom = rangesD.keys()[0:num_stocksD-1]    
    
    #updown = pricesshort.iloc[-1] > priceslong.iloc[-1]
    #downup = pricesshort.iloc[-1] < priceslong.iloc[-1]
    #weight = 1.0/len(updown[updown==True])
    #weightdown = -1.0/len(downup[downup==True])
    hist = history(60, '1m', 'price')
    simple_returns = hist.pct_change()
    avg_simple_return = simple_returns.mean()
    mkt=avg_simple_return[symbol('SPY')]*10000
    mkt1 = data[symbol('SPY')].returns()*100
    record(Spy=mkt)
    record(Spy1=mkt1)    
    
    if abs(mkt)>2:
        for stock in context.portfolio.positions:
            order_target_percent(stock,0)
    
    for sid in context.sids:
        if abs(mkt)<2:
            if sid in top:
                if mkt >0:
                    weight = 1.6/len(top)
                    order_target_percent(sid,weight)
            if sid in bottom:
                if mkt<0:
                    weight = 1.6/len(bottom)
                    order_target_percent(sid,-weight)            
            elif sid not in top and sid not in bottom:
                    order_target_value(sid,0)
        pass                    
There was a runtime error.

Hi Umar,

1) I think you've worked out the 2% logic now, but I've changed it a little. You have to check for open orders.

2) To increase backtest speed, you ideally need to remove all loops. Some loops are unavoidable, but otherwise try to use all pandas/numpy functions that work on arrays. At the moment, you have context.N = 900 days (about 42 months), which is going to be slow with a DollarVolumeUniverse. No way of getting around that really. You could reduce this to 750 days and still get the required 30 months of prices. If you could define a different universe using fundamental data instead (https://www.quantopian.com/help#sample-fundamentals) that might be quicker.

That's very nice of you - help comes for free - but if you feel so inclined, you may pick any cancer research charity (I'm not familiar with US charities).

3) I'm not 100% on what you mean there, but see the example. You can get the past 3 hrs of minutes (or less, if the day just started) and do something with that. If you want to check on that every minute, it will be slow to test.

4) volatile ETFs - that's tricky, but you can rule out most of the leveraged ETFs by checking you don't order any sid in security_lists.leveraged_etf_list. Although I don't think historical leveraged ETFs are included in that list.

What's with the prices.resample(... closed='left') ?

I believe the ranges and rangesD are the same but reversed in order (ignoring sign), i.e. ranges.iloc[0:10] == rangesD.iloc[-10:]. See example.

Note that context.account.leverage is gross leverage.

See what you think. Do check my logic.

Clone Algorithm
6
Loading...
Backtest from to with initial capital
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
#https://www.quantopian.com/posts/meb-fabers-3-way-system
# Meb Faber 3 ways system

#TO DOOO!!!
#consider stock screens on medium volatility stocks/indexs to use
#still far too correlated to SPY ... figure out why
#check out research portfolio that allow different backstests based on chaning a parameter and see how results look
# order the measures to limit to only buy top 6-8 stocks

# Three asset classes: Stocks, bonds, gold.
# Invest equally in whatever is going up (defined as 3 month SMA > 10 month SMA).
# - See more at: http://mebfaber.com/2015/06/16/three-way-model/#sthash.nUERh7tS.dpuf
import pandas as pd
import talib as ta
import numpy as np
from numpy import array

def initialize(context):
    #context.stocks = symbol('IVV')
    #context.bonds = symbol('TLT')
    #context.gold = symbol('GLD') # from 2005
    context.longterm  = 30
    context.shortterm = 2
    context.N = 750 
    set_universe(universe.DollarVolumeUniverse(97.5, 99.9))
    
    #set what fraction of this universe we want to invest in
    context.pct_universe_to_buy = 5     
    schedule_function(handle_data_daily,
                      date_rule=date_rules.every_day(),
                      time_rule=time_rules.market_open(minutes=30))

    
def handle_data(context, data):
    # Anything you do *every minute* here is going to be SLOW.
        
    # every minute, get the last 3 hrs of minute data, but only todays data:
    today = pd.Timestamp(get_datetime().date())
    hist = history(180, '1m', 'price').ix[today:]
    hist = hist[symbol('SPY')] # now a series for SPY
    # it will have a len() between 1 and 180.
    avg_simple_returns = hist.pct_change().mean()*10000
    # Note on the first minute of the day, avg_simple_returns is NaN
    # because pct_change() needs more than one value to work on.
    record(avg_simple_returns = avg_simple_returns)    
    # but the record() function only plots the last value you gave it
    # every day, so most of those values you wont see on the graph!
    
    # do something with avg_simple_returns here...
    
    
    
    
    
def handle_data_daily(context, data):
    #context.sids = data.keys()
    prices = history(context.N, frequency="1d", field='price').dropna(axis=1)
    prices = prices.resample('BM', how='last',closed ='left', label='left')   
    #pricesshort =  prices.apply(ta.SMA, timeperiod=context.shortterm)
    #priceslong  =  prices.apply(ta.SMA, timeperiod=context.longterm)
    priceslong = prices.iloc[-context.longterm:].mean() # might be quicker, try 
    pricesshort = prices.iloc[-context.shortterm:].mean() # it out and see.
    
    ranges = pricesshort - priceslong
    ranges.sort(ascending=False)
    num_stocks = int(min(ranges.shape[0], context.pct_universe_to_buy))
    #top = ranges.keys()[0:num_stocks-1]
    top = ranges.index[0:num_stocks]     
    bottom = ranges.index[-num_stocks:] # check this... 
    
    # you need to account for an edge case that may never happen:
    # sids that are in top might also be in bottom. If the universe is big enough,
    # this won't happen.
    
    #rangesD = priceslong - pricesshort
    #rangesD.sort(ascending=False)
    #num_stocksD = int(min(rangesD.shape[0], context.pct_universe_to_buy))
    #bottom = rangesD.keys()[0:num_stocksD-1]    
    
    
    mkt = data[symbol('SPY')].returns()*100
    record(mkt = mkt)
    record(cash = context.portfolio.cash)
    record(leverage = context.account.leverage)
        
        
    if abs(mkt) > 2:
        for stock in context.portfolio.positions:
            if not get_open_orders(stock):
                order_target(stock,0)
    else:   
        for sid in data:
            if get_open_orders(sid):
                continue # never order when there's already an open order
                
            if sid in top:
                if mkt > 0:
                    weight = 1.6/top.shape[0]
                    order_target_percent(sid,weight)
                else:
                    order_target(sid,0) # there may be an open position
            elif sid in bottom:
                if mkt < 0:
                    weight = 1.6/bottom.shape[0]
                    order_target_percent(sid,-weight)            
                else:
                    order_target(sid,0) # there may be an open position
            else:
                 order_target(sid,0)

                    
                    
                    
There was a runtime error.