Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
The Truth Value of DataFrame Is Ambiguous

I'm getting an error that the data frame is ambiguous when trying to load an if statement that is based on my pct_change variable.

Any help?

from pytz import timezone  
from datetime import datetime, timedelta  
from zipline.utils.tradingcalendar import get_early_closes  
from quantopian.pipeline.data.builtin import USEquityPricing  
import pandas as pd  
import datetime  
def initialize(context):

    set_commission(commission.PerTrade(cost=0))

    set_slippage(slippage.FixedSlippage(spread=0.00))  
    context.minutes_after = 5  
    context.stock = sid(40634)

def handle_data(context, data):  
    yesterdays_close = history(1, "1d", "high")  
    log.info(yesterdays_close)  
    todays_high = data[context.stock].open_price  
    log.info("current price: %f" % todays_high)  
    pct_change = (todays_high - yesterdays_close) / todays_high * 100  
    log.info(pct_change)  
    cash = context.portfolio.cash  
    for stock in data:  
        stock_price = data[stock].price  
        plausible_investment = cash  
        stop_price = stock_price - (stock_price * 0.005)  
        share_amount = int(plausible_investment / stock_price)

        if pct_change >= 2.0:  
            order(stock, -share_amount)  
        if stock_price <= 1.90:  
            order(stock, - share_amount)  


def market_open(context, data):  
    # Checks if it's market open at 9AM EST  
    loc_dt = get_datetime().astimezone(timezone('US/Eastern'))  
    # Backtesting starts the time at 9:31AM  
    if loc_dt.hour == 9 and loc_dt.minute == 31:  
        log.debug(get_datetime())  
        for stock in data:  
            context.daily_stocks[stock] = data[stock].price  
    else:  
        pass  
def market_after_open(context, data):  
    # Checks if it's market open at 9AM EST + however minutes you want to set  
    loc_dt = get_datetime().astimezone(timezone('US/Eastern'))  
    if loc_dt.hour == 9 and loc_dt.minute == 30 + context.minutes_after:  
        log.debug(get_datetime())  
4 responses

yesterdays_close is not a number, it's a pandas dataframe. You need to index into it if you want get the exact number you care about. Hooray dynamic typing.

Thank you, Simon. I figured out how to index the DataFrame using this snippet of code close_index = yesterdays_close.iloc[0][context.stock]
That was the answer I needed and here's my code.

from pytz import timezone  
from datetime import datetime, timedelta  
from zipline.utils.tradingcalendar import get_early_closes  
from quantopian.pipeline.data.builtin import USEquityPricing  
import pandas as pd

def initialize(context):

    set_commission(commission.PerTrade(cost=0))  


    set_slippage(slippage.FixedSlippage(spread=0.00))  
    context.minutes_after = 5  
    context.stock = sid(40634)

def handle_data(context, data):  
    yesterdays_close = history(1, "1d", "high")  
    log.info(yesterdays_close)  
    close_index = yesterdays_close.iloc[0][context.stock]  
    todays_high = data[context.stock].open_price  
    log.info("current price: %f" % todays_high)  
    pct_change = (todays_high - close_index) / todays_high * 100  
    log.info(pct_change)  
    cash = context.portfolio.cash  

    for stock in data:  
        stock_price = data[stock].price  
        plausible_investment = cash  
        stop_price = stock_price - (stock_price * 0.005)  
        buy_amount = int(plausible_investment / stock_price)  
        share_amount = context.portfolio.positions[stock].amount  
        capital_used = context.portfolio.capital_used  
        if capital_used == 0:  
            order(stock, buy_amount, style=LimitOrder(stop_price))  
            print "ordering shares"  
        if pct_change <= -2.0:  
            if context.portfolio.positions_value > 0:  
                order(stock, - share_amount, style=LimitOrder(stop_price))  
                print "selling shares"  
        if stock_price <= 1.90:  
            if share_amount > 1:  
                order(stock, - share_amount, style=LimitOrder(stop_price))  
                print "selling shares"


def market_open(context, data):  
    # Checks if it's market open at 9AM EST  
    loc_dt = get_datetime().astimezone(timezone('US/Eastern'))  
    # Backtesting starts the time at 9:31AM  
    if loc_dt.hour == 9 and loc_dt.minute == 31:  
        log.debug(get_datetime())  
        for stock in data:  
            context.daily_stocks[stock] = data[stock].price  
    else:  
        pass  
def market_after_open(context, data):  
    # Checks if it's market open at 9AM EST + however minutes you want to set  
    loc_dt = get_datetime().astimezone(timezone('US/Eastern'))  
    if loc_dt.hour == 9 and loc_dt.minute == 30 + context.minutes_after:  
        log.debug(get_datetime())  

Okay, double-check you are getting the day you want though. I think history always returns "today" as a partial bar at the end of the data frame, so to get yesterday, you might need to request two bars and then get the first one (at index 0).

Simon - yesterdays_close is actually just a placeholder, I should have renamed it to what I was actually trying to accomplish, which is getting the high price of the stock for the current day.
After the highest price is received I compare that to the current price. If the price below the highest price is less than or equal to 2% I automatically sell the stock.
There is also a function to sell the stock if it reaches or goes below the price at which it was bought.
This lets my position roll while still maintaining relative control over volatility.