Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Problems with algo - data block is not recognized??

Hi All -

I've been playing with the sample algorithm and testing out some of the features of the API. I tried to design a rather simple algorithm, where you essentially buy into SPY when its 15 day MA crosses above its 126 day and sell when 15 crosses below 126. Here is what it looks like:

#Buy and sell SPY when 15 day MA is above 126 day MA

def initialize(context):  
    #Add SPDR SPY  
    context.SPY = sid(8554)  


    #Set min/max notional  
    context.max_notional = 10000.0  
    context.min_notional = -10000.0

def handle_data(context, data):

    notional = context.portfolio.positions[context.SPY].amount * data[context.SPY].price  
    if MARatio_SPY(15,126)>1:  
        order(context.SPY,+100)  
    elif MARatio_SPY(15,126)<1:  
        order(context.SPY,-100)  

def MARatio_SPY(smallday,bigday):  
    #Return the ratio of the small day MA to long day MA for SPY  
    #NOTE if ratio is >1 then small day MA is above long day MA (bullish indicator)  
    return ( data[context.SPY].vwap(15)/data[context.SPY].vwap(126) )  

and here are my build errors:

14 Warning Local variable 'notional' is assigned to but never used
26 Warning Undefined name 'data'
26 Warning Undefined name 'context'
26 Warning Undefined name 'data'
26 Warning Undefined name 'context'
26 Error Runtime exception: NameError: global name 'data' is not defined

Any ideas?

p.s. - What is the benchmark in the backtest and can it be changed?

9 responses

Hi Daniel,

You need to pass data and context into MARatio_SPY as arguments; they are not global variables.

The benchmark is an ETF designed to match the S&P 500. In the future, we plan to make that benchmark configurable so you can choose the benchmark appropriate to your algorithm.

Regards,

Jonathan Kamens

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.

Thanks Jonathan!

Quick follow up - what if I wanted to declare a global variable? I tried a few variations of the code below with no success.

#Buy and sell SPY when 15 day MA is above 126 day MA


def initialize(context):  
    #declare a global  
    global i  
    i=0  
    #Add SPDR SPY  
    context.SPY = sid(8554)  


    #Set min/max notional  
    context.max_notional = 10000.0  
    context.min_notional = -10000.0

def handle_data(context, data):

    notional = context.portfolio.positions[context.SPY].amount * data[context.SPY].price  
    i=i+1  
   # print(i+" "+notional)  

    if MARatio_SPY(data, context, 15, 126)>1: #and notional < context.max_notional:  
        order(context.SPY,+100)  
        print("Ordering +100 shares of SPY")  
    elif MARatio_SPY(data, context, 15, 126)<1: #and notional > context.min_notional:  
        order(context.SPY,-100)  
        print("Ordering -100 shares of SPY")  

def MARatio_SPY(mydata, mycontext, smallday,bigday):  
    #Return the ratio of the small day MA to long day MA for SPY  
    #NOTE if ratio is >1 then small day MA is above long day MA (bullish indicator)  
    #return ( mydata[mycontext.SPY].vwap(smallday)/mydata[mycontext.SPY].vwap(bigday) )  
    return (10)  

You need the "global" declaration in all of the functions that modify the global variable.

In Python, if you reference a global variable in a function but don't modify it, then you'll get back the value of the global variable. But if you modify the variable, and you haven't put a "global" declaration for it in the subroutine, then you'll create a different, local reference rather than modifying the global variable.

Thanks again for the assistance. One more question, I'm getting an error on this code:

#Buy and sell SPY when 15 day MA is above 126 day MA


def initialize(context):  
    #initiate the global i  
#    global i  
#    i=0  
    #Add SPDR SPY  
    context.SPY = sid(8554)  


    #Set min/max notional  
    context.max_notional = 10000.0  
    context.min_notional = -10000.0

def handle_data(context, data):  
#    global i  
#    i=i+1  
#    print(str(i))  
    notional = context.portfolio.positions[context.SPY].amount * data[context.SPY].price  
    if MARatio_SPY(data, context, 15, 126)>1 and notional < context.max_notional:  
        order(context.SPY,+100)  
    elif MARatio_SPY(data, context, 15, 126)<1 and notional > context.min_notional:  
        order(context.SPY,-100)  

def MARatio_SPY(mydata, mycontext, smallday,bigday):  
    #Return the ratio of the small day MA to long day MA for SPY  
    #NOTE if ratio is >1 then small day MA is above long day MA (bullish indicator)  
    return ( mydata[mycontext.SPY].vwap(smallday)/mydata[mycontext.SPY].vwap(bigday) )  

The error is

KeyError: __vwap_15
File test_algorithm_sycheck.py:23, in handle_data
File test_algorithm_sycheck.py:33, in MARatio_SPY
File algoproxy.py:1046, in _transform
File algoproxy.py:1140, in transform
File transformvisitor.py:230, in get_hash

Hi Daniel,

We don't currently support variable transform arguments. If you want to use a transform like vwap, you currently have to hard-code the window of the transform in its call, so you would need to write vwap(15) and vwap(126) above rather than passing the 15 and 126 in as variables.

Jon

Understood. So let's say that I wanted to write my own "vwap" type function. Is that possible? Or more globally, if I'm trying to code my own algorithm based on past price data, do I have access to those past prices? For example, the Sortino ratio is a modified form of the Sharpe ratio in which the denominator is a modified standard deviation to reflect only the RMS deviation of returns from the mean return for downward price movements only (compared to the actual standard deviation which does not bias the price movement)?

You can do that with batch transforms. See the API docs.

Perfect!