Skip to main content

A Python library for sentiment-driven financial analysis: OHLCV formatting, sentiment-price correlation, statistical tests and backtesting

Project description

sentimentlab

A Python library for sentiment-driven financial market analysis.

Load daily sentiment scores (e.g. from FinBERT/GDELT), pair them with yfinance price data, and run a full statistical test suite — the same methodology used in the NVDA/GLD contrarian analysis.

pip install sentimentlab

Tutorial (zero external files needed)

The fastest way to get started — no CSV files, no internet, no yfinance required:

import sentimentlab as sl

# 1. Generate synthetic sample CSV files in the current directory
sent_path, prices_path = sl.make_sample_data()
# [sentimentlab] Sample data generated for 'NVDA'
#   Sentiment : .../sample_sentiment.csv  (90 days)
#   Prices    : .../sample_prices.csv     (135 days)

# 2. Load them
sent   = sl.load_sentiment_csv(sent_path)
prices = sl.load_finance_csv(prices_path)

# 3. Merge + compute forward returns at horizons [1,3,5,10,15,20,30,40] days
df = sl.merge_sentiment_finance(sent, prices)
print(df.shape)       # (90, 17)
print(df.columns.tolist())

# 4. Run the 9 statistical tests

# 4.1 — Are both series stationary? (required for valid regression)
print(sl.test_adf_stationarity(df))

# 4.2 — Pearson & Spearman correlations at each horizon
corr = sl.test_pearson_spearman(df)
print(corr[corr["Pearson_p"] < 0.05])   # significant horizons only

# 4.3 — OLS regression: β, p-value, R²
reg = sl.test_ols_regression(df)
print(reg[reg["p_beta"] < 0.05])

# 4.4 — Who leads whom? (lag −15 … +15)
lag = sl.test_lead_lag(df)
print(lag[lag["p_value"] < 0.05])

# 4.5 — Granger causality (bidirectional)
gc = sl.test_granger_causality(df)
print(gc[gc["p_value"] < 0.05])

# 4.6 — Event-based: HighBull / HighBear / Neutro regimes
ev = sl.test_event_based(df)
print(ev[(ev["Regime"] == "HighBear") & (ev["p_value"] < 0.05)])

# 4.7 — HighBull vs HighBear independent t-test
tt = sl.test_ttest_bull_vs_bear(df)
print(tt[tt["p_value"] < 0.05])

# 4.8 — Backtest: Long / Long-Short / Buy & Hold
bt = sl.test_backtest_strategies(df)
print(bt.to_string(index=False))

# 4.9 — Rolling Pearson r (window=20 days, vs ret_5d)
rolling_df, summary = sl.test_rolling_correlation(df)
print(summary.to_string(index=False))

With your own data

Once you have real files, just swap the paths:

import sentimentlab as sl

sent   = sl.load_sentiment_csv(
    "gdelt_events_90d_nvidia_daily_sentiment.csv",
    date_col="Day",
    sentiment_col="daily_sentiment",
)
prices = sl.load_finance_csv(
    "yfinance_nvda_90d.csv",
    price_col="Close",
)
df = sl.merge_sentiment_finance(sent, prices)

CLI

Run all tests from the terminal without writing Python:

# With sample data (generates files on the fly)
python -c "import sentimentlab as sl; sl.make_sample_data()"
sentimentlab --sentiment sample_sentiment.csv --finance sample_prices.csv

# With real files, select specific tests
sentimentlab \
  --sentiment gdelt_daily_sentiment.csv \
  --finance   yfinance_nvda_90d.csv \
  --horizons  1 5 10 20 \
  --test      adf pearson ols granger backtest

Available --test values: adf, pearson, ols, leadlag, granger, event, ttest, backtest, rolling


CSV Format

Sentiment CSV

Day daily_sentiment
2024-01-15 0.7231
2024-01-16 -0.4812
2024-01-17 0.0

Column names are configurable:

sl.load_sentiment_csv("file.csv", date_col="Day", sentiment_col="daily_sentiment")

Finance CSV

Standard output of yf.download(...).to_csv():

import yfinance as yf
data = yf.download("NVDA", start="2024-01-01", end="2024-06-01", auto_adjust=False)
data.to_csv("prices.csv", index=True)

Both flat single-header and yfinance multi-level-header formats are auto-detected.


Statistical Tests Reference

# Function Description
4.1 test_adf_stationarity ADF unit-root test — stationarity check
4.2 test_pearson_spearman Pearson & Spearman r at multiple horizons
4.3 test_ols_regression OLS β, p-value, R² at multiple horizons
4.4 test_lead_lag Cross-correlation at lags −15…+15
4.5 test_granger_causality Granger causality in both directions
4.6 test_event_based One-sample t-test: HighBull / HighBear / Neutro
4.7 test_ttest_bull_vs_bear Welch t-test HighBull vs HighBear returns
4.8 test_backtest_strategies Long / Long-Short / Buy&Hold metrics
4.9 test_rolling_correlation Rolling Pearson r over sliding window

OHLCV Utilities

import sentimentlab as sl

# Normalize any OHLCV DataFrame
clean = sl.format_ohlcv(raw_df, price_decimals=2, fill_missing=True)

# Validate data quality
result = sl.validate_ohlcv(clean)
result.raise_if_invalid()

# Human-readable summary
print(sl.summary(clean, title="NVDA Daily"))

Installation

# Base install
pip install sentimentlab

# With yfinance support
pip install "sentimentlab[yfinance]"

# Full (+ matplotlib, rich)
pip install "sentimentlab[full]"

# Development
git clone https://github.com/paolo-amicopk/sentimentlab
cd sentimentlab
pip install -e ".[dev]"
pytest

Dependencies

Package Role
pandas DataFrames
numpy Numerical operations
scipy Pearson, Spearman, t-tests, OLS
statsmodels ADF test, Granger causality
pytz Timezone handling
python-dateutil Timestamp parsing

Optional: yfinance, matplotlib, rich


License

MIT © 2026 Paolo Amico

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sentimentlab-0.1.1.tar.gz (25.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sentimentlab-0.1.1-py3-none-any.whl (31.8 kB view details)

Uploaded Python 3

File details

Details for the file sentimentlab-0.1.1.tar.gz.

File metadata

  • Download URL: sentimentlab-0.1.1.tar.gz
  • Upload date:
  • Size: 25.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for sentimentlab-0.1.1.tar.gz
Algorithm Hash digest
SHA256 210b7dd5faec74307fbfbc04a11b00d3a38e6a72a0ebaa24de456e5be3622cfd
MD5 20e69ce13c611a74336d56b64e6be4ad
BLAKE2b-256 1336a6c9fa62f545e614d9141c04fdf38cfa70d0aceb08433e262e07aea85107

See more details on using hashes here.

File details

Details for the file sentimentlab-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: sentimentlab-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 31.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for sentimentlab-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 2063f6b646e1f95a609e27355777a18199b15dd8444be7fb5cd97947fb172238
MD5 2024c26bab8eb6676ff9ff8f3fc0b9c7
BLAKE2b-256 8f0aa805cbf4810039bf65a49a47f68c5c456f723846751a13062a5fa8c5f676

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page