Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
constructing sid from int?

Can I use the integer sids to construct either sid objects or to use in order* calls? This fails, for example:

    for s in data.keys():  
        i = int(s.sid)  
        order(i, 50)  
        #order(sid(i), 50)  

The first order results in an "unknown error" at build time in some contexts and in a runtime error in other contexts. The runtime error is

OrderNonSecurity: 0035 Attempt to order [6992], which is not a security. You must place orders with a Security object. You can construct a Security by calling sid(123).

The second (commented-out) invocation gives a build error "The sid(id) method takes one parameter."

Confusingly, the documentation seems to indicate the integer id and the sid can be used interchangeably, but perhaps I am misinterpreting:

All securities have a unique integer id in our system. Your algorithm can reference a security directly by its id, or use our sid method to look up a security by its id, symbol, or name. Using the sid method brings up a search box that shows you the top results for your search.

In other words, sid(24) and 24 are equivalent, and both refer to Apple.

The documentation for the order* methods seems to specifically require a sid object.

What am I doing wrong?

11 responses

Hello SS TT,

Give this a try:

    for s in data.keys():  
        order(s, 50)  

Worked for me.

Grant

Grant,

Thank you for your response. I understand this works, but it doesn't really answer my question. Suppose I don't have a sid or a Security object or whatever it is, but just its equivalent integer. How do I construct the sid or Security object from it?

As a workaround, I look for a sid in the data.keys() that has the same id as my int and it works, but it's a stupid way to it.

from my own experimentation, it seems that quantopian's python implementation has a pre-compile phase where it scans your code to detect what sids you use, and then does some behind-the-scenes rewrite,

so while i'd wait to hear from a quantopian employee, I think they don't allow it.

SS TT,

The limit is for you to individually and explicitly specify up to 100 sids in your algorithm, which defines the "universe" of securities for the alogrithm (set_universe described on the help page results in effectively the same order-of-magnitude limit).

I've attached an algorithm. If you uncomment this line, you'll see the error that results:

# context.spy = sid(8554)  

To my knowledge, Quantopian has never quite explained the nitty gritty technical details of why they don't allow free-form access to all securities, as you are trying. My sense is that it is basically a computing capacity/scalability limitation.

Note, however, I don't think that the same restrictions apply to the offline zipline backtester (https://github.com/quantopian/zipline). I've never used it, so perhaps somebody else could fill in the details here.

Hope this helps.

Grant

Hi SS TT,

Can you help me understand you use case a little bit more? Where are you getting the integers from? Why are you trying to convert the integers into sids?

Before the algorithm runs, you need to have your universe of stocks initialized - you cannot dynamically change it at each call of handle_data(). As Jason correctly noted, we parse and validate your code before we run the computation. This serves as a security check and to catch any errors in your code. We also pull in the appropriate data for the initialized stocks to make the algo run faster and improve performance.

But I'd be curious to hear more about your scenario and what you're trying to do!

Alisa

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.

It comes from the column name of the DataFrame returned by history. They are already initialized stocks, presumably.

Thanks for looking into this!

I know what you are referring to here. The history DataFrame does not have security objects as its columns, it has an Int64Index so it returns something like Int64Index([22156, 25103]). This can be a headache at times.

I'm not sure what the best solution is, a dict mapping is probably easiest. Things get a little more cumbersome when using the dollarVolume feature.

myUniverse ={  
    2174: sid(2174),  
    8554: sid(8554),  
}

for stock in someDataFrame:  
    order(myUniverse[stock], 1)  

Hello SS TT,

You don't have to use the sid ids. Reference by sid(id) works. For example, in the attached backtest:

print prices[context.sids[0]]  

results in the data for the '24' column.

If you run the attached backtest and look at the log, you'll see the details.

Grant

I use the dollar volume universe selector. I perform some computations on the DataFrame and then select what to trade based on a rank.

I am aware of various workarounds and using one of them, but I was hoping the platform supported a more direct and intuitive interface.

SS TT in your case, I can see where having the keys/columns of the history() DataFrame as Security objects instead of np.int64's would be more facile.

Since that may involve some non-trivial work; In lieu of having the Security objects as the keys, here is another possible workaround, which should be compatible with set_universe:

sids = data.keys()  
for s, price in prices.iterkv():  
    order(100, sids[sids.index(s)])  

(With the caveat that I would not put a stamp on that as an "official" work around, yet, but it may be of some use.)

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.

Hello SS TT,

Here's an approach (functionally equivalent to Eddie's, I suspect):

def initialize(context):  
    set_universe(universe.DollarVolumeUniverse(floor_percentile=20.0, ceiling_percentile=22.0))  
    context.printed = False  
def handle_data(context, data):  
    context.stocks = [sid for sid in data]  
    prices = history(5,'1d','price')  
    if not context.printed:  
        stock = context.stocks[0]  
        print stock.symbol  
        print prices[stock]  
        context.printed = True  

Grant