基于Python实现盈利8371%的交易策略
本文介绍了通过Python和Benzinga API构建自动化交易策略的方法,帮助交易者方便的回测交易策略。原文: An Algo Trading Strategy which made +8,371%: A Python Case Study

导言
传统自动化交易策略(如均线交叉或 RSI 临界点突破策略)已被证明过时了,这些策略过于简单,更重要的是,市场上有大量参与者在尝试执行这些策略。
因此,与其接受这些策略,不如尝试些新东西。本文将基于 Python 和 Benzinga API来构建并回测一种新的交易策略,帮助我们战胜市场。
话不多说,直接进入主题!
交易策略
在编码之前,有必要先了解一下本文将要构建的策略背景,该策略遵循简单但非常有效的突破策略原则。
如果出现以下情况,我们就入市:股价超过 50 周的最高点
如果出现以下情况,我们就出市:股价跌破 40 周的最低点
我们通过唐氏通道指标(Donchian Channel indicator)来跟踪 50 周高点和 40 周低点。本策略是周线交易系统,因此将在周线时间框架内进行回测。
这就是我们要在本文中进行回测的策略。就这么简单,对吧?接下来开始编码。
导入软件包
本文将使用四个主要软件包,即 pandas
、requests
、pandas_ta
和 matplotlib
,次要/可选软件包包括 termcolor
和 math
。下面的代码将把所有提到的包导入到 Python 环境中:
# IMPORTING PACKAGES
import pandas as pd
import requests
import pandas_ta as ta
import matplotlib.pyplot as plt
from termcolor import colored as cl
import math
plt.rcParams['figure.figsize'] = (20,10)
plt.style.use('fivethirtyeight')
如果尚未安装任何导入的软件包,请确保通过 pip
命令进行安装。
提取历史数据
我们将在苹果股票上对突破策略进行回测。为了获取苹果公司的股票历史数据,将使用 Benzinga 的 Historical Bar Data API接口。以下 Python 代码通过该接口提取了 1993 年以来的苹果股票数据:
# EXTRACTING HISTORICAL DATA
def get_historical_data(symbol, start_date, interval):
url = "https://api.benzinga.com/api/v2/bars"
querystring = {"token":"YOUR API KEY","symbols":f"{symbol}","from":f"{start_date}","interval":f"{interval}"}
hist_json = requests.get(url, params = querystring).json()
df = pd.DataFrame(hist_json[0]['candles'])
return df
aapl = get_historical_data('AAPL', '1993-01-01', '1W')
aapl.tail()
在上述代码中,定义了名为 get_historical_data
的函数,该函数获取股票代码、数据起始日期和数据点之间的间隔。
在函数中,我们将把 API URL 和查询字符串存储到各自的变量中。请确保将 YOUR API KEY
替换为实际的 Benzinga API KEY,可以在创建账户后获得该 KEY。然后,调用 API 以获取数据,并将 JSON 响应转换为 Pandas dataframe,最后返回该数据。
基于该函数,我们提取了苹果公司自 1993 年以来每周股票历史数据。这是最终输出结果:

太棒了,我们继续计算提取的苹果公司历史数据的唐氏通道指标。
唐氏通道计算
如果深入研究该指标的数学原理,需要单独撰文进行解释。基本上,唐氏通道揭示了股票在特定时间段内的最高点和最低点。
以下代码使用 pandas_ta
计算指标:
# CALCULATING DONCHIAN CHANNEL
aapl[['dcl', 'dcm', 'dcu']] = aapl.ta.donchian(lower_length = 40, upper_length = 50)
aapl = aapl.dropna().drop('time', axis = 1).rename(columns = {'dateTime':'date'})
aapl = aapl.set_index('date')
aapl.index = pd.to_datetime(aapl.index)
aapl.tail()
第一行使用 pandas_ta
提供的 donchian 函数来计算指标。该函数需要两个参数:下限长度和上限长度,分别是最低点和最高点的回溯周期。由于我们的策略要求 40 周低点和 50 周高点,因此将下限和上限分别设为 40 和 50。
计算之后,执行一些数据处理任务,以清理和格式化数据。这就是最终的数据帧:

为了更好的了解唐氏通道指标,我们用 Matplotlib 库绘制计算值:
# PLOTTING DONCHIAN CHANNEL
plt.plot(aapl[-300:].close, label = 'CLOSE')
plt.plot(aapl[-300:].dcl, color = 'black', linestyle = '--', alpha = 0.3)
plt.plot(aapl[-300:].dcm, color = 'orange', label = 'DCM')
plt.plot(aapl[-300:].dcu, color = 'black', linestyle = '--', alpha = 0.3, label = 'DCU,DCL')
plt.legend()
plt.title('AAPL DONCHIAN CHANNELS 50')
plt.xlabel('Date')
plt.ylabel('Close')
这段代码没有什么特别之处。我们利用 matplotlib
提供的基本功能来实现可视化,这是最终的图表:

从图中可以看出,唐氏通道指标有三个重要组成部分:
-
Upper Band(上限波段):上限波段显示了股票在特定时间段内的最高点。 -
Lower Band(下限波段):基本上与上限相反,显示股票在特定时间段内的最低点。 -
Middle Band(中间波段):这个部分有点不同,显示的是上限波段和下限波段之间的平均值。
唐氏通道是最广泛使用的观察股价走势突破情况的指标之一,这也是本文使用该指标的核心原因之一。
回溯测试策略
接下来是最重要的步骤之一,即对突破策略进行回测。为了简单起见,我们将使用非常基本和直接的回测系统。下面的代码将对该策略进行回测并显示结果:
# BACKTESTING THE STRATEGY
def implement_strategy(aapl, investment):
in_position = False
equity = investment
for i in range(3, len(aapl)):
if aapl['high'][i] == aapl['dcu'][i] and in_position == False:
no_of_shares = math.floor(equity/aapl.close[i])
equity -= (no_of_shares * aapl.close[i])
in_position = True
print(cl('BUY: ', color = 'green', attrs = ['bold']), f'{no_of_shares} Shares are bought at ${aapl.close[i]} on {str(aapl.index[i])[:10]}')
elif aapl['low'][i] == aapl['dcl'][i] and in_position == True:
equity += (no_of_shares * aapl.close[i])
in_position = False
print(cl('SELL: ', color = 'red', attrs = ['bold']), f'{no_of_shares} Shares are bought at ${aapl.close[i]} on {str(aapl.index[i])[:10]}')
if in_position == True:
equity += (no_of_shares * aapl.close[i])
print(cl(f'\nClosing position at {aapl.close[i]} on {str(aapl.index[i])[:10]}', attrs = ['bold']))
in_position = False
earning = round(equity - investment, 2)
roi = round(earning / investment * 100, 2)
print(cl(f'EARNING: ${earning} ; ROI: {roi}%', attrs = ['bold']))
implement_strategy(aapl, 100000)
我不打算深入探讨这段代码,因为解释起来需要一些时间,基本上程序会根据满足的条件执行交易。当入市条件得到满足时,就会入市,而当出市条件得到满足时,就会平仓。以下是程序执行的交易以及回测结果:

正如标题中所说,该策略取得了 8371% 的投资回报率,这是一个巨大的数字。但现在是时候看看我们的策略是否真的跑赢了市场。
与 SPY ETF 对比
将策略回测结果与 SPY ETF 的买入/持有回报进行比较,有助于真正了解策略的表现。以下代码计算了 SPY ETF 多年来的回报:
spy = get_historical_data('SPY', '1993-01-01', '1W')
spy_ret = round(((spy.close.iloc[-1] - spy.close.iloc[0])/spy.close.iloc[0])*100)
print(cl('SPY ETF buy/hold return:', attrs = ['bold']), f'{spy_ret}%')
上述代码首先提取 SPY 的历史数据,其规格与 AAPL 相同。然后使用简单的公式计算该指数的收益百分比,结果是:

该指数的回报率为 936%,其实已经很不错了,但与我们的策略相比,还是有很大差距。我们的策略大大超过了基准,这是个好消息!
结束语
本文通过大量编码过程,对一个简单但非常有效的突破策略进行了回测。不出所料,该策略的结果令人惊叹。我们首先使用 Benzinga API 提取苹果公司的历史数据,然后慢慢探索唐氏通道,最后对该策略进行回测,并将结果与 SPY ETF 进行比较。
该策略还有很多方面可以改进。如果加上佣金和滑点,回测系统就会更加复杂和现实。适当的风险管理必须到位,特别是在算法交易的情况下。
你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。为了方便大家以后能第一时间看到文章,请朋友们关注公众号"DeepNoMind",并设个星标吧,如果能一键三连(转发、点赞、在看),则能给我带来更多的支持和动力,激励我持续写下去,和大家共同成长进步!
本文由 mdnice 多平台发布
相关文章:

基于Python实现盈利8371%的交易策略
本文介绍了通过Python和Benzinga API构建自动化交易策略的方法,帮助交易者方便的回测交易策略。原文: An Algo Trading Strategy which made 8,371%: A Python Case Study Behnam Norouzi Unsplash 导言 传统自动化交易策略(如均线交叉或 RSI 临界点突破策略)已被证…...
如何在Linux中找到正在运行的Java应用的JAR文件
当你在Linux服务器上工作时,可能需要找到某个正在运行的Java应用的JAR文件位置。这对于诊断问题、更新应用或理解部署结构非常有用。以下是一个步骤详细的指南,帮助你找到这些信息。 1. 确定Java进程 首先,你需要确定正在运行的Java应用的进…...
几分钟学会TypeScript
目录 一、类型推断和类型注解二.类型注解,声明时指定类型三、类型断言四、基础类型和联合类型字符串数字和浮点类型布尔空和undefined多类型值限定 五、数组 元组 枚举数组元组,?代表可选参数枚举枚举使用 六、函数函数作为参数 七、类、接口与抽象类类访问修饰符类…...

最新版手机软件App下载排行网站源码/App应用商店源码
内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 一款简洁蓝色的手机软件应用app下载排行,app下载平台,最新手机app发布网站响应式织梦模板。 主要有:主页、app列表页、app介绍详情页、新闻资讯列…...

R语言计算:t分布及t检验
t分布理论基础 t分布也称Student’s t-distribution,主要出现在小样本统计推断中,特别是当样本量较小且总体标准差未知时,用于估计正态分布的均值。其定义基于正态分布和 X 2 X^{2} X2分布(卡方分布)。如果随机变量X服…...
uni-app的地图定位与距离测算功能的实现
文章目录 一、引言二、uni-app地图定位实现三、距离测算技术四、完整代码五、结论本文着重探讨了如何在uni-app中实现地图定位,以及如何计算当前定位与目标位置之间的距离。 一、引言 在移动应用开发中,地图定位与距离测算是常见的功能需求。无论是出行导航、位置签到,还是…...

如何从应用商店Microsoft Store免费下载安装HEVC视频扩展插件
在电脑上打开一张HEIC类型的图片提示缺少HEVC解码器,无法打开查看,现象如下: 这种情况一般会提示我们需要下载安装HEVC解码器,点击“立即下载并安装”会跳转到应用商店,但是我们发现需要付费7元才能下载安装 免费安装…...

【vue】v-if 条件渲染
v-if 不适用于频繁切换显示模式的场景 修改web.user,可看到条件渲染的效果 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…...

Day37:LeedCode 738.单调递增的数字 968.监控二叉树 蓝桥杯 翻转
738. 单调递增的数字 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时,我们称这个整数是单调递增的。 给定一个整数 n ,返回 小于或等于 n 的最大数字,且数字呈 单调递增 。 示例 1: 输入: n 10 输出: 9 思路: 假设这个数是98,…...
详解Qt元对象系统
Qt库作为一款流行的跨平台C应用程序开发框架,其中的元对象系统是其核心特性之一。Qt元对象系统不仅提供了诸如信号槽(Signals & Slots)、属性系统(Property System)等功能,还实现了对C对象的运行时类型…...

无法用raven-js,如何直接使用TraceKit标准化错误字符串(一次有趣的探索)
引子:网上三年前(2020)的文章介绍了一个raven-js 简单说就是把堆栈信息格式化兼容各浏览器,便于查看错误来源。 **but:**到处找了一下raven-js,已经没有官方出处了,只在Sentry的源码仓库里发现…...

Docker学习笔记(二):在Linux中部署Docker(Centos7下安装docker、环境配置,以及镜像简单使用)
一、前言 记录时间 [2024-4-6] 前置文章:Docker学习笔记(一):入门篇,Docker概述、基本组成等,对Docker有一个初步的认识 在上文中,笔者进行了Docker概述,介绍其历史、优势、作用&am…...
uniapp 检查更新
概览 在uniapp中检查并更新应用,可以使用uni-app自带的更新机制。以下是一个简单的示例代码,用于在应用启动时检查更新: // 在App.vue或者其他合适的地方调用 onLaunch: function() {// 当uni-app初始化完成时执行// 判断平台const platfor…...
(Java)数据结构——正则表达式
前言 本博客是博主用于复习数据结构以及算法的博客,如果疏忽出现错误,还望各位指正。 正则表达式概念 正则表达式,又称规则表达式(Regular Expression),是一种文本模式,包括普通字符…...

第6章 6.3.1 正则表达式的语法(MATLAB入门课程)
讲解视频:可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。 MATLAB教程新手入门篇(数学建模清风主讲,适合零基础同学观看)_哔哩哔哩_bilibili 正则表达式可以由一般的字符、转义字符、元字符、限定符等元素组…...

RX8130CE为用户提供带复位延迟和主备电管理的解决方案
实时时钟作为设备的精确时钟来源,其作用如同人的心脏,为设备提供准确稳定的心跳.而便携式设备由于应用场景多变,所以对内部元器件要求也相对较高,这就对作为核心器件的实时时钟模块提出不少挑战。EPSON实时钟模块产品线拥有丰富的…...
JS文件导出变量
如果 config.js 文件中有多个变量要导出,你可以按照以下步骤进行: 1. 在 config.js 文件中定义多个变量,并使用 export 导出它们。 // config.js const baseUrl "http://localhost:8081"; const apiKey "your_api_key&quo…...
已知私钥和密文,如何用python进行RSA解密
要使用Python进行RSA解密,你可以使用pycryptodome库。下面是一个简单的示例,展示了如何使用已知的私钥和密文进行RSA解密: 首先,确保你已经安装了pycryptodome库。如果没有安装,你可以通过运行pip install pycryptodome来安装它。 然后,你可以使用以下代码进行RSA解密:…...
vue2-vue3面试
v-text/v-html/v-once/v-show/v-if/v-for/v-bind/v-on beforeCreate() 已有DOM节点:可以data选项:不可以虚拟DOM节点:不可以 created():掌握 已有DOM节点:可以data选项:可以虚拟DOM节点:不可以 beforeMount…...
jmeter生成随机数的详细步骤及使用方式
Apache JMeter 是一个用于测试性能的开源工具,它可以模拟多种类型的负载并测量应用程序的性能。在 JMeter 中生成随机数可以通过使用预定义的函数来实现。以下是生成随机数的详细步骤及使用方式: 安装 JMeter: 首先,你需要在你的计…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...