量化交易:止盈策略与回测

news2024/11/24 9:31:32

我们买基金或股票的时候通常用最简单的策略进行决策:低买高卖,跌的多了就加仓拉低持有成本,达到收益率就卖出。

那么如何用代码表示这个策略呢?首先定义交易信号则是:0.5%时买入,目标止盈线是1.5%,达到目标收益率就清仓。接下来我们用Python回测一下这个策略的收益情况:


获取数据集

# 安装akshare
!pip3 install akshare --upgrade 
# 调用包
import akshare as ak
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 不显示警告
import warnings
warnings.filterwarnings('ignore')

# 导入上证指数etf
data = ak.fund_etf_fund_info_em('510210','20210122','20230620')


# 筛选要用的时间段
data['year']=pd.to_datetime(data['净值日期']).dt.year # 增加年字段
df = data.loc[data['year']==2023,['净值日期','单位净值']]  # 筛选数据集
df.index=range(len(df)) # 重排索引
df.tail(10) # 查看最近的n条数据

代码详解:

!pip3 install akshare 安装akshare的包获取免费数据集。

fund_etf_fund_info_em()是akshare获取ETF的函数,更多函数看这里 ↓akshare量化交易数据集的获取_akshare怎么用_紫昂张的博客-CSDN博客

pd.to_datetime()可以把数据转为时间格式,原本data['净值日期']是字符串格式;转为时间格式后,才能调用dt.year返回年份。

.loc索引器可以定位行和筛选列;data['year']==2023返回布尔类型的数据,表示定位指定行;['净值日期','单位净值']表示筛选指定列。

.index表示调用DateFrame的索引;range()函数生成从0开始的整数序列,len()获取长度或行数。由于截取了2023年的数据,索引不是从0开始计起,因此需要重新赋值给索引。

运行结果:


判断交易信号

# 计算环比上一个交易日的涨跌幅
df['涨跌幅'] = df['单位净值'].pct_change()
# 判断买入信号和 对应交易数量
df.loc[df['涨跌幅']<-0.005,'买入数量'] = 1000
# 计算当天交易金额
df['交易金额'] = df['买入数量']*df['单位净值']
df = df.fillna(0.0) # 填补空值
df.tail(30)  

代码详解:

pct_change()计算环比,返回当天的收益率,公式为:环比=现期/基期-1。

df.loc[df['涨跌幅']<-0.005,'买入数量'] 用到了.loc索引器,df['涨跌幅']<-0.005是指环比前一天下跌0.5%,是交易信号;如果满足交易信号的买入1000股,中括号里的'买入数量'是我们预设参数,有值的情况下会把结果值1000储存到预设参数里。

有了每天的交易数量后,乘以当天的每股价格就得到当日的交易金额了。

df.fillna(0.0)表示把空值赋值为0,避免后续空值对计算产生影响。

运行结果:


回测

在上一步交易信号计算的步骤中,已知当天买入的交易数量和交易金额,接下来要计算历史持有和历史盈亏情况。


# 定义全局变量
target_return = 0.015  # 止盈比例,收益率超过此比例时抛出

# 初始化变量
df['总持有数量'] = 0
total_num = 0 # 总持有数量
df['总持有成本'] = 0
total_cost = 0 # 总持有成本
df['持仓成本单价'] = 0
per_cost = 0 # 持仓单价
df['总市值'] = 0
stock = 0
df['盈亏额'] = 0
profit = 0
df['盈亏率'] = 0
profit_rate = 0

df['止盈线利润'] = 0


for i in range(len(df)):
    total_num += df['买入数量'][i] # 累计数量
    total_cost += df['交易金额'][i] # 累计成本
    per_cost = total_cost/total_num
    stock = total_num*df['单位净值'][i]
    profit = stock - total_cost
    profit_rate = df['单位净值'][i]/per_cost-1
    
    df = df.fillna(0.0) # 填补空值    

    if profit_rate >= target_return:
        total_num = 0
        total_cost = 0
        df['止盈线利润'][i] = profit
    
    df['总持有数量'][i] = total_num
    df['总持有成本'][i] = total_cost
    df['持仓成本单价'][i] = per_cost
    df['总市值'][i] = stock
    df['盈亏额'][i] = profit
    df['盈亏率'][i] = profit_rate
    
    
df.tail(30)    

代码详解:

由于达到目标收益率有清0的逻辑,所以使用用for循环来表示:

for i in range(len(df)) 指遍历每一行数据;

if profit_rate >= target_return 表示当大于预设值0.015时,持有数量total_num、和持有成本total_cost都归零。

for循环里每个公式的含义:

total_num += df['买入数量'][i]:把每一天买入的股数加和,计算当前累计持有数量;
total_cost += df['交易金额'][i] :把每一天的成本加和,计算累计持有成本;
per_cost = total_cost/total_num:计算每股的成本单价;
stock = total_num*df['单位净值'][i]:计算当前总市值;
profit = stock - total_cost:总利润=总市值-总成本;
profit_rate = df['单位净值'][i]/per_cost-1:收益率=当前股价/每股单位成本-1;

由于我们每一步的计算结果都要存在二维表里,方便后续输出查看,所以要保存的每个字段都需要预设变量,并赋值0。并在每次循环末尾赋值到变量里。

运行结果:


输出结果

max_cost = df['总持有成本'].max()
total_profit = df['止盈线利润'].sum()
profit_rate = total_profit/max_cost
sale_times = (df['止盈线利润']>0).sum()

print('最大持有成本:%f,总利润:%f,收益率:%f,达标次数:%s'%(max_cost,total_profit,profit_rate,sale_times))

代码详解:

max()函数返回 '总持有成本' 列的最大值,表示最大投入成本。

sum()函数返回 '止盈线利润' 列的加和,表示总盈亏额。

(df['止盈线利润']>0)是条件判断,返回布尔值;由于True表示1,所以可以用sum()进行计数。

运行结果:

结果解读:

按照2023年上半年的行情,最大持有成本不到8k,按最大成本算的收益率是3.6%;我们预设的止盈线是1.5%,达到目标收益率就清仓的次数是6次。

用2021年和2022年的数据进行回测收益率接近存款的利率,但实盘可能存在交易手续费没有考虑进去,综合看来这个策略虽然不亏但收益不太理想,还需要继续探索别的方法。

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

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

相关文章

Java官方笔记12异常

Exception Definition: An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the programs instructions. the checked exception 比如&#xff0c;java.io.FileNotFoundException the error 比如&#xff0c;java.i…

Flink流批一体计算(2):Flink关键特性

目录 流式处理 丰富的状态管理 流处理 自定义时间流处理 有状态流处理 通过状态快照实现的容错 流式处理 在自然环境中&#xff0c;数据的产生原本就是流式的。无论是来自 Web 服务器的事件数据&#xff0c;证券交易所的交易数据&#xff0c;还是来自工厂车间机器上的…

优先级队列建立小根堆来解决前K个高频元素(TOP K问题)

目录 场景一&#xff1a;解决前K个高频元素需要解决如下几个问题&#xff1a; 优先级队列PriorityQueue 堆的定义 题目链接 场景二&#xff1a;亿万级数据取前TOP K / 后TOP K 数据 场景一&#xff1a;解决前K个高频元素需要解决如下几个问题&#xff1a; 1.记录每一个元…

【C++】4.工具:读取ini配置信息

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍读取ini配置信息。 学其所用&#xff0c;用其所学。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c;下次更新不迷路&…

医院PACS系统的发展历史

PACS全称Picture Archivingand Communication Systems。它是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;X光机&#xff0c;红外仪、显微仪等设备产生的图像&#xff09;通过各…

【工程应用八】终极的基于形状匹配方案解决(小模型+预生成模型+无效边缘去除+多尺度+各项异性+最小组件尺寸)...

我估摸着这个应该是关于形状匹配或者模版匹配的最后一篇文章了&#xff0c;其实大概是2个多月前这些东西都已经弄完了&#xff0c;只是一直静不下来心整理文章&#xff0c;提醒一点&#xff0c;这篇文章后续可能会有多次修改(但不会重新发文章&#xff0c;而是在后台直接修改或…

【MySQL 日志管理、备份与恢复】

目录 一、数据库备份的分类1、从物理与逻辑的角度1.1、物理备份: 对数据库操作系统的物理文件&#xff08;如数据文件&#xff0c;日志文件等&#xff09;的备份1.2、逻辑备份 2、从数据库的备份策略角度3、常见的备份方法3.1、物理冷备3.2、专用备份工具mysqldump 或者 mysqlh…

【Windows系统】windows服务

概述 Microsoft Windows 服务&#xff08;即&#xff0c;以前的 NT 服务&#xff09;使您能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序。这些服务可以在计算机启动时自动启动&#xff0c;可以暂停和重新启动而且不显示任何用户界面。这种服务非常适合在服…

C++算法:多源最短路径(Floyd)

文章目录 前言一、Floyd算法二、代码实现总结 前言 前文单源最短路径Dijkstra中我们讨论了如何解决有向无环图的最短路径问题&#xff0c;Dijkstra只能解决一个起始点的问题&#xff0c;如果要解决每个顶点到任一顶点的最短路径呢&#xff1f;一个方法就是再循环一次&#xff…

ASEMI代理光宝高速光耦LTV-60L规格,LTV-60L封装

编辑-Z LTV-60L参数描述&#xff1a; 型号&#xff1a;LTV-60L 封装&#xff1a;LSOP-6 储存温度TST&#xff1a;-55~125℃ 工作温度TA&#xff1a;-40~105℃ 隔离电压VISO&#xff1a;5000VRMS 电源电压VCC&#xff1a;7V 平均正向输入电流IF&#xff1a;20mA 输入功…

电脑滤镜软件哪个好 滤镜调色有什么技巧

无论是图片还是视频&#xff0c;滤镜的作用都很大&#xff0c;通过滤镜改变色彩&#xff0c;能让图片或视频增加故事性和美感。电脑滤镜软件哪个好, 电脑滤镜软件有很多&#xff0c;这里我们主要介绍几款视频滤镜软件。滤镜调色有什么技巧&#xff1f;有模板的&#xff0c;我们…

api-hook,更轻量的接口测试工具

目录 前言 现状 api-hook优势 研发介绍 最后 前言 api-hook是一种轻量级的接口测试工具&#xff0c;它基于Python语言编写&#xff0c;可以通过配置文件定义接口测试用例&#xff0c;支持HTTP和HTTPS协议&#xff0c;并提供了灵活的校验机制和数据处理方式。 在网站的开发过…

Tailwindcss 入门

Tailwindcss 是一个功能类优先的 CSS 框架&#xff0c;通过 flex, pt-4, text-center 和 rotate-90 这种原子类组合快速构建网站&#xff0c;而不需要离开你的 HTML。就是记住原子类&#xff0c;不要再自己想 CSS 命名一股脑子写 HTMl 就行了&#xff01; 它与常规的 Bootstra…

佩戴舒适度极好的蓝牙耳机推荐,久戴不累的蓝牙耳机推荐

无论是在日常还是运动的场景下&#xff0c;我们通常都会选择佩戴着耳机&#xff0c;让我们能够释放压力&#xff0c;缓解枯燥的生活。可是&#xff0c;随着市面上的蓝牙耳机层出不穷、各种各样&#xff0c;导致很多小伙伴不知如何选购耳机了&#xff0c;下面我来给大家分享几款…

循踪讲述:成都的夜,有一盏灯为你亮

成都的夜晚总是这样&#xff0c;热闹而梦幻。霓虹灯下的酒吧一条街&#xff0c;你看着手里冒着蒸汽的小龙虾&#xff0c;却心里想着那个人。那个曾经一起在脚手架上挥汗如雨&#xff0c;携手走过平淡岁月&#xff0c;然后在灯红酒绿的生活里逐渐远离的人。 他&#xff0c;一个手…

【数据治理-06】做好数据分类分级,为数据安全有序流动保驾护航

我们常说人以类聚&#xff0c;物以群分&#xff0c;确实是这样&#xff0c;杜威说过“所有知识都是分类”&#xff01;很好理解&#xff0c;分类是认知经济&#xff0c;任何有效分类&#xff0c;都可以极大地节省我们的认知精力。数据分类分级具体说来&#xff0c;其实包含了2个…

欢迎来到 VOXEL WARS!

Sandbox Streams 的全新节目&#xff0c;我们希望你们能参与其中&#xff01; 我们正在寻找 15 名 Voxedit 艺术家&#xff0c;他们将需要抽出 1 小时进行现场表演&#xff08;仅限屏幕共享&#xff09;&#xff0c;并在节奏快速的环境中进行创作&#xff0c;以赢得“最佳快速设…

报道 | 7月国际运筹优化会议汇总

七月召开会议汇总&#xff1a; 30th International Annual EurOMA Conference Location:Leuven Important dates: Conference: July 3, 2023 - July 5, 2023 Details:https://euroma2023.org/ The Equilibrium Computation Workshop at EC Location:Kings College London…

STM32速成笔记—ADC

文章目录 一、什么是ADC二、ADC的用途三、STM32F103ZET6的ADC3.1 ADC通道对应引脚3.2ADC时钟3.3 ADC工作模式3.4 ADC转换时间3.5 ADC校准3.6 ADC转换结果与实际电压的换算 四、ADC配置步骤五、ADC配置程序5.1 ADC初始化程序5.2 软件触发AD转换5.3 读取AD转换结果 六、实战项目6…

运动健身APP开发需要具备哪些功能?

想要开发一款运动健身APP软件&#xff0c;需要具备哪些功能呢&#xff1f; 1、用户注册和登录&#xff1a;用户通过个人信息注册健身APP&#xff0c;登陆之后建立个人账号&#xff0c;以后使用秩序登录自己的账号就可以记录和追踪自己的健身计划和成果。 2、个人…