rquote 0.3.5__tar.gz → 0.3.8__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 (48) hide show
  1. {rquote-0.3.5 → rquote-0.3.8}/PKG-INFO +2 -2
  2. {rquote-0.3.5 → rquote-0.3.8}/README.md +1 -1
  3. {rquote-0.3.5 → rquote-0.3.8}/pyproject.toml +1 -1
  4. {rquote-0.3.5 → rquote-0.3.8}/rquote/__init__.py +35 -1
  5. {rquote-0.3.5 → rquote-0.3.8}/rquote/api/lists.py +1 -1
  6. {rquote-0.3.5 → rquote-0.3.8}/rquote/api/price.py +6 -0
  7. {rquote-0.3.5 → rquote-0.3.8}/rquote/api/stock_info.py +2 -0
  8. {rquote-0.3.5 → rquote-0.3.8}/rquote/data_sources/sina.py +6 -0
  9. {rquote-0.3.5 → rquote-0.3.8}/rquote/data_sources/tencent.py +7 -4
  10. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/cn_stock.py +1 -1
  11. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils/web.py +5 -0
  12. {rquote-0.3.5 → rquote-0.3.8}/rquote.egg-info/PKG-INFO +2 -2
  13. {rquote-0.3.5 → rquote-0.3.8}/tests/test_api.py +1 -1
  14. {rquote-0.3.5 → rquote-0.3.8}/rquote/api/__init__.py +0 -0
  15. {rquote-0.3.5 → rquote-0.3.8}/rquote/api/tick.py +0 -0
  16. {rquote-0.3.5 → rquote-0.3.8}/rquote/cache/__init__.py +0 -0
  17. {rquote-0.3.5 → rquote-0.3.8}/rquote/cache/base.py +0 -0
  18. {rquote-0.3.5 → rquote-0.3.8}/rquote/cache/memory.py +0 -0
  19. {rquote-0.3.5 → rquote-0.3.8}/rquote/config.py +0 -0
  20. {rquote-0.3.5 → rquote-0.3.8}/rquote/data_sources/__init__.py +0 -0
  21. {rquote-0.3.5 → rquote-0.3.8}/rquote/data_sources/base.py +0 -0
  22. {rquote-0.3.5 → rquote-0.3.8}/rquote/exceptions.py +0 -0
  23. {rquote-0.3.5 → rquote-0.3.8}/rquote/factors/__init__.py +0 -0
  24. {rquote-0.3.5 → rquote-0.3.8}/rquote/factors/technical.py +0 -0
  25. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/__init__.py +0 -0
  26. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/base.py +0 -0
  27. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/factory.py +0 -0
  28. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/future.py +0 -0
  29. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/hk_stock.py +0 -0
  30. {rquote-0.3.5 → rquote-0.3.8}/rquote/markets/us_stock.py +0 -0
  31. {rquote-0.3.5 → rquote-0.3.8}/rquote/parsers/__init__.py +0 -0
  32. {rquote-0.3.5 → rquote-0.3.8}/rquote/parsers/kline.py +0 -0
  33. {rquote-0.3.5 → rquote-0.3.8}/rquote/plots.py +0 -0
  34. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils/__init__.py +0 -0
  35. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils/date.py +0 -0
  36. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils/helpers.py +0 -0
  37. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils/http.py +0 -0
  38. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils/logging.py +0 -0
  39. {rquote-0.3.5 → rquote-0.3.8}/rquote/utils.py +0 -0
  40. {rquote-0.3.5 → rquote-0.3.8}/rquote.egg-info/SOURCES.txt +0 -0
  41. {rquote-0.3.5 → rquote-0.3.8}/rquote.egg-info/dependency_links.txt +0 -0
  42. {rquote-0.3.5 → rquote-0.3.8}/rquote.egg-info/requires.txt +0 -0
  43. {rquote-0.3.5 → rquote-0.3.8}/rquote.egg-info/top_level.txt +0 -0
  44. {rquote-0.3.5 → rquote-0.3.8}/setup.cfg +0 -0
  45. {rquote-0.3.5 → rquote-0.3.8}/tests/test_cache.py +0 -0
  46. {rquote-0.3.5 → rquote-0.3.8}/tests/test_config.py +0 -0
  47. {rquote-0.3.5 → rquote-0.3.8}/tests/test_exceptions.py +0 -0
  48. {rquote-0.3.5 → rquote-0.3.8}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rquote
3
- Version: 0.3.5
3
+ Version: 0.3.8
4
4
  Summary: Mostly day quotes of cn/hk/us/fund/future markets, side with quote list fetch
5
5
  Requires-Python: >=3.6.1
6
6
  Description-Content-Type: text/markdown
@@ -83,7 +83,7 @@ sid, name, df = get_price('sh000001', dd=cache_dict)
83
83
  - `i`: 股票代码,使用新浪/腾讯的id形式
84
84
  - `sdate`: 开始日期 (可选,格式:YYYY-MM-DD)
85
85
  - `edate`: 结束日期 (可选,格式:YYYY-MM-DD)
86
- - `freq`: 频率,默认'day' (日线),可选:'week', 'month', 'min'
86
+ - `freq`: 频率,默认'day' (日线),可选:(港A)'week', 'month', (美股)'min'
87
87
  - `days`: 获取天数,默认320天
88
88
  - `fq`: 复权方式,默认'qfq' (前复权),可选:'hfq' (后复权)
89
89
  - `dd`: 本地缓存字典 (可选,已废弃,建议使用MemoryCache)
@@ -71,7 +71,7 @@ sid, name, df = get_price('sh000001', dd=cache_dict)
71
71
  - `i`: 股票代码,使用新浪/腾讯的id形式
72
72
  - `sdate`: 开始日期 (可选,格式:YYYY-MM-DD)
73
73
  - `edate`: 结束日期 (可选,格式:YYYY-MM-DD)
74
- - `freq`: 频率,默认'day' (日线),可选:'week', 'month', 'min'
74
+ - `freq`: 频率,默认'day' (日线),可选:(港A)'week', 'month', (美股)'min'
75
75
  - `days`: 获取天数,默认320天
76
76
  - `fq`: 复权方式,默认'qfq' (前复权),可选:'hfq' (后复权)
77
77
  - `dd`: 本地缓存字典 (可选,已废弃,建议使用MemoryCache)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rquote"
7
- version = "0.3.5"
7
+ version = "0.3.8"
8
8
  description = "Mostly day quotes of cn/hk/us/fund/future markets, side with quote list fetch"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.6.1"
@@ -7,6 +7,9 @@ Copyright (c) 2021 Roi ZHAO
7
7
 
8
8
  '''
9
9
 
10
+ import re
11
+ from pathlib import Path
12
+
10
13
  # API函数
11
14
  from .api import (
12
15
  get_price,
@@ -34,7 +37,38 @@ from . import exceptions
34
37
  from .cache import MemoryCache, Cache
35
38
  from .utils.http import HTTPClient
36
39
 
37
- __version__ = '0.3.5'
40
+
41
+ def _get_version():
42
+ """从 pyproject.toml 读取版本号"""
43
+ # 优先尝试从已安装的包中读取版本
44
+ try:
45
+ from importlib import metadata
46
+ return metadata.version("rquote")
47
+ except Exception:
48
+ pass
49
+
50
+ # 如果包未安装,从 pyproject.toml 读取
51
+ try:
52
+ # 获取项目根目录(__init__.py 的父目录的父目录)
53
+ current_file = Path(__file__).resolve()
54
+ project_root = current_file.parent.parent
55
+ pyproject_path = project_root / "pyproject.toml"
56
+
57
+ if pyproject_path.exists():
58
+ with open(pyproject_path, 'r', encoding='utf-8') as f:
59
+ content = f.read()
60
+ # 使用正则表达式匹配 version = "x.x.x"
61
+ match = re.search(r'version\s*=\s*["\']([^"\']+)["\']', content)
62
+ if match:
63
+ return match.group(1)
64
+ except Exception:
65
+ pass
66
+
67
+ # 如果都失败了,返回默认版本
68
+ return "0.0.0"
69
+
70
+
71
+ __version__ = _get_version()
38
72
 
39
73
  __all__ = [
40
74
  # API函数
@@ -160,7 +160,7 @@ def get_industry_stocks(node):
160
160
  获取指定行业板块的股票列表
161
161
 
162
162
  Args:
163
- node: 行业节点代码
163
+ node: 行业节点名称
164
164
 
165
165
  Returns:
166
166
  股票列表
@@ -20,6 +20,7 @@ def get_price(i: str, sdate: str = '', edate: str = '', freq: str = 'day',
20
20
  i: 股票代码
21
21
  sdate: 开始日期
22
22
  edate: 结束日期
23
+ freq: 频率,默认'day' (日线),可选:'week', 'month', 'min'
23
24
  dd: data dictionary或Cache对象,任何有get/put方法的本地缓存
24
25
  days: 获取天数,覆盖sdate
25
26
  fq: 复权方式,qfq为前复权
@@ -71,3 +72,8 @@ def get_price_longer(i: str, l: int = 2, dd=None) -> Tuple[str, str, pd.DataFram
71
72
  d1 = d0
72
73
  return i, name, a
73
74
 
75
+
76
+ if __name__ == '__main__':
77
+ i = 'usTSLA.N'
78
+ a = get_price(i, freq='min')
79
+ print(a)
@@ -18,6 +18,7 @@ def get_stock_concepts(i: str) -> List[str]:
18
18
  Returns:
19
19
  概念代码列表
20
20
  """
21
+ i = {'6': 'sh', '0': 'sz', '3': 'sz'}.get(i[0], '') + i if i[0] in ['6', '0', '3'] else i
21
22
  url = f'https://proxy.finance.qq.com/ifzqgtimg/appstock/app/stockinfo/plateNew?code={i}&app=wzq&zdf=1'
22
23
  a = hget(url)
23
24
  if not a:
@@ -38,6 +39,7 @@ def get_stock_industry(i: str) -> List[str]:
38
39
  Returns:
39
40
  行业代码列表
40
41
  """
42
+ i = {'6': 'sh', '0': 'sz', '3': 'sz'}.get(i[0], '') + i if i[0] in ['6', '0', '3'] else i
41
43
  url = f'https://proxy.finance.qq.com/ifzqgtimg/appstock/app/stockinfo/plateNew?code={i}&app=wzq&zdf=1'
42
44
  a = hget(url)
43
45
  if not a:
@@ -57,6 +57,9 @@ class SinaDataSource(DataSource):
57
57
  return {'data': data}
58
58
  except json.JSONDecodeError as e:
59
59
  raise ParseError(f"Parse error: {e}")
60
+ finally:
61
+ # 确保响应对象被关闭,释放SSL连接
62
+ response.close()
60
63
 
61
64
  def fetch_tick(self, symbols: List[str]) -> Dict[str, Any]:
62
65
  """
@@ -89,4 +92,7 @@ class SinaDataSource(DataSource):
89
92
  return {'data': result}
90
93
  except Exception as e:
91
94
  raise ParseError(f"Parse tick error: {e}")
95
+ finally:
96
+ # 确保响应对象被关闭,释放SSL连接
97
+ response.close()
92
98
 
@@ -12,9 +12,9 @@ from ..exceptions import DataSourceError, ParseError
12
12
  class TencentDataSource(DataSource):
13
13
  """腾讯数据源"""
14
14
 
15
- BASE_URL = "http://web.ifzq.gtimg.cn/appstock/app/newfqkline/get"
16
- BASE_URL_HK = "http://web.ifzq.gtimg.cn/appstock/app/hkfqkline/get"
17
- BASE_URL_US = "http://web.ifzq.gtimg.cn/appstock/app/usfqkline/get"
15
+ BASE_URL = "https://web.ifzq.gtimg.cn/appstock/app/newfqkline/get"
16
+ BASE_URL_HK = "https://web.ifzq.gtimg.cn/appstock/app/hkfqkline/get"
17
+ BASE_URL_US = "https://web.ifzq.gtimg.cn/appstock/app/usfqkline/get"
18
18
 
19
19
  def __init__(self, http_client: HTTPClient = None):
20
20
  """
@@ -56,7 +56,7 @@ class TencentDataSource(DataSource):
56
56
  if not response:
57
57
  raise DataSourceError(f"Failed to fetch from Tencent: {symbol}")
58
58
 
59
- # 解析响应
59
+ # 解析响应,确保响应对象被正确关闭
60
60
  try:
61
61
  text = response.text
62
62
  # 处理不同的响应格式
@@ -83,6 +83,9 @@ class TencentDataSource(DataSource):
83
83
  return data
84
84
  except json.JSONDecodeError as e:
85
85
  raise ParseError(f"Parse error: {e}")
86
+ finally:
87
+ # 确保响应对象被关闭,释放SSL连接
88
+ response.close()
86
89
 
87
90
  def fetch_tick(self, symbols: List[str]) -> Dict[str, Any]:
88
91
  """获取实时行情(暂未实现)"""
@@ -159,7 +159,7 @@ class CNStockMarket(Market):
159
159
  from ..utils import hget
160
160
  import json
161
161
 
162
- url = f'http://web.ifzq.gtimg.cn/appstock/app/newfqkline/get?param={symbol},{freq},{sdate},{edate},{days},{fq}'
162
+ url = f'https://web.ifzq.gtimg.cn/appstock/app/newfqkline/get?param={symbol},{freq},{sdate},{edate},{days},{fq}'
163
163
  response = hget(url)
164
164
  if not response:
165
165
  raise DataSourceError(f'Failed to fetch data for {symbol}')
@@ -91,6 +91,7 @@ class hget:
91
91
  """
92
92
  def __init__(self, url, *args, **kwargs):
93
93
  self.url = url
94
+ r = None
94
95
  try:
95
96
  r = httpx.get(
96
97
  self.url, follow_redirects=True, headers=WebUtils.headers(),
@@ -101,4 +102,8 @@ class hget:
101
102
  logger.error(f'fetch {self.url} err: {e}')
102
103
  self.text = ''
103
104
  self.content = b''
105
+ finally:
106
+ # 确保响应对象被关闭,释放SSL连接
107
+ if r is not None:
108
+ r.close()
104
109
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rquote
3
- Version: 0.3.5
3
+ Version: 0.3.8
4
4
  Summary: Mostly day quotes of cn/hk/us/fund/future markets, side with quote list fetch
5
5
  Requires-Python: >=3.6.1
6
6
  Description-Content-Type: text/markdown
@@ -83,7 +83,7 @@ sid, name, df = get_price('sh000001', dd=cache_dict)
83
83
  - `i`: 股票代码,使用新浪/腾讯的id形式
84
84
  - `sdate`: 开始日期 (可选,格式:YYYY-MM-DD)
85
85
  - `edate`: 结束日期 (可选,格式:YYYY-MM-DD)
86
- - `freq`: 频率,默认'day' (日线),可选:'week', 'month', 'min'
86
+ - `freq`: 频率,默认'day' (日线),可选:(港A)'week', 'month', (美股)'min'
87
87
  - `days`: 获取天数,默认320天
88
88
  - `fq`: 复权方式,默认'qfq' (前复权),可选:'hfq' (后复权)
89
89
  - `dd`: 本地缓存字典 (可选,已废弃,建议使用MemoryCache)
@@ -4,7 +4,7 @@ API测试(集成测试)
4
4
  """
5
5
  import unittest
6
6
  from rquote import get_price, get_cn_stock_list, get_all_industries
7
- from rquote.exceptions import SymbolError, DataSourceError
7
+ from rquote.exceptions import SymbolError, DataSourceError, NetworkError
8
8
 
9
9
 
10
10
  class TestAPI(unittest.TestCase):
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes