stock_fundamentals/tools/stock_code_formatter.py

244 lines
7.4 KiB
Python
Raw Normal View History

2025-07-03 15:57:04 +08:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
股票代码格式转换工具类
提供多种股票代码格式之间的转换功能
"""
import re
from typing import Optional
class StockCodeFormatter:
"""股票代码格式转换器"""
def __init__(self):
"""初始化"""
pass
def _parse_stock_code(self, stock_code: str) -> tuple:
"""
解析股票代码提取代码和市场信息
Args:
stock_code: 输入的股票代码
Returns:
tuple: (代码数字, 市场标识) ('688008', 'SH')
"""
if not stock_code:
return None, None
stock_code = stock_code.strip().upper()
# 处理 688008.SH 格式
if '.' in stock_code:
parts = stock_code.split('.')
if len(parts) == 2:
code, market = parts[0], parts[1]
return code, market
# 处理 SH688008 格式
elif stock_code.startswith(('SZ', 'SH', 'BJ')):
market = stock_code[:2]
code = stock_code[2:]
return code, market
# 处理纯数字 688008 格式
elif stock_code.isdigit():
# 根据数字前缀自动判断市场
if stock_code.startswith(('60', '68')):
return stock_code, 'SH'
elif stock_code.startswith(('00', '30', '20')):
return stock_code, 'SZ'
elif stock_code.startswith(('8', '43', '87')):
return stock_code, 'BJ'
else:
return stock_code, None
return None, None
def to_dot_format(self, stock_code: str) -> Optional[str]:
"""
转换为点分格式 (: 688008.SH)
Args:
stock_code: 输入的股票代码支持多种格式
Returns:
str: 点分格式的股票代码如果无法转换则返回None
Examples:
>>> formatter = StockCodeFormatter()
>>> formatter.to_dot_format('SH688008')
'688008.SH'
>>> formatter.to_dot_format('688008')
'688008.SH'
>>> formatter.to_dot_format('688008.SH')
'688008.SH'
"""
code, market = self._parse_stock_code(stock_code)
if code and market:
return f"{code}.{market}"
return None
def to_prefix_format(self, stock_code: str) -> Optional[str]:
"""
转换为前缀格式 (: SH688008)
Args:
stock_code: 输入的股票代码支持多种格式
Returns:
str: 前缀格式的股票代码如果无法转换则返回None
Examples:
>>> formatter = StockCodeFormatter()
>>> formatter.to_prefix_format('688008.SH')
'SH688008'
>>> formatter.to_prefix_format('688008')
'SH688008'
>>> formatter.to_prefix_format('SH688008')
'SH688008'
"""
code, market = self._parse_stock_code(stock_code)
if code and market:
return f"{market}{code}"
return None
def to_number_only(self, stock_code: str) -> Optional[str]:
"""
转换为纯数字格式 (: 688008)
Args:
stock_code: 输入的股票代码支持多种格式
Returns:
str: 纯数字格式的股票代码如果无法转换则返回None
Examples:
>>> formatter = StockCodeFormatter()
>>> formatter.to_number_only('688008.SH')
'688008'
>>> formatter.to_number_only('SH688008')
'688008'
>>> formatter.to_number_only('688008')
'688008'
"""
code, market = self._parse_stock_code(stock_code)
if code:
return code
return None
def get_market(self, stock_code: str) -> Optional[str]:
"""
获取股票代码对应的市场标识
Args:
stock_code: 输入的股票代码支持多种格式
Returns:
str: 市场标识 ('SH', 'SZ', 'BJ')如果无法识别则返回None
"""
code, market = self._parse_stock_code(stock_code)
return market
def is_valid_stock_code(self, stock_code: str) -> bool:
"""
验证股票代码是否有效
Args:
stock_code: 输入的股票代码
Returns:
bool: 是否为有效的股票代码
"""
code, market = self._parse_stock_code(stock_code)
return code is not None and market is not None
def batch_convert(self, stock_codes: list, target_format: str = 'dot') -> dict:
"""
批量转换股票代码格式
Args:
stock_codes: 股票代码列表
target_format: 目标格式 ('dot', 'prefix', 'number')
Returns:
dict: {原始代码: 转换后代码} 的映射字典
"""
result = {}
for stock_code in stock_codes:
if target_format == 'dot':
converted = self.to_dot_format(stock_code)
elif target_format == 'prefix':
converted = self.to_prefix_format(stock_code)
elif target_format == 'number':
converted = self.to_number_only(stock_code)
else:
converted = None
result[stock_code] = converted
return result
def main():
"""示例用法"""
print("=== 股票代码格式转换工具示例 ===")
# 创建格式转换器
formatter = StockCodeFormatter()
# 测试用例
test_codes = [
'688008.SH', # 沪市科创板
'SH688008', # 前缀格式
'688008', # 纯数字
'300661.SZ', # 深市创业板
'SZ300661', # 前缀格式
'300661', # 纯数字
'000858.SZ', # 深市主板
'600519.SH', # 沪市主板
'430123.BJ', # 北交所
'BJ430123', # 北交所前缀格式
]
print("\n原始代码 -> 点分格式 -> 前缀格式 -> 纯数字格式 -> 市场")
print("-" * 70)
for code in test_codes:
dot_format = formatter.to_dot_format(code)
prefix_format = formatter.to_prefix_format(code)
number_format = formatter.to_number_only(code)
market = formatter.get_market(code)
is_valid = formatter.is_valid_stock_code(code)
status = "" if is_valid else ""
print(f"{code:12} -> {dot_format or 'None':12} -> {prefix_format or 'None':12} -> {number_format or 'None':8} -> {market or 'None':4} {status}")
# 批量转换示例
print(f"\n=== 批量转换示例 ===")
batch_codes = ['SH688008', '300661', 'BJ430123']
dot_results = formatter.batch_convert(batch_codes, 'dot')
print("转换为点分格式:")
for original, converted in dot_results.items():
print(f" {original} -> {converted}")
prefix_results = formatter.batch_convert(batch_codes, 'prefix')
print("转换为前缀格式:")
for original, converted in prefix_results.items():
print(f" {original} -> {converted}")
if __name__ == "__main__":
main()