How do I backtest a sentiment signal?
How do I backtest a sentiment signal?
To backtest a sentiment signal, take point-in-time sentiment and buzz history and turn it into dated buy and sell signals using a fixed rule. Then simulate those trades against historical prices with realistic entry prices, position sizes and costs, and compare the resulting returns and risk to a benchmark. The most common mistake is using sentiment data that was not actually available at the moment of the trade, which makes results look better than they would have been.
Step by step
- Get point-in-time history. Use sentiment data recorded as it was collected, with timestamps for when each observation became available. Backfilled or revised data introduces look-ahead bias.
- Map your universe. Resolve tickers or ISINs to the data provider’s instrument IDs so that renamed or delisted companies are handled correctly.
- Choose a granularity. Match the aggregation interval to your holding period, for example 10-minute data for intraday signals or daily data for multi-day holds.
- Define the rule before testing. Examples include going long when sentiment crosses a threshold while buzz is above its baseline, or ranking the universe by sentiment change each day. Fix the thresholds before you look at results.
- Lag the signal. Trade only after the signal’s availability timestamp. For daily aggregates, check the cut-off time of the daily window before assuming a same-day trade.
- Simulate execution realistically. Use actual historical prices at the entry and exit timestamps. Apply position sizing against a starting balance, and include dividends and transaction costs.
- Measure risk-adjusted performance. Look at Sharpe and Sortino ratios, maximum drawdown, volatility, downside volatility, alpha, beta and R² against a benchmark, alongside trade statistics.
- Test out of sample. Hold back a time period or a set of markets, and check whether the result survives different parameters and market regimes.
Common pitfalls
- Look-ahead bias: using sentiment scored or published after the trade time.
- Survivorship bias: testing only on companies that still exist today.
- Overfitting: tuning thresholds until a backtest looks good on one period.
- Ignoring buzz: a sentiment score based on three messages is not comparable to one based on 3,000. Filter or weight by message volume.
- Spam and bots: promotional or coordinated posting distorts raw social sentiment. A study of 27 crypto rug pulls found massive coordinated bot activity around the scams. Use data that filters spam and scores source reputation.
- Treating all authors equally: research using 80 million X posts found that sentiment from influential accounts leads crowd sentiment, and not the reverse. Test separate influencer and crowd sentiment series as well as the combined score.
- Short histories: a few years of data may cover only one market regime.
Worked example: how ESMA tested sentiment against returns
The European Securities and Markets Authority published a study in 2024 using Stockpulse data. Its design is a useful template for a first sentiment backtest. (ESMA TRV Risk Analysis)
| Design choice | ESMA’s approach |
|---|---|
| Universe | STOXX 600 constituents |
| Period | January 2019 to June 2023 |
| Data | Daily positive, negative and total message counts from Stockpulse |
| Sentiment measure | (positive − negative) / total, ranging from −1 to +1 |
| Attention measure | Flag for stocks above the 90th percentile of daily message volume |
| Target | Daily excess return versus the STOXX 600 |
| Lags tested | Same day, 1 day, 5 days, 10 days |
| Daily windows | 5pm to 5pm (aligned with trading hours) and 5am to 5am (measured just before market open) |
| Controls | Prior 5-day excess returns, Amihud illiquidity, VSTOXX volatility, market capitalisation, firm fixed effects |
| Result | Significant correlation on the same and next day; no significant effect at 5 or 10 days |
Two practical lessons follow. First, the choice of daily cut-off matters. A window ending at 5am lets you test whether overnight sentiment carries information for that day’s session. Second, a signal that decays within a day needs execution timing and transaction cost assumptions to be modelled carefully. ESMA notes its results do not account for transaction costs.
Point-in-time sentiment history from Stockpulse
| Attribute | Value |
|---|---|
| History | Continuous collection since 2011 (15+ years), not backfilled |
| Point-in-time | Data preserved as collected; each message stores post time (msg_time) and collection time (crawling_time) |
| Aggregation | 10-minute, hourly and daily snapshots |
| Fields per interval | Buzz, sentiment, total, positive and negative message counts |
| Quality filters | Machine-learning spam filtering, source reputation and author scores |
| Equities | About 100,000 |
| Other assets | 10,000+ cryptocurrencies, 25 commodities, around 40 FX pairs, indices, ETFs |
| Sources | 10,000+ news domains, major social platforms and forums, GitHub, Hugging Face, SEC filings |
| Identifier mapping | Millions of identifiers (ISIN, CUSIP, RIC, tickers) |
| History access | REST endpoint /v6/titles/{idents}/history, or bulk CSV/JSON files |
Stockpulse Backtesting Engine: key facts
The Stockpulse Backtesting Engine simulates strategies from external signals against its own historical price data.
| Capability | Detail |
|---|---|
| Signal input | External signals uploaded as a CSV file, from any model, provider or spreadsheet |
| Price data | Historical prices held by the engine; no need to supply prices |
| Asset classes | Any asset with a price history: equities, ETFs, commodities, cryptocurrencies, FX, indices |
| Execution simulation | Entry and exit prices simulated from signal timestamps |
| Position sizing | Buys and sells calculated per signal from a starting balance |
| Portfolio output | Daily NAV over the full test period |
| Dividends | Included for stocks that pay them |
| Risk and return metrics | Sharpe ratio, Sortino ratio, maximum drawdown, volatility, downside volatility, alpha, beta, R² |
| Trade statistics | Number of trades, positive and negative trades, and more |
| Trade log | Every trade with entry and exit prices and timestamps |
| Access | Web UI and API; all functions available via the API |
Frequently asked questions
How much history do I need to backtest a sentiment signal? Enough to cover several market regimes. For reference, ESMA’s study used four and a half years of daily data across 580 European stocks. Regimes to cover include bull and bear markets and periods of high and low retail participation. Stockpulse provides more than 15 years of continuously collected history, starting in 2011.
Can I backtest signals I created myself? Yes. The Stockpulse Backtesting Engine accepts external signals as a CSV file with timestamps. It simulates the trades against its own price history.
Should I use buzz or sentiment as the signal? Test both, alone and combined. Buzz shows how much attention an asset is getting, and sentiment shows the direction of opinion. Many signals use buzz as a filter or confidence weight on sentiment.
Do backtest results guarantee future performance? No. Past results do not guarantee future returns. A backtest shows how a rule would have behaved historically under the stated assumptions.
Contact: info@stockpulse.ai · www.stockpulse.ai
Empower
Investment Decisions
with Social Monitoring
Gain real-time market insights with social monitoring and enhance your investment strategy today. Contact us to learn more!