量化交易:使用 python 进行股票交易回测

执行环境: Google Colab

1. 下载数据

import yfinance as yfticker = 'ZM'
df = yf.download(ticker)
df

在这里插入图片描述

2. 数据预处理

df = df.loc['2020-01-01':].copy()
  • 使用了 .loc 方法来选择索引为 ‘2020-01-01’ 以后的所有行数据。
  • 通过 .copy() 方法创建了一个这些数据的副本,确保对副本的操作不会影响原始数据框。

在这里插入图片描述

df['change_tomorrow'] = df['Adj Close'].pct_change(-1)
df.change_tomorrow = df.change_tomorrow * -1
df.change_tomorrow = df.change_tomorrow * 100
df
  • .pct_change(-1) 这部分使用了 pct_change 方法来计算当前行与后一行的变化率,传入参数 -1 表示计算与后一行的变化率。
  • 将 ‘change_tomorrow’ 列中的数值乘以 -1,将变化率转换为相反的方向。
  • 将 ‘change_tomorrow’ 列中的数值乘以 100,将变化率转换为百分比形式。

在这里插入图片描述

df = df.dropna().copy()
df

在这里插入图片描述

!pip uninstall scikit-learn
!pip install scikit-learn==1.1.3

3. 建立模型

from sklearn.ensemble import RandomForestRegressormodel = RandomForestRegressor(max_depth=20, random_state=42)
y = df.change_tomorrow
X = df.drop(columns='change_tomorrow')
model.fit(X, y)

在这里插入图片描述

model.score(X, y)

0.7973700550772351

4. 创建一个名为 Regression 的策略类

!pip install Backtesting
from backtesting import Strategyclass Regression(Strategy):limit_buy = 1limit_sell = -5def init(self):self.model = modelself.already_bought = Falsedef next(self):explanatory_today = self.data.df.iloc[[-1], :]forecast_tomorrow = self.model.predict(explanatory_today)[0]if forecast_tomorrow > self.limit_buy and self.already_bought == False:self.buy()self.already_bought = Trueelif forecast_tomorrow < self.limit_sell and self.already_bought == True:self.sell()self.already_bought = Falseelse:pass
  • limit_buylimit_sell 分别是买入和卖出的阈值
  • init 方法是初始化方法,在这里设置了模型和一个标记 already_bought,用于追踪是否已经买入
  • next 方法是每个交易周期调用的方法。在这里,首先通过 self.data.df.iloc[[-1], :] 获取了最近一天的数据作为当天的解释变量。然后使用模型 self.model 对明天的预测值进行预测,forecast_tomorrow = self.model.predict(explanatory_today)[0] 这行代码就是进行了明天的预测。
  • 如果预测值高于买入阈值且尚未买入(self.already_bought == False),则执行买入操作并将 already_bought 标记为已买入。
  • 如果预测值低于卖出阈值且已经买入(self.already_bought == True),则执行卖出操作并将 already_bought标记为未买入。

5. 创建一个交易回测的实例

!pip install scikit-optimize
from backtesting import Backtestbt = Backtest(X, Regression, cash=10000,commission = .002, exclusive_orders=True
)
  • X: 这是指定的交易数据或特征数据,用于执行交易策略的数据
  • Regression: 这是之前定义的策略类,表示将使用哪个策略来进行交易
  • cash=10000: 这个参数表示初始资金,设置为 10000
  • commission=.002: 这个参数表示交易佣金,设置为 0.2%
  • exclusive_orders=True: 这个参数表示交易订单是否独占性,设置为 True,意味着同一时间只能有一个买入或卖出订单执行

6. 进行交易回测优化的过程

stats_skopt, heatmap, optimize_result = bt.optimize(limit_buy = [0, 10],limit_sell = [-10, 0],maximize = 'Return [%]',method = 'skopt',max_tries = 500,random_state = 0,return_heatmap = True,return_optimization = True
)
  • limit_buy 的范围设置在 0 到 10 之间,而 limit_sell 的范围设置在 -10 到 0 之间,这表示优化的目标是在这个区间内找到最佳的参数值
  • maximize = 'Return [%]' 指定了要最大化的指标,这里是 ‘Return [%]’,即回报率的百分比。优化的目标是使得回报率最大化
  • method = 'skopt' 指定了优化的方法为 ‘skopt’,这是基于 scikit-optimize 库的一种优化方法
  • max_tries = 500 设置了最大尝试次数为 500 次,意味着在尝试寻找最优参数值时,会进行最多 500 次的尝试
  • return_heatmap = Truereturn_optimization = True 分别指定了返回热图和优化结果
import numpy as npdff = heatmap.reset_index()
dff = dff.pivot(index='limit_buy', columns='limit_sell', values='Return [%]')dff.sort_index(axis=1, ascending=False)\.style.format(precision=0)\.background_gradient(vmin=np.nanmin(dff), vmax=np.nanmax(dff))\.highlight_null(props='background-color: transparent; color: transparent')
  • dff = heatmap.reset_index(): 这行代码是将名为 heatmap 的数据重新设置索引,将原先的索引变为列,并将结果保存在 dff
  • 使用 pivot 方法将 dff 数据重新构造成一个以 ‘limit_buy’ 列为行索引,‘limit_sell’ 列为列索引,‘Return [%]’ 列为值的新数据框,并将结果保存在 dff
  • dff.sort_index(axis=1, ascending=False): 这行代码对列进行降序排序
  • .style.format(precision=0): 这部分代码是对样式进行格式化,将数值的显示精度设置为整数(precision=0
  • 使用了 background_gradient 方法,根据数值的范围进行颜色渐变。vminvmax 参数指定了颜色渐变的最小值和最大值,使用了 np.nanmin()np.nanmax() 函数来忽略 NaN 值并确定渐变的范围
  • 对空值(NaN 值)进行样式化处理,将其背景颜色和文本颜色设置为透明,以减少空值的影响。

在这里插入图片描述

7. 绘制优化过程中的评估结果

from skopt.plots import plot_evaluations_ = plot_evaluations(optimize_result, bins=10)
  • 参数 optimize_result 是优化过程中获得的结果,bins=10 表示将结果分成 10 份以展示评估结果的分布情况
    在这里插入图片描述

8. 绘制优化过程中目标函数的图表

from skopt.plots import plot_objective_ = plot_objective(optimize_result, n_points=10)
  • 参数 optimize_result 是优化过程中获得的结果,n_points=10 表示在图表中显示的离散点的数量为 10 个,用于展示目标函数的走势和变化情况

在这里插入图片描述

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

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

相关文章

Nginx 版本信息泄露解决方案

Nginx 【CVE-2021-23017;CVE-2022-41742】 【影响】 攻击者可能使用泄露的版本信息来确定该版本服务器有哪些安全漏洞&#xff0c;据此展开进一步的攻击。以下是百度的请求示例&#xff0c;也是有版本泄露&#xff1a; 【解决方案】 在Server节点增加以下配置&#xff1a; #…

SDL2 播放视频文件(MP4)

1.简介 这里引入FFmpeg库&#xff0c;获取视频流数据&#xff0c;然后通过FFmpeg将视频流解码成YUV原始数据&#xff0c;再将YUV数据送入到SDL库中实现视频播放。 2.FFmpeg的操作流程 注册API&#xff1a;av_register_all()构建输入AVFormatContext上下文&#xff1a;avform…

【原创课设】java+swing+mysql选课管理系统设计与实现

摘要&#xff1a; 随着学校规模的扩大和课程设置的多样化&#xff0c;传统的手工选课管理方式已经无法满足现代教育的需求。因此&#xff0c;开发一款高效、便捷的选课管理系统变得尤为重要。该系统可以提高选课工作的效率&#xff0c;减少人为错误&#xff0c;同时也能为学生…

verdi merge fsdb出现信号冲突的解决办法

前段时间介绍了verdi用 Edit Virtual File的方式把几个fsdb文件merge起来的方法 由于当时实验的时候只用了两个小的fsdb文件&#xff0c;每个fsdb文件中包含的信号量也比较少&#xff0c;所以并没有发现问题 我是用 Edit Virtual FIle把dump不同hier的fsdb文件merge到一起&am…

【Linux】:静动态库

静动态库 一.静态库1.设计静态库2.生成静态库3.发布静态库4.使用静态库 二.动态库1.设计动态库2.生成和发布动态库3.使用 三.进程地址空间1.程序在加载前的地址2.程序在加载后的地址3.动态库的地址 一.静态库 程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候…

【算法练习Day48】回文子串最长回文子序列

​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 回文子串最长回文子序列总结…

【文章学习系列之模型】DAGMM

本章内容 文章概况模型结构损失函数实验结果实验分析总结 文章概况 《Deep Autoencoding Gaussian Mixture Model for Unsupervised Anomaly Detection》是2018年发表于ICLR的一篇论文&#xff0c;该论文提出一种端到端的无监督异常检测方法DAGMM&#xff0c;取得了不错的效果…

数据结构-散列表

列表&#xff08;Hash Table&#xff09;&#xff0c;又称哈希表&#xff0c;是一种数据结构&#xff0c;特点是&#xff1a;数据元素的关键字与其存储地址直接相关 例&#xff1a;有一堆数据元素&#xff0c;关键字分别为&#xff5b;19&#xff0c;14&#xff0c;23&#xff…

Ansys Lumerical | 用于增强现实系统的表面浮雕光栅

在本示例中&#xff0c;我们使用 RCWA 求解器设计了一个斜面浮雕光栅 (SRG)&#xff0c;它将用于将光线耦合到单色增强现实 (AR) 系统的波导中。光栅的几何形状经过优化&#xff0c;可将正常入射光导入-1 光栅阶次。 然后我们将光栅特性导出为 Lumerical Sub-Wavelength Model …

【NI-DAQmx入门】触发相关

触发概述 触发采集为用户提供了两个主要好处&#xff1a;它对输入信号相对于触发事件进行计时&#xff0c;因此用户仅捕获感兴趣区域中的信号&#xff0c;从而节省硬件带宽和内存。 模拟触发和数字触发 模拟触发和数字触发的区别在于触发源的不同。数字触发是一种 TTL 信号&am…

压测工具主要功能是什么?该怎样选择?

压测工具是一类用于模拟并评估系统在不同负载条件下的性能的软件应用程序。通过模拟大量用户同时访问系统&#xff0c;压测工具能够帮助开发者识别系统的瓶颈、性能瓶颈以及潜在的故障点。这种实时、模拟的方式允许开发者在正式投入使用之前发现并解决问题&#xff0c;提高系统…

数据库操作入门:PyMongo 和 MongoDB 的基本用法

MongoDB MongoDB是一种流行的NoSQL数据库&#xff0c;它将数据存储在类似JSON的文档中&#xff0c;使数据库非常灵活和可扩展 PyMongo Python需要一个MongoDB驱动程序来访问MongoDB数据库。在本教程中&#xff0c;我们将使用MongoDB驱动程序 “PyMongo”。建议使用PIP来安装…