Spaces:
Sleeping
Sleeping
Update sentiment_engine.py
Browse files- sentiment_engine.py +65 -31
sentiment_engine.py
CHANGED
|
@@ -1,39 +1,73 @@
|
|
| 1 |
-
# sentiment_engine.py
|
| 2 |
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
|
| 3 |
import aiohttp
|
|
|
|
| 4 |
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
'
|
| 12 |
-
'bearish': -3.5,
|
| 13 |
-
'
|
| 14 |
-
'pump': 3.0,
|
| 15 |
}
|
| 16 |
-
analyzer.lexicon.update(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
async def get_crypto_sentiment(symbol):
|
| 19 |
-
|
| 20 |
base_coin = symbol.split('/')[0]
|
| 21 |
-
url = f"https://cryptopanic.com/api/v1/posts/?auth_token={API_KEY}¤cies={base_coin}&filter=hot"
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
|
| 2 |
import aiohttp
|
| 3 |
+
import asyncio
|
| 4 |
|
| 5 |
+
# Initialisation de l'analyseur de texte
|
| 6 |
+
analyzer = SentimentIntensityAnalyzer()
|
| 7 |
+
|
| 8 |
+
# --- OPTIMISATION DU LEXIQUE CRYPTO ---
|
| 9 |
+
# On ajoute des mots spécifiques pour que l'IA comprenne le jargon du marché
|
| 10 |
+
crypto_lexicon = {
|
| 11 |
+
'moon': 4.0, 'bullish': 3.5, 'long': 2.0, 'pump': 3.0, 'breakout': 2.5,
|
| 12 |
+
'dump': -4.0, 'bearish': -3.5, 'short': -2.0, 'rug': -5.0, 'scam': -4.5,
|
| 13 |
+
'crash': -4.0, 'rekt': -3.5, 'dip': -1.0, 'fud': -2.5, 'halt': -2.0
|
|
|
|
| 14 |
}
|
| 15 |
+
analyzer.lexicon.update(crypto_lexicon)
|
| 16 |
+
|
| 17 |
+
async def fetch_cryptopanic(session, coin):
|
| 18 |
+
"""Scan des news professionnelles via ton API Key"""
|
| 19 |
+
# Ta clé API est maintenant intégrée ici
|
| 20 |
+
API_KEY = "6388e0c06c9ea848afee62ffe6a3dc9f1022e7ad"
|
| 21 |
+
|
| 22 |
+
# On utilise le filtre 'important' au lieu de 'hot' pour avoir plus de volume de données
|
| 23 |
+
url = f"https://cryptopanic.com/api/v1/posts/?auth_token={API_KEY}¤cies={coin}&filter=important"
|
| 24 |
+
|
| 25 |
+
try:
|
| 26 |
+
async with session.get(url, timeout=5) as resp:
|
| 27 |
+
if resp.status == 200:
|
| 28 |
+
data = await resp.json()
|
| 29 |
+
results = data.get('results', [])
|
| 30 |
+
# On récupère les 10 titres les plus récents
|
| 31 |
+
return " ".join([post['title'] for post in results[:10]])
|
| 32 |
+
except Exception:
|
| 33 |
+
return ""
|
| 34 |
+
|
| 35 |
+
async def fetch_reddit(session, coin):
|
| 36 |
+
"""Scan des discussions communautaires sur r/CryptoCurrency"""
|
| 37 |
+
url = f"https://www.reddit.com/r/CryptoCurrency/search.json?q={coin}&sort=new&limit=10"
|
| 38 |
+
headers = {'User-Agent': 'AlphaBot/V18.6'}
|
| 39 |
+
|
| 40 |
+
try:
|
| 41 |
+
async with session.get(url, headers=headers, timeout=5) as resp:
|
| 42 |
+
if resp.status == 200:
|
| 43 |
+
data = await resp.json()
|
| 44 |
+
posts = data.get('data', {}).get('children', [])
|
| 45 |
+
return " ".join([p['data']['title'] for p in posts])
|
| 46 |
+
except Exception:
|
| 47 |
+
return ""
|
| 48 |
|
| 49 |
async def get_crypto_sentiment(symbol):
|
| 50 |
+
"""Fusionne les sources et calcule le score de 0 à 1"""
|
| 51 |
base_coin = symbol.split('/')[0]
|
|
|
|
| 52 |
|
| 53 |
+
async with aiohttp.ClientSession() as session:
|
| 54 |
+
# Lancement des deux scans en parallèle pour gagner du temps
|
| 55 |
+
results = await asyncio.gather(
|
| 56 |
+
fetch_cryptopanic(session, base_coin),
|
| 57 |
+
fetch_reddit(session, base_coin)
|
| 58 |
+
)
|
| 59 |
+
|
| 60 |
+
all_text = " ".join(results).strip()
|
| 61 |
+
|
| 62 |
+
# Si aucune info n'est trouvée (très rare avec 2 sources), on reste neutre
|
| 63 |
+
if not all_text:
|
| 64 |
+
return 0.5
|
| 65 |
+
|
| 66 |
+
# Calcul du score VADER
|
| 67 |
+
vs = analyzer.polarity_scores(all_text)
|
| 68 |
+
|
| 69 |
+
# Conversion de l'échelle (-1 à 1) vers (0 à 1)
|
| 70 |
+
# 0.0 = Panique totale | 0.5 = Neutre | 1.0 = Euphorie
|
| 71 |
+
sentiment_score = (vs['compound'] + 1) / 2
|
| 72 |
+
|
| 73 |
+
return round(sentiment_score, 3)
|