基金定投需要注意波段操作!(文章有點長,含Python代碼)

最近,在用Python對股市進行量化分析,發現網上流傳很廣的一些結論並不一定正確。

定投策略就是不要管股市是漲是跌,每個月都定期的拿出一筆錢來買基金。股市總是上演七陪二平一賺的股市,散戶因爲沒有能力判斷,索性不判斷,而基金定投就被認爲是一種投資的途徑。

其中,邢不行老師的 《【量化小講堂系列14-Python量化入門】數據告訴你:驚人的指數定投策略》在網上傳播很廣。(2)(3)

而這種理論一個最大的依據是 “巴菲特這一輩子曾經無數次的說過:對於個人投資者,最好的投資方式就是指數基金定投。”

但也有人專門爲此較真,拿了巴菲特的原文,認爲巴菲特根本沒有推薦過這種方法。(1)

那麼定投究竟美不美?爲什麼這麼多的理財和銀行都在推薦?我們用Python進行簡單的分析一下。(文章後面提供源代碼,應該容易讀懂)

首先驗證邢老師的第一個例子,從2007年10月股市最高點開始定投,一直到2009年7月股市3000點,文中用滬深300指數作爲定投標的,但指數不能直接買賣,而滬深300基金(510300)是2012年纔開始,所以我們把50ETF(510050)作爲依據計算定投收益,結果如下,的確如邢不行老師的結論,50ETF價格下降了35.93%,理財定投只有3.91%,50ETF定投收益率達到24.28%。
在這裏插入圖片描述
在這裏插入圖片描述
但我們從圖中看,就很有意思:
(1)基金定投與基金價格的趨勢基本上是一致的,
(2)基金定投的收益明顯高於基金本身的收益,特別在2009年開始後的收益。
(3)基金定投收益一直低於理財定投,只有在2009年6月中旬開始才超過理財定投。
(4)在2007年10月到2008年12月間,股市下跌,50ETF無論是定投還是基金本身,收益都是很差的;而在2008年12月到2009年7月,股市上漲,50ETF無論定投還是基金本身收益都很好,也是因爲這段時間的收益,導致了最終定投收益超過理財收益。

我們再拿滬深300ETF(510300)驗證,假設從成立開始的2012年5月28日開始,就定投基金,一直持有到2018年底,投資收益情況如下:
(1)定投收益率(10.85%)不如理財定投收益(14.75%)不如直接的基金收益(26.79%)
(2) 基金定投收益趨勢與基金價格變化趨勢基本一致。
(3) 基金定投收益與基金價格變化犬牙交錯,並不一定高於基金價格變化。
(4) 這種情況購買反而在2015年股市高峯期後基金定投收益大部分時間高於理財定投收益。
(5) 但在2018年不斷下降中,基金定投收益又開始快速下降,直到2018年末甚至低於理財定投收益。(大家可以自己驗證,在2019年股市上漲中,基金定投收益又會快速上升)
在這裏插入圖片描述
在這裏插入圖片描述
最後我們基本上可以得出這樣的結論:
(1)基金定投並沒有我們想象那麼好,至少在A股市場,基金定投並不是一門好生意。
(2)基金定投依然波段十分明顯,與股市變化趨勢基本一致。抓住幾個大的峯值是十分重要的。
(3)總的而言,基金定投在股市上漲中追不上股市的上漲速度,在股市下跌中下跌也會相對比股市跌幅小,有一定的緩和作用,但作用並不是那麼明顯。
(4)定投策略不僅可以用於基金,也可以用於其他的股票(只要把源碼中參數改變即可驗證),但無論投資品種是什麼,定投策略也必須根據趨勢進行高拋低吸。

最後給出源代碼如下(直接用tushare提供數據源,如果又需要股市的數據文件,可以私信交流):

#你一定要相信,你自己就是一道風景,沒有必要在別人的風景裏仰視!
#不是每一次努力都有收穫,但是每一次收穫都必須努力
#人的一切痛苦,本質上都是對自己的無能的憤怒。——王小波

import pandas as pd
import tushare as ts
import numpy as np
import datetime
import matplotlib.pyplot as plt  

def function(a, b):
	if a == b:
		return 0
	else:
		return 1

#按 利率 計算 期間定投收益,AIP:automatic investment plan
def AIP(inRate,startdate,enddate):

    df = pd.DataFrame(index=None,columns=['date','rate','profit'])

    d1 = datetime.datetime.strptime(startdate, '%Y-%m-%d')
    d2 = datetime.datetime.strptime(enddate, '%Y-%m-%d')
    delta = d2 - d1
    n = delta.days   # 投資的總日期

    df['date'] = pd.date_range(start=startdate,end=enddate,periods=n+1) #按日期數量產生日期
    df['rate'] = inRate/365              # 簡單按365日把年華收益轉化爲日收益
    df['profit']=(df['rate']+1).cumprod()  # 計算累計收益
    df['month']=df['date'].apply(lambda x: datetime.datetime.strftime(x,"%m"))
    df['month1']=df['month'].shift(1)
    df['isinv']=df.apply(lambda x: function(x.month,x.month1),axis=1)  #計算是否爲第一日
    df['理財投資額']=df['isinv']*1000     #如果第一日就會進行投資買入理財產品
    df['理財總投資']=df['理財投資額'].cumsum()   # 累計投資總和
    df['理財份額']=df['理財投資額']/df['profit']  
    df['理財總份額']=df['理財份額'].cumsum()
    df['理財價值']=df['理財總份額']*df['profit']
    df['理財收益']=df['理財價值']-df['理財總投資']
    df['理財收益率']=df['理財收益']/df['理財總投資']

    df.set_index('date',inplace=True)  # 把日期作爲排序依據
    
    return df

# 按某個代碼進行定投計算(可以是基金也可以是股票)
def Stock(sCode,startdate,enddate):

    # 採集數據
    df=ts.get_k_data(code=sCode,start=startdate,end=enddate)
    df['s_month']='1'  #初始化月份填一個數
    df['s_month1']='0'   # 初始化
    df['s_month']=df['date'].str[0:4]+df['date'].str[5:7]  # 月份比較,尋找月初第一日如果是下一日月份沒變 
    df['s_month1']=df['s_month'].shift(1)
    df['date'] = pd.to_datetime(df['date'])
    df['s_isinv']=df.apply(lambda x: function(x.s_month,x.s_month1),axis=1)  # 根據月份變化是否標誌出是否月初
    df['股票份額'] = round(df['s_isinv']*1000/df['close']/100,0)*100  #買賣股票一般按100股進行
    # df['股票份額'] = round(df['s_isinv']*1000/df['close'],0)  # 不按100股買賣進行計算
    df['股票總份額']=df['股票份額'].cumsum()
    df['股票價值']=df['股票總份額']*df['close']
    df['股票投資額']=df['股票份額']*df['close']
    df['股票總投資']=df['股票投資額'].cumsum()
    df['股票收益']=df['股票價值']-df['股票總投資']
    df['股票收益率'] = df['股票收益']/df['股票總投資']

    return df

start_date = '2012-05-12'
end_date = '2018-12-30'
scode = '510300'
plt.figure()
plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標籤
plt.rcParams['axes.unicode_minus']=False #用來正常顯示負號

plt.title(scode +"股票收益率計算")

df1 = Stock(scode,start_date,end_date)

df2 = AIP(0.04,start_date,end_date)

# 把投資和理財合併,並且把沒用的列儘量去除
daily_data=pd.merge(df1,df2,'inner',on='date')
daily_data.drop(['month','month1','s_month','s_month1','isinv','s_isinv'],axis=1,inplace=True)
daily_data.drop(['股票份額','股票投資額','rate','profit','理財投資額','理財份額'],axis=1,inplace=True)

iclose = daily_data['close'].iloc[0]  #取得首日的股價

daily_data['股價變化率'] = daily_data['close']/iclose-1  #單純按最後一天和首日股價進行比較
daily_data.set_index("date",inplace=True)
print('起投日期:',start_date)
print('結束時間:',end_date)
print('收市價收益率','{:.2%}'.format(daily_data.iloc[-1]['股價變化率']))

print('股票總投資',daily_data.iloc[-1]['股票總投資'])
print('股票價值',daily_data.iloc[-1]['股票價值'])
print('股票收益',daily_data.iloc[-1]['股票收益'])
print('股票收益率','{:.2%}'.format(daily_data.iloc[-1]['股票收益率']))

print('理財總投資',daily_data.iloc[-1]['理財總投資'])
print('理財價值',daily_data.iloc[-1]['理財價值'])
print('理財收益',daily_data.iloc[-1]['理財收益'])
print('理財收益率','{:.2%}'.format(daily_data.iloc[-1]['理財收益率']))

daily_data.to_excel("daily.xls")

daily_data['股價變化率'].plot()
daily_data['理財收益率'].plot()
daily_data['股票收益率'].plot()

plt.legend()

plt.show()


參考文獻:
1、巴菲特又被冤枉了,他從沒推薦過指數定投!

2、數據告訴你:驚人的指數定投策略
人大經濟論壇,詳細出處參考: https://bbs.pinggu.org/forum.php?mod=viewthread&tid=4585892&page=1
3、用Python成功驗證巴菲特推崇的“指數定投”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章