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

article/2025/9/19 10:32:58

        搞一个简单的交易策略回测(难点的我也不会啊)。此策略基于布林通道,当股价低于布林通道下轨线且持仓为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')

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

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


http://chatgpt.dhexx.cn/article/E1xMqEUS.shtml

相关文章

量化交易——布林带策略

一、布林带策略介绍 布林带/布林线/保利加通道(Bollinger Band)&#xff1a;由三条轨道线组成&#xff0c;其中上下两条线分别可以看成是价格的压力线和支撑线&#xff0c;在两条线之间是一条价格平均线。 一般来说&#xff0c;股价会运行在压力线和支撑线所形成的通道中。 与M…

【vn.py】源码解析之布林通道(BollChannel)策略

文章目录 Boll&#xff08;布林线&#xff09;指标CCI&#xff08;Commodity Channel Index&#xff09;指标布林通道策略布林通道策略源码分析1、完整源码2、策略参数与变量3、策略执行逻辑 Boll&#xff08;布林线&#xff09;指标 布林线是一种金融衍生品价格走势图中常用的…

量化交易——传统技术分析布林通道BollingerBands的原理及实现

布林通道 布林通道线是根据统计学的标准差来计算的&#xff0c;其具体可由上中下三条曲线展示。其中上下两线分别代表上升压力线和下降支撑线&#xff0c;故而可以根据K线图是否突破布林曲线来判断较好的买卖节点。三条曲线计算方法如下&#xff1a; 中轨线(MID)收盘价的M日移…

Lyndon的量化修炼之路——布林通道优化策略(二)

策略参数优化 //期市妖风大&#xff0c;小心被刮飞。本文不构成任何实质性建议&#xff0c;也不对任何依此进行的交易结果负责参数优化几乎是优化每一个量化交易策略的必经之路&#xff0c;对于参数优化的基本方法已经在双均线优化策略中介绍过&#xff0c;再次不多做介绍&…

【Python量化】布林带策略

文章目录 一、计算布林带三、构建策略&#xff0c;计算持仓头寸序列和买卖信号序列四、计算策略收益五、绘制交易信号 此文章首发于公众号&#xff1a;Python for Finance 链接&#xff1a;https://mp.weixin.qq.com/s/CJR2gwXkkzFRavZ8I98qdw 布林带&#xff08;BOLL&#x…

Lyndon的量化修炼之路——布林通道优化策略(一)

//期市妖风大&#xff0c;小心被刮飞。本文不构成任何实质性建议&#xff0c;也不对任何依此进行的交易结果负责经过某位大佬的提醒&#xff0c;原来大白有另外的含义&#xff0c;侵权了侵权了&#xff08;原谅我孤陋寡闻&#xff09;&#xff0c;所以还是简单点好。 我也不知…

现货黄金指标精讲(布林通道)

现货黄金的特点在于可以多空双向交易&#xff0c;如果投资者能精通一到两种的技术分析手段&#xff0c;必定能大幅提高交易的成功率。布林通道指标不仅能揭示金价运行的趋势&#xff0c;还能提供清晰的买卖信号&#xff0c;帮助长、中、短线的投资者提高交易决策的质量。 一、布…

布林通道 Bollinger Bands——非炒股向个人学习笔记

有一组数据&#xff0c;大多数是以时间序列的数据&#xff0c;如年、月、日为度量的某指标变化。&#xff08;上图的绿线不用管&#xff09; 布林通道的作用是描述数值的近期波动程度&#xff0c;具体表现就表现在轨道的收窄与拓宽上。 一、基本概念 作图需设定的变量&#x…

eclipse安装教程与使用教程

第一首先在电脑的浏览器中输入“eclipse官网”。 然后在网页中点击进入eclipse的官方下载网站。 2 第二然后再点击页面右边的“download”。 在弹出的页面下面点击“download packages”。 3 第三然后在下面找到“eclipse IDE for java developers”的选项。 在选项右边有…

eclipse基础实用教程

一、打开eclipse&#xff0c;创建java文件 1.点击eclipse.exe文件 Workspace&#xff1a;&#xff08;这个是你写的代码存放位置&#xff0c;可以自己选择创建一个文件夹&#xff09; 2.新装的eclipse中在new里面未找到java project&#xff0c; 点击Open Perspective&#…

eclipse使用教程(图文)

很多人都知道要用eclipse来做java开发&#xff0c;但很多的新手朋友却不知道怎么下载和安装eclipse。下面给你介绍一下怎么下载和安装eclipse来用于自己的学习或者项目开发&#xff0c; 很多人都知道要用eclipse来做java开发&#xff0c;但很多的新手朋友却不知道怎么下载和安装…

Eclipse详细安装教程

Eclipse安装教程 前言一、Eclipse是什么&#xff1f;二、安装步骤1. Eclipse下载下载网址 2. Eclipse安装 前言 Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。 一、Eclipse是什么&#xff1f; Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言…

Eclipse最新最简最详细安装教程

Eclipse最新最简最详细安装教程 1、首先打开官方地址&#xff08;见下面&#xff09; Eclipse官方下载地址&#xff1a;点击打开官方链接 2、点击红箭头指向的红框中的“Download Packages”。 3、出现新的页面之后往下翻找到并点击红箭头指向的红色矩形的部分Eclipse IDE f…

Eclipse安装教程 ——史上最详细安装Java Python教程说明

Eclipse安装教程 ——史上最详细安装Java&Python教程说明 (Win7_64位 Eclipse 64位 JDK_8u131_64位 python2.7.8 PyDev5.7.0插件) 适用操作系统&#xff1a;Win7 64位 所需要的软件以及插件&#xff1a;Eclipse 64位、JDK_8u131_64位、python2.7.8、PyDev5.7.0插件 …

Eclipse 教程

Eclipse的使用 前言一、Eclipse的介绍二、下载与安装1.下载2.安装 三、基本使用步骤1.启动2.创建项目3. 创建包及class文件 四、一些使用技巧1. 快速生成构造方法2.自动补全3. 快速生成get-set方法4. 查找某变量所在位置,或者替换某变量的变量名5. 快速导入包6.合理利用eclipse…

视频消重处理,视频原创怎么做,视频处理软件

现在的新传媒行业&#xff0c;有很多小伙伴搬过来的视频都不太清楚怎么把它变成自己的视频&#xff0c;也就是消重&#xff0c;现在有一款工具可以达到这种消重原创&#xff0c;像某头条通过率在96%以上了 这是一个视频消重处理软件&#xff0c;现在给大家说说功能和页面 1&…

视频合成-moviepy

最近发现&#xff0c;公司在进行视频合成的时候&#xff0c;部分业务不是在客户端进行合成&#xff0c;而是在后端进行合成&#xff0c;让我有点惊讶&#xff0c;立马问开发要了代码&#xff0c;想要看看到底在后端如何处理的。 学习文档&#xff1a;https://blog.csdn.net/uc…

计算机图像视频处理

计算机图像视频处理 计算机视觉概论 计算机视觉概念 计算机图像处理&#xff0c;也即数字图像处理(Digital Image Processing)&#xff0c; 是指将图像信号转换成数字信号并利用计算机对其进行处理的过程&#xff0c;是通过计算机对图像进行去除噪声、增强、复原、分割、提取…

视频处理

1.视频处理 在视频压缩前后&#xff0c;对视频图像质量增强的操作视频编解码系统输出的图像主观质量不仅与压缩算法的性能有关&#xff0c;还受视频处理的影响压缩之前对视频的处理称作预处理&#xff08;Pre-processing&#xff09;压缩之后对视频的处理称作后处理&#xff0…

基于PythonOpenCv的视频图像处理

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…