최근 암호화폐 자동 매매 시스템에서는 단순한 가격 분석을 넘어, 뉴스에 내포된 시장 심리까지 분석해 트레이딩 전략에 반영하는 시도가 활발히 이뤄지고 있다.
이 글에서는 Hugging Face의 transformers 라이브러리와 금융 도메인에 특화된 FinBERT 모델을 활용해, 뉴스 제목만으로도 간편하게 감성 분석(sentiment analysis)을 수행하는 방법을 소개하고자 한다. 감성 분석은 텍스트가 긍정적인지, 부정적인지, 또는 중립적인지를 자동으로 분류하는 작업이다.

Hugging Face의 `transformers` 라이브러리에서는 단 한 줄로 감성 분석 파이프라인을 구축할 수 있다.
예를 들면 "Bitcoin surges after ETF approval"이라는 같은 뉴스 제목은 긍정적인 시장 심리를 나타낸다. 감성 분석 코드는 다음과 같다.
from transformers import pipeline
sentiment_pipeline = pipeline("sentiment-analysis")
result = sentiment_pipeline("Bitcoin surges after ETF approval")
print(result)
그러나 결과는 예상 밖으로 다음과 같았다.
[{'label': 'NEGATIVE', 'score': 0.9864112734794617}]
아마도 기존의 감성 분석 모델들이 대부분 영화 리뷰나 SNS 데이터로 학습되었기 때문에, 'surge' 와 같은 단어를 인플레이션, 질병 같은 부정 문맥에서 학습했기 때문으로 생각된다.
FinBERT는 금융 뉴스, SEC 리포트, 투자 분석 문서를 기반으로 훈련된 BERT 모델이다. 가격 상승과 하락과 같은 표현에 대해 투자자 관점에서 감성 판단을 해준다.
똑 같은 텍스트로 감성 분석을 해보자. 코드는 다음과 같다.
from transformers import AutoTokenizer, AutoModelForSequenceClassification
tokenizer = AutoTokenizer.from_pretrained("yiyanghkust/finbert-tone")
model = AutoModelForSequenceClassification.from_pretrained("yiyanghkust/finbert-tone")
sentiment_pipeline2 = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
result2 = sentiment_pipeline2("Bitcoin surges after ETF approval")
print(result2)
결과는 다음과 같다.
[{'label': 'Positive', 'score': 0.9999992847442627}]
이제는 상승 뉴스가 명확하게 긍정으로 분류되었다. 다른 뉴스 제목도 더 테스트해보자.
result3 = sentiment_pipeline2("Ripple recovers with strength post-lawsuit.")
print(result3)
result4 = sentiment_pipeline2("The cryptocurrency market is showing signs of a sharp decline.")
print(result4)
결과는 다음과 같다.
[{'label': 'Positive', 'score': 0.9999988079071045}]
[{'label': 'Negative', 'score': 0.9999963045120239}]
이러한 뉴스의 감성 분석은 암호화폐 자동매매 시스템 구축 시 진입 시점, 익절 판단, 회피 전략 수립에 도움을 줄 수 있다.
암호화폐 뉴스처럼 실시간성과 다양성이 중요한 주제에는 Google 뉴스 검색이 매우 효과적이다. SerpAPI는 구글 뉴스 결과를 간편하게 JSON 형태로 수집 가능하게 하며, 검색어, 언어, 국가, 최신순 등 다양한 필터 지원하므로 BeautifulSoup 없이도 안정적으로 뉴스 크롤링이 가능하다. SerpAPI는 유료 서비스이지만 매월 일정량의 무료 쿼리를 제공하므로, 소규모 프로젝트나 프로토타이핑에도 적합하다.

다음 코드는 SerpAPI를 이용하여 비트코인 뉴스 3건을 수집하는 예이다.
import os
import requests
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
SERP_API_KEY = os.getenv("SERP_API_KEY")
params = {
'engine': 'google',
'q': 'bitcoin news today',
'api_key': SERP_API_KEY,
'tbm': 'nws',
'num': 3,
'tbs': 'qdr:d'
}
response = requests.get("https://serpapi.com/search", params=params)
if response.status_code == 200:
data = response.json()
news = data.get("news_results", [])
print("수집된 뉴스 목록:")
for i, article in enumerate(news, 1):
print(f"\n{i}. {article.get('title')}")
print(f" 출처: {article.get('source')}")
print(f" 날짜: {article.get('date')}")
print(f" 링크: {article.get('link')}")
print(f" 요약: {article.get('snippet')}")
else:
print("뉴스 수집 실패:", response.status_code)
이렇게 호출하면 title, source, date, link, snippet 등의 정보가 포함된 JSON 데이터를 받아올 수 있다.
수집된 뉴스 목록:
1. Here’s what happened in crypto today
출처: TradingView
날짜: 6 hours ago
링크: https://www.tradingview.com/news/cointelegraph:b431ea497094b:0-here-s-what-happened-in-crypto-today/
요약: “We know that there have been efforts to politicize crypto legislation, but with crypto drastically reshaping the global economy the U.S. risks falling behind...
2. Trump Media Plans To Launch ‘Crypto Blue Chip ETF’ Holding Bitcoin, Ether, Solana and More
출처: Investopedia
날짜: 5 hours ago
링크: https://www.investopedia.com/trump-media-plans-to-launch-crypto-blue-chip-etf-holding-bitcoin-ether-solana-and-more-11768442
요약: Trump Media & Technology Group said it plans to launch another exchange-traded fund that holds more than just Bitcoin and Ether.
3. Bitcoin metric says $100K BTC was the bottom: When will a rally to new highs start?
출처: Cointelegraph
날짜: 5 hours ago
링크: https://cointelegraph.com/news/bitcoin-metric-says-100k-btc-was-the-bottom
요약: Key takeaways: Bitcoin's monthly outflow/inflow ratio has dropped to 0.9, signaling renewed long-term confidence and accumulation.
이제 수집한 뉴스에 대해서 감성 분석을 하면 된다. 다음은 비트코인, 리플, USDT 및 전반적인 암호화폐 뉴스를 각각 3개 씩 수집하여 감성 분석을 하는 코드의 예이다.
import os
import requests
from dotenv import load_dotenv
import time
import pandas as pd
from collections import defaultdict
import dateparser
from transformers import pipeline, AutoTokenizer, AutoModelForSequenceClassification
# Load environment variables
load_dotenv()
SERP_API_KEY = os.getenv("SERP_API_KEY")
# Setup FinBERT for sentiment analysis (finance-specific model)
tokenizer = AutoTokenizer.from_pretrained("yiyanghkust/finbert-tone")
model = AutoModelForSequenceClassification.from_pretrained("yiyanghkust/finbert-tone")
sentiment_pipeline = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
# Define crypto keywords
individual_cryptos = ['bitcoin', 'ripple', 'usdt']
market_keywords = ['crypto market']
all_keywords = individual_cryptos + market_keywords
def fetch_crypto_news_with_sentiment():
all_news = []
for keyword in all_keywords:
params = {
'engine': 'google',
'q': f"{keyword} news today",
'api_key': SERP_API_KEY,
'tbm': 'nws',
'num': 3,
'hl': 'en',
'tbs': 'qdr:d'
}
try:
response = requests.get("https://serpapi.com/search", params=params, timeout=30)
if response.status_code == 200:
data = response.json()
news_items = data.get('news_results', [])
for item in news_items:
title = item.get('title', '')
snippet = item.get('snippet', '')
raw_date = item.get('date', '')
parsed_date = dateparser.parse(raw_date)
formatted_date = parsed_date.strftime('%Y-%m-%d %H:%M:%S') if parsed_date else raw_date
sentiment_result = sentiment_pipeline(title[:512])[0]
all_news.append({
'keyword': keyword,
'title': title,
'snippet': snippet,
'source': item.get('source', ''),
'date': formatted_date,
'link': item.get('link', ''),
'sentiment': sentiment_result['label'],
'score': sentiment_result['score']
})
except Exception as e:
print(f"Error fetching news for {keyword}: {e}")
time.sleep(2)
return pd.DataFrame(all_news)
# Fetch data
news_df = fetch_crypto_news_with_sentiment()
# Remove duplicate titles
news_df = news_df.drop_duplicates(subset='title')
# Sort by sentiment score (relevance proxy)
news_df = news_df.sort_values(by='score', ascending=False).reset_index(drop=True)
# Limit total results to 10
news_df = news_df.head(10)
# Display 3 news titles per category
print("\n대표 뉴스 제목 및 요약:")
for group in ['crypto market', 'bitcoin', 'ripple', 'usdt']:
filtered = news_df[news_df['keyword'] == group].head(3)
print(f"\n[{group.upper()}]")
for i, row in filtered.iterrows():
print(f"- {row['title']}")
if row['snippet']:
print(f" 요약: {row['snippet']}")
print(f" 날짜: {row['date']}")
# Summary of sentiment
def summarize_sentiment(df, label):
subset = df[df['keyword'] == label] if label != 'crypto market' else df[df['keyword'] == 'crypto market']
if subset.empty:
return "데이터 없음"
# 라벨을 소문자로 통일해서 비교
sentiments = subset['sentiment'].str.lower()
pos = sum(sentiments == 'positive')
neg = sum(sentiments == 'negative')
neu = sum(sentiments == 'neutral')
return f"긍정: {pos}, 중립: {neu}, 부정: {neg}"
print("\n시장 심리 요약:")
for label in ['crypto market', 'bitcoin', 'ripple', 'usdt']:
summary = summarize_sentiment(news_df, label)
print(f"- {label.upper()}: {summary}")
결과는 다음과 같다.
대표 뉴스 제목 및 요약:
[CRYPTO MARKET]
- [LIVE] Crypto News Today: Latest Updates for July 9, 2025 – Nasdaq-Listed GameSquare Announces $100M ETH Treasury Strategy
요약: Follow up to the hour updates on what is happening in crypto today, July 9. Market movements, crypto news, and more! The post [LIVE] Crypto News Today:...
날짜: 2025-07-09 12:32:32
- XRP News Today: SEC Moves to Approve Spot Crypto ETFs, Boosting Market Integration
요약: The U.S. Securities and Exchange Commission (SEC) is on the verge of approving several spot cryptocurrency exchange-traded funds (ETFs), a move that could...
날짜: 2025-07-09 09:50:32
[BITCOIN]
- Trump Media Plans To Launch ‘Crypto Blue Chip ETF’ Holding Bitcoin, Ether, Solana and More
요약: Trump Media & Technology Group said it plans to launch another exchange-traded fund that holds more than just Bitcoin and Ether.
날짜: 2025-07-09 06:50:25
- Here’s what happened in crypto today
요약: “We know that there have been efforts to politicize crypto legislation, but with crypto drastically reshaping the global economy the U.S. risks falling behind...
날짜: 2025-07-09 06:50:25
- Bitcoin metric says $100K BTC was the bottom: When will a rally to new highs start?
요약: Key takeaways: Bitcoin's monthly outflow/inflow ratio has dropped to 0.9, signaling renewed long-term confidence and accumulation.
날짜: 2025-07-09 07:50:25
[RIPPLE]
- What $2,500 in Ripple (XRP) Today Will Be Worth by 2028, Compared to Ethereum (ETH) and Little Pepe (LILPEPE)
요약: Ripple (XRP) and Ethereum (ETH) are two well-known cryptocurrencies that don't change significantly and don't grow rapidly. Little Pepe (LILPEPE), on the.
날짜: 2025-07-09 04:50:27
- XRP News Today: Ripple Case Spotlighted in Senate—XRP Targets $3 Breakout; BTC Eyes $110k
요약: Market eyes potential July 10 SEC appeal vote that could pave the way for XRP-spot ETFs and reignite bullish momentum toward $3 and beyond.
날짜: 2025-07-09 09:50:27
- XRP News Today: Ripple Lawsuit May Be Strategic Move To Suppress XRP Price
요약: Jesse, a crypto researcher at Apex Crypto Consulting, has dedicated over 9,000 hours to studying Ripple and the global financial system.
날짜: 2025-07-08 23:50:27
[USDT]
- Tether Expands Gold Reserves by 80 Metric Tons to Enhance USDT Stability
요약: Tether Holdings SA, the issuer of USDT, has expanded its gold reserves, storing approximately 80 metric tons of gold valued at around $8 billion in a...
날짜: 2025-07-09 08:50:30
- Tether Acquires $8 Billion in Gold for USDT Reserve Diversification
요약: Tether, under the leadership of CEO Paolo Ardoino since October 2023, has confirmed the acquisition of $8 billion worth of gold, which is securely stored in...
날짜: 2025-07-09 09:50:30
날짜: 2025-07-09 09:50:30
시장 심리 요약:
- CRYPTO MARKET: 긍정: 0, 중립: 2, 부정: 0
- BITCOIN: 긍정: 0, 중립: 3, 부정: 0
- RIPPLE: 긍정: 0, 중립: 3, 부정: 0
- USDT: 긍정: 1, 중립: 1, 부정: 0'AI 에이전트 > 트레이딩' 카테고리의 다른 글
| 텔레그램 메시지 자동 전송 시스템 만들기 (0) | 2025.07.25 |
|---|---|
| 카카오톡 메시지 자동 전송 시스템 만들기 (0) | 2025.07.24 |
| 기술적 지표: 스토캐스틱 (Stochastic) (0) | 2025.07.07 |
| 기술적 지표: 이동평균 수렴확산 (MACD) (0) | 2025.07.06 |
| 기술적 지표: 상대강도지수 (RSI, Relative Strength Index) (0) | 2025.07.04 |
댓글