update get data code

This commit is contained in:
2025-08-20 00:00:14 +08:00
parent af075e642d
commit 3be41434e3
15 changed files with 5088 additions and 3821 deletions

View File

@@ -0,0 +1,197 @@
"""
该代码用于更新日 K 数据
"""
from futu import *
from pymysql import Error
from MySQLHelper import MySQLHelper # MySQLHelper类保存为单独文件
from datetime import datetime
import logging
from typing import Optional, List, Dict, Union, Tuple
import time
import akshare as ak
def get_market_data(market: Market) -> List[str]:
"""
从Futu API获取指定市场的股票代码列表
Args:
market (Market): 市场枚举值,如 Market.SH, Market.SZ
Returns:
List[str]: 股票代码列表
"""
quote_ctx = OpenQuoteContext(host='127.0.0.1', port=11111)
try:
ret, data = quote_ctx.get_stock_basicinfo(market, SecurityType.STOCK)
if ret == RET_OK:
# 提取code列并转换为列表
codes = data['code'].astype(str).tolist()
logging.info(f"获取到 {market} 市场 {len(codes)} 个股票代码")
return codes
else:
logging.error(f"获取股票代码失败: {data}")
return []
except Exception as e:
logging.error(f"获取股票代码时发生异常: {str(e)}")
return []
finally:
quote_ctx.close()
def preprocess_quote_data(df: pd.DataFrame) -> List[Dict]:
"""
预处理行情数据,转换为适合数据库存储的格式
Args:
df (pd.DataFrame): 原始行情数据DataFrame
Returns:
List[Dict]: 处理后的数据列表
"""
processed_data = []
for _, row in df.iterrows():
try:
# 提取市场标识
# market = row['code'].split('.')[0] if '.' in row['code'] else 'UNKNOWN'
# 转换时间格式
# trade_time = datetime.strptime(row['date'], '%Y-%m-%d %H:%M:%S')
item = {
'trade_date': str(row['date']),
'open_price': float(row['open']),
'close_price': float(row['close']),
'high_price': float(row['high']),
'low_price': float(row['low']),
'volume': int(row['volume']) if pd.notna(row['volume']) else None,
}
processed_data.append(item)
except Exception as e:
logging.warning(f"处理行情数据时跳过异常行 {row.get('code', '未知')}: {str(e)}")
continue
return processed_data
def save_quotes_to_db(db_config: dict, quote_data: pd.DataFrame, table_name: str = 'stock_quotes') -> bool:
"""
将行情数据保存到数据库
Args:
db_config (dict): 数据库配置
quote_data (pd.DataFrame): 行情数据DataFrame
table_name (str): 目标表名(默认为'stock_quotes')
Returns:
bool: 是否成功保存
"""
# 预处理数据
processed_data = preprocess_quote_data(quote_data)
if not processed_data:
logging.error("没有有效数据需要保存")
return False
# 动态生成SQL插入语句
insert_sql = f"""
INSERT INTO {table_name} (
trade_date, open_price, close_price, high_price, low_price, volume
) VALUES (
%(trade_date)s, %(open_price)s, %(close_price)s, %(high_price)s, %(low_price)s, %(volume)s
)
ON DUPLICATE KEY UPDATE
open_price = VALUES(open_price),
close_price = VALUES(close_price),
high_price = VALUES(high_price),
low_price = VALUES(low_price),
volume = VALUES(volume)
"""
try:
with MySQLHelper(**db_config) as db:
# 检查表是否存在,不存在则创建
if not db.table_exists(table_name):
create_table_sql = f"""
CREATE TABLE IF NOT EXISTS {table_name} (
id INT AUTO_INCREMENT PRIMARY KEY,
trade_date DATETIME NOT NULL COMMENT '交易日期时间',
open_price DECIMAL(10, 3) COMMENT '开盘价',
close_price DECIMAL(10, 3) COMMENT '收盘价',
high_price DECIMAL(10, 3) COMMENT '最高价',
low_price DECIMAL(10, 3) COMMENT '最低价',
volume BIGINT COMMENT '成交量(股)',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
UNIQUE KEY idx_trade_date (trade_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='股票行情数据表'
"""
db.execute_update(create_table_sql)
logging.info(f"创建了新表: {table_name}")
affected_rows = db.execute_many(insert_sql, processed_data)
logging.info(f"成功插入/更新 {affected_rows} 条行情记录到表 {table_name}")
return True
except Exception as e:
logging.error(f"保存行情数据到表 {table_name} 失败: {str(e)}")
return False
def read_missing_codes_basic(file_path='data\missing_tables_小航富途.txt'):
"""基础读取方法 - 按行读取所有内容"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
# 去除每行末尾的换行符,并过滤空行
codes = [line.strip() for line in lines if line.strip()]
return codes
except FileNotFoundError:
print(f"文件 {file_path} 不存在")
return []
except Exception as e:
print(f"读取文件失败: {str(e)}")
return []
def get_stock_codes() -> List[str]:
"""从conditionalselection表获取所有股票代码"""
try:
with MySQLHelper(**db_config) as db:
sql = f"SELECT DISTINCT stock_code FROM conditionalselection"
results = db.execute_query(sql)
return [row['stock_code'] for row in results if row['stock_code']]
except Exception as e:
logging.error(f"获取股票代码失败: {str(e)}")
return []
if __name__ == "__main__":
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('Debug.log', encoding='utf-8'), # 关键在这里
logging.StreamHandler()
]
)
# 数据库配置
db_config = {
'host': 'localhost',
'user': 'root',
'password': 'bzskmysql',
'database': 'klinedata_1d_hk_akshare'
}
# market_data = get_market_data(Market.HK) # 获取香港市场数据,后面需要改成按照筛选来获取
# # 小航富途
# market_data_hang = read_missing_codes_basic()
#
# market_data = list(set(market_data_all) - set(market_data_hang))
nCount = 0 # 记录账号获取多少只股票的数据
market_data_all = get_stock_codes()
for code in market_data_all:
stock_hk_index_daily_sina_df = ak.stock_hk_index_daily_sina(symbol=code[3:])
custom_table_name = 'hk_' + code[3:] # 自定义表名
success = save_quotes_to_db(db_config, stock_hk_index_daily_sina_df, table_name=custom_table_name)
time.sleep(5)