How to rebalance every month based on a 10 months simple moving average rule ?

Hi, I'm just getting started on quantopian.
I would like to test a simple strategy based on a monthly timeframe :

At the beginning of each month :
• If the SPY is >= to it's 10 months simple moving average we buy it.

• Else we exit all of our positions

I don't manage to get the monthly SMA(10) to test it...
How can I manage this ?

Thank you

4 responses

Here is a sample algorithm which does something close to what you are asking. See if it makes sense.

Good luck!

26
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
'''
Simple algorithm to trade a fixed set of stocks based upon certain rules.
The data is defined in the pipeline definition.
The selection logic is performed in the code.
'''

# The following imports need to included when using Pipeline
from quantopian.algorithm import attach_pipeline, pipeline_output
from quantopian.pipeline import Pipeline

# Import all the built in Quantopian filters and factors (just in case)
import quantopian.pipeline.filters as Filters
import quantopian.pipeline.factors as Factors

# Import Pandas and Numpy (just in case we want to use their functionality)
import pandas as pd
import numpy as np

# Import any specialiazed packages here (eg scipy.optimize or scipy.stats)
pass

# Import any needed datasets
from quantopian.pipeline.data.builtin import USEquityPricing

# Set any 'constants' you will be using
# A list of securities and equally weight each one
MY_STOCKS = symbols('SPY')
WEIGHT = 1.0 / len(MY_STOCKS)

def initialize(context):
"""
Called once at the start of the algorithm.
"""

# Set commission model or omit and the default Q models will be used

# Attach the pipeline defined in my_pipe so we have data to use
attach_pipeline(pipe_definition(context), name='my_data')

# Schedule when to trade.Here it's the beginning of each month.

# Schedule when to record any tracking data
schedule_function(record_vars, date_rules.every_day(), time_rules.market_close())

def pipe_definition(context):
'''
Here is where the pipline definition is set.
Specifically it defines which collumns appear in the resulting dataframe.
Think of its defining a big spreadsheet (really a dataframe) of data.
Don't think of the pipeline as doing any logic. That's later in the algo.
'''

# Create a universe filter which defines our baseline set of securities
# If no filter is used then ALL assets in the Q database will potentially be returned
# This is not what one typically wants because
#    1) it includes a mix of ETFs and stocks
#    2) it includes very low liquid and 'penny' stocks
#
# This filter can also be used as a mask in factors to potentially speed up some calcs
# Just want a single stock though so use the StaticAssets filter
universe = Filters.StaticAssets(MY_STOCKS)

# Create any basic data factors that your logic will use.
# This is done by simply using the 'latest' method on a datacolumn object.
# Just ensure the dataset is imported first.
close_price = USEquityPricing.close.latest

# Create any built in factors you want to use (in this case Returns).
# Hre we want the SMA over 10 months. Thi sis about 10 x 20 days/mo = 200 days.

# Create any built in filters you want to use.
pass

# Create any filters based upon factors defined above.
# These are easily made with the built in methods such as '.top' etc applied to a factor
pass

# Define the columns and any screen which we want our pipeline to return
# This becomes the data that our algorithm will use to make trading decisions
return Pipeline(
columns = {
'close_price' : close_price,
'sma_200' : sma_200,
},
screen = universe,
)

'''
Run pipeline_output to get the latest data for each security.
The data is returned in a 2D pandas dataframe. Rows are the security objects.
Columns are what was defined in the pipeline definition.
'''

# Get a dataframe of our pipe data. Placed in the context object so it's available
# to other functions and methods (quasi global)
context.output = pipeline_output('my_data')

'''
This is a scheduled function to execute all buys and sells
'''
# Note that no logic was done in the pipeline. Just fetched the data.
# Here is where you can filter, sort, and do whatever you want with that data.
# Anything that could have been done in pipeline can be done with the
# dataframe that it returns. Use the pandas methods on context.output.

open_these = context.output.query('close_price >= sma_200').index.tolist()
for stock in open_these:
order_target_percent(stock, WEIGHT)

close_these = context.output.query('close_price < sma_200').index.tolist()
for stock in close_these:
order_target_percent(stock, 0)

def record_vars(context, data):
"""
Plot variables at the end of each day.
"""

# Record the number of positions held each day
record(leverage=context.account.leverage,
positions=len(context.portfolio.positions))
There was a runtime error.

Thank you very much Dan.
So we must use a daily timeframe ?
We cannot change the timeframe to another basis like weekly or monthly ?

olivier,

You may get any time frame from Quantopian data.history() using .resample()

def initialize(context):

#---------------------------------------------
stock, TimeFrame, ma = symbol('SPY'), '1M', 10
#---------------------------------------------
bars = ma*21
if get_open_orders(): return

curr_price = data.current(stock, 'price')
daily_prices = data.history(stock, 'price',  bars, '1d')
monthly_prices = daily_prices.resample(TimeFrame).last()
print monthly_prices
mavg = monthly_prices.mean()