返回介绍

平台介绍

数据接口

机器量化分析(三)——模拟交易与回测

发布于 2023-06-23 16:57:51 字数 7031 浏览 0 评论 1 收藏 0

当我们的经验和策略通过代码的方式实现时,除了一些机器学习的评估方法,还需要通过模拟交易的方式来回测整个策略。策略整体在市场中的表现效果如何,该如何用量化的手段来评估,则是本篇要向大家介绍的内容—— 模拟交易与回测

话不多说马上进入正题,我们现在要做的,就是构建一套自己的模拟交易系统,并用这套系统来回测各种策略。为了让本文更接地气,作者不打算画各种程序流程图或拓扑图等,这样的 “ PPT Style ” 太不接地气了,我们换成以一个 交易员 的视角来思考问题。

模拟交易

股市的交易规则是实时的撮合交易,我们没办法也没必要做到实时的撮合交易,所以在模拟交易系统里,交易规则要简化为: 以下单当日的收盘价作为成交价 。实际上,各大量化平台也是这么做的,做得更细致一点的,可以设定一个参数:“ 滑点 ”——来控制模拟交易和实盘交易的误差。

有了这样一种简化,模拟交易就变得十分简单了——复杂的撮合交易机制简化成了以股票行情的收盘价作为成交价,剩下的只是简单的“ ”和“ ”的交易动作。作为交易的基本动作,号主专门用一个程序来封装,代码如下:Operator.py

import pymysql.cursors
import Deal

def buy(stock_code, opdate, buy_money):...

def sell(stock_code, opdate, predict):...

可见只是封装了 buysell 两个函数而已。

在 buy 函数里我定义了几个参数,分别是 股票代码、交易日期、交易金额 ;在 sell 函数里定义的几个参数分别是 股票代码、交易日期、交易量、交易类型(主动卖或止损卖) 。这几个参数见名知意,这里就不多解释了。

现在我们有了模拟交易的两个基本操作函数,但交易是双向的,我们买和卖的结果体现在哪里呢,这就需要一个 资产账户 来记录。细心的读者肯定发现了,上面的截图里引入了两个包,一个是数据库框架 pymysql,另一个则是 Deal 包,这其实是号主自定义的一个 python 程序,也就是模拟交易中的 资产账户 。先来看一下这个 Deal 文件到底是什么:

import pymysql.cursors

class Deal(object):
    cur_capital = 0.00
    cur_money_lock = 0.00
    cur_money_rest = 0.00
    stock_pool = []
    stock_map1 = {}
    stock_map2 = {}
    stock_map3 = {}
    stock_all = []
    ban_list = []

    ...
    

可见, Deal 类封装了一些参数,初始化函数就是为了更新这些参数。实际上,这些参数分别是 账户总资产,股票资产,现金资产,股票池,股票资产详情 等,整个 Deal 类就是一份 资产账户详单

关于资产账户的数据架构,底层的实现是 mysql 数据库,分成两张 sql 表来实现,一张是 账本表 (记录每一次的买和卖操作),表结构如下:

库名: stock 表名: my_capital

字段名字段类型字段说明
capitalDECIMAL(20, 4)总资产
money_lockDECIMAL(20, 4)股票资产
money_restDECIMAL(20, 4)现金资产
deal_actionVARCHAR2(45)交易动作
stock_codeVARCHAR2(45)股票代码
deal_priceDECIMAL(20, 4)成交价
stock_volINT(11)成交量
profitDECIMAL(20, 4)收益额
profit_rateDECIMAL(20, 4)收益率
bzVARCHAR2(45)备注
state_dtVARCHAR2(45交易日期
seqINT(11)序号(用作表主键)

另一张则是持仓表,表结构如下:

库名: stock 表名: my_stock_pool

字段名字段类型字段说明
stock_codeVARCHAR2(45)股票代码
buy_priceDECIMAL(20, 2)买入价
hold_volINT(11)持仓量(单位:股)
hold_daysINT(11)持仓天数(只计算交易日)

对于交易来说,只需要持仓股票代码和持仓量即可,买入价是为了测算收益,持仓天数则是为了某些策略用的(比如策略对持仓天数有限制时)。

至此,一个最简单的模拟交易过程就完成了,从交易的角度来看,就是通过 buy 和 sell 函数对 Deal 类(资产账户) 里的数据做 写操作 ,比如,买入股票就是扣除现金资产,增加股票资产,同时在持仓表中增加相应记录;卖出股票则是反向操作。

策略回测

有了上述一套模拟交易过程,接下来我们要考虑的就是策略层面的问题了。从交易的角度来看,策略是整个交易过程的入口,是逻辑和决策层。笔者直接用 main 函数来写策略了:

if __name__ == '__main__':
    # 先清空之前的测试记录

    # 建回测时间序列

    # 开始模拟交易
    for i in range(1, len(date_seq)):
        # 选股初始化模块

        # 交易预警模块

        # 模型训练模块

        # 买卖点判断模块(包括但不限于模型的预测结果)

        # 仓位管理

        # 交易执行模块

    # 结果数据可视化模块

代码中简明清晰地展示了号主策略的回测框架:首先清空之前的测试记录,然后 取回测时间段内的交易日序列 ,通过 for 循环来遍历这个序列,每一次迭代,都是一个交易日,都包含了策略的多个功能模块,上一篇的策略并非全部用到这些模块,未用到的下面以“可选”标记:

选股初始化模块(可选): 这个模块的功能主要是选股,由于涉及的逻辑和计算量可能非常庞大,并非每日执行,可以每隔 x 个交易日执行一次。

交易预警模块(可选): 当模型的预测存在结构性误差时,往往需要该预警模块来作为买卖点判断的补充,比如大趋势转变,基本面变化,政策变化等。

模型训练模块: 在策略中,建模方式分单次建模和推进建模,区别是推进建模每日收盘后会根据最新交易日的数据进行重训练,对于推进建模,该模块是必须的(在上篇的策略中,就是应用的推进建模)。

买卖点判断: 包含但不限于模型的预测结果,往往结合其他的逻辑或信号进行判断(比如预警模块给出的信号),最终确定是否买卖。

仓位管理: 确定交易股票的配仓(买入金额或卖出股数)。

交易执行模块: 即上文详述的模拟交易过程,Operator.py 里的 buy 和 sell 函数。

结果数据可视化模块: 当跑完回测后,给出一个直观的结果(折线图,柱图等)。

接下来,让我们看一下上一篇中的那套 portfolio 的回测结果。为了跟测试集的时间序列保持连续,现在 取 2018.03.01~2018.04.01 区间的交易日序列作为回测区间 。首先来看一下投资组合的 市场方向(特征值最小) 的收益情况:

图中 蓝线 代表 大盘的收益曲线 (收益 = 当日收盘价 / 首日收盘价),在这一个月的回测周期中, 大盘指数3273 点震荡到 3168 点, 投资组合 的收益曲线跟大盘趋势基本 保持一致 ,在期末的收益率为 0.39% ,略微跑赢大盘。

接下来再看这套投资组合的账单表:

总计 7 次卖出操作,其中 3 次止盈, 3 次超时平仓, 1 次止损。从收益情况来看, 7 次操作中 5 次盈利, 2 次亏损。

作为对比,我们再来看一下投资组合的 最大收益方向(次最小特征值)

可见,投资组合的收益曲线 背离大盘 。在期末的收益率达到 9.45% ,明显跑赢市场。接下来再看这套投资组合的账单详情:

总计 9 次卖出操作,其中 4 次止盈, 2 次超时平仓, 2 次止损, 1 次预测卖。从收益情况来看, 7 次盈利, 2 次亏损。

与市场方向相比,操作数变多,止盈和止损次数均多于前次。从操作和收益来看也印证了高风险高收益的道理。

至此, 构建投资组合==>回测验证策略 的流程已经结束。详细代码清单与功能如下: https://www.wenjiangs.com/wp-content/uploads/2024/09/code_3.rar

文件名功能
DC.py【数据预处理】将本地存储的日基础行情整合成一份训练集。
Model_Evaluate.py【模型评估】通过回测+推进式建模的方式对模型进行评估,主要计算查准率 Precision,查全率 Recall,F1 分值,并存入结果表。
Portfolio.py【仓位管理】基于马科维茨投资组合理论,计算一段时间序列内投资组合的风险、仓位配比和夏普率,有市场方向和最佳收益方向两种结果。
Deal.py.py【模拟交易】封装类,用于模拟交易过程中获取最新的资产账户相关数据。
Operator.py【模拟交易】封装函数,用于模拟交易过程中执行买和卖操作。
Cap_Update_daily.py【模拟交易】封装函数,用于在回测过程中,每日更新资产表中相关数据。
Filter.py【策略回测】封装函数,用于在回测过程中,处理一些简单的逻辑(更新持仓天数,买卖顺序等)。
main.py【策略回测】策略的框架,回测的主函数。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

mb_Vy62S98i 2024-09-26 17:30:48

没有Operator.py代码

~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文