Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Can I get a help with this logic?

Hello,
I have a code to get out of the market (sell it from a long position once it reaches a certain return, say 10%).

for sid in context.portfolio.positions.items():  
    costBasis = context.portfolio.positions[sid].cost_basis  
    marketPrice = context.portfolio.positions[sid].last_sale_price  
    if (float(marketPrice) / max(float(costBasis),0.01)) > 1.1:  
        sell(context, sid)

of course ...

def sell(context, sid):
if sid not in get_open_orders():
order_target_percent(sid, 0)

However , it is not working. I feel like there is something going on with "sid" and the way "context.portfolio.positions[sid].cost_basis" is supposed to work. Than you very much for your help.

3 responses

When I changed the code slightly to

for sid in context.portfolio.positions:  
    costBasis = context.portfolio.positions[sid].cost_basis  
    marketPrice = context.portfolio.positions[sid].last_sale_price  
    if (float(marketPrice) / max(float(costBasis),0.01)) > 1.5:  
        sell(context, sid)  
        log.info("Got 50 %s" % (sid.symbol))

It seems to be working. Could anyone explain to me what is the difference between having ".items()" and not having it.

The .items() function returns a list of tuples, so iterating over it means that each element will contain 2 values.

data = {'a': 1, 'b': 2}  
data.items() ==> [('a', 1), ('b', 2)]  

You can change the syntax to


for sid, position in context.portfolio.positions.items():  
    cost_basis = position.cost_basis

# or use .iteritems(), this is faster because a generator is returned without creating a new list.

for sid, position in context.portfolio.positions.iteritems():  
    cost_basis = position.cost_basis

Many thanks Edwards!