stock-ai-agent/backend/app/skills/market_data.py
2026-02-03 10:08:15 +08:00

141 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
行情查询技能
提供股票实时行情和K线数据查询
"""
from typing import Dict, Any
from app.skills.base import BaseSkill, SkillParameter
from app.services.tushare_service import tushare_service
from app.services.cache_service import cache_service
from app.utils.logger import logger
class MarketDataSkill(BaseSkill):
"""行情查询技能"""
def __init__(self):
super().__init__()
self.name = "market_data"
self.description = "查询股票实时行情和历史K线数据"
self.parameters = [
SkillParameter(
name="stock_code",
type="string",
description="股票代码如600000、000001",
required=True
),
SkillParameter(
name="data_type",
type="string",
description="数据类型quote实时行情或klineK线数据",
required=False,
default="quote"
),
SkillParameter(
name="start_date",
type="string",
description="开始日期YYYYMMDD格式仅K线数据需要",
required=False
),
SkillParameter(
name="end_date",
type="string",
description="结束日期YYYYMMDD格式仅K线数据需要",
required=False
),
SkillParameter(
name="period",
type="string",
description="K线周期D日线、W周线、M月线",
required=False,
default="D"
)
]
async def execute(self, **kwargs) -> Dict[str, Any]:
"""
执行行情查询
Args:
stock_code: 股票代码
data_type: 数据类型quote/kline
start_date: 开始日期(可选)
end_date: 结束日期(可选)
period: K线周期可选
Returns:
查询结果
"""
stock_code = kwargs.get("stock_code")
data_type = kwargs.get("data_type", "quote")
logger.info(f"查询行情数据: {stock_code}, 类型: {data_type}")
if data_type == "quote":
return await self._get_quote(stock_code)
elif data_type == "kline":
start_date = kwargs.get("start_date")
end_date = kwargs.get("end_date")
period = kwargs.get("period", "D")
return await self._get_kline(stock_code, start_date, end_date, period)
else:
return {
"error": f"不支持的数据类型: {data_type}"
}
async def _get_quote(self, stock_code: str) -> Dict[str, Any]:
"""获取实时行情"""
# 尝试从缓存获取
cache_key = f"quote:{stock_code}"
cached_data = cache_service.get(cache_key)
if cached_data:
logger.info(f"从缓存获取行情: {stock_code}")
return cached_data
# 从Tushare获取
quote_data = tushare_service.get_realtime_quote(stock_code)
if not quote_data:
return {
"error": f"未找到股票数据: {stock_code}"
}
# 缓存30秒
cache_service.set(cache_key, quote_data, ttl=30)
return quote_data
async def _get_kline(
self,
stock_code: str,
start_date: str = None,
end_date: str = None,
period: str = "D"
) -> Dict[str, Any]:
"""获取K线数据"""
# 尝试从缓存获取
cache_key = f"kline:{stock_code}:{start_date}:{end_date}:{period}"
cached_data = cache_service.get(cache_key)
if cached_data:
logger.info(f"从缓存获取K线: {stock_code}")
return {"kline_data": cached_data}
# 从Tushare获取
kline_data = tushare_service.get_kline_data(
stock_code,
start_date,
end_date,
period
)
if not kline_data:
return {
"error": f"未找到K线数据: {stock_code}"
}
# 缓存1小时
cache_service.set(cache_key, kline_data, ttl=3600)
return {"kline_data": kline_data}