量化交易实战【1】自己搭建一个的股票交易回测框架,并通过均线择时策略进行回测

简介: 量化交易实战【1】自己搭建一个的股票交易回测框架,并通过均线择时策略进行回测

前言


本文介绍了一个股票交易的基础回测框架,并且通过均线择时策略,详细的演示了策略搭建的过程,和大家共同学习交流。


  1. 文章示例中使用的‘000001.XSHE.csv’文件,已上传至csdn资源中,可直接下载


  1. 或者关注文末公众号:‘阿旭算法与机器学习’。然后输入:股票数据,即可获取4000多只股票从2015年1月至2022年10月的所有基础数据


1. 导入数据


import pandas as pd
import matplotlib.pyplot as plt


pd.set_option('display.max_columns', None) # 展示所有列
# 000001.XSHE.csv文件包含2015年1月至2022年10月的开盘价、收盘价、最高价、最低价、成交量、成交金额股票的基本数据
df = pd.read_csv('./000001.XSHE.csv')  
df.head()

image.png


# 求该股票每日涨跌幅
df['change_pct'] = df['close'].pct_change()
df = df[['date','open','close','high','low','change_pct']]
df['date'] = pd.to_datetime(df['date'])  # 将交易日期字符串变为日期类型
df.head()


image.png


2. 交易框架搭建–以均线策略为例


当短期均线由下向上穿过长期均线的时候,第二天以开盘价全仓买入并在之后一直持有;


当短期均线由上向下穿过长期均线的时候,第二天以开盘价全仓卖出,之后空仓,直到下次买入


2.1 计算均线数值


此处以短期均线MA=5;长期均线MA=20为例进行说明,至于参数的优化,需要依据不同股票的实际情况修改


# 计算均线
ma_short = 5  #短期均线,ma代表:moving_average
ma_long = 20  #长期均线,ma代表:moving_average
df['ma_short'] = df['close'].rolling(ma_short).mean()
df['ma_long'] = df['close'].rolling(ma_long).mean()
df.head(10)


image.png


#补全上面均线缺失值:补全方式采用扩展窗口函数expanding,移动计算前面所有值之和的均值
df['ma_short'].fillna(value=df['close'].expanding().mean(),inplace=True)
df['ma_long'].fillna(value=df['close'].expanding().mean(),inplace=True)
df.head(10)


image.png


2.2 产生交易信号:即找出买入与卖出信号


# 找买入信号
# 当天的短期均线大于等于长期均线
condition1 = (df['ma_short'] >= df['ma_long'])
# 上一个交易日的短期均线小于长期均线
condition2 = (df['ma_short'].shift(1) < df['ma_long'].shift(1))
# 将买入信号当天的signal设为1
df.loc[condition1 & condition2, 'signal'] = 1
# 找卖出信号
# 当天的短期均线小于等于长期均线
condition1 = (df['ma_short'] <= df['ma_long'])
# 上一个交易日的短期均线大于长期均线
condition2 = (df['ma_short'].shift(1) > df['ma_long'].shift(1))
# 将买入信号当天的signal设为0
df.loc[condition1 & condition2,'signal'] = 0
# 浏览产生交易信号的日期
df[df['signal'].notnull()].head(10)

image.png


2.3 由交易信号计算每天股票仓位


我们用1表示满仓,0表示空仓。当出现买入信号之后,全仓买入,当出现卖出信号之后,全仓卖出。


因此,当交易信号signal为1时,第二天仓位position也会变为1,之后的仓位一直为1,直到出现卖出信号,仓位变为0。


注意:此处因为signal的计算运用了收盘价,是每天收盘之后产生的信号,所以仓位position在第二天才会发生改变。

例如2015-05-01产生买入信号,2015-05-02仓位才会变成1,满仓用1表示,空仓用0表示

将signal信号下移一格,表示第二天买入,用1表示满仓,0表示空仓


# 新建列Pos表示仓位,将交易信号下移一格,表示第二天买入,1表示满仓,0表示空仓
df['pos'] = df['signal'].shift()
# 向上填充,将买入之后的pos全部设置为1
df['pos'].fillna(method='ffill', inplace=True)
# 没有买入的pos全部设置为0
df['pos'].fillna(value=0,inplace=True)
# 预览仓位数据
df[(df['date']>='2015-02-24')&(df['date']<'2015-05-06')][['date','signal','pos']].head(20)


image.png


2.4 排除当天开盘就涨跌停导致无法交易的情况,此时仓位不能改变


注意:开盘涨跌停,是基本无法买入或者卖出股票的。


# 找出开盘涨停的日期:即今天的开盘价相对于昨天的收盘价上涨了9.7%以上,此处不用10%是因为由于4舍5入,涨停不一定就是10%
cond_cannot_buy = df['open'] > df['close'].shift(1) * 1.097
# 将开盘涨停且当前position为1时的'pos'设为空值
df.loc[cond_cannot_buy & (df['pos'] == 1),'pos'] = None
# 找出开盘跌停的日期,即今天的开盘价相对于昨天的收盘价跌了9.7%(1-0.097=0.903)
cond_cannot_sell = df['open'] < df['close'].shift(1) *0.903
# 将开盘跌停且当前position为0时的'pos'设为空值
df.loc[cond_cannot_sell & (df['pos'] == 0),'pos'] = None
# position为空的日期表示不能买卖。position仓位只能和前一个交易日保持一致
df['pos'].fillna(method='ffill', inplace=True)


2.5 计算资金曲线并绘图


# 资金曲线:假设起始资金为100万元的每天资金变化情况
# 首先计算资金曲线每天的涨跌幅,‘equity_change’表示资金每天的涨跌幅
# 当天空仓时,pos为0,资产涨幅为0
# 当天满仓时,pos为1,资产涨幅为股票本身的涨跌幅
df['equity_change'] = df['change_pct'] * df['pos']
# 根据每天的涨跌幅计算资金曲线
df['equity_curve'] = 1000000 * (df['equity_change'] + 1).cumprod()
df = df[['date' , 'change_pct','pos','equity_change','equity_curve']]
df.reset_index(inplace=True, drop=True)  # 重置索引,让他从0开始
df.head(10)


image.png


# 绘制资金曲线
plt.plot(df['equity_curve'])
plt.show()

b7ead3d7595a4976909feb112761e574.png


通过资金曲线我们可以看到,该只股票从2015年1月开始至今,通过该策略最高是1.8倍收益,后面又跌回去了…


当然这个策略只是在此处搭建框架做演示用的,实际策略参数等都需要根据具体情况进行调整。


3. 总结


本文详细的介绍了通过股票数据及均线策略构建股票回测框架的过程:


  1. 导入数据,计算涨跌幅


  1. 通过均线策略产生交易信号


  1. 通过交易信号计算每天仓位


  1. 排除涨跌停无法进行交易的情况


  1. 通过仓位计算每天资金曲线,回测


对于其他择时交易策略,我们只需更改上述框架中的交易信号产生部分,就可以实现回测啦。


后续待改进的地方,本文在计算资金曲线的过程中,没有考虑交易手续费,买入时的价格与当天涨幅不匹配(当天开盘价买入,资金涨幅与当天股票涨幅不是同等的)等问题,下期会写一个实际操作过程中的资金曲线,将这些问题包含进去。如果有不对的地方,欢迎提出来共同学习交流,谢谢!

如果内容对你有帮助,记得点赞、关注哦!也欢迎小伙伴们和我共同学习交流。


更多干货内容持续更新中…


相关文章
|
7天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1922 6
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
5天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
652 111
|
15天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2556 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
7天前
|
人工智能 弹性计算 数据库
阿里云优惠券种类解析:主要券种区别和适用群体及领取和使用指南
2026年阿里云构建了覆盖全用户的七类优惠券,本文逐一拆解了每类优惠券的核心规则、适用人群与使用技巧:大促限定的阶梯满减券分个人、企业双通道,最高可减800元;学生专属300元无门槛券支持全品类通用;按量付费用户可参与消费达标返券形成循环优惠;新用户有低门槛专享满减券尝鲜;老用户可领取系统自动发放的随机福利券;中大型企业迁云可申请最高100万元的专项补贴;云产品通用券还能在活动价基础上实现折上折。不同身份、不同采购场景的用户均可通过精准匹配对应优惠券,最大化享受优惠力度。
462 110
阿里云优惠券种类解析:主要券种区别和适用群体及领取和使用指南
|
13天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1624 2
|
15天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1428 2
|
17天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1500 55
|
2天前
Qoder 一周年 × Qwen3.8-Max 正式上线,多重好礼限时领
8月3日,Qwen3.8-Max 正式上线Qoder,迎来Qoder一周年。新老用户可领800次免费调用,下单再赠2000次;夜间(22:00–08:00)调用5折;邀请好友双方得积分与调用额度。
250 0