更新於 2024/11/11閱讀時間約 9 分鐘

用Python計算「All in 0050股息再投入」的績效

先用yfinance抓取0050由2014-11-01到2024-11-01的股價,程式碼如下:

import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt
df_0050 = yf.download("0050.TW",start='2014-11-01',end='2024-11-01')
df_0050['Close'].plot()

plt.title('0050.TW')
plt.xlabel('Date')
plt.ylabel('')
# Show the plot
plt.show()
raw-image

模擬用100萬All in 0050(包含零股買入),再把0050的股息再投入(股息發放日再All in 0050零股),看績效如何,之後用ffn分析結果。

# Dividends data
Dividends_0050 = {
'Date': [
'2024/08/09', '2024/02/21', '2023/08/11', '2023/03/07', '2022/08/19',
'2022/03/04', '2021/08/24', '2021/03/09', '2020/08/24', '2020/03/06',
'2019/08/22', '2019/03/08', '2018/08/27', '2018/03/13', '2017/08/31',
'2017/03/14', '2016/08/30', '2015/11/26', '2014/11/27'
],
'Dividends': [
1, 3, 1.9, 2.6, 1.8, 3.2, 0.35, 3.05, 0.7, 2.9,
0.7, 2.3, 0.7, 2.2, 0.7, 1.7, 0.85, 2, 1.55
]
}
dividends_df = pd.DataFrame(Dividends_0050)
dividends_df['Date'] = pd.to_datetime(dividends_df['Date'])
dividends_df.set_index('Date', inplace=True)
dividends_df.index = dividends_df.index.tz_localize('UTC')

# Drop the 'Ticker' level from the multi-level columns
df_0050 = df_0050[['Close']]
df_0050.columns = df_0050.columns.droplevel(1) # remove Ticker
df_0050 = df_0050[['Close']].rename(columns={'Close': 'Price'})

merged_df = df_0050.merge(dividends_df, left_index=True, right_index=True, how='left')
merged_df['Dividends'].fillna(0, inplace=True)
merged_df['shares'] = 0
merged_df['buy_today'] = 0
merged_df['remain_cash'] = 0.0
merged_df['value'] = 0

initial_cash = 1000000 # 100W

START_DATE = '2022-01-01'
END_DATE = '2023-01-01' # Convert Date column to datetime if it isn't already

filtered_df = merged_df.loc[START_DATE:END_DATE]

# 零股算法
# 第一天
merged_df.reset_index(inplace=True) # number index
merged_df.loc[0, 'buy_today'] = int( initial_cash / merged_df.loc[0, 'Price'] )
merged_df.loc[0, 'remain_cash'] = initial_cash - int( merged_df.loc[0, 'buy_today'] * merged_df.loc[0, 'Price'] )
merged_df.loc[0, 'shares'] = merged_df.loc[0, 'buy_today']
merged_df.loc[0, 'value'] = initial_cash
for i in range(1, len(merged_df)):
if(merged_df.at[i, 'Dividends'] != 0):
cash_today = merged_df.at[i-1, 'remain_cash'] + merged_df.at[i, 'Dividends'] * merged_df.at[i-1, 'shares']
merged_df.at[i, 'buy_today'] = int( cash_today / merged_df.at[i, 'Price'] )
merged_df.at[i, 'remain_cash'] = cash_today - int( merged_df.at[i, 'buy_today'] * merged_df.at[i, 'Price'] )
merged_df.at[i, 'shares'] = merged_df.at[i-1, 'shares'] + merged_df.at[i, 'buy_today']
# total value
merged_df.at[i, 'value'] = int( merged_df.at[i, 'remain_cash'] + merged_df.at[i, 'shares'] * merged_df.at[i, 'Price'] )
else:
merged_df.at[i, 'buy_today'] = 0
merged_df.at[i, 'remain_cash'] = merged_df.at[i-1, 'remain_cash']
merged_df.at[i, 'shares'] = merged_df.at[i-1, 'shares']
merged_df.at[i, 'value'] = int( merged_df.at[i, 'remain_cash'] + merged_df.at[i, 'shares'] * merged_df.at[i, 'Price'] )

import ffn
result_df = merged_df.copy()
result_df.set_index('Date', inplace=True)
perf = result_df['value'].calc_stats()
print(perf.display())

可以看出10年的報酬率308%,最大回檔約-33%

這個績效比起我上一篇「台灣發行量加權股價報酬指數」還贏過38%,原本以為會很接近。看來買0050還勝過買大盤。

比較一下0050指數佔加權指數的比重多少?

根據加權指數歷史資料臺灣50指數歷史資料,計算一下103/11/03和113/11/01的0050指數佔加權指數的比重多少?

print("103/11/03 0050佔加權指數比重: %.2f%%" % ((6572.20 / 9004.86) * 100))
print("113/11/01 0050佔加權指數比重: %.2f%%" % ((18928.25 / 22780.08) * 100))

可見0050指數的佔比在這10年間增加了10%,難怪會跑贏大盤。






分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.