Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ A sentiment-driven trading algorithm that leverages social media sentiment analy

- **Sentiment Analysis**: LSTM-based neural network for sentiment classification
- **Social Media Integration**: StockTwits API integration for real-time data collection
- **Adanos Sentiment API**: Pre-analyzed sentiment from Reddit, X/Twitter, and Polymarket — no scraping needed ([docs](https://api.adanos.org/docs/))
- **Web Scraping**: Automated data collection from social platforms
- **Database Integration**: MySQL database for storing sentiment data and predictions
- **Machine Learning Pipeline**: Complete ML workflow from data collection to prediction
Expand Down Expand Up @@ -109,6 +110,33 @@ python stocktwitAPI.py
python webscraper.py
```

### Adanos Sentiment API (recommended)

Instead of scraping, you can use the [Adanos Sentiment API](https://api.adanos.org/docs/) to get
pre-analyzed sentiment data from Reddit, X/Twitter, and Polymarket:

```python
from adanos_client import AdanosClient

client = AdanosClient(api_key="your-api-key")

# Get trending stocks with sentiment scores
trending = client.reddit_trending(days=7, limit=20)
for stock in trending:
print(f"{stock['ticker']}: sentiment={stock['sentiment_score']}, buzz={stock['buzz_score']}")

# Get detailed sentiment for a specific stock
aapl = client.reddit_stock("AAPL", days=7)
print(f"Mentions: {aapl['mentions']}, Bullish: {aapl['bullish_pct']}%")

# Compare sentiment across platforms (Reddit + X/Twitter)
datapoints = client.get_sentiment_datapoints(["AAPL", "TSLA", "NVDA"])
for dp in datapoints:
print(f"{dp['ticker']} ({dp['source']}): sentiment={dp['sentiment']}")
```

Get a free API key at [api.adanos.org/docs](https://api.adanos.org/docs/).

## 📁 Project Structure

```
Expand All @@ -118,6 +146,7 @@ feels-trader/
├── models/ # Trained ML models
├── research/ # Research papers and documentation
├── res/ # Resources (database schema, etc.)
├── adanos_client.py # Adanos Sentiment API client
├── dbio.py # Database I/O operations
├── sentiment.py # Sentiment analysis model
├── stocktwitAPI.py # StockTwits API integration
Expand Down Expand Up @@ -146,6 +175,7 @@ The sentiment analysis model uses:

## 📊 Data Sources

- **[Adanos Sentiment API](https://api.adanos.org/docs/)**: Pre-analyzed sentiment from Reddit, X/Twitter, Polymarket, and crypto communities (recommended)
- **StockTwits**: Real-time social sentiment data
- **IMDB Dataset**: For initial model training
- **Web Scraping**: Additional social media platforms
Expand Down Expand Up @@ -186,4 +216,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
## ⚠️ Disclaimer

This software is for educational and research purposes only. Trading decisions should not be made solely based on sentiment analysis. Always conduct thorough research and consider consulting with financial advisors before making investment decisions.

147 changes: 147 additions & 0 deletions adanos_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"""
adanos_client.py

Client for the Adanos Sentiment API (https://api.adanos.org/docs/).
Provides pre-analyzed sentiment data from Reddit, X/Twitter, and Polymarket
so you don't need to scrape social media yourself.

Usage:
from adanos_client import AdanosClient

client = AdanosClient(api_key="sk_live_...")

# Get trending stocks from Reddit
trending = client.reddit_trending(days=7, limit=20)

# Get sentiment for a specific stock
stock = client.reddit_stock("AAPL", days=7)

# Get trending from X/Twitter
x_trending = client.x_trending(days=7, limit=20)

# Compare multiple stocks
comparison = client.reddit_compare(["AAPL", "TSLA", "NVDA"], days=7)
"""

import requests
import os


class AdanosClient:
BASE_URL = "https://api.adanos.org"

def __init__(self, api_key=None):
self.api_key = api_key or os.getenv("ADANOS_API_KEY")
if not self.api_key:
try:
from config import ADANOS_API_KEY
self.api_key = ADANOS_API_KEY
except ImportError:
raise ValueError(
"Adanos API key not found. Set ADANOS_API_KEY env var, "
"pass api_key= to constructor, or add to config.py"
)
self.session = requests.Session()
self.session.headers["X-API-Key"] = self.api_key

def _get(self, path, params=None):
resp = self.session.get(f"{self.BASE_URL}{path}", params=params)
resp.raise_for_status()
return resp.json()

# ── Reddit Stocks ──

def reddit_trending(self, days=7, limit=20, offset=0, type="all"):
"""Get trending stocks from Reddit sentiment analysis."""
return self._get("/reddit/stocks/v1/trending", {
"days": days, "limit": limit, "offset": offset, "type": type,
})

def reddit_stock(self, ticker, days=7):
"""Get detailed sentiment data for a specific stock from Reddit."""
return self._get(f"/reddit/stocks/v1/stock/{ticker}", {"days": days})

def reddit_compare(self, tickers, days=7):
"""Compare sentiment across multiple stocks on Reddit."""
return self._get("/reddit/stocks/v1/compare", {
"tickers": ",".join(tickers), "days": days,
})

def reddit_search(self, query):
"""Search for stocks by name or ticker."""
return self._get("/reddit/stocks/v1/search", {"q": query})

def reddit_sectors(self, days=7, limit=20):
"""Get trending sectors from Reddit."""
return self._get("/reddit/stocks/v1/trending/sectors", {
"days": days, "limit": limit,
})

# ── X/Twitter Stocks ──

def x_trending(self, days=7, limit=20, offset=0, type="all"):
"""Get trending stocks from X/Twitter sentiment analysis."""
return self._get("/x/stocks/v1/trending", {
"days": days, "limit": limit, "offset": offset, "type": type,
})

def x_stock(self, ticker, days=7):
"""Get detailed sentiment data for a specific stock from X/Twitter."""
return self._get(f"/x/stocks/v1/stock/{ticker}", {"days": days})

def x_compare(self, tickers, days=7):
"""Compare sentiment across multiple stocks on X/Twitter."""
return self._get("/x/stocks/v1/compare", {
"tickers": ",".join(tickers), "days": days,
})

# ── Reddit Crypto ──

def crypto_trending(self, days=7, limit=20, offset=0):
"""Get trending crypto tokens from Reddit sentiment analysis."""
return self._get("/reddit/crypto/v1/trending", {
"days": days, "limit": limit, "offset": offset,
})

def crypto_token(self, symbol, days=7):
"""Get detailed sentiment data for a specific crypto token."""
return self._get(f"/reddit/crypto/v1/token/{symbol}", {"days": days})

# ── Helpers ──

def get_sentiment_datapoints(self, tickers, days=7):
"""
Fetch sentiment data for multiple tickers and return as a list of
dicts compatible with FeelsTrader's datapoint format.

Returns list of:
{
"ticker": str,
"sentiment": float, # -1.0 to 1.0
"buzz_score": float,
"mentions": int,
"bullish_pct": float,
"bearish_pct": float,
"trend": str,
"source": str,
}
"""
datapoints = []
for ticker in tickers:
for source, fetch in [("reddit", self.reddit_stock), ("x", self.x_stock)]:
try:
data = fetch(ticker, days=days)
if data.get("found"):
datapoints.append({
"ticker": ticker,
"sentiment": data.get("sentiment_score", 0),
"buzz_score": data.get("buzz_score", 0),
"mentions": data.get("mentions", data.get("total_mentions", 0)),
"bullish_pct": data.get("bullish_pct", 0),
"bearish_pct": data.get("bearish_pct", 0),
"trend": data.get("trend", "stable"),
"source": source,
})
except requests.HTTPError:
continue
return datapoints
4 changes: 4 additions & 0 deletions config.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ STOCKTWITS_USER_ID = "your-user-id"
STOCKTWITS_USERNAME = "your-username"
STOCKTWITS_ACCESS_TOKEN = "your-access-token"

# Adanos Sentiment API (https://api.adanos.org/docs/)
# Get your free API key at: https://api.adanos.org/docs/
ADANOS_API_KEY = "your-adanos-api-key"

# Web Scraper Configuration
WEBSCRAPER_USERNAME = "your-stocktwits-username"
WEBSCRAPER_PASSWORD = "your-stocktwits-password"
Expand Down
25 changes: 25 additions & 0 deletions feelstrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,33 @@
"""

import dbio as dbio
from adanos_client import AdanosClient


def fetch_and_store_sentiment(tickers, days=7):
"""Fetch sentiment from Adanos API and store in database."""
client = AdanosClient()
db = dbio.DbIO()

datapoints = client.get_sentiment_datapoints(tickers, days=days)
for dp in datapoints:
text = (
f"[{dp['source']}] buzz={dp['buzz_score']:.1f} "
f"bullish={dp['bullish_pct']:.0f}% bearish={dp['bearish_pct']:.0f}% "
f"trend={dp['trend']} mentions={dp['mentions']}"
)
sentiment = 1 if dp["sentiment"] > 0 else (0 if dp["sentiment"] == 0 else -1)
db.write_datapoint_record(dp["ticker"], sentiment, text)
print(f"{dp['ticker']} ({dp['source']}): sentiment={dp['sentiment']:.3f}")

return datapoints


if __name__ == "__main__":
db = dbio.DbIO()
#db.write_datapoint_record('AAPL', 10, 'This stock is going places!')

# Fetch sentiment from Adanos API for trending tickers
# Uncomment below to use:
# fetch_and_store_sentiment(["AAPL", "TSLA", "NVDA", "MSFT"])