鉴于最近没有空闲时间,本文不定期更新。如果你有更好的想法,你也可以在评论区进行讨论。
[En]
In view of the lack of free time recently, this article is updated from time to time. If you have better ideas, you can also discuss it in the comments area.
目前进度:
2021-07-13 梳理、修改思路
2021-07-14 步骤1代码完成
背景
1、前两篇文章我们分别对股票量化交易策略进行了定义(详见第一篇)、并对A股所有历史行情数据进行了爬取保存以备后续的数据分析(详见第二篇)
2、策略是否有效可行,我们需要根据大量的历史行情数据来进行回测验证。
目标
1、将量化交易策略用于单个股票进行回测,并将回测结果可视化(策略收益趋势、最大回撤幅度),交易日志展现(交易日期、买入/卖出价格、交易金额、收益情况-金额/幅度)
2、将量化交易策略用于多个股票(可自定义股票池)进行回测,并将回测结果可视化(策略总收益趋势、最大回撤幅度),交易日志展现(交易日期、买入/卖出价格、交易金额、收益情况-金额/幅度)
3、优化策略,若发现原策略有缺陷或收益不符合预期,将进行适当的拟合以达到优化目的。
4、若策略验证可行,则开发自动提醒功能,监测股票池中个股的行情走势,出现买卖点时是自动推送邮件到自己的邮箱(股票名、策略建议-出现买入/卖出点、买入/卖出价格、近日行情趋势参考线)。
实现过程简述
量化定义交易策略→定制股票池→编制历史市场数据→策略实施→回测→数据分析
[En]
Quantitative definition of trading strategy → custom stock pool → preparation of historical market data → strategy implementation of → back test → data analysis
策略量化定义
买入点定义:当股价在连续下跌行情中,出现某日突破5日均线时,次日以5日均价挂买
即:设某交易日为N,MA5连续下跌天数为X,当N-1至N-X区间的MA5连续下跌,且N收盘价>N的收盘MA5价,则在N+1日以N+1的开盘MA5价挂买,如图:
卖出点定义:当买入后当日的收盘价未站稳5日均线,或买入之后在某日跌破5日均线的,则次日开盘卖出。
即:设买入日为N,卖出日为M,对N及N之后的每个交易日依次检验收盘价是否低于当日收盘后MA5价,若低于则次日卖出,如图:
具体实现
准备:①第二篇中提到的个股历史行情数据已经爬行,完成了②要求的第三方模块的安装。
[En]
Preparation: the historical market data of individual stocks mentioned in the second article of ① have crawled to complete the installation of the third-party module required by ②.
1、自定义股票池并读取
①创建自定义股票池文件,命名为"stockcodes.csv",将待回测的股票代码复制到文件当中,本次回测股票池将加入所有A股代码,大家可根据需要自行添加股票代码到股票池文件中,例如:
读取:
#步骤-1
#读取股票池CSV文件,返回stockcodes['600010',...]
def ReadCSV(filename):
stockcodes = [] #个股代码列表
count = 0 #个股代码计数
try:
with open(filename,'r') as f:
reader = csv.reader(f)
for row in reader:
stockcodes.append(row[0])
count += 1
print('读取股票池成功:{}'.format(count))
re = 1 #请求继续运行
except:
print('股票池读取失败,检查文件位置及名称:{}'.format(filename))
re = 0 #请求停止运行
return stockcodes,re
②读取数据库中的所有个股表名
#读取数据库STOCK中的所有股票数据表 s_code,返回tablenames['s_600010',...]
def ReadTableName(dbinfo):
tablenames = [] #数据表名列表
#连接数据库
try:
db = pymysql.connect(
host = dbinfo['host'],
user = dbinfo['user'],
password = dbinfo['password'],
database = dbinfo['dbname'],
port = dbinfo['port']
)
cursor = db.cursor()
print('数据库连接成功!正在读取表名...')
re = 1
except:
print('数据库连接失败,请检查数据库信息配置!')
re = 0
if re :
sql_showtables = 'show tables'
cursor.execute(sql_showtables) #查询表名
for tablename in cursor:
tablenames.append(tablename[0])
print('数据表名称读取完成!')
return tablenames,re
③检查数据库中是否已经存在股票池中的股票数据表。如果它不存在,它需要修改股票池或重新爬行数据。
[En]
③ checks whether the stock data table in the stock pool already exists in the database. If it does not exist, it needs to modify the stock pool or re-crawl the data.
#检查股票池中个股数据是否已存在于数据库,返回miss_tablename['600010',...]
def CheckTableName(stockcodes,tablenames):
re = 1
for stockcode in stockcodes:
s_stockcode = 's_'+stockcode
if s_stockcode not in tablenames:
re = 0 #请求中止程序
print('数据表缺失,请检查或重新爬取该个股数据:{}'.format(s_stockcode))
else:
continue
print('股票池与数据表核对完成!')
return re
④步骤1运行函数
#运行步骤-1
def Step_1(filename,dbinfo):
sotckcodes,re = ReadCSV(filename) #读取股票池
if re: #检验是否继续-成功读取股票池
tablenames,re = ReadTableName(dbinfo) #读取表名
if re: #检验是否继续-成功获取数据库表名
re = CheckTableName(sotckcodes,tablenames) #检查是否有表缺失
return sotckcodes,re
2、读取目标个股历史行情数据,返回DataFrame
检验:可回测区间是否超过X+1天
3、计算个股在设定日期区间内的开盘及收盘MA5价格并与行情数据一起保存为新的数据表,命名为 "MA5_股票代码_股票名称"
收盘MA5价格:设某交易日为N,则N的收盘MA5价格=(N的收盘价+N-1的收盘价+...+N-4的收盘价)/5
开盘MA5价格:设某交易日为N,则N的开盘MA5价格=(N的开盘价+N-1的收盘价+...+N-4的收盘价)/5
输入参数:回测开始日期(含当日)、结束日期(含当日)
[En]
Input parameters: start date (including current day) and end date (including current day) of backtest
返回结果:创建数据表保存,字段如下图:
日期收盘价开盘价最低价收盘MA5开盘MA5
4、读取个股"MA5_股票代码_名称"表
返回结果:股票代码,股票名称,['日期','收盘价',....]
5、遍历个股历史行情数据,找到所有策略买入点
传入参数:步骤4"MA5_股票代码表"读取结果、收盘MA5价下跌天数X的配置
返回结果:列表 ['买入点交易日','买入价']
6、根据买入点,找到对应的策略卖出点
传入参数:步骤4"MA5_股票代码_名称"表的读取结果、步骤5返回的结果(买入点列表)
返回结果:代码,名称,列表[['买入点交易日','买入价格','对应卖出点交易日','对应卖出价格'],...]
若买入之后暂未出现对应卖出点,则返回:代码,名称[...,['买入点交易日','买入价格','null','null'],..]
7、找出除权日(此处多谢一位粉丝的提醒)
除权日定义:判断标准为(N-1日收盘价)/(N日收盘价)-100%>11%,即次日跌幅超过11%
说明:以上是对减权日的粗略判断,因为我们爬行到的股价不受动态减权的影响,因此可能会很大程度上影响结果的准确性,所以在本分析中,我们将对减权日期间发生的交易进行擦除,而不进行统计分析。
[En]
Explanation: the above is a rough judgment of the de-weighting date, because the stock price we crawled to is not subject to dynamic de-weighting, so it may greatly affect the accuracy of the results, so in this analysis, we will erase the transactions that occur during the de-weighting date without statistical analysis.
传入参数:步骤4"MA5_股票代码表"的读取结果
返回结果:代码,名称,列表['除权日期']
8、筛除含除权日的交易记录
传入参数:步骤6返回的买卖点对应列表、步骤7返回的除权日列表
如果在购买点交易日和卖点交易日之间存在取消权利的日期,则删除该购买点和相应的卖点
[En]
If there is a de-entitlement date between the buying point trading day and the selling point trading day, delete the buying point and the corresponding selling point
返回结果:
代码,名称,列表[['买入点交易日','买入价格','对应卖出点交易日或null','对应卖出价格或null'],...]
9、生成交易策略表
对所有的"MA5_股票代码_名称表"进行买卖点标记,并合并为一张交易策略表,命名为tactics表
日期股票代码名称开盘价收盘价最低价收盘MA5开盘MA5操作策略买/卖/null
以上为准备工作,接下来我们还需要创建3个表来对资金情况、持仓情况、交易日志进行记录:
account表:记录每日资金变化
position表:记录每日持仓变化
log表:记录交易日志
9、记录资金账户情况,数据保存到数据表"account"(记录每日资金账户相关数据)
数据表初始化:
日期可用资金总资产头寸价值头寸比率年化收益率累计收益率起始日期设定初始资本000000%0.000.00%
[En]
Date available funds total asset position value position ratio annualized rate of return cumulative rate of return start date set initial capital 000000% 0.000.00%
10、记录持仓情况,数据保存到数据表"position"(记录每日持仓相关数据)
数据表初始化:
日期股票代码名称市值收盘价成本数量盈亏幅度盈亏金额每股股0.00%
市值=现价*数量
成本=(Σ买入时股票单价*买入数量) / 总数量
10、记录交易日志,数据保存到数据表"log"(记录每天的交易数据)
数据表初始化:
日期股票代码名称交易行为价格数量结果日期代码名称买入/卖出每股价格交易数量成功/失败
数量示例:买入100股记 "100",卖出100股记 "-100"
结果:"可用资金不足"、"当日最低价未触达挂买价"时将买入失败;"持仓不足卖出时"将卖出失败;
接下来,开始进行回测
11、遍历个股交易日数据,进行回测
读取交易策略表tactics,
读取资金账户表account,
读取持仓表position,
读取日志表log
对tactics交易策略表进行遍历,判断当日是否符合策略交易条件
是:执行买入/卖出操作,更新log(日志表)、position(持仓表)、account(资金账户表)
否:更新position(持仓表)、account(资金账户表)
12、定义执行买入/卖出操作函数
传入参数:单笔交易数(默认100股),策略(买/卖),资金可用余额
买入检验:①当日最低股价应不小于开盘MA5价格;②账户可用资金应不小于本次交易预算
卖出检验:①可用持仓数量应不小于将卖出数量
返回结果:是否买入/卖出 成功 True/False,买入/卖出总金额
接下来我们对回测结果进行数据统计及可视化展示
13、数据统计
策略总胜率:策略交易盈利次数/总交易次数
策略个股胜率:每只股票的策略交易盈利次数/总交易次数
策略平均收益率:Σ每次策略交易盈利率/总交易次数
策略个股平均收益率:每只股票的策略平均收益率
14、数据展示
策略的总收益率趋势图,年化收益率,最大回撤
15、邮件自动推送
实盘监控,出现策略买卖点后推送邮件提醒:股票名、代码、近30日趋势图、建议买入/卖出价
Original: https://blog.csdn.net/weixin_45881406/article/details/118672994
Author: 蟹老板2020
Title: 利用Python进行股票交易分析(三):A股量化交易策略的验证及数据分析。
相关阅读
Title: Jetson系列TensorRT .onnx转.trt/.engine
一、环境配置
Jetson系列加速器如Nano、Xavier在刷机之后是自动安装了TensorRT的,通过如下命令可以检查是否安装成功:
dpkg -l | grep TensorRT
成功显示:
但是可能一开始在conda环境里加载不出来,是因为没有配置好环境。
首先找到tensor.so的位置:
sudo find / -iname "tensorrt.so"
我的位置在这里:
然后进入自己创建的conda用户环境里(/usr/local/archiconda3/envs/pytorch/lib/python3.6/site-packages)建立软连接:
ln -s /usr/lib/python3.6/dist-packages/tensorrt/tensorrt.so tensorrt.so
现在import tensorrt就不会有问题了:
文件转换还需要用到trtexec这个文件,我找了好久原来在这里:
当然它还是无法直接使用的,要在.bashrc文件里添加一下环境变量:
export PATH=/usr/src/tensorrt/bin:$PATH
记得source一下。
现在环境就基本配置好啦!
二、文件转换
在.onnx目录下运行:
.onnx转.trt
import os
import tensorrt as trt
import sys
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
runtime = trt.Runtime(TRT_LOGGER)
model_path = 'XXX.onnx'
engine_file_path = "XXX.trt"
EXPLICIT_BATCH = 1 << (int)(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH) # batchsize=1
builder = trt.Builder(TRT_LOGGER)
network = builder.create_network(EXPLICIT_BATCH)
parser = trt.OnnxParser(network,TRT_LOGGER)
#with trt.Builder(TRT_LOGGER) as builder, builder.create_network(EXPLICIT_BATCH) as network, trt.OnnxParser(network,TRT_LOGGER) as parser:
builder.max_workspace_size = 1 << 28
builder.max_batch_size = 1
print(network)
if not os.path.exists(model_path):
print('ONNX file {} not found.'.format(model_path))
exit(0)
print('Loading ONNX file from path {}...'.format(model_path))
#with open(model_path, 'rb') as model:
model = open(model_path, 'rb')
print('Beginning ONNX file parsing')
if not parser.parse(model.read()):
print('ERROR: Failed to parse the ONNX file.')
for error in range(parser.num_errors):
print('parser.get_error(error)', parser.get_error(error))
#不加下面两行,生成的engine为None
last_layer = network.get_layer(network.num_layers - 1)
network.mark_output(last_layer.get_output(0))
network.get_input(0).shape = [1, 3, 680, 680] #此处记得修改成自己的inputsize
print('Completed parsing of ONNX file')
engine = builder.build_cuda_engine(network)
with open(engine_file_path, "wb") as f:
f.write(engine.serialize())
print('save trt success!!')
.onnx转.engine
trtexec --onnx=XXX.onnx --saveEngine=XXX.trt
可以在后面添加--int8或者--fp16指定精度。
Original: https://blog.csdn.net/qq_41847894/article/details/124132989
Author: Jodie大白话
Title: Jetson系列TensorRT .onnx转.trt/.engine

基于IMDB评论数据集的情感分析

python-opencv学习笔记(八):判断是否雾天与图像能见度测算

python||判断K-Means聚类最佳数量

李宏毅《深度学习》- Self-attention 自注意力机制

数据增强之Mosaic数据增强的优点、Mixup,Cutout,CutMix的区别

简洁优美的深度学习包-bert4keras

python+keras汉字单字语音识别

电商常用三大数据分析模型–深入浅出

Vision-Transformer详解

【OpenCV 例程200篇】223. 特征提取之多边形拟合(cv.approxPolyDP)

【网络流量识别】【聚类】【二】FCM和GMM—使用聚类技术和性能比较进行网络流量异常检测

语音识别模型网络结构_语音识别端到端模型解读:FSMN及其变体模型

Series转化为DataFrame数据

CONTINUAL SELF-TRAINING WITH BOOTSTRAPPED REMIXING FOR SPEECH ENHANCEMENT
