搞一个简单的交易策略回测(难点的我也不会啊)。此策略基于布林通道,当股价低于布林通道下轨线且持仓为0时,以下轨线价格全仓买入(不关心风险,反正也不要本钱)。当股价突破布林线上轨且有持仓时,以上轨线价格清仓卖出。(期间也没有考虑交易的费用)

首先,从MySQL数据库读取已经下载好的股票历史数据,我用的库名是stock_databases。股票就随便选一个。

from sqlalchemy import create_engine
import pandas as pddef calculate_boll(code):# 用于数据读取的表字段columns = 'date, open, high, low, close, volume'# 连接数据库引擎对象engine = create_engine("mysql+pymysql://root:123456@localhost:3306/stock_databases?charset=utf8")# 读取数据df = pd.read_sql('SELECT {} FROM {}_{}'.format(columns, code[:2], code[3:]),con=engine,index_col='date')print(df.info())calculate_boll('sh.600478')

读取的数据如下图

数据类型在我保存到数据库之前就做了相应的处理,接着计算布林通道:

from sqlalchemy import create_engine
import pandas as pddef calculate_boll(code):# 用于数据读取的表字段columns = 'date, open, high, low, close, volume'# 连接数据库引擎对象engine = create_engine("mysql+pymysql://root:123456@localhost:3306/stock_databases?charset=utf8")# 读取数据df = pd.read_sql('SELECT {} FROM {}_{}'.format(columns, code[:2], code[3:]),con=engine,index_col='date')# 计算标准差standard_deviations = df['close'].rolling(20).std(ddof=1)# 添加布林通道的上轨、下轨和中轨df['md'] = round(df['close'].rolling(20).mean(), 2)df['upper'] = round(df['md'] + 2 * standard_deviations, 2)df['lower'] = round(df['md'] - 2 * standard_deviations, 2)return df

有了布林通道的数据后,就可以通过比较最高价、最低价与上下轨的大小来确定交易信号。

import numpy as np
import pandas as pd
from sqlalchemy import create_enginedef trade_signal(code):"""计算交易信号,当股价低于布林下轨时买入,高于上轨时卖出:param code: 股票代码:return: 包含交易信号的DataFrame"""data = calculate_boll(code)# 新建一个DataFrame,以data的index为indexdf = pd.DataFrame(index=data.index)df[['price', 'upper', 'lower']] = data[['close', 'upper', 'lower']]# 比较最高价、最低价与BOLL上下轨的大小来确定突破信号df['buy_signal'] = np.where(data['low'] < data['lower'], True, False)df['sell_signal'] = np.where(data['high'] > data['upper'], True, False)# 初始化订单状态为0df['orders'] = 0# 初始仓位为0position = 0# 遍历数据表for i in range(len(df)):# 当买入信号为True且仓位为0时买入if df.buy_signal[i] and position == 0:# 买入指令为1df.orders.values[i] = 1# 仓位加1position = 1# 当卖出信号为True且仓位为1时卖出elif df.sell_signal[i] and position == 1:# 卖出指令为-1df.orders.values[i] = -1# 仓位清0position = 0return df

有了交易指令,就可以买进卖出了。当指令为1且持仓为0时,以布林下轨价格全仓买入。当指令为-1且有持仓时,以布林上轨价格清仓卖出。

def calculate_income(code):"""计算收益:param code: 股票代码:return: 计算后的DataFrame"""data = trade_signal(code)# 初始最大可持仓量,可用资金为100000元max_position = 0money = 100000.0# 初始持仓股票手数、可用资金data['stock'] = 0data['money'] = 100000.0for i in range(len(data)):# 当买卖指令为1if data.orders.values[i] == 1:# 以下轨价全仓买入max_position = money // (data.lower.values[i] * 100)# 可用资金减去买入股票所花费的资金money = money - max_position * data.lower.values[i] * 100# 当买卖指令为-1elif data.orders.values[i] == -1:# 可用资金加上卖出股票所得到的资金money = money + max_position * data.upper.values[i] * 100# 持仓清零max_position = 0# 持仓手数、可用资金data['stock'].values[i] = max_positiondata['money'].values[i] = money# 账户资产总额data['total'] = data['stock'] * data['price'] * 100 + data['money']return data

查看一下对不对

如上图所示,2022年8月31日,交易指令为1,全仓买入,狠狠的干了一票。再看'total'列,账户总资产从最初的100000元变成了现在的560000+元(当然我没有考虑交易费用等等之类因素)。乍一看好像还不错,实际上行不行的通?用matplotlib可视化来看一看。

def plt_show(code):"""数据可视化:param code:股票代码:return: None"""# 用来正常显示中文字体plt.rcParams['font.sans-serif'] = ['KaiTi']# 解决负号显示为方块的问题plt.rcParams['axes.unicode_minus'] = Falsedata = calculate_income(code)# 设置画布大小plt.figure(figsize=(10, 6))# 设置标签plt.title('{}布林策略收益图'.format(code))plt.xlabel('日期')plt.ylabel('股价')# 绘制股价、布林上轨和下轨的折线图plt.plot(data.index, data.price, color='black', label='股价')plt.plot(data.index, data.upper, color='blue', label='上轨')plt.plot(data.index, data.lower, color='pink', label='下轨')# 用红色正三角标记买入点plt.scatter(data.loc[data.orders == 1].index, data['lower'][data.orders == 1],marker='^', c='r', s=80, label='买入')# 用绿色倒三角标记卖出点plt.scatter(data.loc[data.orders == -1].index, data['upper'][data.orders == -1],marker='v', c='g', s=80,label='卖出')# 图例放在左上角plt.legend(loc='upper left')# 绘制双坐标plt.twinx()# 绘制收益折线图plt.plot(data.index, data.total, color='red', label='总资产')# 图例放在右上角plt.legend(loc='upper right')plt.show()

请看图

这个。。。。看起来好乱啊!从图中可以看出这是近20年的数据。注意图中红线,从18年开始就脱离了股价噌噌往上,显得有些不真实,是不是我哪里计算错了?

再来放大看看 这个回撤的幅度容易把心脏挤爆

再换一个股票看看

这个看起来好很多,看起来也真实。

完整代码:

from sqlalchemy import create_engine
import pandas as pd
import numpy as np
from matplotlib import pyplot as pltdef calculate_boll(code):"""计算BOLL通道:param code:股票代码:return:添加了BOLL数值的DataFrame"""# 用于数据读取的表字段columns = 'date, open, high, low, close, volume'# 连接数据库引擎对象engine = create_engine("mysql+pymysql://root:123456@localhost:3306/stock_databases?charset=utf8")# 读取数据df = pd.read_sql('SELECT {} FROM {}_{}'.format(columns, code[:2], code[3:]),con=engine, index_col='date')# 计算标准差standard_deviations = df['close'].rolling(20).std(ddof=1)# 添加布林通道的上轨、下轨和中轨.这里注意:下面的保留2位小数,因为python的缘故,并不能做到真正的四舍五入df['md'] = round(df['close'].rolling(20).mean(), 2)df['upper'] = round(df['md'] + 2 * standard_deviations, 2)df['lower'] = round(df['md'] - 2 * standard_deviations, 2)return dfdef trade_signal(code):"""计算交易信号,当股价低于布林下轨时买入,高于上轨时卖出:param code: 股票代码:return: 包含交易信号的DataFrame"""data = calculate_boll(code)# 新建一个DataFrame,以data的index为indexdf = pd.DataFrame(index=data.index)df[['price', 'upper', 'lower']] = data[['close', 'upper', 'lower']]# 比较最高价、最低价与BOLL上下轨的大小来确定突破信号df['buy_signal'] = np.where(data['low'] < data['lower'], True, False)df['sell_signal'] = np.where(data['high'] > data['upper'], True, False)# 初始化订单状态为0df['orders'] = 0# 初始仓位为0position = 0# 遍历数据表for i in range(len(df)):# 当买入信号为True且仓位为0时买入if df.buy_signal[i] and position == 0:# 买入指令为1df.orders.values[i] = 1# 仓位加1position = 1# 当卖出信号为True且仓位为1时卖出elif df.sell_signal[i] and position == 1:# 卖出指令为-1df.orders.values[i] = -1# 仓位清0position = 0return dfdef calculate_income(code):"""计算收益:param code: 股票代码:return: 计算后的DataFrame"""data = trade_signal(code)# 初始最大可持仓量,可用资金为100000元max_position = 0money = 100000.0# 初始持仓股票手数data['stock'] = 0data['money'] = 100000.0for i in range(len(data)):# 当买卖指令为1if data.orders.values[i] == 1:# 以下轨价全仓买入max_position = money // (data.lower.values[i] * 100)# 可用资金减去买入股票所花费的资金money = money - max_position * data.lower.values[i] * 100# 当买卖指令为-1elif data.orders.values[i] == -1:# 可用资金加上卖出股票所得到的资金money = money + max_position * data.upper.values[i] * 100# 持仓清零max_position = 0# 持仓手数、可用资金data['stock'].values[i] = max_positiondata['money'].values[i] = money# 账户资产总额data['total'] = data['stock'] * data['price'] * 100 + data['money']return datadef plt_show(code):"""数据可视化:param code:股票代码:return: None"""# 用来正常显示中文字体plt.rcParams['font.sans-serif'] = ['KaiTi']# 解决负号显示为方块的问题plt.rcParams['axes.unicode_minus'] = Falsedata = calculate_income(code)# 设置画布大小plt.figure(figsize=(10, 6))# 设置标签plt.title('{}布林策略收益图'.format(code))plt.xlabel('日期')plt.ylabel('股价')# 绘制股价、布林上轨和下轨的折线图plt.plot(data.index, data.price, color='black', label='股价')plt.plot(data.index, data.upper, color='blue', label='上轨')plt.plot(data.index, data.lower, color='pink', label='下轨')# 用红色正三角标记买入点plt.scatter(data.loc[data.orders == 1].index, data['lower'][data.orders == 1],marker='^', c='r', s=80, label='买入')# 用绿色倒三角标记卖出点plt.scatter(data.loc[data.orders == -1].index, data['upper'][data.orders == -1],marker='v', c='g', s=80,label='卖出')# 图例放在左上角plt.legend(loc='upper left')# 绘制双坐标plt.twinx()# 绘制收益折线图plt.plot(data.index, data.total, color='red', label='总资产')# 图例放在右上角plt.legend(loc='upper right')plt.show()plt_show('sz.002056')

股市有风险,入市须谨慎!

这个粗糙的策略是极不靠谱的。

Python股票量化学习(3)——简单的策略回测相关推荐

  1. 京东量化教你如何用简单的策略回测盈利

    阅读原文:http://club.jr.jd.com/quant/topic/963245 今天来教大家使用量化平台中Python的部分,完成一个简单的策略回测. 首先,回测界面是长这个样子的 可以看 ...

  2. Python股票量化学习(1)——股票代码下载

    我有一个梦想:每天不用干活,银行账户里每天有钱进账!!!(不要误会,不是说把钱存银行吃利息啊,本金不够,会俄死的.) 量化交易也许是一条实现梦想的路,姑且来学一学.于是乎写下这篇博客,一来是为了记录自 ...

  3. Python股票量化学习(2)——股票历史日线数据下载

    利用baostock下在股票历史数据 bs.query_history_k_data_plus(code, fields, start_date, end_date, frequency, adjus ...

  4. python 策略回测期货_量化投资实战教程(1)—基于backtrader的简单买入卖出策略

    都说Python可以用于量化投资,但是很多人都不知道该怎么做,甚至觉得是非常高深的知识,其实并非如此,任何人都可以在只有一点Python的基础上回测一个简单的策略. Backtrader是一个基于Py ...

  5. python 量化策略回测_在python中创建和回测对交易策略

    python 量化策略回测 Pairs trading is one of the many mean-reversion strategies. It is considered non-direc ...

  6. 《Python股票量化交易从入门到实践》随书赠送“回测框架”的使用帮助

    点击:QTYX最新版本使用指南[文字版] 点击:QTYX最新版本使用指南[视频版] 点击: QTYX历史版本更新说明 赠送"回测框架"的目的 为了帮助读者再建立一座从书本知识到实战 ...

  7. python 股票量化盘后分析系统 V0.4

    前言: 思考了段时间,分析股票回测最终还是选择了backtrader,大体写了个框架,目前的效果图如下(后期还会改): 这次新添加了两个py文件,分别是stock_backtrader.py跟func ...

  8. python股票量化投资课程 百度云_网易云课堂 Python股票量化投资课程|百度云|天翼云|GD|OD下载...

    目录:/07 Python股票量化投资课程(完结) [6.4G] ┣━━01第一课资料 [0B] ┃ ┗━━视频课程分享资料 ┣━━02第二课资料 [0B] ┃ ┗━━class2 ┣━━03第三课资 ...

  9. python 股票量化盘后分析系统V0.42

    前言:先放效果图吧 开发的过程中因为知识水平有限,且对backtrader的各种不熟悉,相关的属性跟对象操作资料较少,实在写的很吃力,看官方那个API,水平有限,实在看得头晕. 效果图的图形输出用的是 ...

  10. python股票量化有什么特点吗?

    python股票量化交易的特点其实就是通过编写软件程序,并且能够实时监测市场交易情况,并且设定一些条件,一旦当市场交易情况满足这些条件时就会自动执行一些交易策略,比如买入.卖出策略等程序,然后在股票量 ...

最新文章

  1. Git:如何从远程源主服务器更新/签出单个文件?
  2. hiveserver2 kerberos 认证失败
  3. iOS 代码实现获得应用的版本号(Version/Build)
  4. Head First JSP---随笔七
  5. 华为手机没有耳塞插口_鸿蒙OS 2.0手机版开启公测!名单中只有华为手机没有荣耀...
  6. Ubuntu实现树莓派交叉编译
  7. 10个最常见的JS错误
  8. 【Unity3D基础】让物体动起来②--UGUI鼠标点击逐帧移动
  9. Php流式 大文件,如何使用PHP解析XML大文件
  10. 【2016年第5期】面向图数据管理系统基准评测的知识图谱统计特征分析
  11. RX异常点检测算法(马氏距离)
  12. 可视化折线圆形统计图_统计图表的优雅变换:Altair|可视化系列06
  13. 【转】20个Java 代码生成器
  14. 3DMAX制作载具模型导入UE4导致轮子无碰撞解决方案
  15. python 初学之环境配置及IED搭建
  16. GIF 斗图警告!GitHub 标星 5.5k+,Sorry 会编程就是可以 为所欲为!
  17. 插上移动硬盘计算机没反应,usb硬盘插上电脑没反应怎么办,手把手教你怎么解决...
  18. 【极客时间-网络编程实战】
  19. 【Ubuntu疑难杂症】无法定位软件包?
  20. 英语口语六级模拟测试软件,2017英语六级口语考试试题及答案_英语六级口语试题及答案 doc完整版...

热门文章

  1. PowerDesigner修改设置表格背景色
  2. 世界排名在20多位的无名小站
  3. 软件后台《积分制 / 绩效考核表》管理制度
  4. SQL server中模式的定义和删除
  5. 快的打车创始人带着区块链“杀”回来了,要与滴滴再次决一死战?
  6. Number.EPSILON
  7. Markdown从入门到放弃
  8. 实现网站二维码扫描登录
  9. 写博客这些Markdown语法够用
  10. python 进化树_科学网-应用Raxml软件构建最大似然法系统进化树-王翠的博文