柒拾- tushare 模拟策略交易 (一)

2024-03-06 21:04

本文主要是介绍柒拾- tushare 模拟策略交易 (一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、背景

过年无聊在家,想上网获取各公司的损益表,结果搜着搜着看到一个平台好像有些数据,平台叫 《Tushare》。
然后看着看着里面的文档,诶 ~ 居然有模拟交易 ~~ ,但看着看着,发现里面居然没有完整代码。
于是自己照着他的来学习一下啥是量化分析。

二、建个数据库

首先装好 MySQL ,然后按照文章上的内容先建好各种表:

/**Descripttion:*Version: 1.0*Author: BerryBC*Date: 2024-03-06 18:48:28*LastEditors: BerryBC*LastEditTime: 2024-03-06 19:02:26
*/
-- --------------------------------------------------------
-- 主机:                           127.0.0.1
-- 服务器版本:                        8.0.12 - MySQL Community Server - GPL
-- 服务器操作系统:                      Win64
-- HeidiSQL 版本:                  11.1.0.6116
-- --------------------------------------------------------/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET NAMES utf8 */;
/*!50503 SET NAMES utf8mb4 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;-- 导出 db_tushare_stock 的数据库结构
CREATE DATABASE IF NOT EXISTS `db_tushare_stock` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `db_tushare_stock`;-- 导出  表 db_tushare_stock.tb_all_stock_list 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 这个是存全量股票的
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_all_stock_list` (`ind` int(11) DEFAULT NULL,`ts_code` varchar(50) DEFAULT NULL COMMENT 'TS代码',`symbol` varchar(50) DEFAULT NULL COMMENT '股票代码',`name` varchar(200) DEFAULT NULL COMMENT '股票名称',`area` varchar(100) DEFAULT NULL COMMENT '地域',`industry` varchar(200) DEFAULT NULL COMMENT '所属行业',`fullname` varchar(400) DEFAULT NULL COMMENT '股票全称',`enname` varchar(400) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '英文全称',`cnspell` varchar(200) DEFAULT NULL COMMENT '拼音缩写',`market` varchar(200) DEFAULT NULL COMMENT '市场类型',`exchange` varchar(200) DEFAULT NULL COMMENT '交易所代码',`curr_type` varchar(50) DEFAULT NULL COMMENT '交易货币',`list_status` varchar(50) DEFAULT NULL COMMENT '上市状态 L上市 D退市 P暂停上市',`list_date` varchar(50) DEFAULT NULL COMMENT '上市日期',`delist_date` varchar(50) DEFAULT NULL COMMENT '退市日期',`is_hs` varchar(50) DEFAULT NULL COMMENT '是否沪深港通标的,N否 H沪股通 S深股通',`act_name` varchar(400) DEFAULT NULL COMMENT '实控人名称',`act_ent_type` varchar(200) DEFAULT NULL COMMENT '实控人企业性质'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_bt_daily_cfg 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 存回测策略的记录表
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_bt_daily_cfg` (`bt_ind` int(11) DEFAULT NULL,`bt_title` varchar(200) DEFAULT NULL,`bt_desc` text,`bt_init_cash` float DEFAULT NULL,`bt_time` timestamp NULL DEFAULT NULL,UNIQUE KEY `bt_ind` (`bt_ind`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_bt_daily_my_capital 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 存每次交易数据
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_bt_daily_my_capital` (`capital` float DEFAULT NULL COMMENT '总资产',`money_lock` float DEFAULT NULL COMMENT '股票资产',`money_rest` float DEFAULT NULL COMMENT '现金资产',`deal_action` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '交易动作',`stock_code` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '股票代码',`deal_price` float DEFAULT NULL COMMENT '成交价',`stock_vol` int(11) DEFAULT NULL COMMENT '成交量',`profit` float DEFAULT NULL COMMENT '收益额',`profit_rate` float DEFAULT NULL COMMENT '收益率',`comment` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '备注',`state_dt` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '交易日期',`seq` int(11) NOT NULL AUTO_INCREMENT COMMENT '序号(用作表主键)',`bt_ind` int(11) DEFAULT NULL,UNIQUE KEY `seq` (`seq`),KEY `bt_ind` (`bt_ind`),KEY `state_dt_bt_ind` (`state_dt`,`bt_ind`)
) ENGINE=InnoDB AUTO_INCREMENT=5681 DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_bt_daily_tmp_my_stock_pool 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 当此回测的当前持仓
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_bt_daily_tmp_my_stock_pool` (`stock_code` varchar(50) DEFAULT NULL COMMENT '股票代码',`buy_price` float DEFAULT NULL COMMENT '买入价',`hold_vol` int(11) DEFAULT NULL COMMENT '持仓量(单位:股)',`hold_days` int(11) DEFAULT NULL COMMENT '持仓天数(只计算交易日)',`bt_ind` int(11) DEFAULT NULL,KEY `bt_ind` (`bt_ind`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_bt_mid_daily_period_trend 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 中间表 - 简单 By 天计算趋势
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_bt_mid_daily_period_trend` (`DAY_GAP` bigint(20) DEFAULT NULL,`END_DATE` longtext CHARACTER SET latin1,`TS_CODE` varchar(50) DEFAULT NULL COMMENT 'TS代码',`NAME` varchar(200) DEFAULT NULL COMMENT '股票名称',`INDUSTRY` varchar(200) DEFAULT NULL COMMENT '所属行业',`EXCHANGE` varchar(200) DEFAULT NULL COMMENT '交易所代码',`TRADE_DAY` bigint(21) DEFAULT NULL,`MIN_COLSE` float DEFAULT NULL,`MAX_COLSE` float DEFAULT NULL,`MIN_PCT_CHG` float DEFAULT NULL,`MAX_PCT_CHG` float DEFAULT NULL,`DOWN_DAY` bigint(21) DEFAULT NULL,`UP_DAY` bigint(21) DEFAULT NULL,`BEGIN_CLOSE` float DEFAULT NULL,`END_CLOSE` float DEFAULT NULL,`ALL_PCT_CHG` double DEFAULT NULL,`UP_DAY_PCT` decimal(24,4) DEFAULT NULL,`DOWN_DAY_PCT` decimal(24,4) DEFAULT NULL,`END_CLOSE_PCT_C` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_calendar 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 计算交易日期
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_calendar` (`trade_date` varchar(50) DEFAULT NULL COMMENT '交易日期',`trade_date_dt` timestamp NULL DEFAULT NULL COMMENT '交易日期(日期格式)'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_cfg 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 整体配置
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_cfg` (`field_key` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,`field_value` varchar(200) DEFAULT NULL,`update_date` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。-- 导出  表 db_tushare_stock.tb_daily_stock_quote 结构
-- -*-*-*-*-*-*-*-*-*-*-*-*
-- 股票行情,直接获取
-- -*-*-*-*-*-*-*-*-*-*-*-*
CREATE TABLE IF NOT EXISTS `tb_daily_stock_quote` (`ts_code` varchar(50) DEFAULT NULL COMMENT '股票代码',`trade_date` varchar(50) DEFAULT NULL COMMENT '交易日期',`open` float DEFAULT NULL COMMENT '开盘价',`high` float DEFAULT NULL COMMENT '最高价',`low` float DEFAULT NULL COMMENT '最低价',`close` float DEFAULT NULL COMMENT '收盘价',`pre_close` float DEFAULT NULL COMMENT '昨收价',`change` float DEFAULT NULL COMMENT '涨跌额',`pct_chg` float DEFAULT NULL COMMENT '涨跌幅',`vol` float DEFAULT NULL COMMENT '成交量',`amount` float DEFAULT NULL COMMENT '成交额',KEY `ts_code` (`ts_code`),KEY `ts_code_trade_date` (`ts_code`,`trade_date`),KEY `trade_date` (`trade_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 数据导出被取消选择。/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

三、获取数据

需要看着文档来获取,在网站上注册完后,填完个人信息,就可以参考数据获取文章得到数据了。
为了方便,我封装了对数据库的操作以及简单的 Tushare 的调用。
代码如下:

'''
Descripttion: 数据库链接库
Version: 1.0
Author: BerryBC
Date: 2024-02-18 12:12:35
LastEditors: BerryBC
LastEditTime: 2024-03-06 19:27:53
'''import datetime
import time
import mysql.connector
from sqlalchemy import create_engine
import tushareclass claDBConn(object):def __init__(self):'''description: 初始化'''# 以下信息为系统配置赋值self.strDBPW = 'WatsonsBI'self.strDBUser = 'Berry'self.strPort = 1988self.strDBName = 'db_tushare_stock'self.strDBHost = '127.0.0.1'self.ts = tushare.pro_api('3245fd623dfsdf3hsfajhkh23k4jh34k52345ljh234o5h234io5uh345kljh')def RunSQLOnce(self, strSQL):'''description: 就单独运行一次代码param: strSQL 传入代码'''conn = mysql.connector.connect(host=self.strDBHost, user=self.strDBUser, password=self.strDBPW, port=self.strPort, database=self.strDBName)cursor = conn.cursor()cursor.execute(strSQL)conn.commit()cursor.close()conn.close()return Truedef ReturnSQLData(self, strSQL):'''description: 根据代码返回数据param: strSQL 传入代码return: {list}  返回输出的表, 以数组形式'''conn = mysql.connector.connect(host=self.strDBHost, user=self.strDBUser, password=self.strDBPW, port=self.strPort, database=self.strDBName)cursor = conn.cursor()cursor.execute(strSQL)listDataTable = cursor.fetchall()cursor.close()conn.close()return listDataTabledef RetrunDBEngine(self):'''description: 创建引擎'''engMySQL = create_engine('mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(self.strDBUser, self.strDBPW, self.strDBHost, self.strPort, self.strDBName))return engMySQLdef RefreshDailyQuote(self):'''description: 更新数据库中的日数据return: {int}   0 成功1 失败'''# 创建链接字符strDBEng=self.RetrunDBEngine()# 查询数据库最 Update 的时间strSQLMaxDate = "SELECT MAX(field_value) FROM tb_cfg WHERE field_key='DailyQuoteDate'"listMaxDate = self.ReturnSQLData(strSQLMaxDate)intMaxStartDate = ''# 如果不存在则从 2000年开始提取if listMaxDate is not None and listMaxDate[0][0] is not None:intMaxStartDate = listMaxDate[0][0]else:intMaxStartDate = '20000101'# intMaxStartDate = '20240101'# 获取日期的 GapdateStart = datetime.datetime.strptime(intMaxStartDate, "%Y%m%d")dateEnd = datetime.datetime.now()intDayGap = (dateEnd - dateStart).days# 循环获取if intDayGap > 0 :for intDayAdd in range(intDayGap):strQueryDate = (dateStart+datetime.timedelta(days=(intDayAdd+1))).strftime('%Y%m%d')dfDateF = self.ts.daily(**{"ts_code": "","trade_date": "","start_date": strQueryDate,"end_date": strQueryDate,"offset": "","limit": ""}, fields=["ts_code","trade_date","open","high","low","close","pre_close","change","pct_chg","vol","amount"])dfDateF.to_sql('tb_daily_stock_quote', strDBEng, index=False, if_exists='append', chunksize=5000)time.sleep(0.1)print('Done - '+ strQueryDate + str(datetime.datetime.now()))# 更新当前最新时间strSQLDataMaxDate = "SELECT max(trade_date) FROM tb_daily_stock_quote"listDataMaxDate = self.ReturnSQLData(strSQLDataMaxDate)# 如果存在最新的数据,则记录,这里反复记录也没所谓if listDataMaxDate is not None and listDataMaxDate[0][0] is not None:intMaxStartDate = listDataMaxDate[0][0]strInsertMaxDataDateSQL="INSERT INTO tb_cfg (field_key, field_value,update_date) VALUES ('DailyQuoteDate', '"+intMaxStartDate+"' ,now());"self.RunSQLOnce(strInsertMaxDataDateSQL)strDBEng.dispose()return Truedef FixCalDay(self):'''description: 重新计算一个日历'''strTruncateCal="TRUNCATE TABLE tb_calendar"self.RunSQLOnce(strTruncateCal)strInsertCal="INSERT INTO tb_calendar SELECT trade_date,STR_TO_DATE(trade_date,'%Y%m%d') FROM tb_daily_stock_quote GROUP BY trade_date ORDER BY trade_date ASC"self.RunSQLOnce(strInsertCal)return Truedef GetAllStockBaseInfo(self):'''description: 更新股票基本信息'''# 创建链接字符strDBEng=self.RetrunDBEngine()# 清空原表strCleanTable='TRUNCATE TABLE tb_all_stock_list'self.RunSQLOnce(strCleanTable)# 插入获取的信息表dfDateF = self.ts.stock_basic(**{"ts_code": "","name": "","exchange": "","market": "","is_hs": "","list_status": "","limit": "","offset": ""}, fields=["ts_code","symbol","name","area","industry","cnspell","market","list_date","act_name","act_ent_type","fullname","enname","exchange","curr_type","list_status","delist_date","is_hs"])dfDateF.to_sql('tb_all_stock_list', strDBEng, index=False, if_exists='append', chunksize=5000)return True

四、简单更新数据

通过代码,调用一下就可以更新数据了

from Lib.DBConn import claDBConn# 创建对象
dbConn = claDBConn()
# 获取基础的股票列表
dbConn.GetAllStockBaseInfo()
# 更新 By Day 的股票走势
dbConn.RefreshDailyQuote()
# 计算交易日期
dbConn.FixCalDay()

这里我就要吐槽一下,为什么交易日历的 API https://tushare.pro/document/2?doc_id=26 是要 2000 积分?
反而获取行情倒只需要 200分?
所以只能自己在 SQL 计算一下交易日期自己创建一个表

五、模拟交易

好了,老婆回来了,我得跟她去吃饭了,再见
说真的,股票行情这东西对于我来说也不会用,我其实是想要他获取各公司损益表的数据的,但需要积分是 2000积分
等我真要用的时候我再捐款给他们获取积分呗~不过学习一下其他东西倒挺好玩的

这篇关于柒拾- tushare 模拟策略交易 (一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/781338

相关文章

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

Redis的数据过期策略和数据淘汰策略

《Redis的数据过期策略和数据淘汰策略》本文主要介绍了Redis的数据过期策略和数据淘汰策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录一、数据过期策略1、惰性删除2、定期删除二、数据淘汰策略1、数据淘汰策略概念2、8种数据淘汰策略

SpringBoot中的404错误:原因、影响及解决策略

《SpringBoot中的404错误:原因、影响及解决策略》本文详细介绍了SpringBoot中404错误的出现原因、影响以及处理策略,404错误常见于URL路径错误、控制器配置问题、静态资源配置错误... 目录Spring Boot中的404错误:原因、影响及处理策略404错误的出现原因1. URL路径错

Redis多种内存淘汰策略及配置技巧分享

《Redis多种内存淘汰策略及配置技巧分享》本文介绍了Redis内存满时的淘汰机制,包括内存淘汰机制的概念,Redis提供的8种淘汰策略(如noeviction、volatile-lru等)及其适用场... 目录前言一、什么是 Redis 的内存淘汰机制?二、Redis 内存淘汰策略1. pythonnoe

Python 中 requests 与 aiohttp 在实际项目中的选择策略详解

《Python中requests与aiohttp在实际项目中的选择策略详解》本文主要介绍了Python爬虫开发中常用的两个库requests和aiohttp的使用方法及其区别,通过实际项目案... 目录一、requests 库二、aiohttp 库三、requests 和 aiohttp 的比较四、requ

Redis过期键删除策略解读

《Redis过期键删除策略解读》Redis通过惰性删除策略和定期删除策略来管理过期键,惰性删除策略在键被访问时检查是否过期并删除,节省CPU开销但可能导致过期键滞留,定期删除策略定期扫描并删除过期键,... 目录1.Redis使用两种不同的策略来删除过期键,分别是惰性删除策略和定期删除策略1.1惰性删除策略

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

usaco 1.2 Transformations(模拟)

我的做法就是一个一个情况枚举出来 注意计算公式: ( 变换后的矩阵记为C) 顺时针旋转90°:C[i] [j]=A[n-j-1] [i] (旋转180°和270° 可以多转几个九十度来推) 对称:C[i] [n-j-1]=A[i] [j] 代码有点长 。。。 /*ID: who jayLANG: C++TASK: transform*/#include<

hdu4431麻将模拟

给13张牌。问增加哪些牌可以胡牌。 胡牌有以下几种情况: 1、一个对子 + 4组 3个相同的牌或者顺子。 2、7个不同的对子。 3、13幺 贪心的思想: 对于某张牌>=3个,先减去3个相同,再组合顺子。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOExcepti