Skip to content

Commit

Permalink
Merge pull request #1380 from quantopian/show-correct-symbol
Browse files Browse the repository at this point in the history
BUG: always show the most recent symbol in Asset objects
  • Loading branch information
llllllllll committed Aug 9, 2016
2 parents 24f2ef8 + 586a41f commit 05ec87b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 15 deletions.
18 changes: 14 additions & 4 deletions tests/test_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,18 +568,24 @@ def test_lookup_symbol_change_ticker(self):

for asof in pd.date_range('2014-01-01', '2014-01-05', tz='utc'):
# from 01 through 05 sid 0 held 'A'
A_result = finder.lookup_symbol('A', asof)
assert_equal(
finder.lookup_symbol('A', asof),
A_result,
finder.retrieve_asset(0),
msg=str(asof),
)
# the symbol should always be the last symbol
assert_equal(A_result.symbol, 'B')

# from 01 through 05 sid 1 held 'C'
C_result = finder.lookup_symbol('C', asof)
assert_equal(
finder.lookup_symbol('C', asof),
C_result,
finder.retrieve_asset(1),
msg=str(asof),
)
# the symbol should always be the last symbol
assert_equal(C_result.symbol, 'A')

# no one held 'B' before 06
with self.assertRaises(SymbolNotFound):
Expand All @@ -596,20 +602,24 @@ def test_lookup_symbol_change_ticker(self):
# from 06 through 10 sid 0 held 'B'
# we test through the 11th because sid 1 is the last to hold 'B'
# so it should ffill
B_result = finder.lookup_symbol('B', asof)
assert_equal(
finder.lookup_symbol('B', asof),
B_result,
finder.retrieve_asset(0),
msg=str(asof),
)
assert_equal(B_result.symbol, 'B')

# from 06 through 10 sid 1 held 'A'
# we test through the 11th because sid 1 is the last to hold 'A'
# so it should ffill
A_result = finder.lookup_symbol('A', asof)
assert_equal(
finder.lookup_symbol('A', asof),
A_result,
finder.retrieve_asset(1),
msg=str(asof),
)
assert_equal(A_result.symbol, 'A')

def test_lookup_symbol(self):

Expand Down
50 changes: 39 additions & 11 deletions zipline/assets/assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -440,22 +440,50 @@ def _select_assets_by_sid(asset_tbl, sids):
def _select_asset_by_symbol(asset_tbl, symbol):
return sa.select([asset_tbl]).where(asset_tbl.c.symbol == symbol)

def _lookup_most_recent_symbols(self, sids):
def _select_most_recent_symbols_chunk(self, sid_group):
"""Retrieve the most recent symbol for a set of sids.
Parameters
----------
sid_group : iterable[int]
The sids to lookup. The length of this sequence must be less than
or equal to SQLITE_MAX_VARIABLE_NUMBER because the sids will be
passed in as sql bind params.
Returns
-------
sel : Selectable
The sqlalchemy selectable that will query for the most recent
symbol for each sid.
Notes
-----
This is implemented as an inner select of the columns of interest
ordered by the end date of the (sid, symbol) mapping. We then group
that inner select on the sid with no aggregations to select the last
row per group which gives us the most recently active symbol for all
of the sids.
"""
symbol_cols = self.equity_symbol_mappings.c
inner = sa.select(
(symbol_cols.sid,) +
tuple(map(
op.getitem(symbol_cols),
symbol_columns,
)),
).where(
symbol_cols.sid.in_(map(int, sid_group)),
).order_by(
symbol_cols.end_date.asc(),
)
return sa.select(inner.c).group_by(inner.c.sid)

def _lookup_most_recent_symbols(self, sids):
symbols = {
row.sid: {c: row[c] for c in symbol_columns}
for row in concat(
self.engine.execute(
sa.select(
(symbol_cols.sid,) +
tuple(map(op.getitem(symbol_cols), symbol_columns)),
).where(
symbol_cols.sid.in_(map(int, sid_group)),
).order_by(
symbol_cols.end_date.desc(),
).group_by(
symbol_cols.sid,
)
self._select_most_recent_symbols_chunk(sid_group),
).fetchall()
for sid_group in partition_all(
SQLITE_MAX_VARIABLE_NUMBER,
Expand Down

0 comments on commit 05ec87b

Please sign in to comment.