2.1.2 一个关于y=ax+b的故事

跳转到根目录:知行合一:投资篇

已完成:
1、投资&技术
  1.1.1 投资-编程基础-numpy
  1.1.2 投资-编程基础-pandas
  1.2 金融数据处理
  1.3 金融数据可视化
2、投资方法论
  2.1.1 预期年化收益率
  2.1.2 一个关于y=ax+b的故事
3、投资实证
  [3.1 2023这一年] 被鸽

文章目录

  • 1. 系统自己画!最佳拟合线
    • 1.1. 沪深300的最佳拟合线
    • 1.2. 横向对比:一个个算
    • 1.3. 横向对比:数据标准化
    • 1.4. 看图说话
  • 2. 系统自己算!线性回归
    • 2.1. 沪深300线性回归,斜率0.00099414
    • 2.2. 沪深300线性回归的年化,年化8.5%
    • 2.3. 沪深300首尾点的年化,4.72%
    • 2.4. 中证500线性回归,斜率0.0008
    • 2.5. 中证500线性回归的年化
    • 2.6. 中证500首尾点的年化
  • 3. 总结

当看到一个在k线图上画直线的时候,斜率是可以自动计算的吗?

最佳拟合的直线,计算出来的斜率是多少?最佳拟合直线代表的年化是多少?

1. 系统自己画!最佳拟合线

1.1. 沪深300的最佳拟合线

顾名思义,这就是对于散点图,画一条最佳拟合的直线。那什么又叫最佳拟合线?

最佳拟合直线是指,我们可以找到一条直线,样本点到该直线的[离差平方和]达到最小的直线。这条直线用公式y = ax + b表示。

a表示回归系数,b表示截距。

再简单的说,就是存在一条线,这条线,能让各个点,都比较“满意”地分布在其上下。

我们拿沪深300的历史收盘价作为散点图,来看看其所谓的最佳拟合线是什么样的。

import qstock as qs
import seaborn as sns
import numpy as np

sh300=qs.get_data('510300')
# 因为设想中,x轴,可以是一个顺序的数组,比如从0开始往后数,step为1。这其实就是暗合着,随着时间的增加,close是否能拟合一条向上的直线?
sh300['day'] = np.arange(0, sh300.shape[0], 1)

sns.set_style("white")
gridobj = sns.lmplot(x="day", y="close", data=sh300, 
                     ci=95, scatter_kws={'color': 'orange'}, line_kws={'color': 'green'}, markers='o')

1.2. 横向对比:一个个算

看过了沪深300,肯定会有疑惑啊,总是要横向对比的吧?比如沪深300和中证500、券商ETF、红利ETF、房地产ETF、黄金ETF等标的,能进行横向对比来看谁的斜率(赚钱效应)更好吗?

Of course ,动手!

import qstock as qs
import seaborn as sns
import numpy as np

stocks_info = [
    {'code': '510300', 'name': '沪深300'},
    {'code': '510500', 'name': '中证500'},
    {'code': '512010', 'name': '医药ETF'},
    {'code': '512000', 'name': '券商ETF'},
    {'code': '516160', 'name': '新能源ETF'},
    {'code': '510800', 'name': '红利ETF'},
    {'code': '518880', 'name': '黄金ETF'},
    {'code': '512200', 'name': '房地产ETF'}
]
for stock in stocks_info:
    df=qs.get_data(stock['code'])
    # 因为设想中,x轴,可以是一个顺序的数组,比如从0开始往后数,step为1。这其实就是暗合着,随着时间的增加,close是否能拟合一条向上的直线?
    df['day'] = np.arange(0, df.shape[0], 1)
    df['标的'] = stock['name']

    sns.set_style("white")
    # 这个是seaborn中文乱码的处理。经过试验,在这里,plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'],这种设置是不行的。
    sns.set_style(rc= {'font.sans-serif':"Arial Unicode MS"})
    gridobj = sns.lmplot(x="day", y="close", data=df,  hue="标的", 
                         ci=95, scatter_kws={'color': 'orange'}, line_kws={'color': 'green'}, markers='o')

这里要说明一下,上面其实是一个个图生成的,然后我一张张图拼接起来的结果。

如果想直接横向着来看,还需要对数据进行标准化处理,如果不进行标准化,那比如不同标的的收盘价,差异很大,有的是十几块,像ETF,可能就是1块,那结果就很难看,就像下面这种:

1.3. 横向对比:数据标准化

所以,下面就是要将不同的标的进行标准化处理,这种标准化,意味着,将价格进行处理变成相对值,才可以进行比较,这里使用的是sklearn模块的StandardScaler,核心方法是fit_transform(df_all)。如果没有安装sklearn,需要先进行安装pip install -U scikit-learn

下面是一个完整的案例:

import qstock as qs
import pandas as pd

#默认日频率、前复权所有历史数据
#open:开盘价,high:最高价,low:最低价,close:收盘价 vol:成交量,turnover:成交金额,turnover_rate:换手率
# 沪深300, 中证500, 医药ETF, 券商ETF, 新能源ETF, 红利ETF, 黄金ETF, 房地产ETF
stocks_info = [
    {'code': '510300', 'name': '沪深300'},
    {'code': '510500', 'name': '中证500'},
    {'code': '512010', 'name': '医药ETF'},
    {'code': '512000', 'name': '券商ETF'},
    {'code': '516160', 'name': '新能源ETF'},
    {'code': '510800', 'name': '红利ETF'},
    {'code': '518880', 'name': '黄金ETF'},
    {'code': '512200', 'name': '房地产ETF'}
]
for stock in stocks_info:
    df = qs.get_data(stock['code'])  # 从qstock获取对应的股票历史数据
    stock['history_df'] = df         # 将其存在 history_df 这个key里面。

# 只保留收盘价,合并数据
df_all = pd.DataFrame()
for stock in stocks_info:
    df = stock['history_df']
    df = df[['close']]         # 只需要 date 和 close 2列就行了。
    df.rename(columns={'close': stock['name']}, inplace=True)  # 用股票的名字来重命名close列
    if df_all.size == 0:
        df_all = df
    else:
        df_all = df_all.join(df)  # join是按照index来连接的。

# print(df_all)

# 对dataframe的数据进行标准化处理
import sklearn
from sklearn import preprocessing
z_scaler = preprocessing.StandardScaler()   # 建立 StandardScaler 对象
z_data = z_scaler.fit_transform(df_all) #数据标准化(从第三列开始)
z_data = pd.DataFrame(z_data)                           #将数据转为Dataframe
z_data.columns = df_all.columns
df_all = z_data
print(df_all)


# 只保留收盘价,合并数据
df_new = pd.DataFrame()
for stock in stocks_info:
    df = df_all[[stock['name']]]
    df.columns = ['close']
    df['标的'] = stock['name']
    if df_new.size == 0:
        df_new = df
    else:
        df_new = pd.concat([df_new, df], axis=0)

print(df_new)
df_new['day'] = df_new.index

# 这个是seaborn中文乱码的处理。经过试验,在这里,plt.rcParams['font.sans-serif'] = ['Arial Unicode MS'],这种设置是不行的。
sns.set_style(rc= {'font.sans-serif':"Arial Unicode MS"})
df = sns.lmplot(x="day", y="close",data=df_new,col="标的")

         close      标的
0    -1.316309   沪深300
1    -1.275999   沪深300
2    -1.284061   沪深300
3    -1.290107   沪深300
4    -1.290107   沪深300
...        ...     ...
2826 -2.711143  房地产ETF
2827 -2.684416  房地产ETF
2828 -2.702234  房地产ETF
2829 -2.666598  房地产ETF
2830 -2.675507  房地产ETF

[22648 rows x 2 columns]

1.4. 看图说话

从上面的横向对比图可以看出:

  1. 沪深300的斜率,是高于中证500的
  2. 券商ETF,基本是一条横线,说明什么?做T啊,稳赚不赔!
  3. 新能源ETF、房地产ETF,可能是时间还太短,所处的周期内,就是向下的。
  4. 其他的,黄金看的是长周期,可能是几十年,还是慎重为好;红利,说不好,不懂的就先不碰了。

2. 系统自己算!线性回归

2.1. 沪深300线性回归,斜率0.00099414

首先从 sklearn 下的 linear_model 中引入 LinearRegression,再创建估计器起名 model,设置超参数 normalize 为 True,指的在每个特征值上做标准化,这样会加速数值运算。(可能是版本不同,有时候会报错LinearRegression got an unexpected keyword argument 'normalize',此时反而要去掉normalize=True这个参数。)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

df=qs.get_data('510300')

model = LinearRegression()
model
x = np.arange(df.shape[0])
y = df['close']

X = x[:, np.newaxis]
model.fit( X, y )

print( model.coef_ )  # 斜率 0.00099414,就是y=ax+b的a
print( model.intercept_ )  # 截距 1.9,就是y=ax+b的b

# 根据上面计算的结果,我们绘制一个收盘价走势图和一条y=ax=b的直线
plt.plot( x, y,  linestyle='-', color='green' )
plt.plot(x, 0.00099414*x + 1.9, linestyle='--', color='r')  # 这个是根据最后计算的“斜率”和“截距”,再叠加绘制的斜线

2.2. 沪深300线性回归的年化,年化8.5%

之前计算的沪深300最佳拟合的直线,斜率和截距:

plt.plot(x, 0.00099414*x + 1.9, linestyle='--', color='r')  # 这个是根据最后计算的“斜率”和“截距”,再叠加绘制的斜线

沪深300,如果按照上面的直线来看,那:

起始点:1.9

终点:y=ax+b,即y=0.00099414*x + 1.9,最后的x,其实是x轴的个数,是:df.shape[0],也就是行数:x=2832;那么计算的y = 0.00099414 * 2832 + 1.9 = 4.71540448

按照上面的计算:

import math

begin = 1.9
end = 4.71540448
year = 2832/255.0

# 年化收益率计算
rate = math.pow(end / begin, 1.0 / year) - 1
print('开始价=%s, 最终价=%s, year=%s,年化收益率=%s' % (str(begin), str(end), str(year), str(rate)))

开始价=1.9, 最终价=4.71540448, year=11.105882352941176,年化收益率=0.0852895190354479

2.3. 沪深300首尾点的年化,4.72%

如果不考虑中间的波动,那沪深300的年化收益率计算:

import pandas as pd
import math

df=qs.get_data('510300')

begin = df['close'][0]
end = df['close'][-1]
year = df.shape[0]/255.0

# 年化收益率计算
rate = math.pow(end / begin, 1.0 / year) - 1
print('开始价=%s, 最终价=%s, year=%s,年化收益率=%s' % (str(begin), str(end), str(year), str(rate)))

开始价=2.004, 最终价=3.345, year=11.105882352941176,年化收益率=0.047211214375309396

2.4. 中证500线性回归,斜率0.0008

对比看下中证500斜率如何

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

df=qs.get_data('510500')

model = LinearRegression()
model
x = np.arange(df.shape[0])
y = df['close']

X = x[:, np.newaxis]
model.fit( X, y )

print( model.coef_ )  # 斜率 0.00080245,就是y=ax+b的a
print( model.intercept_ )  # 截距 4.353948387096773,就是y=ax+b的b

# 根据上面计算的结果,我们绘制一个收盘价走势图和一条y=ax=b的直线
plt.plot( x, y,  linestyle='-', color='green' )
plt.plot(x, 0.00080245*x + 4.353948387096773, linestyle='--', color='r')  # 这个是根据最后计算的“斜率”和“截距”,再叠加绘制的斜线

2.5. 中证500线性回归的年化

计算中证500最佳拟合的直线,斜率和截距:

plt.plot(x, 0.00080245*x + 4.353948387096773, linestyle='--', color='r')  # 这个是根据最后计算的“斜率”和“截距”,再叠加绘制的斜线

起始点:4.353948387096773

终点:y=ax+b,即y=0.00080245*x + 4.353948387096773,最后的x,其实是x轴的个数,是:df.shape[0],也就是行数:x=2635;那么计算的y = 0.00080245 * 2635 + 4.353948387096773 = 6.468404137096773

按照上面的计算:

import math

begin = 4.353948387096773
end = 6.468404137096773
year = 2635/255.0

# 年化收益率计算
rate = math.pow(end / begin, 1.0 / year) - 1
print('开始价=%s, 最终价=%s, year=%s,年化收益率=%s' % (str(begin), str(end), str(year), str(rate)))

开始价=4.353948387096773, 最终价=6.468404137096773, year=10.333333333333334,年化收益率=0.039050907738202856

2.6. 中证500首尾点的年化

中证500年化收益率:

import pandas as pd
import math

df=qs.get_data('510500')

begin = df['close'][0]
end = df['close'][-1]
year = df.shape[0]/255.0

# 年化收益率计算
rate = math.pow(end / begin, 1.0 / year) - 1
print('开始价=%s, 最终价=%s, year=%s,年化收益率=%s' % (str(begin), str(end), str(year), str(rate)))

开始价=3.021, 最终价=5.279, year=10.333333333333334,年化收益率=0.055499799550948525

3. 总结

如果用最佳拟合直线,那么沪深300的年化是8.5%,中证500的年化是3.9%

如果是按照收盘价的首尾点来计算,那么沪深300的年化是4.72%,中证500的年化是5.55%

为什么最佳拟合直线和首尾点计算的年化差异这么大?还是因为今天2024年1月15日,收盘价跟最佳拟合直线的差距很大,自然会有很大的偏差,如果哪天能所谓的“价值回归”或是就应该是这个价,那2者会慢慢合理起来。

波动很大,但是最终的结果,还是能达到5%左右的年化收益率。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux/Uinx 什么是栈帧?

什么是栈帧? 栈帧是计算机内存中的一个独立区域,用于存储程序函数调用过程中的局部变量、参数和返回地址。每当一个函数被调用时,都会在栈上创建一个新的栈帧。函数执行完毕后,对应的栈帧将被销毁。栈帧的概念有助于理解程序函数…

MS-DETR: Efficient DETR Training with Mixed Supervision论文学习笔记

论文地址:https://arxiv.org/pdf/2401.03989.pdf 代码地址(中稿后开源):GitHub - Atten4Vis/MS-DETR: The official implementation for "MS-DETR: Efficient DETR Training with Mixed Supervision" 摘要 DETR 通过迭代…

canvas绘制图片的三种方法(图文示例)

查看专栏目录 canvas示例教程100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

我如何知道我的MinIO集群复制是最新的?

客户可以在任何需要快速、弹性、可扩展对象存储的地方运行 MinIO。MinIO 包括多种类型的复制,以确保每个应用程序都使用最新的数据,无论它在哪里运行。在之前有关批量复制、站点复制和存储桶复制的文章中,我们详细介绍了各种可用的复制选项及…

(N-139)基于springboot,vue宠物领养系统

开发工具:IDEA 服务器:Tomcat9.0, jdk1.8 项目构建:maven 数据库:mysql5.7 系统分前后台,项目采用前后端分离 前端技术:vue3element-plus 服务端技术:springbootmybatis-plusr…

MySQL体系结构

MySQL体系结构 MySQL采用的是客户/服务器体系结构,实际是有两个程序,一个是MySQL服务器程序,指的是mysqld程序,运行在存放数据库的机器上,负责在网络上监听并处理来自客户的服务请求,根据这些请求去访问数据…

彩超框架EchoSight开发日志记录

EchoSight开发记录 蒋志强 我会不定期的更新 开发进展。最近更新进展于2024年1月15日 1.背景 由于某些不可抗逆的原因,离开了以前的彩超大厂,竞业在家,难得有空闲的时间。我计划利用这段时间 自己独立 从零开始 搭建一套 彩超系统的软件工…

datax关系数据库插件设计和实现解释

背景 DataX是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路&#xff0…

GO——cobra

定义 Cobra 是 Go 的 CLI 框架 CLI,command-line interface,命令行界面 使用 注意 第一个cmd的USE即使命名了也没有意义,一般保持和项目名一致。 示例 package mainimport ("fmt""github.com/spf13/cobra" )func …

构建稳健的Web应用:LAMP 实践

LAMP 介绍 LAMP 代表 Linux、Apache、MySQL 和 PHP/Python/Perl(这些选项中一种)的组合,用于搭建 Web 应用程序的开发和运行环境。 Linux:作为操作系统的基础,提供整个 LAMP 堆栈的基础。Linux 提供稳定、安全的环境&…

Linux/OpenAdmin

Enumeration nmap 用nmap扫描发现目标对外开放了22和80,端口详细信息如下 从nmap的结果看到,是apache的default page,使用工具跑一下目录,看了官 网文档的结果然后写个小字典节约时间,扫描结果如下 On the page at /…

深入了解WPF控件:基础概念与用法(三)

掌握WPF控件:熟练常用属性(三) DataGrid 用于显示和编辑数据的表格控件。它可以从多种数据源(如SQL数据库、LINQ查询或任何其他可绑定的数据源)中显示和编辑数据,支持排序、筛选、分页等功能。 DataGrid…

2024全新开发API接口调用管理系统网站源码 附教程

2024全新开发API接口调用管理系统网站源码 附教程 用layui框架写的 个人感觉很简洁 方便使用和二次开发

Android 11.0 mtp模式下连接pc后显示的文件夹禁止删除copy重命名功能实现

1.前言 在11.0的系统rom定制化开发中,usb连接pc端的时候有好几种模式,在做otg连接pc端的时候,改成mtp模式的时候,在pc端可以看到产品设备 的显示的文件夹的内容,对于产品设备里面的文件在pc端禁止做删除重命名拷贝等操作功能的实现 2.mtp模式下连接pc后显示的文件夹禁止删…

项目:基于OpenCV+百度云人脸识别项目

一.项目框架 基于OpenCV和百度云人脸识别的项目可以使用以下的框架来实现: 数据采集和预处理:使用OpenCV来采集摄像头或读取图像文件,并对图像进行预处理操作,例如裁剪、调整大小、灰度化等。 人脸检测:使用OpenCV的人…

MySQL多表查询(改进版)

1.创建student和score表 mysql> CREATE TABLE student (-> id INT(10) NOT NULL UNIQUE PRIMARY KEY ,-> name VARCHAR(20) NOT NULL ,-> sex VARCHAR(4) ,-> birth YEAR,-> department VARCHAR(20) ,-> address VARCHAR(50)-> ); Query O…

Leetcode2707. 字符串中的额外字符

Every day a Leetcode 题目来源:2707. 字符串中的额外字符 解法1:动态规划 题目要求将字符串 s 分割成若干个互不重叠的子字符串(以下简称为子串),同时要求每个子串都必须在 dictionary 中出现。一些额外的字符可能…

uniapp使用Android Studio离线打包

环境准备 Android Studio: 下载地址APP离线SDK下载: 下载地址; 目前我使用得是“Android-SDK3.8.7.81902_20230704”;需要与hbuider版本配套使用。Appkey: 参考我 以上三步准备好后,进行接下来的不住: 准备工程 导…

SpringBoot中整合ElasticSearch快速入门以及踩坑记录

场景 若依前后端分离版手把手教你本地搭建环境并运行项目: 若依前后端分离版手把手教你本地搭建环境并运行项目_本地运行若依前后端分离-CSDN博客 参考上面搭建项目。 ElaticSearch Elasticsearch 是java开发的,基于 Lucene 的搜索引擎。它提供了一…

Spring中的事件机制

文章目录 摘要正文jdk事件Spring事件Spring事件监听ApplicationContext主动监听注解监听Bean监听 Spring事件发布 总结 摘要 在这篇文章我们将介绍Spring的事件机制,包括Spring内置事件、自定义事件、事件监听、事件发布、事件广播机制、事件异常处理等内容。Sprin…