Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Help with Backtest Code -- Code Breaking ... any advice would be appreciated

Import Optimize API module

import quantopian.optimize as opt
import talib
import pandas as pd
import numpy as np

def initialize(context):
# VDE

context.security = sid(26667)  

# Set cash limit for trading  

context.portfolio.cash = 100000.0  
context.max_leverage = 1.0  
context.min_leverage = -1.0

def rebalance(context, data):

 # Constrain target portfolio's leverage  
max_leverage = opt.MaxGrossExposure(context.max_leverage)  
min_leverage = opt.MinGrossExposure(context.min_leverage)  

def handle_data(context, data):

cash = context.portfolio.cash  


# We get the price history for the last 15 days.  
price_history = data.history(  
    context.security,  
    fields='price',  
    bar_count=15,  
    frequency='1d'  
)  


# Then we take an average.  
average_price = price_history.mean()  
sma = price_history.sma()  


# We also get the stock's current price.  

low_price = data.current(context.security,'low')  


    # If the current price is 2% below the sma => buy,  

for stock in context.security:  

    current_position = context.portfolio.positions[stock].amount  
    current_price = data.current(context.security, 'price')  

    if current_price < (0.90 * average_price) and current_position <= 0:  
        # Place the buy order (positive means buy, negative means sell)  
        order_target_percent(context.security, 1)  
        target_shares = cash // data[stock].price  
        order_target(stock, target_shares)  
        log.info('buying shares'.format(  
        stock.symbol, price[stock], target_shares  

    elif current_price > (1.10 * average_price) and current_position >= 0:  
        # Sell all of our shares by setting the target position to zero  
        order_target_percent(context.security, -1)  
        log.info("Selling %s" % (context.security.symbol))  
    else:  
       log.info( "no activity")  

# Use the record() method to track up to five custom signals.  
# Record Apple's current price and the average price over the last  
# five days.  
record(current_price=current_price, average_price=average_price)  
2 responses

In no particular order

  • One cannot set the 'context.portfolio.cash' property it's read only. The starting portfolio cash is set in the backtest amount box next to the backtest date entry. Eliminate the following line
    context.portfolio.cash = 100000.0  

  • The 'rebalance' method isn't scheduled so it's never executed. I assume this is a work in process for future using optimize?

  • The line ' sma = price_history.sma() won't work. 'price history' is a pandas series and has no method 'sma'. Use 'mean' instead.

  • The following isn't correct. When using the 'order_target_percent' method, the second parameter (in this case 1) is the percent of the current total portfolio value that one wants the stock to be. The method then either buys or sells shares to adjust the position to that amount. The code above will either buy or sell shares so the dollar value of the position is equal to the 100% of the portfolio value (or perhaps not do anything if the current value is already equal to the portfolio value).

    # Place the buy order (positive means buy, negative means sell)  
    order_target_percent(context.security, 1)  

  • Similar to above, the following isn't correct. Setting the second parameter to -1 means one wants to hold 100% of the current portfolio value as a short position. Again, it will either buy or sell to adjust the position to this amount. To sell everything, simply set the parameter to 0 (not -1).
    # Sell all of our shares by setting the target position to zero  
    order_target_percent(context.security, -1) 

  • Generally not a good idea to put a 'record' method in 'handle_data'. It will be executed every minute and REALLY slows things down. Additionally, it won't show up very well anyway on the daily graph.

  • The 'context.security' variable is just a plain equity object. One can't iterate over it. The following won't work

    for stock in context.security:  

    # maybe do this...

    for stock in [context.security]:  

  • Take out the '=' in the following line. One doesn't want/need to do anything if there aren't any shares held.
    elif current_price > (1.01 * average_price) and current_position >= 0:  

  • One needs to account for there being outstanding (ie open orders which haven't filled yet) before ordering more. The easiest way is to simply not place orders if there are any outstanding orders. Something like this.
    if get_open_orders(stock):  
        # There are outstanding orders so don't order more  
        continue  

FInally, it's easier for folks to provide help if a backtest is attached rather than simply pasting code into a post. I've attached a backtest with these changes made. Good luck.

Thank you Dan ... appreciate your help VERY MUCH!!