Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Chinese A-share stock analysis via natural language using AKShare — real-time quotes, technicals, fundamentals, sectors, and derivatives.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
router.py
1#!/usr/bin/env python32# -*- coding: utf-8 -*-34from dataclasses import dataclass5from datetime import datetime, timedelta6from typing import Optional7import re8910INDEX_REALTIME = "INDEX_REALTIME"11KLINE_ANALYSIS = "KLINE_ANALYSIS"12KLINE_CHART = "KLINE_CHART" # 新增:K线绘图13INTRADAY_ANALYSIS = "INTRADAY_ANALYSIS"14VOLUME_ANALYSIS = "VOLUME_ANALYSIS" # 新增:分时量能分析15LIMIT_STATS = "LIMIT_STATS"16MONEY_FLOW = "MONEY_FLOW"17FUNDAMENTAL = "FUNDAMENTAL"18STOCK_OVERVIEW = "STOCK_OVERVIEW"19MARGIN_LHB = "MARGIN_LHB"20SECTOR_ANALYSIS = "SECTOR_ANALYSIS"21DERIVATIVES = "DERIVATIVES"22FUND_BOND = "FUND_BOND"23HK_US_MARKET = "HK_US_MARKET"24NEWS = "NEWS"25RESEARCH_REPORT = "RESEARCH_REPORT"26STOCK_PICK = "STOCK_PICK"27HELP = "HELP" # 使用说明28PORTFOLIO = "PORTFOLIO" # 持仓管理293031# Common A-share stock aliases for quick name-to-symbol routing.32# Keep this list lightweight and focused on frequently queried names.33STOCK_NAME_MAP = {34"贵州茅台": "600519",35"茅台": "600519",36"宁德时代": "300750",37"比亚迪": "002594",38"五粮液": "000858",39"招商银行": "600036",40"中国平安": "601318",41"隆基绿能": "601012",42"药明康德": "603259",43"美的集团": "000333",44"格力电器": "000651",45"长城汽车": "601633",46}474849@dataclass50class IntentObj:51intent: str52query: str53symbol: Optional[str] = None54date: Optional[str] = None55period: Optional[str] = None56top_n: Optional[int] = None575859def _extract_symbol(query: str) -> Optional[str]:60m = re.search(r"\b(?:sh|sz)?(\d{6})\b", query.lower())61if m:62return m.group(1)6364for name in sorted(STOCK_NAME_MAP, key=len, reverse=True):65if name in query:66return STOCK_NAME_MAP[name]6768m = re.search(r"\b(hk\d{4,5}|[A-Z]{1,5})\b", query)69if m:70return m.group(1)7172return None737475def _extract_date(query: str) -> Optional[str]:76m = re.search(r"(\d{4})[-/]?(\d{2})[-/]?(\d{2})", query)77if m:78return f"{m.group(1)}-{m.group(2)}-{m.group(3)}"7980if "今天" in query or "今日" in query:81return datetime.now().strftime("%Y-%m-%d")82if "昨天" in query or "昨日" in query:83return (datetime.now() - timedelta(days=1)).strftime("%Y-%m-%d")8485return None868788def _extract_period(query: str) -> Optional[str]:89q = query.lower()90if "1m" in q or "1分钟" in query:91return "1"92if "5m" in q or "5分钟" in query:93return "5"94if "15m" in q or "15分钟" in query:95return "15"96if "30m" in q or "30分钟" in query:97return "30"98if "60m" in q or "60分钟" in query:99return "60"100if "周线" in query or "week" in q:101return "weekly"102if "月线" in query or "month" in q:103return "monthly"104if "日线" in query or "day" in q or "daily" in q:105return "daily"106107return None108109110def _extract_top_n(query: str) -> Optional[int]:111m = re.search(r"top\s*(\d+)", query.lower())112if m:113return int(m.group(1))114115m = re.search(r"前\s*(\d+)\s*(名|条|个)?", query)116if m:117return int(m.group(1))118119# 支持"近N日"、"最近N天"等120m = re.search(r"近\s*(\d+)\s*(日|天|周|月)", query)121if m:122return int(m.group(1))123m = re.search(r"最近\s*(\d+)\s*(日|天|周|月)", query)124if m:125return int(m.group(1))126127return None128129130def _classify_intent(query: str) -> str:131q = query.lower()132133if any(k in query for k in ["涨停", "跌停", "涨跌停"]):134return LIMIT_STATS135if any(k in query for k in ["推荐股票", "选股", "股票推荐", "有什么股票推荐"]):136return STOCK_PICK137if any(k in query for k in ["分时", "盘口", "逐笔"]):138return INTRADAY_ANALYSIS139# 分时量能分析140if any(k in query for k in ["量能", "放量", "缩量", "主力动向", "抢筹", "出货", "封单", "分时量能"]):141return VOLUME_ANALYSIS142if any(k in query for k in ["k线", "K线", "日线", "周线", "月线"]) or "kline" in q:143return KLINE_ANALYSIS144# 绘图功能:K线图、走势、行情图145if any(k in query for k in ["走势图", "趋势图", "行情图", "K线图", "k线图", "绘制", "画图", "图"]):146return KLINE_CHART147if any(k in query for k in ["怎么样", "分析", "看下", "评估", "综合"]):148return STOCK_OVERVIEW149if any(k in query for k in ["资金流", "主力资金", "北向资金", "南向资金", "东向资金", "行业资金", "板块资金"]):150return MONEY_FLOW151if any(k in query for k in ["基本面", "财报", "财务", "市盈率", "市净率", "估值", "roe", "ROE", "毛利率", "净利率", "资产负债率"]):152return FUNDAMENTAL153if any(k in query for k in ["融资融券", "龙虎榜", "两融", "融资余额", "融券余额"]):154return MARGIN_LHB155if any(k in query for k in ["研报", "研究报告", "机构评级"]):156return RESEARCH_REPORT157if "财经新闻" in query:158return NEWS159160if any(k in query for k in ["港股", "美股", "纳斯达克", "道琼斯", "标普", "恒生", "恒指"]) or any(k in q for k in ["nasdaq", "dow", "sp500", "s&p", "hang seng", "hk", "us"]):161return HK_US_MARKET162if any(k in query for k in ["期货", "期权", "衍生品", "主力合约", "if", "ih", "ic", "im"]):163return DERIVATIVES164if any(k in query for k in ["基金", "净值", "可转债", "转债", "债券", "etf", "ETF"]):165return FUND_BOND166if any(k in query for k in ["板块", "行业", "概念", "题材", "轮动", "涨幅榜", "跌幅榜"]):167return SECTOR_ANALYSIS168169if any(k in query for k in ["大盘", "指数", "上证", "深证", "创业板", "实时"]):170return INDEX_REALTIME171172# 使用说明173if any(k in query for k in ["介绍股市", "股市怎么用", "使用说明", "帮助", "help", "说明", "玩法", "有哪些功能"]):174return HELP175176# 持仓管理177if any(k in query for k in ["持仓", "仓位", "我的股票"]):178return PORTFOLIO179180return INDEX_REALTIME181182183def parse_query(query: str) -> IntentObj:184query = (query or "").strip()185return IntentObj(186intent=_classify_intent(query),187query=query,188symbol=_extract_symbol(query),189date=_extract_date(query),190period=_extract_period(query),191top_n=_extract_top_n(query),192)193