141 lines
4.3 KiB
Python
141 lines
4.3 KiB
Python
"""
|
||
行情查询技能
|
||
提供股票实时行情和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(实时行情)或kline(K线数据)",
|
||
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}
|