Is there a reliable way to exclude "when-issued" securities from fundamentals screens?

My backtest logs are full of stuff like this:

2002-05-22 PRINT THO_WI wasn't in data!
2002-05-22 PRINT RLIWI wasn't in data!
2002-05-22 PRINT SWN_WI wasn't in data!


I could block all symbols ending in "WI" but I am sure that would kill some legitimate ones too. Any ideas?

6 responses

An entry for the security sec is in the data dictionary only if sec was traded in the latest time bar. This may happen with stocks not yet admitted to trading, delisted, suspended, renamed, or many low-volume small- and mid-caps. One way around this is to use a pattern seen in some examples:

for sec in context.securities:
if sec in data:
# look at sec, buy it low or sell it high


Then, if sec was not traded in the latest bar, sec in data is False, and you will not attempt to look at the non-existent data[sec].

If the only concern is trying to trade before or after the security was admitted, you can instead do this:

for sec in context.securities:
if sec.security_start_date <= get_date time() <= sec.security_end_date:
order(sec, 1)
log.info("{}: Buying {} ({})".format(get_datetime("US/Eastern"), sec.security_name, sec.symbol))


Try this with Walgreen Co. (WAG) and Walgreen Boots Alliance (WBA) from December 2014 through January 2015, see http://www.marketwatch.com/story/walgreen-ticker-changes-to-wba-after-merger-with-boots-alliance-2014-12-31.

Hmm yes I think I can make your second suggestion work, if I filter a larger universe than I need, and in my second-stage price-based filtering where I have a data[], I can exclude stocks where the start_date hasn't happened yet. It's not ideal, but perhaps it will work.

Tried to run my "second suggestion", with trading date checks:

Something went wrong. Sorry for the inconvenience. Try using the built-in debugger to analyze your code. If you would like help, send us an email.

This is what I am now doing, seems to work okay:

    # drop assets which are not trading yet (ie: "when-issued securities")
prices = history(bar_count=5, frequency='1d', field='price')
have_prices = topN.index.intersection(prices.dropna(axis=1).columns)
subset = topN[topN.index.isin(have_prices)]
topN = subset


There seems to be some sort of change happening in the security object, they might be switching from Security to Asset now, so perhaps you need to do sec.start_date ?

I mentioned it here:

Any change in the class name from Security to Asset should not affect this code. The loop variable sec should know which class it belongs to.

But if the names of data members were also changed, and sec no longer has security_start_date or security_end_date, but eg. start_date and/or end_date, that's another matter.