在金融数据分析领域,个股资金流向数据是投资者判断市场情绪和资金动向的重要依据。然而,如何高效、自动化地采集和存储这些数据,是许多数据分析师和开发者面临的挑战。本文将带你从零开始,使用 Python、Tushare、SQLAlchemy 和 MySQL 构建一个完整的个股资金流向数据采集系统。
1. 为什么需要自动化数据采集系统?
在金融市场中,数据是决策的基础。个股资金流向数据能够帮助投资者了解主力资金的动向,判断市场的热点和趋势。然而,手动采集这些数据不仅耗时耗力,还容易出错。因此,构建一个自动化数据采集系统显得尤为重要。
通过自动化系统,我们可以:
-
定时采集数据:确保数据的实时性和准确性。
-
高效存储数据:将数据存储在数据库中,便于后续分析和查询。
-
减少人工干预:降低人为错误,提高工作效率。
2. 技术栈介绍
在本文中,我们将使用以下技术栈:
-
Tushare:一个免费、开源的金融数据接口,提供丰富的股票、基金、期货等金融数据。
-
SQLAlchemy:一个强大的 Python SQL 工具包和对象关系映射(ORM)工具,支持多种数据库。
-
MySQL:一个流行的关系型数据库管理系统,广泛应用于数据存储和管理。
3. 系统设计与实现
3.1 初始化 Tushare API
首先,我们需要初始化 Tushare API,并设置访问令牌。Tushare 提供了丰富的金融数据接口,我们可以通过 pro.moneyflow_dc
接口获取个股资金流向数据。
import tushare as ts
# 初始化 Tushare API
ts.set_token(TUSHARE_TOKEN)
pro = ts.pro_api()
3.2 数据库设计与创建
接下来,我们需要设计数据库表结构,并创建数据库和数据表。我们使用 SQLAlchemy 来管理数据库连接和操作。
3.2.1 解析数据库连接字符串
# 解析 DB_URI 获取数据库名称
db_name = DB_URI.split("/")[-1].split("?")[0] # 从连接字符串中提取数据库名称
base_uri = DB_URI.rsplit("/", 1)[0] # 获取基础连接字符串(不含数据库名称)
3.2.2 创建数据库(如果不存在)
def create_database_if_not_exists():
try:
# 连接到 MySQL(不指定数据库)
temp_engine = create_engine(base_uri)
with temp_engine.connect() as conn:
# 检查数据库是否存在
result = conn.execute(text(f"SHOW DATABASES LIKE '{db_name}'"))
if not result.fetchone():
# 如果数据库不存在,则创建
conn.execute(text(f"CREATE DATABASE {db_name} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"))
print(f"数据库 {db_name} 创建成功!")
else:
print(f"数据库 {db_name} 已存在,跳过创建。")
except Exception as e:
print(f"创建数据库时出错: {e}")
3.2.3 创建数据表(如果不存在)
def create_table_if_not_exists():
try:
# 连接到指定数据库
engine = create_engine(DB_URI)
with engine.connect() as conn:
# 检查表是否存在
result = conn.execute(text("SHOW TABLES LIKE 'moneyflow_dc'"))
if not result.fetchone():
# 如果表不存在,则创建
create_table_sql = """
CREATE TABLE `moneyflow_dc` (
`id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '自增主键',
`trade_date` CHAR(8) NOT NULL COMMENT '交易日期 (YYYYMMDD)',
`ts_code` VARCHAR(20) NOT NULL COMMENT '股票代码',
`name` VARCHAR(50) COMMENT '股票名称',
`pct_change` DECIMAL(10, 2) COMMENT '涨跌幅',
`close` DECIMAL(10, 2) COMMENT '最新价',
`net_amount` DECIMAL(15, 2) COMMENT '今日主力净流入额(万元)',
`net_amount_rate` DECIMAL(10, 2) COMMENT '今日主力净流入净占比(%)',
`buy_elg_amount` DECIMAL(15, 2) COMMENT '今日超大单净流入额(万元)',
`buy_elg_amount_rate` DECIMAL(10, 2) COMMENT '今日超大单净流入占比(%)',
`buy_lg_amount` DECIMAL(15, 2) COMMENT '今日大单净流入额(万元)',
`buy_lg_amount_rate` DECIMAL(10, 2) COMMENT '今日大单净流入占比(%)',
`buy_md_amount` DECIMAL(15, 2) COMMENT '今日中单净流入额(万元)',
`buy_md_amount_rate` DECIMAL(10, 2) COMMENT '今日中单净流入占比(%)',
`buy_sm_amount` DECIMAL(15, 2) COMMENT '今日小单净流入额(万元)',
`buy_sm_amount_rate` DECIMAL(10, 2) COMMENT '今日小单净流入占比(%)',
UNIQUE KEY `unique_stock_date` (`ts_code`, `trade_date`) COMMENT '股票代码和交易日期唯一索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='东方财富个股资金流向数据表';
"""
conn.execute(text(create_table_sql))
print("表 moneyflow_dc 创建成功!")
else:
print("表 moneyflow_dc 已存在,跳过创建。")
except Exception as e:
print(f"创建表时出错: {e}")
3.3 数据采集与存储
在数据库和表创建完成后,我们可以开始采集个股资金流向数据,并将其存储到数据库中。
3.3.1 获取个股资金流向数据
def fetch_and_store_moneyflow_data(stock_code, stock_name, index, total):
try:
# 打印当前进度
print(f"正在处理第 {index + 1}/{total} 只股票:{stock_code} ({stock_name})")# 获取个股资金流向数据
df = pro.moneyflow_dc(ts_code=stock_code, start_date='20200101', end_date='20250120')# 打印获取到的数据日期范围
if not df.empty:
start_date = df['trade_date'].min() # 获取最早日期
end_date = df['trade_date'].max() # 获取最晚日期
print(f"获取到的数据日期范围:{start_date} 到 {end_date}")
else:
print("未获取到数据。")# 将数据存入 MySQL 数据库
engine = create_engine(DB_URI)
df.to_sql('moneyflow_dc', con=engine, if_exists='append', index=False)
print(f"数据已成功存入数据库: {stock_code} ({stock_name})\n")
except Exception as e:
print(f"获取或存储数据时出错: {stock_code} ({stock_name}), 错误信息: {e}\n")
3.3.2 从 CSV 文件中读取股票代码
def read_stock_list_from_csv(file_path):
try:
df = pd.read_csv(file_path)
stock_list = [(row['ts_code'], row['name']) for _, row in df.iterrows()]
return stock_list
except Exception as e:
print(f"从 CSV 文件读取股票列表时出错: {e}")
return []
3.4 主程序逻辑
最后,我们将所有功能整合到主程序中,实现完整的自动化数据采集系统。
if __name__ == "__main__":
# 创建数据库(如果不存在)
create_database_if_not_exists()# 创建表(如果不存在)
create_table_if_not_exists()# 让用户选择数据源
print("请选择股票代码来源:")
print("1. 从股票池中获取")
print("2. 从 CSV 文件中获取")
choice = input("请输入选项(1 或 2):")stock_list = []
if choice == "1":
# 从股票池中获取股票代码
stock_list = [(stock['ts_code'], stock['name']) for stock in STOCK_POOL]
elif choice == "2":
# 从 CSV 文件中获取股票代码
stock_list = read_stock_list_from_csv(STOCK_LIST_FILE)
else:
print("无效选项,程序退出。")
exit()total_stocks = len(stock_list)
if total_stocks == 0:
print("未找到股票代码,程序退出。")
exit()# 遍历股票代码并获取数据
for index, (stock_code, stock_name) in enumerate(stock_list):
fetch_and_store_moneyflow_data(stock_code, stock_name, index, total_stocks)print("所有股票资金流向数据已成功获取并存入数据库。")
4. 总结
通过本文的介绍,我们成功构建了一个自动化个股资金流向数据采集系统。该系统不仅能够高效地采集和存储数据,还能够根据用户的选择灵活地获取股票代码。未来,我们可以进一步扩展该系统,例如增加定时任务、数据可视化等功能,以满足更多的业务需求。
希望本文能够帮助你理解如何利用 Python 和相关的技术栈构建一个实用的金融数据采集系统。如果你有任何问题或建议,欢迎在评论区留言讨论!