【python量化交易】qteasy使用教程07——创建更加复杂的自定义交易策略

news2025/1/13 7:42:06

创建更加复杂的自定义交易策略

  • 使用交易策略类,创建更复杂的自定义策略
    • 开始前的准备工作
    • 本节的目标
    • 继承Strategy类,创建一个复杂的多因子选股策略
      • 策略和回测参数配置,并开始回测
    • 本节回顾

使用交易策略类,创建更复杂的自定义策略

qteasy是一个完全本地化部署和运行的量化交易分析工具包,Github地址在这里,并且可以通过pip安装:

$ pip install qteasy -U

qteasy具备以下功能:

  • 金融数据的获取、清洗、存储以及处理、可视化、使用
  • 量化交易策略的创建,并提供大量内置基本交易策略
  • 向量化的高速交易策略回测及交易结果评价
  • 交易策略参数的优化以及评价
  • 交易策略的部署、实盘运行

通过本系列教程,您将会通过一系列的实际示例,充分了解qteasy的主要功能以及使用方法。

开始前的准备工作

在开始本节教程前,请先确保您已经掌握了下面的内容:

  • 安装、配置qteasy —— QTEASY教程1
  • 设置了一个本地数据源,并已经将足够的历史数据下载到本地——QTEASY教程2
  • 学会创建交易员对象,使用内置交易策略,——QTEASY教程3
  • 学会使用混合器,将多个简单策略混合成较为复杂的交易策略——QTEASY教程4
  • 了解自定策略的基础——QTEASY教程5 ,QTEASY教程6

在QTEASY文档中,还能找到更多关于使用内置交易策略、创建自定义策略等等相关内容。对qteasy的基本使用方法还不熟悉的同学,可以移步那里查看更多详细说明。

qteasy的内核被设计为一个兼顾高速执行以及足够的灵活性的框架,理论上您可以实现您所设想的任何类型的交易策略。

同时,qteasy的回测框架也做了相当多的特殊设计,可以完全避免您无意中在交易策略中导入"未来函数",确保您的交易策略在回测时完全基于过去的数据,同时也使用了很多预处理技术以及JIT技术对内核关键函数进行了编译,以实现不亚于C语言的运行速度。

不过,为了实现理论上无限可能的交易策略,仅仅使用内置交易策略以及策略混合就不一定够用了,一些特定的交易策略,或者一些特别复杂的交易策略是无法通过内置策略混合而成的,这就需要我们使用qteasy提供的Strategy基类,基于一定的规则创建一个自定义交易策略了。

本节的目标

在本节中,我们将介绍qteasy的交易策略基类,通过一个具体的例子详细讲解如何基于这几个基类,创建一个只属于您自己的交易策略。为了说明

继承Strategy类,创建一个复杂的多因子选股策略

在这个例子中,我们使用

import qteasy as qt
import numpy as np

def market_value_weighted(stock_return, mv, mv_cat, bp_cat, mv_target, bp_target):
    """ 根据mv_target和bp_target计算市值加权收益率,在策略中调用此函数计算加权收益率

    """
    sel = (mv_cat == mv_target) & (bp_cat == bp_target)
    mv_total = np.nansum(mv[sel])
    mv_weight = mv / mv_total
    return_total = np.nansum(stock_return[sel] * mv_weight[sel])
    return return_total


class MultiFactors(qt.FactorSorter):
    """ 开始定义交易策略
    """
    def __init__(self, pars: tuple = (0.5, 0.3, 0.7)):
    	"""交易策略的初始化参数"""
        super().__init__(
                pars=pars,  
                par_count=3,  # 策略的可调参数有三个
                par_types=['float', 'float', 'float'],  # 参数1:大小市值分类界限,参数2:小/中bp分界线,参数3,中/大bp分界线
                par_range=[(0.01, 0.99), (0.01, 0.49), (0.50, 0.99)],
                name='MultiFactor',
                description='根据Fama-French三因子回归模型估算HS300成分股的alpha值选股',
                strategy_run_timing='close',  # 在周期结束(收盘)时运行
                strategy_run_freq='m',  # 每月执行一次选股(每周或每天都可以)
                strategy_data_types='pb, total_mv, close',  # 执行选股需要用到的股票数据
                data_freq='d',  # 数据频率(包括股票数据和参考数据)
                window_length=20,  # 回测时的视窗长度为20天
                use_latest_data_cycle=True,  # 设置使用最新的数据
                reference_data_types='close-000300.SH',  # 选股需要用到市场收益率,使用沪深300指数的收盘价计算,因此设置HS300指数的收盘价作为参考数据传入
                max_sel_count=10,  # 最多选出10支股票
                sort_ascending=True,  # 选择因子最小的股票
                condition='less',  # 仅选择因子小于某个值的股票
                lbound=0,  # 仅选择因子小于0的股票
                ubound=0,  # 仅选择因子小于0的股票 
        )
    
    def realize(self, h, **kwargs):
		""" 策略的选股逻辑在realize()函数中定义
		"""
        size_gate_percentile, bp_small_percentile, bp_large_percentile = self.pars
        # 读取投资组合的数据PB和total_MV的最新值
        pb = h[:, -1, 0]  # 当前所有股票的PB值
        mv = h[:, -1, 1]  # 当前所有股票的市值
        pre_close = h[:, -2, 2]  # 当前所有股票的前收盘价
        close = h[:, -1, 2]  # 当前所有股票的最新收盘价

        # 读取参考数据(r)
        market_pre_close = r[-2, 0]  # HS300的昨收价
        market_close = r[-1, 0]  # HS300的收盘价

        # 计算账面市值比,为pb的倒数
        bp = pb ** -1
        # 计算市值的50%的分位点,用于后面的分类
        size_gate = np.nanquantile(mv, size_gate_percentile)
        # 计算账面市值比的30%和70%分位点,用于后面的分类
        bm_30_gate = np.nanquantile(bp, bp_small_percentile)
        bm_70_gate = np.nanquantile(bp, bp_large_percentile)
        # 计算每只股票的当日收益率
        stock_return = pre_close / close - 1

        # 根据每只股票的账面市值比和市值,给它们分配bp分类和mv分类
        # 市值小于size_gate的cat为1,否则为2
        mv_cat = np.ones_like(mv)
        mv_cat += (mv > size_gate).astype('float')
        # bp小于30%的cat为1,30%~70%之间为2,大于70%为3
        bp_cat = np.ones_like(bp)
        bp_cat += (bp > bm_30_gate).astype('float')
        bp_cat += (bp > bm_70_gate).astype('float')

        # 获取小市值组合的市值加权组合收益率
        smb_s = (market_value_weighted(stock_return, mv, mv_cat, bp_cat, 1, 1) +
                 market_value_weighted(stock_return, mv, mv_cat, bp_cat, 1, 2) +
                 market_value_weighted(stock_return, mv, mv_cat, bp_cat, 1, 3)) / 3
        # 获取大市值组合的市值加权组合收益率
        smb_b = (market_value_weighted(stock_return, mv, mv_cat, bp_cat, 2, 1) +
                 market_value_weighted(stock_return, mv, mv_cat, bp_cat, 2, 2) +
                 market_value_weighted(stock_return, mv, mv_cat, bp_cat, 2, 3)) / 3
        smb = smb_s - smb_b
        # 获取大账面市值比组合的市值加权组合收益率
        hml_b = (market_value_weighted(stock_return, mv, mv_cat, bp_cat, 1, 3) +
                 market_value_weighted(stock_return, mv, mv_cat, bp_cat, 2, 3)) / 2
        # 获取小账面市值比组合的市值加权组合收益率
        hml_s = (market_value_weighted(stock_return, mv, mv_cat, bp_cat, 1, 1) +
                 market_value_weighted(stock_return, mv, mv_cat, bp_cat, 2, 1)) / 2
        hml = hml_b - hml_s

        # 计算市场收益率
        market_return = market_pre_close / market_close - 1

        coff_pool = []
        # 对每只股票进行回归获取其alpha值
        for rtn in stock_return:
            x = np.array([[market_return, smb, hml, 1.0]])
            y = np.array([[rtn]])
            # OLS估计系数
            coff = np.linalg.lstsq(x, y)[0][3][0]
            coff_pool.append(coff)

        # 以alpha值为股票组合的选股因子执行选股
        factors = np.array(coff_pool)

        return factors

策略和回测参数配置,并开始回测

定义好上面的策略之后,就可以开始进行回测了,我们需要在qteasy中创建一个交易员对象,操作前面创建的策略:

shares = qt.filter_stock_codes(index='000300.SH', date='20190501')  # 选择股票池,包括2019年5月以来所有沪深300指数成分股
# 设置回测的运行参数
qt.config(mode=1,  # mode=1表示回测模式
       invest_start='20160405',  # 回测开始日期
       invest_end='20210201',  # 回测结束日期
       asset_type='E',  # 投资品种为股票
       asset_pool=shares,  # shares包含同期沪深300指数的成份股
       trade_batch_size=100,  # 买入批量为100股
       sell_batch_size=1,  # 卖出批量为整数股
       trade_log=True,  # 生成交易记录
       )
       
#  开始策略的回测

alpha = MultiFactors()  # 生成一个交易策略的实例,名为alpha
op = qt.Operator(alpha, signal_type='PT')  # 生成交易员对象,操作alpha策略,交易信号的类型为‘PT',意思是生成的信号代表持仓比例,例如1代表100%持有股票,0.35表示持有股票占资产的35%
op.op_type = 'stepwise'  # 运行模式为步进模式
op.set_blender('1.0*s0', "close")  # 交易策略混合方式,只有一个策略,不需要混合
op.run()  # 开始运行

在这里插入图片描述

本节回顾

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

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

相关文章

mapreduce | 自定义Partition分区(案例2)

1.需求 统计每个手机号消费总金额,按照消费金额降序排序,最终联通、电信、移动分别写入不同的文件。 130、131、132(联通) 133(电信) 135、136、137、138、139 (移动) 手机号,消费记…

MFC编程之设计美丽的对话框

目录 写在前面: Part 1:美美的设计一下计算器的布局 1.描述文字: ​编辑 2.ID: Part 2:美美熟悉一下计算器的工作流程 Part 3:美美设计一下控件功能 1.edit control: 2.相关变量初始化&…

2.分布式-算法

目录 一、限流算法有哪些? 1.计数器算法(Counter-Based Algorithm) 2.固定窗口算法(Fixed Window) 3.滑动窗口算法(Sliding Window) 4.令牌桶算法(Token Bucket) 5.…

PyQt5中的QtDesigner窗口

文章目录 1. 简介2. QtDesigner的MainWindow2.1 创建MainWindow2.2 添加组件2.3 预览2.4 查看对应的Python代码2.5 保存窗口并命名为login.ui,如下所示2.6对ui文件进行转换得到.py原件 3. 窗口常用属性及说明3.1 设置对象名称3.2 改变标题名字3.3 修改窗口大小 4. 更…

pdf 版面分析与优化策略

1. 简介 版面分析作为RAG的第一步工作,其效果对于下游工作至关重要。 前常见的 PDF 解析方法包括三种 基于规则:根据 PDF 的组织特征确定每个部分的规则(风格和内容)缺点:不通用(PDF格式不固定&#xf…

DSA理解理解蓝桥杯例题signature

一、历史 1991年8月,NIST(Nation Institute of Standards and Technology,美国国家标准技术研究所)提出了数字签名算法(DSA)用于他们的数字签名标准(DSS)中。 DSA是算法&#xff0c…

C++的数据结构(四):队列

在数据结构中,队列(Queue)是一种特殊的线性表,只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。队列中没有元素时,称为空队列。队列的…

python数据分析——matplotlib可视化基础

参考资料:活用pandas库 # 导入库 import pandas as pd import matplotlib.pyplot as plt # 导入数据 anscombepd.read_csv(r"...\seaborn常用数据案例\anscombe.csv") anscombe.head() 大多数基本图表的名字以plt.plot开头。 # 创建数据子集 # 只包含数…

消息中间件Kafka(PHP版本)

小编最近需要用到消息中间件,有需要要复习一下以前的东西,有需要的自取,强调一点,如果真的想了解透彻,一定要动手,脑袋会了不代表就会写了 Kafka是由Scala和Java编写。Kafka是一种高吞吐量的分布式发布订阅…

py黑帽子学习笔记_环境准备

1 下载os装os 下载一个kali虚机镜像然后用虚机管理软件创虚机,装完如下图,我用的版本是2024.1的版本kali-linux-2024.1-installer-amd64,可以从镜像站下载,官网下的慢还断网Index of /kali-images/kali-2024.1/ | 清华大学开源软…

AI 问答 API 对接说明

我们知道,市面上一些问答 API 的对接还是相对没那么容易的,比如说 OpenAI 的 Chat Completions API,它有一个 messages 字段,如果要完成连续对话,需要我们把所有的上下文历史全部传递,同时还需要处理 Token…

47岁古天乐唯一承认女友约「御用阿妈」过母亲节

日前关宝慧在IG晒出一张聚会照,并写道:「预祝各位#母亲节快乐🌹#dinner #happy #friends #好味」相中所见,前TVB金牌监制潘嘉德、卢宛茵、黄𨥈莹、黎萨达姆都有出席饭局。 当中黄𨥈莹身穿卡其色西装褛&…

【35分钟掌握金融风控策略24】定额策略实战

目录 基于客户风险评级的定额策略 确定托底额度和盖帽额度 确定基础额度 基于客户风险评级确定风险系数 计算最终授信额度 确定授信有效期 基于客户风险评级的定额策略 在开发定额策略时,精准确定客户的基础额度是一个关键步骤,通常会基于客户的收…

整体安全设计

人员和资产的安全是当今许多组织的最高优先事项之一。随着暴力事件在美国各地盛行——枪击事件、袭击、内乱等——建筑物业主必须为其建筑物及其居住者的安全做好计划。 为了创造一个安全的环境,新设施或园区的安全设计必须超越基本的摄像头和访问控制设备&#xf…

纯血鸿蒙APP实战开发——首页下拉进入二楼效果案例

介绍 本示例主要介绍了利用position和onTouch来实现首页下拉进入二楼、二楼上划进入首页的效果场景,利用translate和opacity实现动效的移动和缩放,并将界面沉浸式(全屏)显示。 效果图预览 使用说明 向下滑动首页页面超过触发距…

【Linux】centos7安装软件(rpm、yum、编译安装),补充:查找命令的相关文件路径,yum安装mysql

【Linux】技术上,Linux是内核。而术语上,我们通常说的Linux是完整的操作系统,其实称为"Linux发行版",是将Linux内核和应用系统打包,由不同的发行家族发行了不同版本。Linux发行版众多,主要有RedH…

HCIP-Datacom-ARST自选题库_07_割接【35道题】

一、单选题 1.在割接的测试阶段,符合以下哪一种情况的可以判断为割接成功? 网络承载的上层应用业务测试正常 网络设备的配置查看结果正常 网络流量路径正常 路由协议运行正常 2.在割接的测试阶段中,表明已经完成测试的标准是: IP设备的配置查看结…

org.postgresql.util.PSQLException: 错误: 关系 “dual“ 不存在

springboot 项目连接 postgreps,启动时报错 org.postgresql.util.PSQLException: 错误: 关系 "dual" 不存在。 查阅资料后发现这是由配置文件中的配置 datasource-dynamic-druid-validationQuery 导致的 spring:datasource:druid:stat-view-servlet:ena…

二叉树介绍

引入 定义 区别 定义不同 形态不同 基本形态

Ubuntu18.04解决有线网卡连接问题(不更新内核成功版)

https://www.realtek.com/Download/List?cate_id584 (需要翻一下) 不想自己去下载,直接去我资源里下载我上传的包就好啦(😂😂😂刚刚看了下别人下载要VIP还是自己去网站下很快的) 下载后解压,在…