GoshawkVortexAI commited on
Commit
c4d3621
·
verified ·
1 Parent(s): 068ebdb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +111 -0
app.py ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import pandas as pd
3
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
4
+ import torch
5
+ import torch.nn.functional as F
6
+ from datetime import datetime
7
+
8
+ # ==========================
9
+ # 1️⃣ FINBERT LOAD
10
+ # ==========================
11
+ MODEL_NAME = "ProsusAI/finbert"
12
+
13
+ tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
14
+ model = AutoModelForSequenceClassification.from_pretrained(MODEL_NAME)
15
+ model.eval()
16
+
17
+ # ==========================
18
+ # 2️⃣ REUTERS SCRAPER
19
+ # ==========================
20
+ def fetch_reuters_articles(section="/business/", size=20):
21
+ """
22
+ Reuters unofficial JSON endpoint
23
+ """
24
+ url = "https://www.reuters.com/pf/api/v3/content/fetch/articles-by-section-alias-or-id-v1"
25
+
26
+ query = {
27
+ "query": {
28
+ "section_id": section,
29
+ "size": size
30
+ }
31
+ }
32
+
33
+ params = {
34
+ "query": str(query).replace("'", '"')
35
+ }
36
+
37
+ headers = {
38
+ "User-Agent": "Mozilla/5.0"
39
+ }
40
+
41
+ response = requests.get(url, params=params, headers=headers)
42
+ data = response.json()
43
+
44
+ articles = []
45
+ try:
46
+ contents = data["result"]["articles"]
47
+ for item in contents:
48
+ headline = item.get("title", "")
49
+ summary = item.get("description", "")
50
+ published = item.get("published_time", "")
51
+ articles.append({
52
+ "headline": headline,
53
+ "summary": summary,
54
+ "published": published
55
+ })
56
+ except Exception as e:
57
+ print("Parsing error:", e)
58
+
59
+ return pd.DataFrame(articles)
60
+
61
+
62
+ # ==========================
63
+ # 3️⃣ FINBERT SENTIMENT
64
+ # ==========================
65
+ def finbert_score(text):
66
+ inputs = tokenizer(
67
+ text,
68
+ return_tensors="pt",
69
+ truncation=True,
70
+ padding=True,
71
+ max_length=512
72
+ )
73
+
74
+ with torch.no_grad():
75
+ outputs = model(**inputs)
76
+ probs = F.softmax(outputs.logits, dim=1)
77
+
78
+ labels = ["negative", "neutral", "positive"]
79
+ scores = probs[0].tolist()
80
+
81
+ return dict(zip(labels, scores))
82
+
83
+
84
+ # ==========================
85
+ # 4️⃣ PIPELINE
86
+ # ==========================
87
+ def run_pipeline():
88
+ df = fetch_reuters_articles(section="/business/", size=25)
89
+
90
+ sentiments = []
91
+ for _, row in df.iterrows():
92
+ text = row["headline"] + ". " + row["summary"]
93
+ score = finbert_score(text)
94
+ sentiments.append(score)
95
+
96
+ sentiment_df = pd.DataFrame(sentiments)
97
+ final_df = pd.concat([df, sentiment_df], axis=1)
98
+
99
+ # Hawkish score (neg - pos)
100
+ final_df["hawkish_score"] = final_df["negative"] - final_df["positive"]
101
+
102
+ filename = f"reuters_finbert_{datetime.today().date()}.csv"
103
+ final_df.to_csv(filename, index=False)
104
+
105
+ print("Saved:", filename)
106
+ print(final_df.head())
107
+
108
+
109
+ # ==========================
110
+ if __name__ == "__main__":
111
+ run_pipeline()