Back to Community
Simple Moving Average algo with 2 stocks

I'm trying to make a simple moving average algorithm where if the moving average of two stocks(apple and google) are good, it will buy them. However when I backtest it, the algorithm doesn't end up buying anything and it has 0.00% returns. Does anyone know what I'm doing wrong? Thanks!


import quantopian.algorithm as algo  
from quantopian.pipeline import Pipeline  
from quantopian.pipeline.data.builtin import USEquityPricing  
from quantopian.pipeline.filters import QTradableStocksUS


def initialize(context):  
    """  
    Called once at the start of the algorithm.  
    """  
    context.security1 = symbol('GOOG')  
    context.security2 = symbol('AAPL')

def handle_data_spy(context, data):  
    """  
    Called every minute.  
    """  
    price_hist1 = data.history(context.security1, 'price', 50, '1d')  
    ma1 = price_hist1.mean()  
    price_hist2 = data.history(context.security1, 'price', 200, '1d')  
    ma2 = price_hist2.mean()  
    price_hist3 = data.history(context.security2, 'price', 50, '1d')  
    ma3 = price_hist3.mean()  
    price_hist4 = data.history(context.security2, 'price', 200, '1d')  
    ma4 = price_hist4.mean()

    current_price1 = data[context.security1].price  
    current_positions1 = context.portfolio.positions[symbol('GOOG')].amount  
    current_price2 = data[context.security2].price  
    current_positions2 = context.portfolio.positions[symbol('AAPL')].amount

    cash = context.portfolio.cash  
    if ma1>ma2 and ma3>ma4 and current_positions == 0:  
        number_of_shares = int(cash/current_price)  
        order(context.security1, number_of_shares)  
        order(context.security2, number_of_shares)  
    elif ma1<ma2 and ma3<ma4 and current_positions != 0:  
        order_target(context.security1, 0)  
        order_target(context.security2, 0)  
    pass  
1 response

The basic problem is the handle_data_spy function is never scheduled. Use the schedule_function to schedule it something like this

# Execute every day, 1 hour after market open.  
algo.schedule_function(  
    handle_data_spy,  
    algo.date_rules.every_day(),  
    algo.time_rules.market_open(hours=1),  
)

Only the functions with the name handle_data and before_trading_start are auto executed.

I made a few minor changes to your code. Use the order_target_percent method to open orders. It's easier than calculating the number of shares to order. Also added some recording to see what the signals look like. This is very useful during debugging.

Good luck.

Clone Algorithm
5
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
"""
Simple algo to trade based upon sma
"""

def initialize(context):  
    """  
    Called once at the start of the algorithm.  
    """  
    context.security1 = symbol('GOOG')  
    context.security2 = symbol('AAPL')
    
    # Execute every day, 1 hour after market open.
    schedule_function(
        handle_data_spy,
        date_rules.every_day(),
        time_rules.market_open(hours=1),
    )

def handle_data_spy(context, data):  
    """  
    Scheduled function
    """  
    price_hist1 = data.history(context.security1, 'price', 50, '1d')  
    ma1 = price_hist1.mean()  
    price_hist2 = data.history(context.security1, 'price', 200, '1d')  
    ma2 = price_hist2.mean()  
    price_hist3 = data.history(context.security2, 'price', 50, '1d')  
    ma3 = price_hist3.mean()  
    price_hist4 = data.history(context.security2, 'price', 200, '1d')  
    ma4 = price_hist4.mean()

    current_positions1 = context.portfolio.positions[context.security1].amount 
    current_positions2 = context.portfolio.positions[context.security2].amount
    
    # Added this. 
    current_positions = current_positions1 + current_positions2

    if ma1>ma2 and ma3>ma4 and current_positions == 0:  
        order_target_percent(context.security1, .5)  
        order_target_percent(context.security2, .5)
        
    elif ma1<ma2 and ma3<ma4 and current_positions != 0:  
        order_target(context.security1, 0)  
        order_target(context.security2, 0)  
      
    # Added some recording to see what the signals look like
    record(ma1 = ma1>ma2, ma2 = ma3>ma4)
There was a runtime error.
Disclaimer

The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.