Python量化交易学习——Part12:回归模型的典型应用

news2024/12/23 5:04:33

回归模型在很多的时候被应用于对股票的基本面数据进行分析,例如经典的CAPM模型、Fama-French三因子模型以及最新的PB_ROE模型等。这些都是已经应用于现实中的金融市场并获得较好收益的经典模型。本章将通过介绍PB_ROE模型,进一步讲解回归分析在实战过程中的使用。

PB-ROE 回归模型的使用

选股的核心思想在于寻找价格低于内在价值的股票,从而获取未来价格修复的收益。具体来看,符合价值投资理念的标的首先要有良好的基本面,其次要有合理的价格。PB-ROE选股模型便是价值投资中的一种经典方法。该模型中,ROE作为基本面指标,用于衡量公司质地是否优良,PE作为估值指标,用于衡量当前价格是否低估。

市净率(Price-to-Book Ratio,简称P/B PBR)指的是每股股价与每股净资产的比率。 市净率可用于股票投资分析,一般来说市净率较低的股票,投资价值较高,相反,则投资价值较低;但在判断投资价值时还要考虑当时的市场环境以及公司经营情况、盈利能力等因素。
股东权益报酬率=可供普通股东分配的净利润/平均普通股东权益×100%,这个比率通常也被称为净资产收益率,英文缩写ROE

因此PB-ROE选股策略可以概况为以下几点:
(1)获取股票的PB\ROE数据,建立PB-ROE数据之间的回归模型;
(2)一般来说,净资产收益率高的股票,市净率也应该高一些,因此可以根据回归模型计算单个股票拟合后的PB值,与真实PB值进行比较,并对差值进行排序,当(真实PB-预测PB)的值越大,说明股票越被高估,当值越小,说明越被低估。
(3)根据排序后的结果进行股票买卖
(4)在导入股票的时候,我们只选择了沪深主板的股票,原因很简单,因为我没有创业板和科创板买卖权限…

# coding=utf-8
from __future__ import print_function, absolute_import
import statsmodels.api as sm
import numpy as np
import matplotlib.pyplot as plt
import random
import pandas as pd
from gm.api import *
import datetime
import os
import statsmodels.api as sm
# from MSCI_tools import mcsi_tools as tools


set_token('a7f3404da7e8c9a3aea631b5ae0c893b1d57161d')
now, hour_and_mins = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')).split(" ")


# 获取A股除了流动性不足的股票以及ST股票外,入选中证组合的几乎全部的股票清单(沪深主板)
def get_symbol_list_all():

    A_share_list = {"SHSE.000010": "SHANG_ZHENG180", "SHSE.000016": "SHANG_ZHENG50", "SHSE.000300": "HU_SHEN300",
                    "SHSE.000903": "ZHONG_ZHENG100",
                    "SHSE.000904": "ZHONG_ZHENG200", "SHSE.000905": "ZHONG_ZHENG500", "SHSE.000906": "ZHONG_ZHENG800",
                    "SHSE.000907": "ZHONG_ZHENG700", "SHSE.000852": "ZHONG_ZHENG1000"}
    A_share_main = {"600", "601", "602", "603", "000", "001", "002", "003"} #沪深主板股票代码的开头
    symbol_list_all = pd.DataFrame([])
    for key in A_share_list.keys():
        symbol_list = stk_get_index_constituents(key)  # 获取指数成分股数据
        symbol_list_all = pd.concat([symbol_list_all, symbol_list], ignore_index=True)
        # symbol_list_all =symbol_list_all.append(symbol_list)  #新语句中append已经弃用
    symbol_set = symbol_list_all["symbol"].values
    target_symbol_list= []
    for symbol in symbol_set:#从股票池中寻找主板股票
        if symbol[5:8]  in A_share_main and symbol not in target_symbol_list:
            target_symbol_list.append(symbol)
    print("沪深主板股票资源池数量",len(target_symbol_list))
    return target_symbol_list

def PB_ROE_strategy(symbol_list,now):
    last_day = get_previous_trading_date("SHSE",now)
    ROE = stk_get_finance_deriv_pt(symbols=symbol_list,fields="roe",date=last_day,df=True)
    ROE = ROE.sort_values(["symbol"],ascending=False)
    ROE = ROE.reset_index(drop=True)
    PB = stk_get_daily_valuation_pt(symbols=symbol_list, fields="pb_mrq", trade_date=last_day, df=True)
    PB = PB.sort_values(["symbol"],ascending=False)
    PB = PB.reset_index(drop=True)
    ROE_PB_list = pd.merge(ROE, PB)
    drop_num =[]
    for num in range(len(ROE_PB_list)-1):
        if ROE_PB_list["roe"].values[num] < 0 or ROE_PB_list["pb_mrq"].values[num] > 6:
            drop_num.append(num)
    ROE_PB_list = ROE_PB_list.drop(drop_num)
    ROE_PB_list.dropna()
    symbol_roe = ROE_PB_list["roe"].values #自变量
    symbol_pb = ROE_PB_list["pb_mrq"].values #因变量
    symbol_roe[np.isnan(symbol_roe)] = 0
    symbol_roe[np.isinf(symbol_roe)] = 0
    symbol_pb[np.isnan(symbol_pb)] = 0
    symbol_pb[np.isinf(symbol_pb)] = 0
    #进行回归分析
    symbol_roe = sm.add_constant(symbol_roe)
    model = sm.OLS(symbol_pb, symbol_roe)  # 前面为因变量,后面为自变量
    result = model.fit()
    bias, weight = (result.params)  # 前面为截距,后面为斜率
    ROE_PB_list["PB_new"] = bias + ROE_PB_list["roe"]*weight
    # print(ROE_PB_list)
    ROE_PB_list["value"] = ROE_PB_list["PB_new"] -ROE_PB_list["pb_mrq"] #大于0说明是低估
    ROE_PB_list = ROE_PB_list.sort_values(["value"],ascending=False)
    ROE_PB_list = ROE_PB_list.reset_index(drop=True)
    # print(ROE_PB_list)

    #绘制ROE-PB关系曲线
    # fig = plt.figure()
    # #将画图窗口分为1行1列,选择第一块区域做子图
    # ax = fig.add_subplot(111)
    # ax.set_title("ROE-PB model")
    # ax.set_xlabel("ROE")
    # ax.set_ylabel("PB")
    # ax.scatter(ROE_PB_list["roe"].values,ROE_PB_list["pb_mrq"].values,c="k",marker=".")
    # ax.plot(ROE_PB_list["roe"].values,ROE_PB_list["PB_new"].values,c="b")
    # plt.show()

    return ROE_PB_list["symbol"].values

symbol_list = get_symbol_list_all()
PB_ROE_strategy(symbol_list,now)
# symbol_list1 = stk_get_index_constituents("SHSE.000903")
# symbol_list2 = stk_get_index_constituents("SHSE.000016")
# print(symbol_list1)
# print(symbol_list2)
# print(symbol_list1.append(symbol_list2))

# coding=utf-8


def init(context):
    # 每天14:50 定时执行algo任务,
    # algo执行定时任务函数,只能传context参数
    # date_rule执行频率,目前暂时支持1d、1w、1m,其中1w、1m仅用于回测,实时模式1d以上的频率,需要在algo判断日期
    # time_rule执行时间, 注意多个定时任务设置同一个时间点,前面的定时任务会被后面的覆盖
    schedule(schedule_func=algo, date_rule='1m', time_rule='09:31:00')
    context.count = 1
    context.num = 5
    context.fields = "open,high,low,close"

def algo(context):
    now = context.now
    last_day = get_previous_trading_date("SHSE",now)
    target_symbol_list = get_symbol_list_all()
    ROE_PB_list = PB_ROE_strategy(target_symbol_list,now)
    target_list = ROE_PB_list[0:context.num]
    positions = context.account().positions()

    for position in positions:
        symbol = position["symbol"]
        if symbol not in target_list:
            order_target_percent(symbol=symbol,percent=0,order_type=OrderType_Market,position_side=PositionSide_Long)
    positions = context.account().positions()
    holded_symbol = []

    for position in positions:
        symbol = position["symbol"]
        holded_symbol.append(symbol)
    print(holded_symbol)

    for symbol in target_list:
        if symbol not in holded_symbol:
            print(symbol)
            data = history_n(symbol=symbol,frequency='1d',count=2,end_time=now,fields=context.fields,adjust=ADJUST_PREV, df=True)
            open =data["open"].values
            close = data["close"].values
            if open[-1] < close[0]*1.08: #没有涨停,涨停就无法买入了
                order_target_percent(symbol=symbol,percent=(1/context.num)*0.95,order_type=OrderType_Market,position_side=PositionSide_Long)
            else:
                pass


# 查看最终的回测结果
def on_backtest_finished(context, indicator):
    print(indicator)


if __name__ == '__main__':
    '''
        strategy_id策略ID, 由系统生成
        filename文件名, 请与本文件名保持一致
        mode运行模式, 实时模式:MODE_LIVE回测模式:MODE_BACKTEST
        token绑定计算机的ID, 可在系统设置-密钥管理中生成
        backtest_start_time回测开始时间
        backtest_end_time回测结束时间
        backtest_adjust股票复权方式, 不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
        backtest_initial_cash回测初始资金
        backtest_commission_ratio回测佣金比例
        backtest_slippage_ratio回测滑点比例
        backtest_match_mode市价撮合模式,以下一tick/bar开盘价撮合:0,以当前tick/bar收盘价撮合:1
    '''
    run(strategy_id='8e30d6a2-3b4c-11ef-94ca-e073e7f1ba05',
        filename='pb_roe_strategy.py',
        mode=MODE_BACKTEST,
        token='自己的token码',
        backtest_start_time='2022-11-01 09:30:00',
        backtest_end_time='2024-06-20 15:00:00',
        backtest_adjust=ADJUST_PREV,
        backtest_initial_cash=10000,
        backtest_commission_ratio=0.0001,
        backtest_slippage_ratio=0.0001,
        backtest_match_mode=1)


结果如下:从结果看,获得了一定的超额收益,但收益并不明显,通过绘制PB-ROE散点图我们也可以看到,两者之间的关系并不是很明显。
在这里插入图片描述

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

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

相关文章

深入探讨【C++容器适配器】:现代编程中的【Stack与Queue】的实现

目录 一、Stack&#xff08;栈&#xff09; 1.1 Stack的介绍 1.2 Stack的使用 1.3 Stack的模拟实现 二、Queue&#xff08;队列&#xff09; 2.1 Queue的介绍 2.2 Queue的使用 2.3 Queue的模拟实现 三、容器适配器 3.1 什么是适配器 3.2 为什么选择deque作为stack和…

【web】-sql注入-login

根据网址提示打开如图&#xff1a; 查看源代码前台并没有过滤限制、扫描后台也没有发现特殊文件。看到标题显示flag is in database&#xff0c;尝试sql注入。 由于post,bp抓包如下&#xff1a; 运行python sqlmap.py -r 1.txt --dump 获取flag 42f4ebc342b6ed4af4aadc1ea75f…

solidity实战练习3——荷兰拍卖

//SPDX-License-Identifier:MIT pragma solidity ^0.8.24; interface IERC721{function transFrom(address _from,address _to,uint nftid) external ; }contract DutchAuction { address payable immutable seller;//卖方uint immutable startTime;//拍卖开始时间uint immut…

Facebook 开源计算机视觉 (CV) 和 增强现实 (AR) 框架 Ocean

Ocean 是一个独立于平台的框架&#xff0c;支持所有主要操作系统&#xff0c;包括 iOS、Android、Quest、macOS、Windows 和 Linux。它旨在彻底改变计算机视觉和混合现实应用程序的开发。 Ocean 主要使用 C 编写&#xff0c;包括计算机视觉、几何、媒体处理、网络和渲染&#x…

git安装使用gitlab

第一步&#xff1a;下载git 第二步&#xff1a;安装 第三步&#xff1a;配置sshkey 第四步&#xff1a;处理两台电脑的sshkey问题 第一步下载git 网址&#xff1a;Git点Downloads根据你的操作系统选择对应的版本&#xff0c;我的是Windows&#xff0c;所以我选择了Windows …

细数「人力资源」的「六宗罪」

细数「人力资源」的「六宗罪」 不要让人力资源成为企业发展的障碍 人力资源的六宗罪: 招聘与配置培训与开发薪酬与绩效请您先「点赞」+「在看」+「收藏」+关注@netkiller,转发给你的朋友,再慢慢看,方便查看往期精彩文章,以防手划找不到,您的支持就是我最大的动力。 人力…

玩转springboot之SpringBoot打成jar包的结构

SpringBoot打成jar包的结构 springboot通常会打成jar包&#xff0c;然后使用java -jar来进行执行&#xff0c;那么这个jar包里的结构是什么样的呢 其中 BOOT-INF 中包含的classes是我们程序中所有的代码编译后的class文件&#xff0c;lib是程序所引用的外部依赖 META-INF 这个…

解答|服务器只能开22端口可以申请IP地址SSL证书吗?

IP地址SSL证书&#xff0c;是一种专门颁发给公网IP地址的SSL证书&#xff0c;而不是常见的基于域名的SSL证书。SSL证书主要用于保障数据在客户端&#xff08;如用户的浏览器&#xff09;和服务器之间传输时的加密性和安全性&#xff0c;以防止数据被截取或篡改。 服务器只能开…

希尔排序——C语言

希尔排序是插入排序的一种更高效的改进版本。希尔排序通过比较相距一定间隔的元素来进行排序&#xff0c;随着算法的进行&#xff0c;这个间隔逐渐减少&#xff0c;直到最后变为1&#xff0c;此时的排序其实就是一次插入排序。 希尔排序和插入排序的区别是希尔排序是插入排序的…

【C++】入门基础(命名空间、缺省参数、函数重载)

目录 一.命名空间&#xff1a;namespace 1.namespace的价值 2.namespace的定义 3.namespace的使用方法 3.1 域解析运算符:: 3.2 using展开 3.3 using域解析运算符 二.输入输出 三.缺省参数 四.函数重载 1.参数类型不同 2.参数个数不同 3.参数顺序不同 一.命名空间&…

员工的离职成本到底有多高?

员工的离职成本到底有多高? 少有公司意识到离职率这个问题,表面上是员工主动提辞的,所以企业常常将离职率归罪于员工。 可以用“铁打的营盘,流水的兵”来概括离职率。 90/00后高频离职原因,企业揣着明白装糊涂 知乎上常常看到关于抱怨90/00后任性离职的问题,我说这是…

【python数据结构精讲】双端队列

通过总结《流畅的Python》等书中的知识&#xff0c;总结Python中常用工具的方法。 deque&#xff0c;学名双端队列。 1. 常用方法 append()&#xff1a;队列尾部添加appendleft()&#xff1a;队首添加pop()&#xff1a;移除队列最后一个元素popleft()&#xff1a;移除队列第一…

聊聊接入Arbitrum的正确姿势

本文首发于公众号&#xff1a;Keegan小钢 前言 我们知道&#xff0c;目前最主流的 Ethereum Layer2 方案中&#xff0c;主要有 Optimistic Rollup 和 ZK Rollup 两大类。而 Optimistic Rollup 的实现方案中&#xff0c;则是 Optimism 和 Arbitrum 最受关注。而我们最近接入了 …

ONLYOFFICE最新8.1版本新功能解析

ONLYOFFICE最新8.1版本新功能解析 书接上文&#xff1a; 深度解析 ONLYOFFICE 协作空间 2.5 版本新功能https://blog.csdn.net/VincentYoung/article/details/139665603?spm1001.2014.3001.5502 讲解了ONLYOFFICE协作空间今年最新升级的2.5版本的新功能&#xff0c;这里继续…

《代理选择与反爬虫策略探究:如何优化网络爬虫效率与稳定性》

代理IP如何选以及常见反爬策略 为什么需要代理&#xff1f; 因为有的网站会封IP&#xff0c;用户如果没有登录&#xff0c;那IP就是身份标识&#xff0c;如果网站发现用户行为异常就非常可能封IP 什么是代理IP 就是让一个人帮你转交请求&#xff0c;帮你转交的人对面不熟&a…

简单的SQL字符型注入

目录 注入类型 判断字段数 确定回显点 查找数据库名 查找数据库表名 查询字段名 获取想要的数据 以sqli-labs靶场上的简单SQL注入为例 注入类型 判断是数字类型还是字符类型 常见的闭合方式 ?id1、?id1"、?id1)、?id1")等&#xff0c;大多都是单引号…

DEBUG:电脑突然无法联网

问题 mqtt启动时候开启了本地代理 解决 关闭本地的代理

生物素标记降钙素Biotin-α-CGRP, rat 中间体

生物素标记降钙素Biotin-α-CGRP, rat 中间体是一种特定的生物化学试剂&#xff0c;主要用于科学研究领域。以下是对该产品的详细介绍&#xff1a; 一、基本信息 产品名称&#xff1a;生物素标记降钙素Biotin-α-CGRP, rat 中间体 英文名称&#xff1a;Biotin-α-CGRP, rat 纯度…

对接企业微信API自建应用配置企业可信IP

前言 为了实现系统调用团队会议功能&#xff0c;组织发起企业微信会议&#xff0c;于是需要和企业微信做API对接。对接过程很难受&#xff0c;文档不清晰、没有SDK、没有技术支持甚至文档报文和实际接口报文都不匹配&#xff0c;只能说企业微信的API是从业以来见过的最难用的AP…

使用 Python OpenCV 创建图像到卡通转换器

https://pyseek.com/2022/07/image-to-cartoon-converter-in-python/ 一、说明 你有没有试过把自己的照片转换成卡通画&#xff1f;顺便说一句&#xff0c;这不是开玩笑。很多人喜欢把他们的照片变成卡通画并在社交媒体上分享。就连我自己也多次尝试过这种技术。有很多在线工具…