15天搭建ETF量化交易系统Day14—MySQL回测数据管理指南

BQ25798双电源输入4节电池升降压充电与最大功率跟踪于光伏板应用 介绍一颗具有窄范围直流电压NVDC、路径管理PPMT、光伏板最大功率跟踪及反向放电OTG升降压充电控制器,带I2C接口能对内部寄存器做控制 阅读详情

e2dada3202fc2ffd827444481e0d83a2.png

搭建过程

a2aa358a1dce1e068fd7b8c2b8489cf0.png

每个交易者都应该形成一套自己的交易系统。


 

很多交易者也清楚知道,搭建自己交易系统的重要性。现实中,从0到1往往是最难跨越的一步。

授人鱼不如授人以渔,为了帮助大家跨出搭建量化系统的第一步,我们决定推出这个主题系列。

这个系列中,我们用Python从0开始一步步搭建出一套ETF量化交易系统(选择ETF标的是因为对于普通交易者来说,ETF相对于选强势股难度要小,而且没有退市风险)。大家可以跟随着我们的实现路径来一起学习,从过程中掌握方法。

掌握了方法之后,你可以换成期货系统、比特币系统、美股系统,然后在实战中不断去完善自己的系统了。

搭建一套ETF量化交易系统涉及多个模块和组件的协同工作,包括数据源模块、量化策略模块、可视化模块、数据库模块、回测评估模块、自动交易模块等等。

DAY1链接如下:15天搭建ETF量化交易系统Day1—数据源模块
DAY2链接如下:15天搭建ETF量化交易系统Day2—图形显示模块
DAY3链接如下:15天搭建ETF量化交易系统Day3—上手经典回测框架
DAY4链接如下:15天搭建ETF量化交易系统Day4—玩转海龟交易策略
DAY5链接如下:15天搭建ETF量化交易系统Day5—打造实盘量化机器人
DAY6链接如下:15天搭建ETF量化交易系统Day6—打通同花顺自动交易
DAY7链接如下:15天搭建ETF量化交易系统Day7—全自动化交易系统
DAY8链接如下:15天搭建ETF量化交易系统Day8—强化自动交易模块
DAY9链接如下:15天搭建ETF量化交易系统Day9—玩大A必学网格策略

DAY10链接如下:15天搭建ETF量化交易系统Day10—借用网格思想做仓位管理

DAY11链接如下:15天搭建ETF量化交易系统Day11—miniQMT自动交易真香!

DAY12链接如下:15天搭建ETF量化交易系统Day12—雏形系统关键代码讲解!

DAY13链接如下:15天搭建ETF量化交易系统Day13—入手MySQL搭建数据库


 

回测是量化系统中重要环节之一,它通过对历史数据的模拟交易,评估投资策略的有效性和盈利能力。搭建数据库为回测提供了数据的支持,是不可或缺的基础设施。

DAY13我们已经入手了MySQL数据库,但是要把MySQL用于量化策略回测阶段的数据管理还有很多问题要解决!比如:

“如何为每个股票在MySQL中创建表?”
“每天获取的股票数据怎么存入到MySQL数据库中?”
“如何从MySQL中取出我们想要的股票数据呢?”
……

本期我们以回测数据管理为例,分享MySQL作为量化回测数据库的操作方法。

  • 如何创建个股数据表

  • 如何避免重复创建数据表

  • 如何插入股票数据表

  • 如何更新股票数据表

  • 如何查询股票数据表

  • 如何删除股票数据表


 

 

 

 

 

74a33fbd839a1ba14c1e5abeabb08632.png

如何创建单个ETF数据表

2bda5f822f12e598f09a98f6ec8900d7.png

存储ETF数据需要先为该品种创建一个数据表。完整的创建表的语句如下所示:

f8f6223ec86a707027193193757757c2.png

为大家解读下语句的含义,遵循的SQL语法格式为:

CREATE TABLE <表名> ([表定义选项]);

其中,[表定义选项]的格式为:<列名1> <类型1> [,…] <列名n> <类型n>

“CREATE TABLE”是创建表的关键字。这里的表名是 “minute_tb”,表定义的选项包括了ID、时间戳、代码、最高价、最低价、收盘价、开盘价、成交量、成交额、涨跌幅、描述。

“PRIMARY KEY”关键字是来指定数据表的主键的,我们既可以为表中的一个字段设置主键,也可以为表中多个字段设置联合主键。但是不论使用哪种方法,在一个表中主键值必须唯一标识表中的每一行,且不能为 NULL,即表中不可能存在有相同主键值的两行数据。这是唯一性原则。此处我们把“ID”字段设置为了数据表的主键约束,

我们把“ID”字段添加 AUTO_INCREMENT属性来实现主键自增长。当主键定义为自增长后,这个主键的值就不再需要用户输入数据了,而由数据库系统根据定义自动赋值。每增加一条记录,主键会自动以相同的步长进行增长。需要注意的是:

一个表中只能有一个字段使用 AUTO_INCREMENT 约束,且该字段必须有唯一索引,以避免序号重复(即为主键或主键的一部分)。

AUTO_INCREMENT约束的字段必须具备 NOT NULL 属性。

AUTO_INCREMENT 约束的字段只能是整数类型(TINYINT、SMALLINT、INT、BIGINT 等)。

AUTO_INCREMENT 约束字段的最大值受该字段的数据类型约束,如果达到上限,AUTO_INCREMENT 就会失效。


546e3c44363141db9000107529174cb6.png

如何避免重复创建数据表

042424631921f0d5974e4e61df174aaa.png

在更新ETF数据时,如果数据库中不存在该ETF的数据表,那么我们需要为这个ETF创建一个数据表,但是如果已经存在数据表的话,只需要更新数据就行。

我们可以使用SQL语句“show tables”获取当前数据库中所有表的名称,然后查看其中是否包含该股的数据表即可。

2f44d2947a88820c8993cd0ae18f38f9.png




1ecbb40b3379edcbe574a318978aed7f.png

如何插入ETF数据表

b0dcbcd180818867ba6b000273472c58.png

每天收盘后要把当天新增的股票数据插入到数据表中,可以使用“INSERT INTO”语句。

insert into有两种语法,分别如下:

一种语法无需指定要插入数据的列名,只需提供被插入的值即可,比如INSERT INTOtable_name VALUES (value1,value2,value3,...);  

另外一种是需要指定插入数据的列名,并且插入的值需要和列名一一对应:

cursor.execute("INSERT INTO minute_tb (ID, Time, Code, High, Low ,Close, Open, Volume, Amount, PctChg, Description) \
            VALUES (1, '2019-1-1', 600123, 10.12, 10.12, 10.12, 10.12, 111111, 10.12, 2.12, 'TP')")



40e5442818ef75ab498efd08803f29d1.png

如何更新股票数据表

24b9a2acf6864f10535015ba65dd7698.png

如果要更新数据表中已有的数据,那么可以使用“UPDATE” 语句。需要注意的是,使用“UPDATE”时WHERE 子句规定哪条记录或者哪些记录需要更新,如果省略了 WHERE 子句,所有的记录都将被更新!

如下所示,是让ID为1的那条数据额Code更新为“510050”“

cursor.execute("UPDATE minute_tb set Code = 510050 where ID=1")

a83f7da2ed175e64fea607c6fb58fb55.png

如何查询ETF数据表

6a18c404491afc91ae57a57111f5fe37.png

在分析ETF的时候就需要从数据库中查询ETF数据表中的数据了,此时可以使用 “SELECT”语句,这里的“*”号是表示从数据表中获取全部的数据。如果要再针对性地获取数据,可以在语句中增加条件判断。

然后再通过fetchone()返回满足条件的一行数据,或者通过fetchall()返回满足条件的全部数据。

cursor.execute("select * from minute_tb")

732ed7295c05d1b4385a37de18658d0e.png

如何删除ETF数据表

3e315c3cae44bbba39ecfaca7222dcec.png

为了对数据库做有效率的管理,有时候我们会决定我们需要从数据库中删除一个表格。此时使用“DROP TABLE”语句删除股票数据表:

cursor.execute("DROP TABLE minute_tb")

59693cf3dcd93b8fdd6a4bebe1393dbb.png

封装接口

5db49ec9cc4c2b5911e14acf38cde68e.png

接下来我们把前面那些特定的操作方法封装为类,这样可以在系统的回测模块中进行调用。

class mysql_handler():


    # 需要更改为自己的数据库配置
    host = 'localhost'
    port = 3306
    db = 'quanttrader'
    user = 'root'
    password = ''
    table_name = 'minute_tb'


    def __init__(self):
        # 连接数据库
        self.conn = self.get_connection()
        # 创建执行SQL语句游标,通过游标对象就可对数据库进行增、删、查、改 
        self.cursor = self.conn.cursor()  # 得到一个可以执行SQL语句的光标对象, 执行完毕返回的结果集默认以元组显示


    # ---- 用pymysql 操作数据库
    def get_connection(self):
        conn = pymysql.connect(host=self.host, port=self.port, db=self.db, user=self.user, password=self.password)
        return conn


    def detect_table_exist(self, conn, cursor, table):


        status = False


        sql = "show tables"
        cursor.execute(sql)
        tables = cursor.fetchall()


        tables_list = re.findall('(\'.*?\')',str(tables))
        tables_list = [re.sub("'",'',each)for each in tables_list]


        if table in tables_list:
            print("table exists")
            status = True
        else:
            print("table not exists")
            status = False
        return status


    def creat_table(self, conn, cursor, sql):


        try :
            cursor.execute(sql)
            conn.commit()
            print("Successfully added table")
        except:
            conn.rollback()
            print("UnSuccessfully added table")


    def exe_sql(self, sql):
        try:
            self.cursor.execute(sql)
            self.conn.commit()
        except:
            traceback.print_exc()


    def quit(self):
        self.cursor.close()
        self.conn.commit()
        self.conn.close()


    def etf_data_source(self, code="510050", period="60"):


        data = ak.fund_etf_hist_min_em(symbol=code, period="60", adjust="")
        data.rename(columns={"时间": "datetime", "收盘": "close", "最高": "high", "最低": "low",
                            "成交量":"vol", "成交额":"amount", "涨跌幅":"pctchg"}, inplace=True)
        #data.set_index("date", drop=True, inplace=True)
        return data


    def check_it(self, type="ETF"):


        # 篇幅原因 此处省略部分代码
        # 创建表
        """
        create table 表名(字段名 字段类型,字段名 字段类型, ......)
        """
        if self.detect_table_exist(conn, cursor, self.table_name) == False:
        
            # TEXT 可变长度 65535个字符
            # CHAR 固定长度 255个字符
            createTable =   """
                             """
            self.creat_table(conn, cursor, createTable)


            # 插入表TP
            # 篇幅原因 此处省略部分代码
            
            # 更新表
            # 篇幅原因 此处省略部分代码
            
            # df格式转换入表
            # 篇幅原因 此处省略部分代码
            conn.commit()


            # 查询表
            # 篇幅原因 此处省略部分代码
            
        # 删除表(测试时候添加 正式使用时去除)
        cursor.execute("DROP TABLE minute_tb")


        # 关闭数据库连接
        cursor.close()
        conn.close()

4c505fa3c5439d32605b88b5017049c5.png

总结

f32e2a0cb066a3f6184ede35a66ac4de.png

掌握了MySQL作为量化回测数据库的操作方法,接下来我们可以持续收集历史数据并存储起来,当需要优化和改进策略时,就可以从数据库中加载历史数据用于策略回测!

说明

此系列为连载专栏,完整代码会上传知识星球《玩转股票量化交易》!作为会员们的学习资料。

想要加入知识星球《玩转股票量化交易》的小伙伴记得先微信call我获取福利!

非星球会员需要的话,需要单独联系我购买!

知识星球介绍点击:知识星球《玩转股票量化交易》精华内容概览

c574edf2c73e052c20b1ab8fdc47eec3.jpeg

别再只调电位器了!用单片机PWM控制LM317输出电压,精度和玩法都多了 本文探讨了如何利用单片机PWM控制LM317输出电压,替代传统的电位器调节方案。通过PWM信号的有源滤波和运放处理,实现了更高精度(±5mV)、更好温度稳定性(0.01%/°C)的数控稳压电源设计,支持远程控制和可编程曲线输出,为经典电路注入数字化智能。 阅读详情

相关推荐

8. 详解低门槛搭建个人量化平台 - vnpy+backtesting策略测(7)

上篇谈到简单使用backtrader+pyfolio 做策略测。 这篇使用vn.py backtesting引擎,做策略测,并将结果展示在自己的量化平台的web页面上。 在vn.py 下载最新的开源软件包,按照提示一步步安装(这里我使用的是之前下载的 vnpy2.1.7.1,python3.7.7版本)。 vnpy的run.py中: 插入下面代码,确保 CTABacktesterAPP的开启: from vnpy.app.cta_backtester import CtaBacktest

AI 量化 2392

15搭建ETF量化交易系统Day15ETF走势叠加分析择强入池

搭建过程每个交易者都应该形成一套自己的交易系统。很多交易者也清楚知道,搭建自己交易系统的重要性。现实中,从0到1往往是最难跨越的一步。授人鱼不如授人以渔,为了帮助大家跨出搭建量化系统的第一步,我们决定推出这个主题系列。这个系列中,我们用Python从0开始一步步搭建出一套ETF量化交易系统(选择ETF标的是因为对于普通交易者来说,ETF相对于选强势股难度要小,而且没有退市风险)。大家可以跟随着我们...

hangzhouyx的博客 1123

(77页PPT)企业级AIAgent价值及应用报告甲子光年.pptx

(77页PPT)企业级AIAgent价值及应用报告甲子光年.pptx

Redis缓存和MySQL数据一致性方案详解

Redis与MySQL数据一致性解决方案 摘要 本文探讨了高并发系统中Redis缓存与MySQL数据库的数据一致性问题。首先分析了Cache-Aside模式下读写并发导致的数据不一致场景,包括"先删缓存再写库"和"先写库再删缓存"两种策略的缺陷。 文章介绍了两种过渡方案:延时双删策略和删除缓存重试机制,并指出了它们的局限性。随后提出企业级解决方案——"先更新DB再删缓存+Canal订阅Binlog异步兜底"架构,该方案通过Spring事务事件驱动确保数据库事务成功后删除缓存,并利用Canal监听Binlog

qq_23277595的博客 467

Python正则表达式

正则表达式是Python中用于文本模式匹配的强大工具,通过re模块实现

lingjiuwonder的博客 214

mysql之排序查询

首先按照年龄升序排序,如果年龄相同,按照id降序排序。样表如下,表名叫tb_user。升序用asc,降序用desc。

2301_81968528的博客 176

MySQL 事务隔离级别深度解析:并发问题、隔离级别与 MVCC 底层原理

本文深入探讨MySQL事务隔离级别及MVCC实现原理。首先分析并发事务导致的脏读、不可重复读和幻读问题,通过实操演示四种隔离级别的差异。重点剖析InnoDB的MVCC机制,包括三个隐藏字段、undo日志版本链和ReadView可见性判断规则。揭示RC与RR隔离级别的本质区别在于ReadView生成时机:RC每次快照读新建ReadView导致不可重复读,而RR复用首次ReadView实现可重复读。最后总结事务的ACID特性与面试高频考点,帮助开发者理解MySQL如何平衡数据一致性与并发性能。

2501_91275995的博客 499

LeetCode //MySQL - 1204. Last Person to Fit in the Bus

This SQL query solves the problem of finding the last person who can board a bus without exceeding the 1000 kg weight limit. The solution involves: Calculating a running total of weights ordered by boarding turn using a window function Filtering to only in

Made in Code 374

MySQL 中的约束

MySQL约束类型及用法详解 摘要:MySQL提供多种约束类型来保证数据完整性和一致性,包括主键(PRIMARY KEY)、外键(FOREIGN KEY)、唯一(UNIQUE)、非空(NOT NULL)、检查(CHECK)和默认值(DEFAULT)约束。主键用于唯一标识记录,外键维护表间引用关系,唯一约束防止重复值,非空约束禁止NULL值,检查约束验证自定义条件,默认值约束提供默认数据。这些约束可在建表时定义或后期通过ALTER TABLE修改,支持列级和表级约束,并能设置级联操作。MySQL 8.0.16

梦想不只是梦与想的博客 302

MySQL 中的动态数据脱敏:无需更改应用程序即可保护敏感数据

MySQL 9.7 LTS 企业版推出动态数据脱敏(DDM)功能,通过在列级别设置脱敏策略,根据执行用户或角色返原始值或脱敏值,无需修改应用或维护数据副本。该功能通过CASE表达式定义策略,使用CURRENT_USER_IN()和CURRENT_ROLE_IN()进行权限控制,并支持mask_ssn()等内置脱敏函数。示例展示了如何对SSN字段实现基于用户/角色的访问控制,确保只有授权用户能看到原始数据。相比代理层方案,服务器端强制执行更安全可靠,适用于分析、AI等多种工作负载,帮助满足GDPR、HIPA

阮胜昌的专栏 261

MySQL 管理复制拓扑【MySQL第四课】

多线程(并行复制)从库:配置slave_parallel_workers开启,生成多个工作线程,可并发放事务,加快同步速度。重置从库:执行RESET SLAVE,清除从库保存的主库连接、日志坐标等复制信息,断开和旧主库关联,用来重新配置复制环境。2.通过中继日志坐标、主库日志坐标,可以判断复制延迟。单线程从库:默认模式,只有 1 个 SQL 线程,串行执行中继日志里的事务,放速度慢,容易产生复制延迟。3.Last_IO_Error、Last_SQL_Error可以查看 I/O、SQL 线程报错信息。

2602_96636859的博客 228

MySQL内外连接

本文介绍了SQL中的内连接和外连接操作。内连接通过WHERE子句筛选两个表的笛卡尔积,示例展示了显示SMITH名字和部门名称的两种写法。外连接分为左外连接和右外连接:左外连接保留左表所有记录,即使右表无匹配;右外连接保留右表所有记录,即使左表无匹配。通过学生表和成绩表的例子演示了这两种连接的使用场景,并提供了列出部门及员工信息的两种实现方法。

记录学习过程 166

gozero整合mysql,gorm,redis.jwt

gozero,是一个常见的微服务框架,这里分享一下整合mysql,redis,jwt的相关的代码。

KEELON的博客 80

MySQL__MongoDB__Redis 入门

本文总结了MySQL数据库的基本操作,包括连接数据库、DDL数据定义语言、DML数据操作语言和DQL数据查询语言。主要内容有: 数据库连接与基本操作:展示不同方式的MySQL连接命令,以及创建、查看、删除数据库等基础操作。 数据定义语言(DDL):详细说明表的创建、修改和删除操作,包括列定义、索引创建和表结构调整。 数据操作语言(DML):涵盖数据的插入、更新和删除操作,包括单条/批量处理、条件操作和使用子查询等高级用法。 数据查询语言(DQL):介绍基础查询语法,包括列选择、别名、条件查询、NULL值处理

m0_59041021的博客 250

MySQL 内置函数:日期函数、字符串函数、数学函数、其他函数

【代码】MySQL 内置函数:日期函数、字符串函数、数学函数、其他函数。

Wangshijie1015的博客 269

MySQL 5.7 在 CentOS 7 环境安装:从清理 MariaDB 到初始化与完善配置

MySQL 官方提供了适用于 Linux 系统的 Yum 存储库,这些存储库包含了预编译的 MySQL 软件包及其所有依赖项 为什么要使用 Yum 安装 MySQL? 自动解决依赖关系:Yum 会自动解析并安装 MySQL 运行所需的所有依赖库 版本管理便捷:可以直接通过 Yum 命令升级或降级 MySQL 版本 标准化配置:官方 Yum 源中的 MySQL 包已经针对特定 Linux 发行版进行了优化 2.2 下载 MySQL 官方 Yum 源 访问 MySQL 官方 Yum 存储库页面 MySQL 官方

枫亭湖区的博客 309

MySQL 文件读写函数详解:从 CTF 实战到 LOAD_FILE、INTO OUTFILE、LOAD DATA INFILE 应用

读取服务器文件将查询结果写入文件将数据以原始形式写入文件将服务器文件中的数据导入表和 LOAD DATA INFILE类似,但重点区别是:LOCAL 表示数据文件来自客户端,而不是MySQL服务器。基本格式:文件路径表名;

2303_82039857的博客 249

Spring Boot 3 + Vue 3 全栈外卖系统:RabbitMQ异步解耦、MySQL/Neo4j双引擎推建

后端:Spring Boot 3.2.5 + MyBatis-Plus + Redis + RabbitMQ + Neo4j + 支付宝沙箱前端核心业务覆盖:用户注册登录、菜品浏览、购物车管理、下单结算、支付宝支付、订单状态实时同步、支付成功邮件通知等完整闭环。系统实现了基于用户行为的个性化推荐、基于图数据库的购物车共现推荐、以及基于消息队列的全链路异步解耦。

2303_79635409的博客 512

MySQL 中的事务隔离级别有哪些?

一共4种隔离级别:读未提交、读已提交RC、可重复读RR、串行化;MySQL默认RR;RC每次查询生成ReadView,RR事务首次查询生成ReadView;InnoDB在RR下依靠MVCC+临键锁解决幻读;隔离级别越高一致性越好,并发性能越低。

程序员夏洛的博客 238

MySQL 索引下推(ICP):为什么能少几次表?

MySQL 面试里有个题,单独问的时候不算多,但一问就容易露馅:索引下推(ICP)是什么?很多人能背出"减少表次数"这六个字,再往下就被问住了——为什么能减少?省的是哪一步 IO?它跟覆盖索引又是什么关系?索引下推(Index Condition Pushdown,简称 ICP)是 MySQL 5.6 引入的查询优化。当你用二级索引查数据时,MySQL 会把本该在 server 层做的条件判断,下推到存储引擎层,在数据遍历的那一刻就顺手筛掉,少几次表。

633

MySQL 不同操作系统的安装方式

MySQL Installer 是 Windows 上最简单、最推荐的安装方式,它集成了安装、配置和管理工具,尤其适合新手。:如果安装的是 MySQL 5.7 等旧版本,安装过程中可能会弹出一个对话框,显示临时的 root 默认密码,:安装器会自动检测系统是否缺少必要的依赖(如 Visual C++),并提示安装。(使用强密码加密),这是 MySQL 8.0 引入的更安全的标准。:完整离线版,体积较大,包含所有组件,适合网络不好的环境。,网络安装版,体积小,安装过程中需要联网下载组件。

梦想不只是梦与想的博客 290
上一篇: ETF指数通行红绿灯对接自动交易框架!添加绿灯品种进交易池!股票量化分析工具QTYX-V2.8.9...
下一篇: ETF实盘全自动交易框架升级策略池!增加布林带突破!股票量化分析工具QTYX-V2.9.1...
元宵大师
博客等级 码龄15年 2623粉丝 567原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值