ETF轮动+RSRS择时,加上卡曼滤波:年化48.41%,夏普比1.89

news2024/11/28 4:30:24

原创文章第112篇,专注“个人成长与财富自由、世界运作的逻辑, AI量化投资”。

昨天我们设计了一个不错的策略:etf动量轮动+大盘择时:年化30%的策略。ETF动量轮动+RSRS择时,动量其实一直都有效,如何定义动量可以有优化空间。今天我们继续来优化它。

01 从tushare下载ETF数据

在现实世界中,我们会交易指数对应的ETF而非指数,从理论上讲,收益只会更高,因为指数本身不包含分红之类的信息。

如下是一些常用的ETF,包括宽基:上证50, 沪深300,创业板,创业板50,行业如医药,消费,红利,新能车等。

etfs = ['510300.SH',  # 沪深300ETF
        '159949.SZ',  # 创业板50
        '510050.SH',  # 上证50ETF
        '159928.SZ',  # 中证消费ETF
        '510500.SH',  # 500ETF
        '159915.SZ',  # 创业板 ETF
        '512120.SH',  # 医药50ETF
        '159806.SZ',  # 新能车ETF
        '510880.SH',  # 红利ETF
        ]

download_etfs(etfs)

dowload_etfs里面调用了get_etf

def download_etfs(etfs):
    for etf in etfs:
        print(etf)
        df = get_etf(etf)
        print(df)
        if df is None or len(df) == 0:
            print('error')
            continue
        with pd.HDFStore('{}/index.h5'.format(DATA_DIR_HDF5.resolve())) as store:
            store[symbol] = df

这里需要特别注意一点,就是etf有“复权信息”,一般我们把复权因子直接乘到对应的OHLV数据上。

def get_etf(code):
    # 拉取数据
    df = pro.fund_daily(**{
        "trade_date": "",
        "start_date": "",
        "end_date": "",
        "ts_code": code,
        "limit": "",
        "offset": ""
    }, fields=[
        "ts_code",
        "trade_date",
        "open",
        "high",
        "low",
        "close",
        "vol"
    ])

    df.rename(columns={'trade_date': 'date', 'ts_code': 'code', 'vol': 'volume'}, inplace=True)
    df.set_index('date', inplace=True)
    # 拉取数据
    df_adj = pro.fund_adj(**{
        "ts_code": code,
        "trade_date": "",
        "start_date": "",
        "end_date": "",
        "offset": "",
        "limit": ""
    }, fields=[
        "trade_date",
        "adj_factor"
    ])
    df_adj.rename(columns={'trade_date': 'date'}, inplace=True)
    df_adj.set_index('date', inplace=True)
    df = pd.concat([df, df_adj], axis=1)
    df.dropna(inplace=True)
    for col in ['open', 'high', 'low', 'close']:
        df[col] *= df['adj_factor']
    df.index = pd.to_datetime(df.index)
    df.sort_index(ascending=True, inplace=True)
    return df

02 换成真实的ETF回测

symbols = ['510300.SH', '159915.SZ']
names = ['order_by']
fields = ['Slope($close,20)']
# fields = ['$close/Ref($close,20)-1']

from engine.bt_engine import BacktraderEngine
from datetime import datetime

e = BacktraderEngine(init_cash=1000000, benchmark='399006.SZ', start=datetime(2014, 1, 1))
e.add_features(symbols, names, fields)
e.add_extra('000300.SH', fields=['RSRS($high,$low,18,600)', '$RSRS_beta<0.8'], names=['RSRS', 'signal'])

from engine.strategy.algos import SelectTopK, PickTime, WeightEqually

e.run_algo_strategy([SelectTopK(K=1), PickTime(), WeightEqually()])
e.analysis(pyfolio=False)

年化31.11%, 回撤降为31.06%。

若把RSRS择时标准更换为ETF本身,即510500.SH。

年化提升到38.17%, 回撤降至23.57%,夏普比达到1.55

symbols = [
    '510050.SH',  # 上证50ETF
    #'159928.SZ',  # 中证消费ETF
    '510300.SH',  # 沪深300ETF
    '159915.SZ',  # 创业板50
    #'512120.SH',  # 医药50ETF
    #'159806.SZ',  # 新能车ETF
    #'510880.SH',  # 红利ETF
]

添加行业进来轮动,会降低收益率,原因待分析。

03 卡尔曼过滤

添加一个卡尔曼滤波的函数:

from pykalman import KalmanFilter


class KF(Rolling):

    def __init__(self, feature, damping=1, N=1):
        super(KF, self).__init__(feature, N, "kalman")
        self.damping = damping

    def _load_internal(self, instrument):
        series = self.feature.load(instrument)
        series = series.fillna(0.0)
        observation_covariance = 0.15
        initial_value_guess = 1
        transition_matrix = 1
        transition_covariance = 0.1

        kf = KalmanFilter(transition_matrices=[1],
                          observation_matrices=[1],
                          initial_state_mean=0,
                          initial_state_covariance=1,
                          observation_covariance=1,
                          transition_covariance=.01)
        pre, _ = kf.smooth(np.array(series))
        pre = pre.flatten()
        series = pd.Series(pre, index=series.index)
        return series

对昨天的“动量信号”进行滤波etf动量轮动+大盘择时:年化30%的策略。

年化提升到48.41%,回撤降至21.48%,夏普比达到1.89!

names = ['order_by']
fields = ['KF(Slope($close,20))']

明天继续可以对RSRS进行标准分的优化。

小结:

ETF动量轮动是个好策略,卡尔曼滤波是一个好策略,RSRS是个不错的指标。

代码、数据已经上传到星球-量化专栏。

我的开源项目及知识星球

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

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

相关文章

java图形验证码到底是怎么生成的?

真正的大师,永远都怀着一颗学徒的心&#xff01; 一、项目简介 java图形验证码到底是怎么生成的&#xff1f;支持中文、gif、算术等类型 二、实现功能 支持gradle方式的引入 支持maven方式引入 支持jar包下载 支持10种漂亮的内置字体&#xff0c;不依赖系统字体 支持输出…

Codeforces Round #835 (Div. 4) A~G

比赛链接&#xff1a;https://codeforces.com/contest/1760 A. Medium Number 题目大意&#xff1a; t组测试&#xff0c;每组给三个数求中位数。 代码&#xff1a; #include<bits/stdc.h> #define rep(i,a,b) for (register int ia;i<b;i) #define per(i,a,b) …

无人驾驶(二)---室外导航之RTK配置与接入及GPS与UTM坐标转换

1. RTK 概述 RTK 载波相位差分技术&#xff0c;是实时处理两个测量站载波相位观测量的差分方法&#xff0c;将基准站采集的载波相位发给用户接收机&#xff0c;进行求差解算坐标。一般包含流动站 (移动站) 和基准站 (基站) 。本文中RTK定位采用千寻定位&#xff0c; 参考的也是…

39Java System类

目录 System类 1.定义 2.预备知识 3.常用方法 (1).currentTimeMillis返回系统时间 (2).exit终止虚拟机 (3).arraycopy拷贝数组 System类 1.定义 Java System类是一个提供与系统相关的方法 System类所在包为java.lang包&#xff0c;因此在使用的时候不需要进行导包。并且Sy…

外汇天眼:FCA 已向交易应用程序运营商发出警告,要求其停止交易游戏化

英国市场监管机构希望交易应用程序开发商重新考虑关键设计元素。 根据新的研究&#xff0c;游戏化可能会导致类似赌博的行为。 负责监管英国金融市场的金融行为监管局 ( FCA )周一发布了有关交易应用程序设计的市场警告。金融业监管机构担心零售交易越来越像一场游戏&#xff…

A. Row GCD(更相减损术+gcd的性质)

Problem - 1458A - Codeforces 给你两个正整数序列a1,...,an和b1,...,bm。对于每个j1,...,m&#xff0c;求a1bj,...,anbj的最大公除数。 输入 第一行包含两个整数n和m&#xff08;1≤n&#xff0c;m≤2⋅105&#xff09;。 第二行包含n个整数a1,...,an&#xff08;1≤ai≤101…

Linux学习记录——이 基本指令(2)

接着上一篇继续写指令。 man指令 man指令是一个手册功能的指令&#xff0c;可以查看系统内的接口&#xff0c;指令等等&#xff0c;也可以查看一个指令有什么用法。如果是需要查看C语言中的指令&#xff0c;比如printf&#xff0c;就可以man 3 printf。不过man大多数情况是用…

旋转数组的最小数字、二维数组中的查找、调整数组顺序使奇数位于偶数前面

文章目录1、 旋转数组的最小数字2、调整数组顺序使奇数位于偶数前面3、二维数组中的查找1、 旋转数组的最小数字 本题考点&#xff1a;核心考点&#xff1a;数组理解&#xff0c;二分查找&#xff0c;临界条件 牛客链接 题目描述&#xff1a; 有一个长度为 n 的非降序数组&am…

简述Spring Bean生命周期

前言 在Spring容器里&#xff0c;Bean的完整生命周期比较长。但是我们必须要掌握它。 Bean周期总览 Bean周期总体如下所示。 接下来会简单讲下各个步骤的主要功能。 Bean实例化 必须步骤。 此步骤主要是实例化一个Bean&#xff0c;例如new一个对象。这个步骤主要是设置be…

运动无线耳机什么牌子好?六款实用性不错的运动耳机推荐

跑步的过程如果没有音乐真的很难继续跑下去&#xff0c;当然&#xff0c;有了音乐的加入&#xff0c;运动过程也变得更加有动力&#xff0c;烦恼的心情也会随着烟消云散。一款好的运动耳机能让我们运动变得更加轻松&#xff0c;什么运动耳机值得大家入手&#xff1f;今天我就来…

计算机毕业设计java+ssm舞蹈管理系统(源码+系统+mysql数据库+Lw文档)

项目介绍 舞蹈管理系统是使用JAVA的SSM技术&#xff0c;MySQL作为数据库开发&#xff0c;用户通过查看舞蹈信息&#xff0c;在线预约课程&#xff0c;实现舞蹈管理。首先对本论文进行分析后&#xff0c;提出平台的相关技术&#xff0c;然后整理系统的需求分析&#xff0c;根据…

_c++11( lambda)

lambda表达式1 C98中的一个例子2 lambda表达式3 lambda表达式语法4 函数对象与lambda表达式1 C98中的一个例子 在C98中&#xff0c;如果想要对一个数据集合中的元素进行排序&#xff0c;可以使用std::sort方法。 #include <algorithm> #include <functional> voi…

[附源码]计算机毕业设计JAVA教师业绩考核系统

[附源码]计算机毕业设计JAVA教师业绩考核系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

Sharding-JDBC 基础

Sharding-JDBC 是当当网开源的适用于微服务的分布式数据访问基础类库&#xff0c;完整的实现了分库分表&#xff0c;读写分离和分布式主键功能&#xff0c;并初步实现了柔性事务。 从 2016 年开源至今&#xff0c;在经历了整体架构的数次精炼以及稳定性打磨后&#xff0c;如今…

AQS源码解析 3.lock() unlock() 加锁解锁过程

AQS源码解析 3.lock() & unlock() 加锁解锁过程 Lock() 过程 这里使用 ReentrantLock 的公平锁去看 AQS 的加锁过程。在 ReentrantLock 的实现中&#xff0c;其默认构造的锁是非公平锁。 详细流程图 尝试获取锁 构造节点入队过程 在队列中被挂起 被唤醒重新抢锁的过…

说一下 ArrayList 和 LinkedList 的区别?

本文已收录到 AndroidFamily&#xff0c;技术和职场问题&#xff0c;请关注公众号 [彭旭锐] 提问。 前言 大家好&#xff0c;我是小彭。 在上一篇文章里&#xff0c;我们聊到了基于动态数组 ArrayList 线性表&#xff0c;今天我们来讨论一个基于链表的线性表 —— LinkedList…

JavaScript构造函数和原型:ES5 中的新增方法

ES5 新增方法概述 ES5 中给我们新增了一些方法&#xff0c;可以很方便的操作数组或者字符串&#xff0c;这些方法主要包括&#xff1a; 数组方法 字符串方法 对象方法 数组方法 迭代(遍历)方法&#xff1a;forEach()、map()、filter()、some()、every()&#xff1b; arr…

AVL右旋转思路分析与图解

AVL树右旋转思路分析与图解 其实我们前面讲过了左旋转之后再学习右旋转就会非常的简单了, 因为我们的右旋转相对我们的左旋转只是换了一个方向而已, 那么下面我们就来讲解右旋转的实现 对于数列{10, 12, 8, 9 ,7, 6} , 当我们插入6的时候leftHeight() - rightHeight() > 1…

Linux 之 Ubuntu 代码开发工具 Visual Studio Code(VSCode) 的安装与一些常用插件配置的简单整理

Linux 之 Ubuntu 代码开发工具 Visual Studio Code(VSCode) 的安装与一些常用插件配置的简单整理 目录 Linux 之 Ubuntu 代码开发工具 Visual Studio Code(VSCode) 的安装与一些常用插件配置的简单整理 一、简单介绍 二、Visual Studio Code 下载与安装 三、 Visual Studio…

【操作系统】第一章总结

1.1 操作系统介绍 1.1.1 操作系统的概念、功能和目标 1.1.1 操作系统的概念、功能和目标&#xff08;系统资源的管理者、提供接口、作为扩充机器、虚拟机&#xff09;_StudyWinter的博客-CSDN博客 1.1.2 操作系统的特点 1.1.2 操作系统的特征&#xff08;并发、共享、虚拟、…