96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
import asyncio
|
|
from typing import Optional
|
|
|
|
from .base import BaseAgent
|
|
from ..db import create_task, update_task_status, get_agent_config, add_log
|
|
from .. import service_proxy
|
|
|
|
class StockAgent(BaseAgent):
|
|
agent_id = "stock"
|
|
display_name = "주식 트레이더"
|
|
|
|
async def on_schedule(self) -> None:
|
|
if self.state not in ("idle", "break"):
|
|
return
|
|
|
|
task_id = create_task(self.agent_id, "news_summary", {"limit": 15})
|
|
await self.transition("working", "뉴스 수집 중...", task_id)
|
|
|
|
try:
|
|
news = await service_proxy.fetch_stock_news(limit=15)
|
|
indices = await service_proxy.fetch_stock_indices()
|
|
|
|
summary = self._format_news_summary(news, indices)
|
|
|
|
update_task_status(task_id, "succeeded", {
|
|
"summary": summary,
|
|
"news_count": len(news) if isinstance(news, list) else 0,
|
|
})
|
|
|
|
await self.transition("reporting", "뉴스 요약 전송 중...")
|
|
|
|
from ..telegram_bot import send_stock_summary
|
|
await send_stock_summary(summary)
|
|
|
|
await self.transition("idle", "뉴스 요약 완료")
|
|
|
|
except Exception as e:
|
|
add_log(self.agent_id, f"News summary failed: {e}", "error", task_id)
|
|
update_task_status(task_id, "failed", {"error": str(e)})
|
|
await self.transition("idle", f"오류: {e}")
|
|
|
|
async def on_command(self, command: str, params: dict) -> dict:
|
|
if command == "fetch_news":
|
|
await self.on_schedule()
|
|
return {"ok": True, "message": "뉴스 수집 시작"}
|
|
|
|
if command == "add_alert":
|
|
config = get_agent_config(self.agent_id)
|
|
alerts = config["custom_config"].get("alerts", [])
|
|
alerts.append({
|
|
"symbol": params["symbol"],
|
|
"name": params.get("name", params["symbol"]),
|
|
"target_price": params["target_price"],
|
|
"direction": params.get("direction", "above"),
|
|
})
|
|
from ..db import update_agent_config
|
|
update_agent_config(self.agent_id, custom_config={**config["custom_config"], "alerts": alerts})
|
|
return {"ok": True, "message": f"알람 추가: {params['symbol']}"}
|
|
|
|
if command == "list_alerts":
|
|
config = get_agent_config(self.agent_id)
|
|
alerts = config["custom_config"].get("alerts", [])
|
|
return {"ok": True, "alerts": alerts}
|
|
|
|
return {"ok": False, "message": f"Unknown command: {command}"}
|
|
|
|
async def on_approval(self, task_id: str, approved: bool, feedback: str = "") -> None:
|
|
pass
|
|
|
|
def _format_news_summary(self, news, indices) -> str:
|
|
lines = ["📈 [주식 에이전트] 아침 뉴스 요약", "━" * 20]
|
|
|
|
if isinstance(news, list):
|
|
for item in news[:10]:
|
|
title = item.get("title", "")
|
|
if title:
|
|
lines.append(f"• {title}")
|
|
elif isinstance(news, dict) and "articles" in news:
|
|
for item in news["articles"][:10]:
|
|
title = item.get("title", "")
|
|
if title:
|
|
lines.append(f"• {title}")
|
|
|
|
if indices:
|
|
lines.append("")
|
|
lines.append("📊 주요 지수")
|
|
if isinstance(indices, dict):
|
|
for key, val in indices.items():
|
|
if isinstance(val, dict):
|
|
name = val.get("name", key)
|
|
price = val.get("price", "")
|
|
change = val.get("change", "")
|
|
lines.append(f"{name}: {price} ({change})")
|
|
|
|
return "\n".join(lines)
|