多股回测(backtrader+quantstats+akshare)

导包

#引入技术指标数据
from __future__ import (absolute_import ,division,print_function,unicode_literals)
import datetime #用于datetime对象操作
import os.path  #用于管理路径
import sys      #用于在argvTo[0]中找到脚本名称
import backtrader as bt #引入backtrader框架
%matplotlib inline

策略

#创建策略
class TestStrategy(bt.Strategy):params = (('maperiod1',5),('maperiod2',13),('maperiod3',21),('maperiod4',34),('maperiod5',55),('printlog',True),('poneplot' , False),#是否打印到同一张图('pstake' , 100000) #单笔交易股票数据)def log(self,txt,dt=None,doprint = False):dt = dt or self.datas[0].datetime.date(0)#print('%s,%s' % (dt.isoformat(),txt))"""策略的日志函数"""if self.params.printlog or doprint:dt = dt or self.datas[0].datetime.date(0)print('%s,%s' % (dt.isoformat(),txt))def __init__(self):self.inds = dict()for i, d in enumerate(self.datas):self.inds[d] = dict()self.inds[d]['ma1'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod1)self.inds[d]['ma2'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod2)self.inds[d]['ma3'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod3)self.inds[d]['ma4'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod4)self.inds[d]['ma5'] = bt.indicators.SimpleMovingAverage( d.close,period = self.params.maperiod5)self.inds[d]['D1'] = bt.ind.CrossOver(self.inds[d]['ma5'],self.inds[d]['ma4']) #交叉信号self.inds[d]['A1'] = bt.ind.CrossOver(self.inds[d]['ma1'],self.inds[d]['ma2']) #交叉信号   self.inds[d]['C1'] = bt.ind.CrossOver(self.inds[d]['ma2'],self.inds[d]['ma3'])#跳过第一只股票data,第一只股票data作为主图数据if i > 0:if self.p.poneplot:d.plotinfo.plotmaster = self.datas[0]def notify_trade(self,trade):if not trade.isclosed:returnself.log('OPERATION PROFIT,GROSS %.2F,NET %.2F' %(trade.pnl,trade.pnlcomm))#多股回测时使用,数据读取。 def prenext(self):self.next()def next(self):# 获取当天日期date = self.datas[0].datetime.date(0)# 获取当天valuevalue = self.broker.getvalue()for i , d in enumerate(self.datas):            dt,dn = self.datetime.date(),d._name             #获取时间及股票代码        pos = self.getposition(d).size sig1 = ((self.inds[d]['D1'][-1]>0) and (self.inds[d]['A1'][0]>0)) and (self.inds[d]['ma2'][0] >self.inds[d]['ma4'][0])and (self.inds[d]['ma4'][0] >self.inds[d]['ma4'][-1])sig2 = ((self.inds[d]['D1'][-1]>0)  or (self.inds[d]['A1'][0]>0 ))and(self.inds[d]['ma2'][0] >self.inds[d]['ma2'][-1])and(d.close[0]/d.open[0]>1.05)and(d.volume[0] /d.volume[-1]>2)sig3 = ((self.inds[d]['D1'][-1]>0)  or (self.inds[d]['A1'][0]>0 ))and(self.inds[d]['ma2'][0] >self.inds[d]['ma3'][0] )and(self.inds[d]['ma3'][0] >self.inds[d]['ma4'][0] )and(self.inds[d]['ma4'][0] >self.inds[d]['ma4'][-1] )sig4 = self.inds[d]['C1'][0]<0#print('sig1',sig1)if not pos:                                      # 不在场内,则可以买入  vol成交量, ref日前if sig1 or sig2 and sig3: #如果金叉self.buy(data =d,size =self.p.pstake)    #买self.log('%s,BUY CREATE, %.2f ,%s' % (dt, d.close[0] ,d._name))#self.order = self.buy()elif sig4:              #在场内。且死叉self.close(data = d)                     #卖self.log('%s,SELL CREATE,%.2f,%s' % (dt, d.close[0] ,d._name))#self.order = self.sell()

印花税

class stampDutyCommissionScheme(bt.CommInfoBase):params = (('stamp_duty',0.005),#印花税率('percabs',True),)def _gotcommission(self,size,price,pseudoexec):if size >0:#买入,不考虑印花税return size*price * self.p.commissionelif size<0:#卖出,考虑印花税return -size*price*(self.p.stamp_duty + self.p.commission)else:return 0

开始回测

#创建cerebro实体
cerebro = bt.Cerebro()
#添加策略
cerebro.addstrategy(TestStrategy)

添加数据

#创建价格数据
import akshare as ak
import baostock as bs
import pandas as pd
import datetime#获取股票池数据
from os import listdir
filename = listdir('D:/stock_data')
stk_pools = filenamefor i in stk_pools[:]:try:datapath = 'D:/stock_data/'+idf = pd.read_csv('D:/stock_data/'+i)#将数据长度不足的股票删去if len(df)<55:passelse:try:data = bt.feeds.GenericCSVData(dataname = datapath,fromdate = datetime.datetime(2010,4,1),todate = datetime.datetime(2021,7,8),nullvalue = 0.0,dtformat = ('%Y-%m-%d'),datetime = 1,open =2,high = 3,low = 4,close = 5,volume = 6,openinterest = -1)cerebro.adddata(data,name = i)except:continue except:continue

 设置参数

#设置启动资金
cerebro.broker.setcash(len(stk_pools[:50])*10000)
#设置交易单位大小
cerebro.addsizer(bt.sizers.FixedSize,stake = 100)
#设置佣金为千分之一
comminfo = stampDutyCommissionScheme(stamp_duty=0.005,commission=0.001)
cerebro.broker.addcommissioninfo(comminfo)
#不显示曲线
for d in cerebro.datas:d.plotinfo.plot = False
#打印开始信息
print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

回测数据分析

#查看策略效果
cerebro.addanalyzer(bt.analyzers.PyFolio, _name='pyfolio')
back  = cerebro.run(maxcpus=12,exactbars=True,stdstats=False)import warnings
warnings.filterwarnings('ignore')
strat = back[0]
portfolio_stats = strat.analyzers.getbyname('pyfolio')
returns, positions, transactions, gross_lev = portfolio_stats.get_pf_items()
returns.index = returns.index.tz_convert(None)import quantstats
quantstats.reports.html(returns, output='stats.html', title='Stock Sentiment')import webbrowser
f = webbrowser.open('stats.html')
#打印最后结果
print('Final Profolio Value : %.2f' %cerebro.broker.getvalue())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cron表达式、定时任务

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Cron表达式。但这个表示式本身就够复杂了。下面会有说明。 例子&#xff1a; cronSchedule("0 0/2 8-17 * * ?") // 每天8:0…

【转载】ASP.NET自定义404和500错误页面

在ASP.NET网站项目实际上线运行的过程中&#xff0c;有时候在运行环境下会出现400错误或者500错误&#xff0c;这些错误默认的页面都不友好&#xff0c;比较简单单调&#xff0c;其实我们可以自行设置这些错误所对应的页面&#xff0c;让这些错误跳转到我们指定的路径。此文将介…

年薪15万的80后小本科:只要6分钟,告诉你少走6年弯路

这个社会是很残酷的&#xff0c;尤其是对于那些刚刚步入社会的80后而言。当很多人都在抱怨这个社会竞争压力太大、没有自己的追求&#xff0c;并因此而丧失斗志的时候&#xff0c;一个年薪15W的80后小本却发出了这个的感慨&#xff0c;“一个人的成就&#xff0c;与岁月无关&am…

Google Go Programming In Eclipse

http://www.tutorialsavvy.com/2013/04/google-go-programming-in-eclipse.html/ Google Go Programming In Eclipse The new “Go” programming language is from Google co.It has many features better then other languages.Go language features are:-– High Speed Comp…

pycharm打开ipynb显示为文本格式解决办法

然后进入 添加类型 jupyter notebook 然后下方添加 *.ipynb

quartz各版本MySQL数据库存储建表SQL语句

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 用quartz管理任务计划很方便&#xff0c;但是当使用数据库作为存储介质的时候&#xff0c;必须要先创建表&#xff0c;不然就会报错。1.…

[基础篇]ESP32-RTOS-SDK教程(一)之Windows环境搭建

当下正是物联网最好的时代&#xff0c;学习新的技术怎么能只学习ESP8266呢&#xff1f;要知道ESP8266还有一个孪生兄弟呢&#xff0c;最重要的是这个孪生兄弟要比ESP8266是更厉害的&#xff0c;所以我们也是非常有必要学习一下的&#xff0c;其实这篇文章去年就已经写了&#x…

对话Linus Torvalds:大多黑客甚至连指针都未理解

摘要&#xff1a;Linus Torvalds坦言那些狡诈的通过文件名查找高速缓存&#xff0c;然后又抱怨自己能力一般的内核“恶魔”才是他欣赏的&#xff1b;相反&#xff0c;很多人连低水平的内核编程都还没学好。 几周前&#xff0c; Linus Torvalds在Slashdot上回答了一些问题。其中…

总结学习(提纲)

之前在私募做期权量化学习了那么久&#xff0c;趁着毕业找工作这段时间&#xff0c;对之前学习的东西&#xff0c;制作的函数等进行一个系统性的总结&#xff0c;顺便每天更新的时候&#xff0c;记录下自己的体重与波比跳次数。 1.MC的学习与策略编写 2.python基础学习资料的…

安卓系统上的远程 JS 调试 Remote JavaScript Debugging on Android

每当在 Android 移动设备上调试网页时&#xff0c;开发人员往往都会不自觉陷入调试的泥潭中去。《Android开发指南》提供了一个解决方案&#xff0c;却有点繁琐复杂。因此&#xff0c;许多 Web 开发人员会倾向于使用类似 Firefox Firebug 的或像 WebKit 的 Web Inspector 之类的…

js关于表单校验完善

<!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title>注册页面</title> <style type"text/css"> .left{ width: 100px; …

Python高效编程技巧

摘要&#xff1a;作者有多年的Python编程经验&#xff0c;并且有很多的编程小技巧和知识&#xff0c;其中大多数是通过阅读很流行的开源软件&#xff0c;如Django, Flask, Requests中获得的。 我已经使用Python编程有多年了&#xff0c;即使今天我仍然惊奇于这种语言所能让代码…

quartz 任务调试 建表 sql 语句、create table语句

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; DROP TABLE IF EXISTS QRTZ_SCHEDUL…

关于ttk的使用与安装

ttk是tkinter中的子模块&#xff0c;在python2.x中是作为独立模块。但是在python3.x中则是成为了tkinter的子模块&#xff0c;因此调用时&#xff0c;转变为 from Tkinter import ttk

SEO艺术

SEO艺术 编辑推荐 在本书中&#xff0c;四位搜索引擎优化&#xff08;SEO&#xff09;领域最受瞩目的专家阐述了制订以及执行一个完善的SEO策略时应遵循的一些实用指南与最新技术。 基本信息 原书名&#xff1a; The Art of SEO原出版社&#xff1a; OReilly作者&#xff1a; (…

ActiveMQ支持的传输协议

连接到ActiveMQ Connector:ActiveMQ提供的&#xff0c;用来实现连接通信的功能。包括:client-to-broker、broker-to-broker。ActiveMQ允许客户端使用多种协议来进行连接。 client-to-broker模式一般是配置文件中的transportConnector配置 broker-to-broker:一般是指网络(networ…

http状态码301和302详解及区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 一直对http状态码301和302的理解比较模糊&#xff0c;在遇到实际的问题和翻阅各种资料了解后&#xff0c;算是有了一定的理解。这里记录下…

哪些编程语言需要修复?

摘要&#xff1a;编程语言有十全十美的吗&#xff1f;每种语言都有缺陷吗&#xff1f;这不&#xff0c;Java、C、C、Python都中枪了。语言之间也可相互“掐架”&#xff0c;一起来看下。 原文作者Kevin Kelleher采用一种比较新颖的方式来比较编程语言&#xff1a;即描述每个编程…

时间修改,学习

设定时间格式 import datetime print datetime.datetime.now().strftime("%Y-%m-%d %H:%M") # 2018-05-08 16:54 时间增加 import datetime print (datetime.datetime.now()datetime.timedelta(days1)).strftime("%Y-%m-%d %H:%M:%S") days改为hours m…

Python标准库

《Python标准库》基本信息原书名&#xff1a; The Python Standard Library by Example 原出版社&#xff1a; Pearson Education 作者&#xff1a; (美)Doug Hellmann 译者&#xff1a; 刘炽 出版社&#xff1a;机械工业出版社 ISBN&#xff1a;9787111378105上架时间&#xf…