百色金融新闻网
您的位置:百色金融新闻网 > 理财保险 > 「Python量化」怎么在基金定投上实现收益最大化-基金定投收益

「Python量化」怎么在基金定投上实现收益最大化-基金定投收益

作者:百色金融新闻网日期:

返回目录:理财保险

最新资讯《「Python量化」怎么在基金定投上实现收益最大化-基金定投收益》主要内容是基金定投收益,——巴菲特引言继上一篇文章《Python数说指数定投策略》,今天为大家分享一篇推文。基金定投作为"懒人理财"的头号玩家,当然得贯彻其"懒人"思维,我们想知道到底定投多久,才能说大概率地获得较为满意的收益。,现在请大家看具体新闻资讯。

我们也会有恐惧和贪婪,只不过在别人贪婪的时候我们恐惧,在别人恐惧的时候我们贪婪。——巴菲特

引言

继上一篇文章《

Python数说指数定投策略》,今天为大家分享一篇推文(原文来源:SAMshare),讨论一下更加深入的Ideas,总结来说主要有两点:1) 是否存在最合适的定投周期?

2) 我们到底要设置多少止盈点较为合适?

什么意思呢?我们展开来说,

☝️对于第一点:是否存在最合适的定投周期?

基金定投作为"懒人理财"的头号玩家,当然得贯彻其"懒人"思维,我们想知道到底定投多久,才能说大概率地获得较为满意的收益。

这里有几个点需要理一下:

  • 入场的随机性:因为涉及到实际操作,每个人的入场时间不尽相同,所以这里探讨最合适的定投周期,要考虑入场时机的随机性。
  • 指数的异质性:我们讨论的是指数基金,但不同的指数之间,也是可能会存在不一样的性质,这里也要考虑。
  • 人性的弱点:因为是定投,实际操作的还是人,所以当定投期结束时,是否会因为当前是所谓的"上涨"or"下跌"行情而纠结?
  • 何为"满意的收益”:如何判断“满意”呢,不同人对满意的态度不同,如何定义一个基准。

针对以上的几点,我在自己思考后给出了下面的验证方式:

在指定的定投周期内(定投周期为0.5年的整数倍),遍历所有可能的入场点,卖出点取离场点当月的指数均值,如果收益率大于余额宝定存相同周期时间内的收益的,即为之"满意",同时验证多几个指数。

简单解释一下,我们验证的定投周期,均是0.5年的整数倍,比如定投1年、1.5年、2年等等,买入日期,选择月初,而卖出点,不会是最后的那个月的月初,而是取其当月的指数均值,比如2019年1月1日开始定投,定投1年,那么卖出点就是2020年2月的指数均值,就是为了防止有的人因为当时股价变化而出现的纠结情绪。

当指数基金定投收益率大于余额宝定存收益率的,记为1,为我们的正样本,反之则记为0,为我们的负样本。我们就来统计一下,不同的定投周期,正负样本的比例关系,看下怎么样的定投周期,具备较大概率的"满意"结果!

✌️对于第二点:我们到底要设置多少止盈点较为合适?

关于这点,我们就是为了找出多少的止盈点较为合适。这个结合我们上篇文章的内容,我们知道如果我们定投的周期越长,收益率当然就是越大的,所以,不同定投周期之间的收益率没有可比性。所以我们需要指定一个定投周期(姑且我们用第一点得到的"最优"定投周期N来作为我们的观测周期)。

我们的验证方式:

在指定的定投周期内,遍历所有可能的入场点,卖出点取离场点当月的指数均值,记录此时的收益率情况,统计收益率的大概率集中区间,即为我们的参考止盈点。

接下来,我们就针对以上的2个内容,来用python代码验证一波。(:show time~)

是否存在最合适的定投周期?

1. 导入相关库

 1# -*- coding: UTF-8 -*-
2import matplotlib as mpl
3import matplotlib.pyplot as plt
4import pandas as pd
5import numpy as np
6import tushare as ts
7from datetime import datetime
8
9#解决中文显示问题,Mac
10%matplotlib inline
11from matplotlib.font_manager import FontProperties
12
13plt.rcParams['figure.figsize'] = (10.0, 4.0) # 设置figure_size尺寸
14plt.rcParams['image.interpolation'] = 'nearest' # 设置 interpolation style
15plt.rcParams['image.cmap'] = 'gray' # 设置 颜色 style
16plt.rcParams['savefig.dpi'] = 100 #图片像素
17plt.rcParams['figure.dpi'] = 100 #分辨率
18
19# 利用plotly绘图
20import plotly.offline as of
21import plotly.graph_objs as go

2. 数据获取

这里还是适用Tushare的接口来获取数据,具体代码如下:

 1# 设置token
2ts.set_token('your token')
3
4# 初始化接口
5pro = ts.pro_api()
6
7# 获取基本信息
8sh_basic = pro.index_basic(market='SSE') # 上交所
9sz_basic = pro.index_basic(market='SZSE') # 深交所
10
11
12# 000001.SH 上证综指
13# 399001.SZ 深证成指
14data_sh = pro.index_daily(ts_code='000001.SH', start_date='19901219', end_date='20190401')
15data_sz = pro.index_daily(ts_code='399001.SZ', start_date='19901219', end_date='20190401')
16data_sh.head()

3. 代码封装

对上面提及的验证方式进行逻辑封装:

 1def Log_of_AIP(data, n, money):
2 '''
3 data:测试数据集,即指数历史走势数据
4 n:定投周期,6个月的整数倍,如n=1代表定投6个月
5 money:定投金额
6 '''
7
8 data = data.loc[:,['open','trade_date']]
9 data['trade_month'] = data['trade_date'].apply(lambda x:str(x)[0:6])
10 data['date'] = data['trade_date'].apply(lambda x:datetime.strptime(x,'%Y%m%d'))
11 data = data.set_index('date').sort_index()
12
13 # 假设余额宝的年化收益率为 4%
14 data['余额宝利率'] = (4.0/100+1)**(1.0/250)-1
15 data['理财收益_净值'] = (data['余额宝利率']+1).cumprod()
16
17 # 选择每个月的第一个交易日进行定投
18 trading_day = data.resample('M', kind='date').first()
19
20 # 确定循环次数,因为得保证满足定投周期
21 try:
22 All_Sales = pd.DataFrame()
23 for i in range(len(trading_day) - (6*n)):
24 # 在定投周期结束后一个月卖出
25 trading_cycle = trading_day.iloc[i:i+6*n+1]
26
27 # 计算卖出点 下个月的指数均值
28 in_month = data[data['trade_month']==list(trading_cycle['trade_month'][-1:])[0]]
29 sales_point = in_month.pivot_table(values='open', index='trade_month').mean().values[0]
30
31
32 # 定投指数基金
33 AIP = pd.DataFrame(index=trading_cycle.index)
34 AIP['定投金额'] = int(money)
35
36 # 以基金当天的开盘价作为当天买入的价格
37 AIP['基金价格'] = trading_cycle['open']
38 AIP['购买基金份额'] = AIP['定投金额']/AIP['基金价格']
39 AIP['累计基金份额'] = AIP['购买基金份额'].cumsum()
40
41 # 定期购买理财产品
42 AIP['购买理财产品份额'] = AIP['定投金额']/trading_cycle['理财收益_净值']
43 AIP['累计理财产品份额'] = AIP['购买理财产品份额'].cumsum()
44
45 # 累计投入本金
46 AIP['累计定投本金'] = AIP['定投金额'].cumsum()
47
48 # 计算每个交易日的本息(即本金+利息,公式=当天的份额 X 当天的基金价格)
49 result = pd.concat([trading_cycle, AIP], axis=1)
50 result['基金本息'] = (result['open'] * result['累计基金份额']).astype('int')
51 result['理财本息'] = (result['理财收益_净值'] * result['累计理财产品份额']).astype('int')
52
53 # 买入点 result['trade_date'][0]
54 # 定投周期(月) 6*n
55 # 定投投入本金 result['累计定投本金'][-2:-1][0]
56 # 基金卖出后本息 result['累计基金份额'][-2:-1][0] * sales_point
57 # 余额宝卖出后本息 result['理财本息'][-2:-1][0]
58
59
60 Each_Sales = pd.DataFrame([[result['trade_date'][0],
61 6*n,
62 result['累计定投本金'][-2:-1][0],
63 result['累计基金份额'][-2:-1][0] * sales_point,
64 result['理财本息'][-2:-1][0]]],
65 columns=['买入点','定投周期(月)', '累计定投本金', '基金卖出后本息', '余额宝卖出后本息'])
66 Each_Sales['基金收益率%'] = 100*(Each_Sales['基金卖出后本息'][0]/Each_Sales['累计定投本金'][0] - 1)
67 Each_Sales['余额宝收益率%'] = 100*(Each_Sales['余额宝卖出后本息'][0]/Each_Sales['累计定投本金'][0] - 1)
68 Each_Sales['LikeOrNot'] = Each_Sales['基金卖出后本息'] > Each_Sales['余额宝卖出后本息']
69 All_Sales = All_Sales.append(Each_Sales)
70
71 return All_Sales
72
73 except:
74 print("定投周期大于历史股价走势!请重新设置定投周期。")
75
76
77def Rate_of_Like(data, money):
78 data= data
79 money= money
80
81 Rate_of_like = pd.DataFrame()
82 for i in range(int(len(trading_day)/6)):
83 tt = Log_of_AIP(data_sh, i+1, 2000)
84 rate = pd.DataFrame([[(i+1)*6, (tt['LikeOrNot'].value_counts()/len(tt))[True]]],
85 columns=['定投周期(月)','定投基金满意占比'])
86 Rate_of_like = Rate_of_like.append(rate)
87 return Rate_of_like

4. 函数调用&猜想验证

1rate_of_sh = Rate_of_Like(data_sh, 2000)
2rate_of_sh.head()
 1# 绘制定投满意概率图
2of.offline.init_notebook_mode(connected=True)
3
4trace1 = go.Scatter(
5 x=rate_of_sh['定投周期(月)'],
6 y=rate_of_sh['定投基金满意占比'],
7 mode = 'lines+markers',
8 name = '定投基金满意的次数占比'
9)
10data = go.Data([trace1])
11
12layout = dict(title = '是否存在最合适的定投周期?',
13 yaxis = dict(showgrid=True, #网格
14 zeroline=False, #是否显示基线,即沿着(0,0)画出x轴和y轴
15 nticks=20,
16 showline=True,
17 title='定投基金满意的次数占比'),
18
19 xaxis = dict(showgrid=True, #网格
20 zeroline=False, #是否显示基线,即沿着(0,0)画出x轴和y轴
21 nticks=20,
22 showline=True,
23 title='定投周期(月)')
24 )
25fig = dict(data=data, layout=layout)
26of.plot(fig, filename='rate_of_like')
「Python量化」怎么在基金定投上实现收益最大化

上面,我只是验证了上证综指,从数据中可以看出,当定投周期超出240个月,即20年,我们获得满意(即定投收益跑赢余额宝定存收益)的基金定投的概率超出80%!

此外,我们看到,好像定投周期在300个月以上,获得满意的概率竟然得到了100%,但是我们知道这不太符合实际,原因是因为这基本是从上证开盘就开始定投,也不太满足我们的实际操作。

综上所述:(针对上证综指)

  • 定投周期在50个月之内的,获得满意的概率是一半一半,定投的威力还没体现出来;
  • 当定投周期在60个月左右的满意概率与定投60~120个月的满意概率差不多;
  • 定投240个月左右的满意概率可以达到80%,定投的威力终于来了!

设置多少止盈点较为合适?

1. 函数调用

 1log = Log_of_AIP(data_sh, 40, 2000)
2log = log.sort_values(['基金收益率%'])
3
4# 转化为密度函数,以10%为一个单位
5log['density'] = log['基金收益率%'].apply(lambda x:int(x/10))
6log2 = log.pivot_table(values='LikeOrNot', index='density', aggfunc=len).reset_index()
7log2['density2'] = log2['density'].apply(lambda x:str(10*x) +'%~'+str(10*(x+1)) + '%')
8
9# 帕累托图
10log2['density3'] = log2['density'].cumsum()
11log2['density4'] = log2['density3']/(log2.tail(1).reset_index()['density3'][0])
12log2

2. 猜想绘制

这里只是贴了其中一个绘制代码:

 1# 绘制收益分布图
2of.offline.init_notebook_mode(connected=True)
3
4trace1 = go.Scatter(
5 x = pd.Series(range(len(log))),
6 y = log['基金收益率%'],
7 mode = 'markers',
8 name = '基金 收益率分布图'
9)
10
11trace2 = go.Scatter(
12 x = pd.Series(range(len(log))),
13 y = log['余额宝收益率%'],
14 mode = 'markers',
15 name = '余额宝 收益率分布图'
16)
17
18data = go.Data([trace1,trace2])
19
20layout = dict(title = '设置多少止盈点较为合适?',
21 yaxis = dict(showgrid=True, #网格
22 zeroline=False, #是否显示基线,即沿着(0,0)画出x轴和y轴
23 nticks=20,
24 showline=True,
25 title='投资收益率%'),
26
27 xaxis = dict(showgrid=True, #网格
28 zeroline=False, #是否显示基线,即沿着(0,0)画出x轴和y轴
29 nticks=20,
30 showline=True,
31 title='迭代次数'
32 )
33 )
34fig = dict(data=data, layout=layout)
35of.plot(fig,filename='log')
「Python量化」怎么在基金定投上实现收益最大化

我们按照定投最优的周期(240个月)来进行止盈点的计算,从上图可以看出,余额宝在定投240个月后,收益率大概维持在50%左右,而基金大多数的收益率都是大于余额宝的。

「Python量化」怎么在基金定投上实现收益最大化

「Python量化」怎么在基金定投上实现收益最大化

根据基金的收益率,我进行了密度转换,可以看出,我们的收益率,大致都是集中在60~70%之间。

综上所述:(针对上证综指)

  • 定投20年基金,大概率(80%)水平上会获得比余额宝要好得多的收益;
  • 定投20年基金,止盈点定在80~90%,发生的可能性为80%;
  • 定投20年基金,止盈点定在130~140%,发生的可能性为50%;
  • 定投20年基金,止盈点定在200~210%,发生的可能性为20%;

其他策略

此外,我也从网上看到了其他更佳复杂的投资策略,这里就先不验证,先放出来给大家参考,下次一起验证:

方法一:高抛低吸降成本

熊市中,不要相信某一次上涨行情可能是新一轮牛市的开端,牛市的到来远远比你想象的要遥远。对于部分套牢的基金,建议在反弹10%以上时,逐步卖出,保留一部分底仓。然后遇到下跌,再买回来。这样做,大概率上会降低成本。

要牢牢记住,反弹多了就减仓,就算你很不幸,卖在了牛市的起步阶段,你也可以在牛市行情确立的时候再买回来。

这样高抛低吸的来回交易,对主动管理型基金来说,成本费用太高。建议买入创业板ETF或者中小板ETF,手续费更便宜。

方法二:10%补仓法

不断进行补仓,使亏损比例控制在10%以内,然后一个10%的反弹就解套了。是不是很简单?缺点就是要有足够的资金。

本文总结

我们通过上述的验证,大致可以得到下面的结论,当然这个结论是针对上证综指的,按道理我应该看过几个指数,但是授之以鱼不如授之以渔,方法都在代码里,大家不妨自己动手试试?自己得到一些结论不是来得更有feel不

  • 定投周期在50个月之内的,定投跑赢余额宝的概率是50%;
  • 当定投周期在60个月(5年)左右的满意概率与定投60~120个月的满意概率差不多,大概是65%;
  • 定投240个月(20年)左右的满意概率可以达到80%,大概率水平上会获得比余额宝要好得多的收益!
  • 定投20年基金,止盈点定在80~90%,发生的可能性为80%;
  • 定投20年基金,止盈点定在130~140%,发生的可能性为50%;
  • 定投20年基金,止盈点定在200~210%,发生的可能性为20%;

Reference

  • 深度实战,当下最好的投资策略 — 复利人生
  • Python在基金定投上的验证

关于Python金融量化

专注于分享Python在金融量化领域的应用。加入知识星球,可以免费获取30多g的量化投资视频资料、公众号文章Python完整源码、量化投资前沿分析框架,与博主直接交流、结识圈内朋友等。

相关阅读

关键词不能为空

经济新闻_金融新闻_财经要闻_理财投资_理财保险_百色金融新闻网