real-time-stock-mcp-service 1.1.2__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/PKG-INFO +5 -5
  2. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/README.md +4 -4
  3. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/pyproject.toml +1 -1
  4. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/technical_data.py +30 -0
  5. real_time_stock_mcp_service-1.2.1/src/stock_mcp/crawler/test.py +5 -0
  6. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/test_count_changes.py +1 -1
  7. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/data_source_interface.py +17 -6
  8. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/kline_data.py +104 -1
  9. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/stock_data_source.py +4 -1
  10. real_time_stock_mcp_service-1.1.2/src/stock_mcp/crawler/test.py +0 -16
  11. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/.gitignore +0 -0
  12. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/LICENSE +0 -0
  13. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/__init__.py +0 -0
  14. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/__main__.py +0 -0
  15. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/app.py +0 -0
  16. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/__init__.py +0 -0
  17. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/base_crawler.py +0 -0
  18. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/basic_data.py +0 -0
  19. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/financial_analysis.py +0 -0
  20. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/fundamental_data.py +0 -0
  21. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/market.py +0 -0
  22. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/real_time_data.py +0 -0
  23. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/smart_review.py +0 -0
  24. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/crawler/valuation_data.py +0 -0
  25. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/__init__.py +0 -0
  26. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/financial_analysis.py +0 -0
  27. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/fundamental.py +0 -0
  28. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/market.py +0 -0
  29. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/real_time_data.py +0 -0
  30. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/search.py +0 -0
  31. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/smart_review.py +0 -0
  32. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/mcp_tools/valuation.py +0 -0
  33. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/utils/__init__.py +0 -0
  34. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/utils/markdown_formatter.py +0 -0
  35. {real_time_stock_mcp_service-1.1.2 → real_time_stock_mcp_service-1.2.1}/src/stock_mcp/utils/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: real-time-stock-mcp-service
3
- Version: 1.1.2
3
+ Version: 1.2.1
4
4
  Summary: 一个获取实时股票数据服务和分析的MCP服务器
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -24,15 +24,15 @@ Description-Content-Type: text/markdown
24
24
  ## 功能特性
25
25
 
26
26
  - 📊 查找股票
27
- - 📈 K线数据查询(支持B股,H股,大盘)
28
- - 📉 技术指标分析 (MA,MACD,BOLL,KDJ等等)
27
+ - 📈 K线数据查询(支持B股,H股,大盘,分时图)
28
+ - 📉 技术指标分析 (MA,MACD,BOLL,RSI等等)
29
29
  - 💰 基本面数据分析(主营构成、经营范围等)
30
30
  - 📊 财务分析(财务比率、业绩概况等)
31
31
  - 💰 估值分析数据(市盈率、市净率等)
32
32
  - 📈 市场行情跟踪(板块行情、同行对比、资金流向等)
33
33
  - 🤖 智能点评和评分
34
34
 
35
- 33个MCP工具
35
+ 34个MCP工具
36
36
 
37
37
  ## 使用方法
38
38
 
@@ -92,7 +92,7 @@ https://modelscope.cn/mcp/servers/DannyWong/real-time-stock-mcp
92
92
 
93
93
  ## 工具模块
94
94
 
95
- 项目包含33个MCP工具模块,每个模块提供特定领域的功能:
95
+ 项目包含34个MCP工具模块,每个模块提供特定领域的功能:
96
96
 
97
97
  - `search.py` - 股票搜索和交易日信息
98
98
  - `real_time_data.py` - 实时股票行情数据
@@ -12,15 +12,15 @@
12
12
  ## 功能特性
13
13
 
14
14
  - 📊 查找股票
15
- - 📈 K线数据查询(支持B股,H股,大盘)
16
- - 📉 技术指标分析 (MA,MACD,BOLL,KDJ等等)
15
+ - 📈 K线数据查询(支持B股,H股,大盘,分时图)
16
+ - 📉 技术指标分析 (MA,MACD,BOLL,RSI等等)
17
17
  - 💰 基本面数据分析(主营构成、经营范围等)
18
18
  - 📊 财务分析(财务比率、业绩概况等)
19
19
  - 💰 估值分析数据(市盈率、市净率等)
20
20
  - 📈 市场行情跟踪(板块行情、同行对比、资金流向等)
21
21
  - 🤖 智能点评和评分
22
22
 
23
- 33个MCP工具
23
+ 34个MCP工具
24
24
 
25
25
  ## 使用方法
26
26
 
@@ -80,7 +80,7 @@ https://modelscope.cn/mcp/servers/DannyWong/real-time-stock-mcp
80
80
 
81
81
  ## 工具模块
82
82
 
83
- 项目包含33个MCP工具模块,每个模块提供特定领域的功能:
83
+ 项目包含34个MCP工具模块,每个模块提供特定领域的功能:
84
84
 
85
85
  - `search.py` - 股票搜索和交易日信息
86
86
  - `real_time_data.py` - 实时股票行情数据
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "real-time-stock-mcp-service"
3
- version = "1.1.2"
3
+ version = "1.2.1"
4
4
  description = "一个获取实时股票数据服务和分析的MCP服务器"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -14,6 +14,7 @@ class KlineSpider(EastMoneyBaseSpider):
14
14
 
15
15
  BASE_URL = "https://push2his.eastmoney.com/api/qt/stock/kline/get"
16
16
  TECHNICAL_INDICATORS_URL = "https://datacenter-web.eastmoney.com/api/data/v1/get"
17
+ PKYD_URL = "https://push2.eastmoney.com/api/qt/pkyd/get" # 盘口异动API
17
18
 
18
19
  # K线周期常量
19
20
  KLT_1MIN = 1
@@ -108,6 +109,35 @@ class KlineSpider(EastMoneyBaseSpider):
108
109
 
109
110
  return merged_data
110
111
 
112
+ def get_intraday_changes(self, stock_code: str) -> List[str]:
113
+ """
114
+ 获取分时图盘口异动数据
115
+
116
+ :param stock_code: 股票代码,如"300274.SZ"
117
+ :return: 盘口异动数据列表
118
+ """
119
+ secid = self.format_secid(stock_code)
120
+
121
+ params = {
122
+ "fields": "f1,f2,f3,f4,f5,f6,f7",
123
+ "secids": secid,
124
+ "lmt": "40",
125
+ "ut": "fa5fd1943c7b386f172d6893dbfba10b",
126
+ "wbp2u": "1849325530509956|0|1|0|web",
127
+ "cb": "quote_jp0"
128
+ }
129
+
130
+ response = self._get_jsonp(self.PKYD_URL, params)
131
+
132
+ if not response or not response.get("data"):
133
+ raise RuntimeError(f"获取盘口异动数据失败: {response}")
134
+
135
+ pkyd_data = response["data"].get("pkyd")
136
+ if pkyd_data is None:
137
+ raise RuntimeError(f"响应无 pkyd 字段: {response}")
138
+
139
+ return pkyd_data
140
+
111
141
  def _get_macd_data(self, stock_code: str, page_size: int) -> List[Dict[Any, Any]]:
112
142
  """
113
143
  获取MACD技术指标数据
@@ -0,0 +1,5 @@
1
+ from src.stock_mcp.crawler.technical_data import KlineSpider
2
+
3
+ kline_spider = KlineSpider()
4
+ intraday_changes = kline_spider.get_intraday_changes("300274.SZ")
5
+ print(intraday_changes)
@@ -7,7 +7,7 @@ from src.stock_mcp.crawler.market import MarketSpider
7
7
  def main():
8
8
  # 创建爬虫实例
9
9
  spider = MarketSpider()
10
-
10
+ # 当日异动对数据对比情况
11
11
  result = spider.get_current_count_changes()
12
12
 
13
13
  # 打印结果
@@ -14,11 +14,6 @@ class DataSourceError(Exception):
14
14
  pass
15
15
 
16
16
 
17
- class LoginError(DataSourceError):
18
- """Exception raised for login failures to the data source."""
19
- pass
20
-
21
-
22
17
  class NoDataFoundError(DataSourceError):
23
18
  """Exception raised when no data is found for the given query."""
24
19
  pass
@@ -648,4 +643,20 @@ class FinancialDataInterface(ABC):
648
643
  Raises:
649
644
  DataSourceError: 当数据源出现错误时
650
645
  """
651
- pass
646
+ pass
647
+
648
+ @abstractmethod
649
+ def get_intraday_changes(self, stock_code: str) -> Optional[List[Dict[Any, Any]]]:
650
+ """
651
+ 获取分时图盘口异动数据
652
+
653
+ Args:
654
+ stock_code: 股票代码,如 300750
655
+
656
+ Returns:
657
+ 分时图盘口异动数据列表
658
+
659
+ Raises:
660
+ DataSourceError: 当数据源出现错误时
661
+ """
662
+ pass
@@ -123,6 +123,74 @@ def format_technical_indicators_data(technical_data: List[Dict]) -> List[Dict]:
123
123
  return formatted_data
124
124
 
125
125
 
126
+ def format_intraday_changes_data(intraday_changes: List[str]) -> List[Dict]:
127
+ """
128
+ 格式化分时图盘口异动数据
129
+
130
+ Args:
131
+ intraday_changes: 原始分时图盘口异动数据列表
132
+
133
+ Returns:
134
+ 格式化后的分时图盘口异动数据列表
135
+ """
136
+ formatted_data = []
137
+
138
+ # 事件类型码含义映射
139
+ event_type_map = {
140
+ 1: "有大买盘",
141
+ 101: "有大卖盘",
142
+ 2: "大笔买入",
143
+ 102: "大笔卖出",
144
+ 201: "封涨停板",
145
+ 301: "封跌停板",
146
+ 202: "打开涨停",
147
+ 302: "打开跌停",
148
+ 203: "高开5日线",
149
+ 303: "低开5日线",
150
+ 204: "60日新高",
151
+ 304: "60日新低",
152
+ 401: "向上缺口",
153
+ 501: "向下缺口",
154
+ 402: "火箭发射",
155
+ 502: "高台跳水",
156
+ 403: "快速反弹",
157
+ 503: "快速下跌",
158
+ 404: "竞价上涨",
159
+ 504: "竞价下跌",
160
+ 405: "60日大幅上涨",
161
+ 505: "60日大幅下跌"
162
+ }
163
+
164
+ for item in intraday_changes:
165
+ if not item:
166
+ continue
167
+
168
+ fields = item.split(',')
169
+ if len(fields) >= 7:
170
+ time_str = fields[0] # 时间
171
+ event_type_code = int(fields[4]) # 事件类型码
172
+ value = fields[5] # 具体数值
173
+ direction = fields[6] # 方向标识
174
+
175
+ # 获取事件类型描述
176
+ event_type_desc = event_type_map.get(event_type_code, f"未知事件({event_type_code})")
177
+
178
+ # 解析方向
179
+ direction_desc = "买入" if direction == "1" else "卖出" if direction == "2" else "未知"
180
+
181
+
182
+ formatted_item = {
183
+ '时间': time_str,
184
+ '事件类型': event_type_desc,
185
+ '具体数值': value,
186
+ '方向': direction_desc
187
+ }
188
+
189
+ formatted_data.append(formatted_item)
190
+
191
+ return formatted_data
192
+
193
+
126
194
  def register_kline_tools(app: FastMCP, data_source: FinancialDataInterface):
127
195
  """
128
196
  注册K线数据相关工具
@@ -254,4 +322,39 @@ def register_kline_tools(app: FastMCP, data_source: FinancialDataInterface):
254
322
 
255
323
  except Exception as e:
256
324
  logger.error(f"获取技术指标时出错: {e}")
257
- return f"获取技术指标失败: {str(e)}"
325
+ return f"获取技术指标失败: {str(e)}"
326
+
327
+ @app.tool()
328
+ def get_intraday_changes(
329
+ stock_code: str,
330
+ ) -> str:
331
+ """
332
+ 获取指定股票的分时图盘口异动数据,包括重要交易事件和异常波动信息。
333
+
334
+ Args:
335
+ stock_code: 股票代码,要在数字后加上交易所代码,格式如300750.SZ
336
+
337
+ Returns:
338
+ 分时图盘口异动数据的Markdown表格
339
+
340
+ Examples:
341
+ - get_intraday_changes("300750.SZ")
342
+ """
343
+ try:
344
+ # 从数据源获取原始数据
345
+ raw_intraday_changes = data_source.get_intraday_changes(stock_code)
346
+
347
+ if not raw_intraday_changes:
348
+ return f"未找到股票代码 '{stock_code}' 的分时图盘口异动数据"
349
+
350
+ # 格式化数据
351
+ formatted_data = format_intraday_changes_data(raw_intraday_changes)
352
+
353
+ # 生成Markdown表格
354
+ table = format_list_to_markdown_table(formatted_data)
355
+
356
+ return f"## {stock_code}分时图盘口异动数据\n\n{table}"
357
+
358
+ except Exception as e:
359
+ logger.error(f"获取分时图盘口异动时出错: {e}")
360
+ return f"获取分时图盘口异动失败: {str(e)}"
@@ -209,4 +209,7 @@ class WebCrawlerDataSource(FinancialDataInterface):
209
209
  return self.smart_review_crawler.get_main_force_control(stock_code)
210
210
 
211
211
  def get_participation_wish(self, stock_code: str) -> Optional[List[Dict[Any, Any]]]:
212
- return self.smart_review_crawler.get_participation_wish(stock_code)
212
+ return self.smart_review_crawler.get_participation_wish(stock_code)
213
+
214
+ def get_intraday_changes(self, stock_code: str) -> Optional[List[Dict[Any, Any]]]:
215
+ return self.kline_spider.get_intraday_changes(stock_code)
@@ -1,16 +0,0 @@
1
- from src.stock_mcp.crawler.real_time_data import RealTimeDataSpider
2
- from src.stock_mcp.crawler.fundamental_data import FundamentalDataCrawler
3
-
4
- print("获取股票代码300750.SZ的实时数据")
5
- real_time_spider = RealTimeDataSpider()
6
- real_time_data = real_time_spider.get_real_time_data("300750.SZ")
7
- print(real_time_data)
8
-
9
- print("获取股票代码300750.SZ的实时市场指数")
10
- mark_indices = real_time_spider.get_real_time_market_indices()
11
- print(mark_indices)
12
-
13
- # print("获取股票代码300750.SZ的 main_business")
14
- # fundamental_spider = FundamentalDataCrawler()
15
- # main_business = fundamental_spider.get_main_business("300750.SZ")
16
- # print(main_business)