Back to Community
Testing SACEMS, Mamabear?

Hi

I have seen different forms of this strategy, including at https://www.cxoadvisory.com/momentum-strategy/ and at https://muscularportfolios.com/mama-bear/. Both strategies are basically the same, but with a slightly different look back. The strategies have also been tested at https://allocatesmartly.com/livingstons-muscular-portfolios/
But when I test the Portfoliovisualizer strategy myself, I can't reproduce the same results.

I've tried to research the forum here to see if I can find anyone who has researched the strategy, but I can't find anything.
Is there anyone better than me at Phyton who can test how the strategy would do it?

Here is the link to my test: https://www.portfoliovisualizer.com/test-market-timing-model?s=y&coreSatellite=false&timingModel=4&startYear=1985&endYear=2020&includeYTD=false&initialAmount=10000&periodicAdjustment=0&adjustmentAmount=0&inflationAdjusted=true&adjustmentPercentage=0.0&adjustmentFrequency=4&symbols=DBC%2CEEM%2CIWM%2CSPY%2CEFA%2CGLD%2CVNQ%2CBIL%2CTLT&singleAbsoluteMomentum=false&volatilityTarget=9.0&downsideVolatility=false&outOfMarketStartMonth=5&outOfMarketEndMonth=10&outOfMarketAssetType=1&movingAverageSignal=1&movingAverageType=1&multipleTimingPeriods=false&periodWeighting=2&windowSize=4&windowSizeInDays=105&movingAverageType2=1&windowSize2=10&windowSizeInDays2=105&excludePreviousMonth=false&normalizeReturns=false&volatilityWindowSize=0&volatilityWindowSizeInDays=0&assetsToHold=3&allocationWeights=1&riskControl=false&riskWindowSize=10&riskWindowSizeInDays=0&rebalancePeriod=1&separateSignalAsset=false&tradeExecution=0&comparedAllocation=1&benchmark=VFINX&timingPeriods%5B0%5D=5&timingUnits%5B0%5D=2&timingWeights%5B0%5D=100&timingUnits%5B1%5D=2&timingWeights%5B1%5D=0&timingUnits%5B2%5D=2&timingWeights%5B2%5D=0&timingUnits%5B3%5D=2&timingWeights%5B3%5D=0&timingUnits%5B4%5D=2&timingWeights%5B4%5D=0&volatilityPeriodUnit=1&volatilityPeriodWeight=0

6 responses

I tried to create some coding, based on the script I found on the forum.

The rotation strategy is simple:

  • Buy the top three ETFs out of nine, which have the highest percentage return over the last four months
  • These are the current ETFs: ('IWM', 'EEM', 'TLT', 'GLD', 'DBC', 'SPY', 'CAR', 'EFA', 'VNQ')
  • Rebalances end of mont, around closing price
  1. I'm not sure why the script only selects an ETF, I can't figure out how to change this to 3
  2. This section "and data [stock] .close_price> data [stock] .mavg (200)" (line 47) is also not correct in terms of the strategy above, but I'm not sure how to remove it without getting an error message.

The only buy signal in the strategy is to keep the top three asset classes at all times.

I attach the strategy below:

# For this example, we're going to write a simple momentum script.  
# When the stock goes up quickly, we're going to buy;  
# when it goes down we're going to sell.  
# Hopefully we'll ride the waves.

# To run an algorithm in Quantopian, you need two functions:  
# initialize and handle_data  
from operator import itemgetter

def initialize(context):  
    context.topMom = 1  
    context.rebal_int = 3  
    context.lookback = 84  
    set_symbol_lookup_date('2015-01-01')  
    #context.stocks = symbols('SPY', 'VOO', 'IVV')  
    #context.stocks = symbols('XLF', 'XLE', 'XLU', 'XLK', 'XLB', 'XLP', 'XLY', 'XLI', 'XLV', 'BIL')  
    #context.stocks = symbols('SPY', 'VEA', 'BIL')  
    #context.stocks = symbols('SPY', 'EFA', 'BND', 'VNQ', 'GSG', 'BIL')  
    context.stocks = symbols('IWM' ,'EEM', 'TLT' ,'GLD', 'DBC' , 'SPY' ,'BIL', 'EFA' ,'VNQ')  
    #context.stocks = symbols('DDM', 'MVV', 'QLD', 'SSO', 'UWM', 'SAA', 'UYM', 'UGE', 'UCC', 'UYG', 'RXL', 'UXI', 'DIG', 'URE', 'ROM', 'UPW', 'BIL')  
# endret til endt of mont, og market close  
    schedule_function(rebalance,  
                      date_rule=date_rules.month_end(),  
                      time_rule=time_rules.market_close(hours=2))  


def rebalance(context, data):  
    #Create stock dictionary of momentum  
    MomList = GenerateMomentumList(context, data)  
    #sell all positions  
    for stock in context.portfolio.positions:  
        order_target(stock, 0)  
    #create % weight  
    spy = symbol('SPY')  
    #if data[spy].price < data[spy].mavg(200):  
    #    order_target_percent(symbol('IEF'), 1)  
    #    return  
    weight = 0.95/context.topMom

    #buy  
    for l in MomList:  
        stock = l[0]  
        if stock in data and data[stock].close_price > data[stock].mavg(200):  
            order_percent(stock, weight)  
    pass

def GenerateMomentumList(context, data):  
    MomList = []  
    price_history = history(bar_count=context.lookback, frequency="1d", field='price')  
    for stock in context.stocks:  
        now = price_history[stock].ix[-1]  
        old = price_history[stock].ix[0]  
        pct_change = (now - old) / old  
        #if now > data[stock].mavg(200):  
        MomList.append([stock, pct_change, price_history[stock].ix[0]])  


    #sort in descending order, the price change (%)  
    MomList = sorted(MomList, key=itemgetter(1), reverse=True)  
    #return only the top "topMom" number of securities  
    MomList = MomList[0:context.topMom]  
    print((MomList[0][0].symbol))

    return MomList


def change(one, two):  
    return(( two - one)/one)  
def handle_data(context, data):  
    pass  

@ MY W .

Here is my simplified implementation of "Mama Bear" with the original setup.
But its performance lately not even close to performance of "My all weather trio".

Clone Algorithm
11
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
# The Mama Bear Portfolio
# original setup https://allocatesmartly.com/livingstons-muscular-portfolios/
# --------------------------------------------------------------------------------------------------
ASSETS = symbols('DBC','EEM','EFA','GLD','IWM','SHV','SPY','TLT','VNQ',); MOM = 105; N = 3; LEV = 1.0;
# --------------------------------------------------------------------------------------------------
def initialize(context):  
    schedule_function(rebalance, date_rules.month_end(), time_rules.market_close(minutes = 65))

def rebalance(context, data):  
    C = data.history(ASSETS, 'price', MOM + 1, '1d')                             
    R = C.iloc[-1] / C.iloc[0] - 1. 
    R = R.dropna()
    picks = R.sort_values(ascending = False).head(N).index  
    wt = {}
    
    for sec in ASSETS:
        if sec in picks: 
            wt[sec] = LEV / N if len(picks) != 0 else 0
        else: 
            wt[sec] = 0
            
    for sec, target_wt in wt.items(): 
        order_target_percent(sec, target_wt);
        
    print(picks)
    record(leverage = context.account.leverage, )
There was a runtime error.

Thank you very much, I'll check out the strategy you're referring to. As I understand "My all weather trio", it is an alternative to the 60/40 strategy - then with levraged etf and shorting against ex-US developed markets, with monthly rebalancing to a fixed percentage of the total portfolio. Very Interesting. I can post my comments under that forum thread. But what I immediately ask myself is:
- is it very sensitive to the choice of etf, specifically QQQ?
- is there something to gain from rebalancing less frequently, for example every three months?
- how sensetive is it to market crash (see Luke Izlar's posting, Apr 25, 2017)?
- I trade from a European perspective, with the Norwegian krone as the base currency. I understand that the purpose of shorting the developed markets is to create a dollar neutral portfolio, but what will this mean from a European perspective, where a dollar appreciation is positive for the foreign investor (in most cases)?


Thanks also for your help with Mamabear. I'm not surprised it has been doing worse lately, typically.

It's probably simple:
- but how do I add a stop target price ((stop-gain) rule) to the Mamabear. In the cxoadvisory version (SACEMS), he advocates a stop gain rule of 14%: https://www.cxoadvisory.com/technical-trading/add-stop-gain-to-asset-class-momentum-strategy /
- Is there any way to improve the strategy by, for example, buying limit 0.5% above yesterday's low, and selling 0.5% lower than yesterday's high. If the order is not executed, sell at market close. (I am a little puzzled by how many of these strategies use market order. There is so much intraday volatility, that it should be possible to enter (exit) at a better price than just market close (or market open)).
- Or a version of sell open and buy close (as you do with 65 minutes from close)

Anyway, and thanks again for the help with the strategy.

@ MY W

To answer your questions:

how sensitive is it to the choice of etf, specifically QQQ, EFA?
how sensitive is it to market crash?
how sensitive is it to re balance frequency?

I just created a notebook:

Comparing "My all weather trio" with different constituents and different rebalance frequency.

And I'll ask you to fly to your own questions.

Loading notebook preview...

Thank you, very impressive. It seems to be a simple, but at the same time very good strategy.

@ MY W

Comparison "My all weather trio" with original constituents but different rebalance frequency (weekly, monthly, quarterly, half_year, yearly)

Loading notebook preview...