0
点赞
收藏
分享

微信扫一扫

Python 数据处理与分析(三) 设计一个高回报的投资组合(投资回报和风险分析)任务 2:计算不同类型的收益率和投资组合的收益率

小磊z 2022-01-24 阅读 148

文章目录

1. 学习目标

2. 操作讲解

3、作业结果


1. 学习目标

  • 理解简单收益率和对数收益率
  • 通过 Pandas 和 NumPy,为不同的股票计算投资收益率
  • 通过线性加和,计算投资组合的收益率


2. 操作讲解

从这个任务开始,我们将使用 Python 及其相关的软件包,来进行投资领域的数据分析。

任何投资都要考虑两点:可能的收益和可能的损失。人们总是希望增加获取收益的机会,并降低蒙受损失的风险。但是这两者是“鱼和熊掌不可兼得”的关系,通常高收益就意味着高风险。

例如,银行的定期存款利息很低,但是只要银行不倒闭,本金总是有保障。相比之下,期货市场意味着短期内的高收益,但是也可能让投资者蒙受巨大的本金损失。那么怎样通过科学的方式来评估某种投资的收益和风险,并找到一个相对的均衡点呢?

不用急,我们一步步来看。

首先是收益率的定义,通常有两种收益率计算方式:简单收益率(Simple Rate of Return)和对数收益率(Logarithm Rate of Return)。


通常比较不同种类投资的时候,从量纲考虑,多数情况下使用简单收益率,而比较同一种投资的不同阶段,可以使用对数收益率。

理解了收益率,我们需要预测投资在未来的收益。当然,由于现实世界对投资的影响因素太多,我们不可能面面俱到,做出一个完全精准的模型,所以严格意义上来说,未来是不可预测的。我们所能做的就是根据投资的历史行为,进行一种大致的猜测,以此来近似人们对未来的预期。在这里,我们通过股票市场的历史数据来进行评估和预测。获取阿里巴巴、京东和腾讯在股票市场的股价数据。

import numpy as np
import pandas as pd

# 获取阿里巴巴2021年1月股价数据
BABA = pd.read_csv('./BABA.csv', sep='\t', index_col=0)

# 显示最初的几条数据
print('阿里巴巴2021年1月初的股价', BABA.head())
# 显示最后的几条数据
print('阿里巴巴2021年1月底的股价', BABA.tail())
print()

# 获取京东2021年1月股价数据
JD = pd.read_csv('./JD.csv', sep='\t', index_col=0)
# 显示最初的几条数据
print('京东2021年1月初的股价', JD.head())
# 显示最后的几条数据
print('京东2021年1月底的股价', JD.tail())
print()

# 获取腾讯2021年1月股价数据
TC = pd.read_csv('./TC.csv', sep='\t', index_col=0)
# 显示最初的几条数据
print('腾讯2021年1月初的股价', TC.head())
# 显示最后的几条数据
print('腾讯2021年1月底的股价', TC.tail())
print()

这里我们通过3个.csv文件,获取阿里巴巴(股票代码BABA)、京东(股票代码JD)、腾讯(股票代码TCTZF)这三个股票从2021年1月的股价。pandas的read_csv()函数所返回的股票数据,都是以pandas的dataframe形式存储的,这种数据结构类似关系型数据库里的表,行表示记录,列表示字段或者属性。之后我们就可以在这些dataframe上进行操作,例如使用下述代码获取每天的简单收益率。

# 获取阿里巴巴的简单收益率
BABA['simple_return'] = round((BABA['Adj Close'] / BABA['Adj Close'].shift(1)) - 1, 4)
print(BABA['simple_return'])

上述代码中,BABA[‘simple_return’] 表示在阿里巴巴股票数据的 dataframe 中,增加一个名为simple_return 的列,它的值是 round((BABA[‘Adj Close’] / BABA[‘Adj Close’].shift(1)) - 1, 4)。

函数 round() 和 SQL 里的 ROUND() 函数功能相同,都是保留小数点后面若干位。而简单收益率的重点在(BABA[‘Adj Close’] / BABA[‘Adj Close’].shift(1)) - 1,这里BABA[‘Adj Close’]表示当天的调整后收盘价格,而BABA[‘Adj Close’].shift(1)表示前一天的调整后收盘价格,shift(1) 表示往回 1 天。

也正是因为如此,第 1 天是没有收益率的,因为前面不存在比较的基数,你会在收益率计算后的最终结果中看到,第一天的收益率为NaN。请你练习一下,计算京东和腾讯每天的简单收益率。

下一步,我们使用下述代码来计算这些天的日均简单收益率和年均简单收益率。

# 获取阿里巴巴的日平均简单收益率
print('阿里巴巴的日平均简单收益率', round(BABA['simple_return'].mean() * 100, 4), '%')
# 获取阿里巴巴的年平均简单收益率
print('阿里巴巴的年平均简单收益率', round(BABA['simple_return'].mean() * 250 * 100, 4), '%')

通过 BABA[‘simple_return’].mean() 获取了简单收益率的平均值,也就是日均简单收益率。然后我们假设一年有 250 个交易日,那么这一年的年均简单收益率是前面日均值的 250 倍。此外,代码将小数转为了保留小数点后面 4 位的百分比。请你使用类似的方式,来获取京东和腾讯的日均以及年均简单收益率。

类似地,我们也可以为上述股票计算对数收益率。下面的代码列出了阿里巴巴日均对数收益率和年均对数收益率。

# 获取阿里巴巴的日平均对数收益率
BABA['log_return'] = round(np.log((BABA['Adj Close'] / BABA['Adj Close'].shift(1))), 4)
print('阿里巴巴的日平均对数收益率', round(BABA['log_return'].mean() * 100, 4), '%')
# 获取阿里巴巴的年平均对数收益率
print('阿里巴巴的年平均对数收益率', round(BABA['log_return'].mean() * 250 * 100, 4), '%')

请你使用类似的方式,来获取京东和腾讯的日均以及年均对数收益率。以下列出之前的完整代码,供你参考:

import numpy as np
import pandas as pd

# 获取阿里巴巴2021年1月股价数据
BABA = pd.read_csv('./BABA.csv', sep='\t', index_col=0)

# 显示最初的几条数据
print('阿里巴巴2021年1月初的股价', BABA.head())
# 显示最后的几条数据
print('阿里巴巴2021年1月底的股价', BABA.tail())
print()

# 获取京东2021年1月股价数据
JD = pd.read_csv('./JD.csv', sep='\t', index_col=0)
# 显示最初的几条数据
print('京东2021年1月初的股价', JD.head())
# 显示最后的几条数据
print('京东2021年1月底的股价', JD.tail())
print()

# 获取腾讯2021年1月股价数据
TC = pd.read_csv('./TC.csv', sep='\t', index_col=0)
# 显示最初的几条数据
print('腾讯2021年1月初的股价', TC.head())
# 显示最后的几条数据
print('腾讯2021年1月底的股价', TC.tail())
print()


# 获取阿里巴巴的简单收益率
BABA['simple_return'] = round((BABA['Adj Close'] / BABA['Adj Close'].shift(1)) - 1, 4)
print(BABA['simple_return'])

# 获取阿里巴巴的日平均简单收益率
print('阿里巴巴的日平均简单收益率', round(BABA['simple_return'].mean() * 100, 4), '%')
# 获取阿里巴巴的年平均简单收益率
print('阿里巴巴的年平均简单收益率', round(BABA['simple_return'].mean() * 250 * 100, 4), '%')


# 获取阿里巴巴的日平均对数收益率
BABA['log_return'] = round(np.log((BABA['Adj Close'] / BABA['Adj Close'].shift(1))), 4)
print('阿里巴巴的日平均对数收益率', round(BABA['log_return'].mean() * 100, 4), '%')
# 获取阿里巴巴的年平均对数收益率
print('阿里巴巴的年平均对数收益率', round(BABA['log_return'].mean() * 250 * 100, 4), '%')

很多时候,我们的投资并不会依赖单一的种类,而是由多种投资组合而成,例如储蓄、基金、股票、地产等等。即使仅仅投资一种,比如说股票,也可以拥有不同公司的股票。这个时候,我们就需要计算投资组合的综合回报率。假设你用于投资股票的资金,30% 用来购买了阿里巴巴的股票,35% 用来购买了京东的股票,最后 35% 用来购买了腾讯的股票,那么综合的投资收益率就是

这种线性加和的方式和我们之前计算综合相似度是一样的。下面的代码是具体实现:

import numpy as np
import pandas as pd

# 使用多个股票代码,构建新的dataframe
BABA = pd.read_csv('./BABA.csv', sep='\t', index_col=0)
JD = pd.read_csv('./JD.csv', sep='\t', index_col=0)
TC = pd.read_csv('./TC.csv', sep='\t', index_col=0)

stock_data = pd.DataFrame()
stock_data['BABA'] = BABA['Adj Close']
stock_data['JD'] = JD['Adj Close']
stock_data['TCTZF'] = TC['Adj Close']

# 获取全部股票的每日简单收益率
returns = stock_data / stock_data.shift(1) - 1
print(returns)

# 设置每个股票的资金占比
weights = np.array([0.3, 0.35, 0.35])
# 通过线性加和,算出综合的简单收益率
combined_return = np.dot(returns, weights)
print(combined_return)

上述代码新建了名为stock_data 的dataframe,其中每一列对应于一个股票的单日收盘价。这样的stock_data也是一种矩阵,可以直接使用stock_data / stock_data.shift(1) - 1完成每一列(也就是每个股票)的单日简单收益率计算。得到的结果returns变量也是一种矩阵结构,所以我们使用np.array和np.dot实现了股票收益矩阵returns和权重向量weights的点乘,最终获取了每日的综合简单收益率,它是各只股票的加权平均。

你可以练习一下,在 combined_return 的基础上,计算年平均的综合简单收益率。在完成练习的同时,请你注意把关键过程和最终结果截图,放到一个文件夹中打包,并用“任务2”来命名,我们在项目的「课后作业」部分为你设置了统一提交的入口。


3、作业结果

# -*- coding: utf-8 -*-
# @Software: PyCharm
# @File : Task2.py 
# @Author : Benjamin
# @Time : 2021/9/10 10:10


import numpy as np
import pandas as pd



# 使用多个股票代码,构建新的dataframe
BABA = pd.read_csv('../baba.csv', sep='\t', index_col=0)
JD = pd.read_csv('../jd.csv', sep='\t', index_col=0)
TC = pd.read_csv('../tc.csv', sep='\t', index_col=0)

stock_data = pd.DataFrame()
stock_data['BABA'] = BABA['Adj Close']
stock_data['JD'] = JD['Adj Close']
stock_data['TCTZF'] = TC['Adj Close']


# 获取全部股票的每日简单收益率
returns = stock_data / stock_data.shift(1) - 1
print(returns)


# 设置每个股票的资金占比
weights = np.array([0.3, 0.35, 0.35])

# 通过线性加和,算出综合的简单收益率
combined_return = np.dot(returns, weights)
print(combined_return)



# 0.055082+0.106220+0.047821=0.209123
# 0.055080*0.3+0.106220*0.35+0.047821*0.35=0.07043835
# 年平均简单收益率
# 通过 BABA[‘simple_return’].mean() 获取了简单收益率的平均值,也就是日均简单收益率。然后我们假设一年有 250 个交易日,那么这一年的年均简单收益率是前面日均值的 250 倍。此外,代码将小数转为了保留小数点后面 4 位的百分比。请你使用类似的方式,来获取京东和腾讯的日均以及年均简单收益率。
combined_return = np.delete(combined_return,0,axis = 0)
print(round(np.average(combined_return) * 250 * 100, 4), '%')


如果觉得文章写不错,那就点个赞,点个收藏吧。


举报

相关推荐

0 条评论