quantlab.acquisition.wrds.crsp.CrspQueries#
- class quantlab.acquisition.wrds.crsp.CrspQueries[source]#
Bases:
objectSQL statements for the CRSP tables on WRDS, and the calls that run them.
The builder methods are pure: they return a
psycopg2.sqlcomposable (an object that renders to safely quoted SQL) and open no connection, so their exact text can be tested without a server. The network methods take a session and only hand a built statement to the session’sschema_usable,fetch_rowsorcopy_csv. Every value is asql.Literaland every table or column name asql.Identifier. No SQL is assembled by string formatting, which also makes reserved column names such asfromandthruincomp.idxcst_hissafe to use.- Attributes:
- STOCK_SCHEMAstr
The CRSP annual-update stock schema.
- INDEX_SCHEMAstr
The CRSP annual-update index schema.
- COMPUSTAT_SCHEMAstr
The Compustat schema (company fundamentals and index membership).
- CCM_SCHEMAstr
The CRSP/Compustat Merged schema, which links the two databases.
- DAILY_TABLEstr
The daily stock table inside
STOCK_SCHEMA.
Examples
>>> where = CrspQueries.daily_where([14593], "2020-08-01", "2020-08-31") >>> query = CrspQueries.copy_query( ... "crsp_a_stock", "dsf_v2", ("permno", "dlycaldt", "dlyprc"), where ... )
Running it needs a live
WrdsSession:raw = CrspQueries.copy( session, "crsp_a_stock", "dsf_v2", ("permno", "dlycaldt"), where )
- DAILY_TABLE = 'dsf_v2'#
The daily table, unique on
(permno, dlycaldt). If that ever stops holding,stkdlysecuritydatais the fallback, and this constant is the only thing to change.
- classmethod assert_entitled(session, schemas)[source]#
Check that the account may read every schema in
schemas.Called before the first data query of a download, so a product the account has not subscribed to stops the run before any data is copied, instead of failing every batch.
- Parameters:
- sessionWrdsSession
The shared WRDS session.
- schemasiterable of str
Schema names to check.
- Raises:
- WrdsEntitlementError
Naming every schema the account cannot read.
Examples
Needs a live
WrdsSession:CrspQueries.assert_entitled(session, (CrspQueries.STOCK_SCHEMA,))
- classmethod columns_query(schema, table)[source]#
Build the query that lists one table’s columns and their positions.
It reads the standard
information_schema.columnscatalogue. Here the schema and table names are compared as values, so they are passed as literals. The result is sorted byordinal_positionin Python rather than with ORDER BY, which keeps this module free of ordering clauses.- Parameters:
- schemastr
Schema name.
- tablestr
Table name.
- Returns:
- psycopg2.sql.Composed
A query returning
(column_name, ordinal_position)rows.
Examples
>>> query = CrspQueries.columns_query("crsp_a_stock", "dsf_v2")
which renders as:
SELECT "column_name", "ordinal_position" FROM "information_schema"."columns" WHERE "table_schema" = 'crsp_a_stock' AND "table_name" = 'dsf_v2'
- classmethod copy(session, schema, table, columns, where)[source]#
Run the statement from
copy_queryand return the CSV bytes.- Parameters:
- sessionWrdsSession
The shared WRDS session.
- schemastr
Schema name.
- tablestr
Table name.
- columnsiterable of str
Column names to select, in this order.
- wherepsycopg2.sql.Composable or None
The condition, or
Nonefor the whole table.
- Returns:
- bytes
The CSV output, starting with a header line.
Examples
Needs a live
WrdsSession:raw = CrspQueries.copy( session, "crsp_a_stock", "stkdelists", ("permno", "delret"), None )
- classmethod copy_query(schema, table, columns, where=None)[source]#
Build a
COPY (SELECT ...) TO STDOUTstatement in CSV format.COPY ... TO STDOUTstreams the query result to the client as CSV, which is much faster than fetching rows one by one. The statement has no ORDER BY, GROUP BY or DISTINCT, so rows arrive exactly as the server stores them.- Parameters:
- schemastr
Schema name, quoted as an identifier.
- tablestr
Table name, quoted as an identifier.
- columnsiterable of str
Column names to select, in this order.
- wherepsycopg2.sql.Composable or None, default None
An optional condition, such as the result of
daily_where.
- Returns:
- psycopg2.sql.Composed
The complete statement. The CSV output includes a header line.
Examples
>>> query = CrspQueries.copy_query( ... "crsp_a_stock", "dsf_v2", ("permno", "dlycaldt", "dlyprc"), ... CrspQueries.daily_where([14593], "2020-08-01", "2020-08-31"), ... )
which renders as:
COPY (SELECT "permno", "dlycaldt", "dlyprc" FROM "crsp_a_stock"."dsf_v2" WHERE "permno" = ANY(ARRAY[14593]) AND "dlycaldt" BETWEEN '2020-08-01' AND '2020-08-31') TO STDOUT WITH (FORMAT csv, HEADER true)
- classmethod count(session, schema, table, where)[source]#
Return the number of rows in the table that match
where.- Parameters:
- sessionWrdsSession
The shared WRDS session.
- schemastr
Schema name.
- tablestr
Table name.
- wherepsycopg2.sql.Composable or None
The condition, or
Noneto count the whole table.
- Returns:
- int
The row count.
Examples
Needs a live
WrdsSession:rows = CrspQueries.count(session, "crsp_a_stock", "stkdelists", None)
- classmethod count_query(schema, table, where=None)[source]#
Build
SELECT count(*)over the samewherea COPY uses.Passing the same condition object to both statements guarantees that a count and the download it checks select the same rows.
- Parameters:
- schemastr
Schema name.
- tablestr
Table name.
- wherepsycopg2.sql.Composable or None, default None
An optional condition.
- Returns:
- psycopg2.sql.Composed
The count statement.
Examples
>>> query = CrspQueries.count_query("crsp_a_stock", "stkdelists")
which renders as:
SELECT count(*) FROM "crsp_a_stock"."stkdelists"
- classmethod daily_where(permnos, start, end)[source]#
Build the WHERE condition selecting PERMNOs and a date range.
PERMNOs are converted to
int, so a value that is not a PERMNO cannot reach the statement, even as a quoted literal.- Parameters:
- permnositerable of int or str
The PERMNOs to select.
- start, endstr, date or datetime
First and last calendar day, inclusive.
- Returns:
- psycopg2.sql.Composed
The condition, without the
WHEREkeyword.
- Raises:
- ValueError
If
permnosis empty. Without the PERMNO condition the query would read the whole 110-million-row table.
Examples
>>> where = CrspQueries.daily_where( ... ["14593", "10107"], "2020-01-01", "2020-12-31" ... )
which renders as:
"permno" = ANY(ARRAY[14593, 10107]) AND "dlycaldt" BETWEEN '2020-01-01' AND '2020-12-31'
- classmethod product_end(session)[source]#
Return the last date in the daily table.
This date identifies the annual release (vintage) the account currently reads.
- Parameters:
- sessionWrdsSession
The shared WRDS session.
- Returns:
- datetime.date
The last
dlycaldtindsf_v2.
- Raises:
- CrspProductEndError
If the table reports no maximum date.
Examples
Needs a live
WrdsSession:product_end = CrspQueries.product_end(session)
- classmethod product_end_query()[source]#
Build the query for the last date in the daily table.
The answer identifies which annual release (vintage) the account currently reads.
- Returns:
- psycopg2.sql.Composed
A query returning one row with one date.
Examples
>>> query = CrspQueries.product_end_query()
which renders as:
SELECT max("dlycaldt") FROM "crsp_a_stock"."dsf_v2"
- classmethod table_columns(session, schema, table)[source]#
Return the table’s column names in the server’s column order.
- Parameters:
- sessionWrdsSession
The shared WRDS session.
- schemastr
Schema name.
- tablestr
Table name.
- Returns:
- tuple of str
Column names, sorted by their position in the table.
Examples
Needs a live
WrdsSession:columns = CrspQueries.table_columns(session, "crsp_a_stock", "dsf_v2")