
Tracking Korean earnings-season moves is tedious when you're doing it manually — scanning financial news, checking sector momentum, then cross-referencing US peer stocks to confirm the thesis. This post walks through automating that exact three-step flow with a lightweight AI pipeline you can run from your terminal.
1. Why This Matters During Earnings Season
Korean earnings season (typically April–May and October–November) floods the market with press releases, disclosure filings, and analyst notes — all in Korean, all at different times. The problem isn't a lack of data. The problem is that by the time you've manually connected "Samsung SDI beat on margins" → "battery sector is repricing" → "Albemarle and Livent are also up 3% in pre-market," the trade window is often gone.
The real pain most retail traders feel is signal latency, not information scarcity. The three-step framework — news confirmation → sector reaction → US peer corroboration — is a well-known filter, but applying it manually for more than a handful of tickers is unsustainable.
What AI does here is compress that latency to near-zero by automating the lookup and synthesis at each step.
The automation pays off most during the first 48 hours of an earnings release, when the sentiment signal is strongest and the price move hasn't fully propagated across related tickers.
2. The Core Idea
Run a structured three-step lookup in sequence: news continuity check → sector reaction → US peer flow — and score each step before forming a view.
Think of it like a traffic light with three sensors. If all three are green, you have a confirmed signal. If only the first sensor trips, you have a rumor. The structured pipeline prevents you from acting on incomplete information.
| Step | Signal Source | What You're Checking |
|---|---|---|
| 1. News continuity | KRX disclosures, financial press | Is the earnings story still developing? |
| 2. Sector reaction | KOSPI sector indices, ETFs | Is the broader sector repricing with the name? |
| 3. US peer flow | NYSE/NASDAQ peer stocks | Are global investors confirming the thesis? |
Each step is a filter, not a trigger. You only move to step 3 if steps 1 and 2 are both active. This keeps false positives low during noisy earnings periods.
3. How to Implement It
The stack I use is Python + the Claude API for synthesis, with raw HTTP calls to public data endpoints for the news and price feeds. No proprietary data subscription required for the prototype.
Install dependencies:
pip install anthropic httpx python-dotenv
Set up your environment:
# .env
ANTHROPIC_API_KEY=sk-ant-...
Core pipeline script:
import os
import httpx
import anthropic
from dotenv import load_dotenv
load_dotenv()
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
def fetch_kr_news(ticker_kr: str) -> str:
"""Pull recent headlines for a Korean ticker via a free aggregator."""
url = f"https://finance.naver.com/item/news.naver?code={ticker_kr}"
headers = {"User-Agent": "Mozilla/5.0"}
resp = httpx.get(url, headers=headers, timeout=10)
# In production, parse the HTML with BeautifulSoup.
# For this example, we return a stub.
return resp.text[:3000] # raw HTML slice for AI parsing
def fetch_us_peer_delta(tickers: list[str]) -> dict:
"""Get price delta % for US peer tickers (Yahoo Finance public API)."""
deltas = {}
for t in tickers:
url = f"https://query1.finance.yahoo.com/v8/finance/chart/{t}?interval=1d&range=2d"
r = httpx.get(url, timeout=10).json()
closes = r["chart"]["result"][0]["indicators"]["quote"][0]["close"]
if len(closes) >= 2 and closes[-2]:
deltas[t] = round((closes[-1] - closes[-2]) / closes[-2] * 100, 2)
return deltas
def analyze_signal(ticker_kr: str, sector: str, us_peers: list[str]) -> str:
news_raw = fetch_kr_news(ticker_kr)
peer_deltas = fetch_us_peer_delta(us_peers)
prompt = f"""
You are a Korean stock market analyst. Evaluate the signal strength for {ticker_kr} in the {sector} sector.
Step 1 - News continuity: Parse the following raw news data and tell me if the earnings story is still developing (more than 1 article in the last 24h, bullish/bearish tone):
---
{news_raw[:1500]}
---
Step 2 - Sector reaction: Based on the news tone, infer whether the broader {sector} sector is likely repricing. State your confidence: High / Medium / Low.
Step 3 - US peer confirmation: Here are the 2-day price deltas for comparable US stocks:
{peer_deltas}
Verdict: Score the overall signal as STRONG / WATCH / DROP with a 2-sentence rationale.
"""
message = client.messages.create(
model="claude-opus-4-5",
max_tokens=512,
messages=[{"role": "user", "content": prompt}]
)
return message.content[0].text
# Example run
if __name__ == "__main__":
result = analyze_signal(
ticker_kr="006400", # Samsung SDI
sector="battery",
us_peers=["ALB", "LTHM"] # Albemarle, Livent
)
print(result)
Expected output:
Step 1 - News continuity: 3 articles detected in the last 24h. Tone is cautiously bullish — margin beat on the cathode material segment. Story is still developing. ✓
Step 2 - Sector reaction: HIGH confidence that battery sector is repricing. Peer disclosure from LG Energy Solution shows similar margin trend.
Step 3 - US peer confirmation:
ALB: +2.4%
LTHM: +1.8%
Both peers are up meaningfully, confirming global lithium demand repricing.
Verdict: STRONG — All three filters are active. Earnings beat is propagating across the sector and confirmed by US peer flow.
Quick verification — check your API call succeeded:
python signal_tracker.py | grep "Verdict:"
# Expected: Verdict: STRONG — ...
4. What to Watch in Production
Rate limits hit faster than you expect. Naver Finance blocks aggressive scrapers; add a time.sleep(1.5) between ticker calls and rotate User-Agent strings. Yahoo Finance's public API is undocumented and can go down without notice — Polygon.io or Alpha Vantage are more stable alternatives once you need reliability.
The news parser is the weakest link. Passing raw HTML to Claude works for prototyping, but you're burning tokens on boilerplate. In production, preprocess with BeautifulSoup to extract article titles and timestamps only.
from bs4 import BeautifulSoup
def parse_headlines(html: str) -> list[str]:
soup = BeautifulSoup(html, "html.parser")
return [a.get_text(strip=True) for a in soup.select(".title a")][:10]
Model selection matters for cost. At scale — say, 50 tickers every 30 minutes during earnings season — claude-haiku-4-5 is fast and cheap enough for steps 1 and 2. Reserve claude-opus-4-5 for the final verdict synthesis only.
| Stage | Recommended Model | Reason |
|---|---|---|
| News parsing | claude-haiku-4-5 | Speed, low cost |
| Sector inference | claude-haiku-4-5 | Short output |
| Final verdict | claude-opus-4-5 | Nuanced judgment |
Mac vs. Linux: The script runs identically on both. If you're containerizing, add httpx and beautifulsoup4 to your requirements.txt — they're not bundled by default in slim Python images.
Currency of the signal degrades fast. The three-step filter is most useful within the first 6–12 hours of an earnings release. After that, analyst notes have already been published and the price move has largely happened. Build a timestamp check into the pipeline and suppress signals older than 12 hours.
The earnings-season noise problem is really a sequencing problem — and the fix is applying the right filter at each step, not reading more news. Once you have the pipeline running, the natural next upgrade is adding a Slack or email alert so the verdict lands in your inbox without you polling a terminal.
🐦 Faster updates on X: @baegseungh7061
📚 More in this series: AI Market Notes
💌 Subscribe: Follow on X or grab the RSS
댓글
댓글 쓰기