从零开始构建个股资金流向数据采集系统:Tushare + SQLAlchemy + MySQL

在金融数据分析领域,个股资金流向数据是投资者判断市场情绪和资金动向的重要依据。然而,如何高效、自动化地采集和存储这些数据,是许多数据分析师和开发者面临的挑战。本文将带你从零开始,使用 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 和相关的技术栈构建一个实用的金融数据采集系统。如果你有任何问题或建议,欢迎在评论区留言讨论!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值