Hello,
I'm a complete newbie, so please excuse my beginner's question.
I'm trying to implement the Dual Moving Average Crossing Trend-Following Method on Quantopian. I've got this code:
def initialize(context):
# Define which stocks we want to work with. I'm starting with just one, but you can add up to 10.
context.sids = [sid(24)]
context.N = len(context.sids)
# This section initializes a dictionary that will later track whether we invested in a particular stock
context.invested = {}
for cur_sid in context.sids:
context.invested[cur_sid] = False
def handle_data(context, data):
# Uncomment the line below if you want to log the sids that you're testing. Be careful, it's a lot of
# log lines if you're doing a full backtest!
# log.info(data.keys())
# allocate part of our portfolio for each sid in our list
cash_per_sid = context.portfolio.starting_cash / context.N
# This loop goes over the specified sids
for cur_sid in context.sids:
# skip sids that have no data (like Facebook pre-IPO)
if not (cur_sid) in data:
continue
# buy if short moving average crossed long moving average going up
if (data[cur_sid].mavg(10) > data[cur_sid].mavg(50)) and not context.invested[cur_sid]:
order_in_cash(data, cur_sid, cash_per_sid)
context.invested[cur_sid] = True
# sell if short moving average crossed long moving average going down
elif (data[cur_sid].mavg(10) < data[cur_sid].mavg(50)) and context.invested[cur_sid]:
# log the fact that we're closing our position, and the conditions that triggered it
log.info('Selling SID %i by %i shares. mavg(10) is %i, mavg(50) is %i' %(cur_sid, context.portfolio.positions[cur_sid].amount, data[cur_sid].mavg(10), data[cur_sid].mavg(50)))
# sell the amount we invested
order(cur_sid, -context.portfolio.positions[cur_sid].amount)
context.invested[cur_sid] = False
def order_in_cash(data, security, cash):
# This function calculates how many shares to buy given the price and cash available
shares = cash // data[security].price
# log.debug("security: %i, cash: %f, shares: %i"% (security, cash, shares))
if shares < 0:
shares += 1
# to fix python's flooring of negative integer division.
# log the fact that we're going long, and the conditions that triggered it
log.info('Ordering %i shares of sid %i. mavg(10) is %i, mavg(50) is %i' %(shares, security, data[security].mavg(10), data[security].mavg(50)))
order(security, shares)
The code works, but when the short MA goes below the long MA, the position is just eliminated, but I would like to initiate a short position. How do I do that?
Kind regards
Florian