Data Explorer#

A quick tour of all datasets assembled for the Chen, Kelly, and Xiu (2022) replication. Data sources: RavenPack news analytics, CRSP stock/index data, and FRED macro series.

from pathlib import Path

import polars as pl

from settings import config

DATA_DIR = Path(config("DATA_DIR"))

RavenPack#

Dow Jones newswire articles scored by RavenPack’s NLP analytics engine.

ravenpack_djpr.parquet#

Raw RavenPack Dow Jones Press Release analytics — one row per news article/entity event.

rp = pl.scan_parquet(DATA_DIR / "ravenpack_djpr.parquet")
shape = rp.select(pl.len()).collect().item()
cols = rp.collect_schema().names()
print(f"Rows: {shape:,}  |  Columns: {len(cols)}")
print(f"Columns: {cols}")
Rows: 28,808,984  |  Columns: 25
Columns: ['timestamp_utc', 'rp_story_id', 'rp_entity_id', 'entity_type', 'entity_name', 'country_code', 'relevance', 'event_sentiment_score', 'event_relevance', 'event_similarity_key', 'event_similarity_days', 'topic', 'rp_group', 'rp_type', 'sub_type', 'property', 'fact_level', 'category', 'news_type', 'rp_source_id', 'source_name', 'provider_id', 'provider_story_id', 'headline', 'css']
rp.head(5).collect()
shape: (5, 25)
timestamp_utcrp_story_idrp_entity_identity_typeentity_namecountry_coderelevanceevent_sentiment_scoreevent_relevanceevent_similarity_keyevent_similarity_daystopicrp_grouprp_typesub_typepropertyfact_levelcategorynews_typerp_source_idsource_nameprovider_idprovider_story_idheadlinecss
datetime[ns]strstrstrstrstrf64f64f64strf64strstrstrstrstrstrstrstrstrstrstrstrstrf64
2000-01-01 17:52:28"52D513EA9040443376A6B1747B0FA8…"047E26""COMP""Sprint Corp.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000112""Sprint Says No Y2K Rollover Pr…-0.06
2000-01-01 17:52:28"96F65B2BE41EEFA2ACE91BC7D0F550…"047E26""COMP""Sprint Corp.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000112""Sprint Says No Y2K Rollover Pr…-0.06
2000-01-01 19:11:58"32E2DF0E449A5530F32029BAC016B8…"248F44""COMP""Motors Liquidation Co.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000121""Air Traffic -2: Amtrak,General…0.0
2000-01-01 19:11:58"5827127FF74AC65C491DBCC82DE130…"248F44""COMP""Motors Liquidation Co.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000121""Air Traffic -2: Amtrak,General…0.0
2000-01-01 18:02:50"64A24375781C0F561C0C1E6F160682…"61B81B""COMP""PNC Financial Services Group I…"US"91.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000113""PNC Bank Says Computer Systems…0.04
rp.select(
    pl.col("timestamp_utc").min().alias("earliest"),
    pl.col("timestamp_utc").max().alias("latest"),
).collect()
shape: (1, 2)
earliestlatest
datetime[ns]datetime[ns]
2000-01-01 00:24:512019-06-29 22:00:11.548

ravenpack_djpr_with_permno.parquet#

RavenPack articles linked to CRSP PERMNOs via the crosswalk table.

rp_permno = pl.scan_parquet(DATA_DIR / "ravenpack_djpr_with_permno.parquet")
shape = rp_permno.select(pl.len()).collect().item()
cols = rp_permno.collect_schema().names()
print(f"Rows: {shape:,}  |  Columns: {len(cols)}")
print(f"Columns: {cols}")
Rows: 28,147,995  |  Columns: 27
Columns: ['timestamp_utc', 'rp_story_id', 'rp_entity_id', 'entity_type', 'entity_name', 'country_code', 'relevance', 'event_sentiment_score', 'event_relevance', 'event_similarity_key', 'event_similarity_days', 'topic', 'rp_group', 'rp_type', 'sub_type', 'property', 'fact_level', 'category', 'news_type', 'rp_source_id', 'source_name', 'provider_id', 'provider_story_id', 'headline', 'css', 'permno', '__index_level_0__']
rp_permno.head(5).collect()
shape: (5, 27)
timestamp_utcrp_story_idrp_entity_identity_typeentity_namecountry_coderelevanceevent_sentiment_scoreevent_relevanceevent_similarity_keyevent_similarity_daystopicrp_grouprp_typesub_typepropertyfact_levelcategorynews_typerp_source_idsource_nameprovider_idprovider_story_idheadlinecsspermno__index_level_0__
datetime[ns]strstrstrstrstrf64f64f64strf64strstrstrstrstrstrstrstrstrstrstrstrstrf64i64i64
2000-01-01 17:52:28"52D513EA9040443376A6B1747B0FA8…"047E26""COMP""Sprint Corp.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000112""Sprint Says No Y2K Rollover Pr…-0.06390870
2000-01-01 17:52:28"96F65B2BE41EEFA2ACE91BC7D0F550…"047E26""COMP""Sprint Corp.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000112""Sprint Says No Y2K Rollover Pr…-0.06390871
2000-01-01 19:11:58"32E2DF0E449A5530F32029BAC016B8…"248F44""COMP""Motors Liquidation Co.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000121""Air Traffic -2: Amtrak,General…0.0120792
2000-01-01 19:11:58"5827127FF74AC65C491DBCC82DE130…"248F44""COMP""Motors Liquidation Co.""US"92.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000121""Air Traffic -2: Amtrak,General…0.0120793
2000-01-01 18:02:50"64A24375781C0F561C0C1E6F160682…"61B81B""COMP""PNC Financial Services Group I…"US"91.0nullnullnullnullnullnullnullnullnullnullnull"FULL-ARTICLE""B5569E""Dow Jones Newswires""DJ""DN20000101000113""PNC Bank Says Computer Systems…0.04604424
# PERMNO coverage
total = rp_permno.select(pl.len()).collect().item()
matched = rp_permno.filter(pl.col("permno").is_not_null()).select(pl.len()).collect().item()
n_permnos = rp_permno.select(pl.col("permno").n_unique()).collect().item()
print(f"Total rows: {total:,}")
print(f"Rows with PERMNO: {matched:,} ({matched / total * 100:.1f}%)")
print(f"Unique PERMNOs: {n_permnos:,}")
Total rows: 28,147,995
Rows with PERMNO: 28,147,995 (100.0%)
Unique PERMNOs: 10,626

raven_crsp_crosswalk.parquet#

Maps RavenPack entity IDs to CRSP PERMNOs.

crosswalk = pl.read_parquet(DATA_DIR / "raven_crsp_crosswalk.parquet")
print(f"Shape: {crosswalk.shape}")
crosswalk.head(5)
Shape: (16376, 2)
shape: (5, 2)
permnorp_entity_id
i64str
57293"5F8A7F"
14704"8FEF3B"
21971"23E688"
12030"812BD2"
80804"ECC614"
print(f"Unique RavenPack entities: {crosswalk['rp_entity_id'].n_unique()}")
print(f"Unique PERMNOs: {crosswalk['permno'].n_unique()}")
Unique RavenPack entities: 15799
Unique PERMNOs: 16242

CRSP#

Stock and index returns from the Center for Research in Security Prices.

CRSP_MSF_INDEX_INPUTS.parquet#

Monthly stock file — individual security returns and market cap used as index inputs.

msf = pl.read_parquet(DATA_DIR / "CRSP_MSF_INDEX_INPUTS.parquet")
print(f"Shape: {msf.shape}")
print(f"Columns: {msf.columns}")
msf.head(5)
Shape: (4447518, 24)
Columns: ['permno', 'permco', 'date', 'ret', 'retx', 'shrout', 'prc', 'vol', 'cfacshr', 'cfacpr', 'primaryexch', 'siccd', 'naics', 'issuertype', 'securitytype', 'securitysubtype', 'sharetype', 'usincflg', 'tradingstatusflg', 'altprc', 'adj_shrout', 'adj_prc', 'market_cap', '__index_level_0__']
shape: (5, 24)
permnopermcodateretretxshroutprcvolcfacshrcfacprprimaryexchsiccdnaicsissuertypesecuritytypesecuritysubtypesharetypeusincflgtradingstatusflgaltprcadj_shroutadj_prcmarket_cap__index_level_0__
i64i64datetime[ns]f64f64f64f64f64f64f64stri64strstrstrstrstrstrstrf64f64f64f64i64
1000079521986-01-31 00:00:000.7073170.7073173.68e64.375177082.01.01.0"Q"3990"0""ACOR""EQTY""COM""NS""Y""A"4.3753.68e64.3751.61e70
1000079521986-02-28 00:00:00-0.257143-0.2571433.68e63.2582800.01.01.0"Q"3990"0""ACOR""EQTY""COM""NS""Y""A"3.253.68e63.251.196e71
1000079521986-03-31 00:00:000.3653850.3653853.68e64.4375107801.01.01.0"Q"3990"0""ACOR""EQTY""COM""NS""Y""A"4.43753.68e64.43751.633e72
1000079521986-04-30 00:00:00-0.098592-0.0985923.793e64.095700.01.01.0"Q"3990"0""ACOR""EQTY""COM""NS""Y""A"4.03.793e64.01.5172e73
1000079521986-05-30 00:00:00-0.222656-0.2226563.793e63.109375107362.01.01.0"Q"3990"0""ACOR""EQTY""COM""NS""Y""A"3.1093753.793e63.1093751.1794e74
date_col = [c for c in msf.columns if "date" in c.lower()][0]
print(f"Date range: {msf[date_col].min()} to {msf[date_col].max()}")
print(f"Unique PERMNOs: {msf['permno'].n_unique():,}")
Date range: 1925-12-31 00:00:00 to 2024-12-31 00:00:00
Unique PERMNOs: 31,716

CRSP_DSI.parquet#

Daily stock index — aggregate market returns and counts.

dsi = pl.read_parquet(DATA_DIR / "CRSP_DSI.parquet")
print(f"Shape: {dsi.shape}")
dsi.head(5)
Shape: (26051, 11)
shape: (5, 11)
datevwretdvwretxewretdewretxtotvaltotcntusdvalusdcntsprtrnspindx
datetime[ns]f64f64f64f64f64i64f64f64f64f64
1925-12-31 00:00:00nullnullnullnull2.7487e7503nullnullnullnull
1926-01-02 00:00:000.0056890.0056890.0095160.0095162.7600e74972.7367e7494.0nullnull
1926-01-04 00:00:000.0007060.0007060.005780.005782.7578e75022.7480e7495.0nullnull
1926-01-05 00:00:00-0.004821-0.004867-0.001927-0.002032.7530e75012.7562e7499.0nullnull
1926-01-06 00:00:00-0.000423-0.0004270.0011820.0011552.7619e75052.7527e7500.0nullnull
date_col = [c for c in dsi.columns if "date" in c.lower()][0]
print(f"Date range: {dsi[date_col].min()} to {dsi[date_col].max()}")
Date range: 1925-12-31 00:00:00 to 2024-12-31 00:00:00

CRSP_MSIX.parquet#

Monthly stock index returns.

msix = pl.read_parquet(DATA_DIR / "CRSP_MSIX.parquet")
print(f"Shape: {msix.shape}")
msix.head(5)
Shape: (1189, 35)
shape: (5, 35)
caldtvwretdvwinddvwretxvwindxewretdewinddewretxewindxsprtrnspindxdecret1decind1decret2decind2decret3decind3decret4decind4decret5decind5decret6decind6decret7decind7decret8decind8decret9decind9decret10decind10totvaltotcntusdvalusdcnt
datetime[ns]f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64i64f64f64
1925-12-31 00:00:00null1.474607null12.20626null0.404439null2.596484null12.46null0.101595null0.421553null0.856283null0.971508null0.784855null0.767571null0.828015null1.631464null0.935128null1.7547152.7487e7503nullnull
1926-01-30 00:00:000.0005611.475434-0.00139512.189230.0231740.4138120.0213952.6520370.02247212.740.143660.116190.0439820.4400930.0038390.8595710.0213340.9922340.0264450.805611-0.0016350.7663160.0042530.8315370.0028181.6360620.0047260.939547-0.0038371.7479832.7624e75062.7413e7496.0
1926-02-27 00:00:00-0.0330461.426677-0.03658711.74326-0.053510.391668-0.0555472.504724-0.04395612.18-0.0457180.110878-0.0676020.410342-0.0457790.820221-0.0796990.913154-0.070860.748526-0.0535580.725274-0.052080.78823-0.0564641.543682-0.0355080.906186-0.0223921.7088432.6752e75142.7601e7500.0
1926-03-31 00:00:00-0.0640021.335367-0.07002110.92098-0.0968240.353745-0.1014042.250734-0.05911311.46-0.1398630.095371-0.0951920.371281-0.1259090.716948-0.1169520.806359-0.0936620.678417-0.0883670.661184-0.0998820.7095-0.0752991.427445-0.069460.843242-0.0518741.6201982.5083e75192.6684e7507.0
1926-04-30 00:00:000.0370291.3848140.03404311.292770.0329750.365410.0301562.3186070.02268811.720.0466330.0998180.0112150.3754450.0103180.7243450.0556620.8512420.0628170.7210330.0212490.6752330.041720.73910.0443961.4908170.0344770.8723140.0362931.6792.5887e75212.4921e7513.0

FRED#

Macroeconomic time series from the Federal Reserve Economic Data service.

fred = pl.read_parquet(DATA_DIR / "fred.parquet")
print(f"Shape: {fred.shape}")
print(f"Columns: {fred.columns}")
fred.head(5)
Shape: (9699, 25)
Columns: ['GDP', 'CPIAUCNS', 'GDPC1', 'INDPRO', 'PAYEMS', 'DPCREDIT', 'EFFR', 'OBFR', 'SOFR', 'DFEDTARU', 'DFEDTARL', 'WALCL', 'TOTRESNS', 'TREAST', 'CURRCIR', 'GFDEBTN', 'WTREGEN', 'RRPONTSYAWARD', 'RRPONTSYD', 'RPONTSYD', 'WSDONTL', 'Gen_IORB', 'ONRRP_CTPY_LIMIT', 'ONRP_AGG_LIMIT', 'DATE']
shape: (5, 25)
GDPCPIAUCNSGDPC1INDPROPAYEMSDPCREDITEFFROBFRSOFRDFEDTARUDFEDTARLWALCLTOTRESNSTREASTCURRCIRGFDEBTNWTREGENRRPONTSYAWARDRRPONTSYDRPONTSYDWSDONTLGen_IORBONRRP_CTPY_LIMITONRP_AGG_LIMITDATE
f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64f64datetime[ns]
null9.8nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull1913-01-01 00:00:00
null9.8nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull1913-02-01 00:00:00
null9.8nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull1913-03-01 00:00:00
null9.8nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull1913-04-01 00:00:00
null9.7nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull1913-05-01 00:00:00
date_col = [c for c in fred.columns if "date" in c.lower()][0]
print(f"Date range: {fred[date_col].min()} to {fred[date_col].max()}")
Date range: 1913-01-01 00:00:00 to 2026-02-12 00:00:00
# Non-null counts per series
fred.select(pl.all().is_not_null().sum()).unpivot(
    variable_name="series",
    value_name="non_null_count",
).sort("non_null_count")
shape: (25, 2)
seriesnon_null_count
stru32
"GFDEBTN"239
"GDP"315
"GDPC1"315
"PAYEMS"1045
"INDPRO"1284
……
"WTREGEN"7872
"WSDONTL"7872
"TOTRESNS"9147
"CURRCIR"9644
"DATE"9699

Market Data#

Computed market-level return and volatility measures.

market = pl.read_parquet(DATA_DIR / "market_data.parquet")
print(f"Shape: {market.shape}")
market.head(5)
Shape: (402, 3)
shape: (5, 3)
market_returnmarket_volatilitydate
f64f64datetime[ns]
-0.9258690.626671984-01-01 00:00:00
-3.9634521.0128331984-02-01 00:00:00
1.3407710.7997221984-03-01 00:00:00
0.5450690.7370191984-04-01 00:00:00
-6.1191010.6051251984-05-01 00:00:00
market.describe()
shape: (9, 4)
statisticmarket_returnmarket_volatilitydate
strf64f64str
"count"402.0402.0"402"
"null_count"0.00.0"0"
"mean"0.668510.961621"2000-09-15 09:43:52.835820"
"std"4.3374230.600189null
"min"-24.5428030.256884"1984-01-01 00:00:00"
"25%"-1.6933310.620898"1992-05-01 00:00:00"
"50%"1.0617610.804608"2000-10-01 00:00:00"
"75%"3.4581211.095015"2009-02-01 00:00:00"
"max"12.3780036.119488"2017-06-01 00:00:00"