import pandas as pd
import numpy as np
#import numpy_financial as npf
import os
fpath = r”P:\PythonExe\doc\SmallValue.csv”
dfRaw = pd.read_csv(fpath)
#[52 rows x 9 columns]
dfSV = dfRaw.iloc[:, 0:4]
#Small Value
#[52 rows x 4 columns]
dfSVdrop = dfSV.dropna(how = “all”).reset_index(drop = True)
#[51 rows x 4 columns]
lisCol = dfSVdrop.columns.tolist()
#[‘Year’, ‘US Large Cap’, ‘US Small Cap’, ‘US Large Cap Value’]
aryYear = dfSVdrop[ lisCol[0] ].values.astype(np.int64) #np.uint64更好
aryLarge = dfSVdrop[ lisCol[1] ].values.astype(np.float64)
arySmall = dfSVdrop[ lisCol[2] ].values.astype(np.float64)
aryLValue = dfSVdrop[ lisCol[3] ].values.astype(np.float64)
lisLS_LV = [aryLarge, arySmall, aryLValue]
#Large, Small, LargeValue
dfEM = dfRaw.iloc[:, 5:9]
# Emerging Markets
#[52 rows x 4 columns]
dfEMdrop = dfEM.dropna(how = “all”).reset_index(drop = True)
#[28 rows x 4 columns]
lisColEM = dfEMdrop.columns.tolist()
#[‘Year.1’, ‘US Stock Market’, ‘Emerging Markets’, ‘Global ex-US Stock Market’]
aryYear1 = dfEMdrop[ lisColEM[0] ].values.astype(np.int64)
aryUS = dfEMdrop[ lisColEM[1] ].values.astype(np.float64)
aryEM = dfEMdrop[ lisColEM[2] ].values.astype(np.float64)
aryIntl = dfEMdrop[ lisColEM[3] ].values.astype(np.float64)
# =================================
# start = 0
# nYear = 5
# end = start + nYear
# lis_totReturnN = []
# #aryLargeN = aryLarge[start : end]
# =================================
def ary2lis_totReturnN( ary = aryLarge , nYear=5):
“””
讀進來一個array = aryLarge與 nYear=5,
輸出lis_totReturnN
該list之元素為滾動五年的總報酬率
以及lisIRR,該list元素為滾動五年IRR
“””
lis_totReturnN = []
lisIRR = []
start = 0
#nYear = 5
end = start + nYear
while True:
aryN = ary [start : end]
# aryN_IRR = npf.irr(aryN)
# lisIRR.append(aryN_IRR)
# 很多nan,因為aryN並不是正負現金流,
# 而是各年度報酬率
# std = np.std(aryN) #若要收集波動度資料
if len(aryN) < nYear : break
totReturnN = 1
for i in range(nYear):
totReturnN *= (1 + aryN[i])
totReturnN = totReturnN-1
irr = (1+totReturnN)**(1/nYear) – 1
lisIRR.append(irr) #len(lisIRR) =47
lis_totReturnN.append( totReturnN )
#len(lis_totReturnN) = 47
#47次滾動五年
start += 1
end = start + nYear
return lis_totReturnN, lisIRR
# ========================================
# lis_totReturnN, lisIRR = \
# ary2lis_totReturnN( ary = aryLarge , nYear=5)
# ========================================
def lisKinds2ary(lisKinds = lisLS_LV, nYear1 = 5):
“””
lisKinds = lisLS_LV
lisLS_LV = [aryLarge, arySmall, aryLValue]
讀進來一個list,其元素為
大型股,小型股,大型價值股之各年度報酬率
1972年初~2022年底,共51個完整年度
#len(aryLarge) = 51
輸出兩個2D array: ary_totReturnN2D, aryIRR2D
參數nYear1 = 5,
array axis0 = 0,1,2分別代表大型,小型,大型價值股
array axis1 = 47,有47次滾動五年的總報酬率,IRR
“””
lis_totReturnN2D = []
lisIRR2D = []
for ele in lisLS_LV: #for ele in lisKinds: #訂正,結果剛好一樣
lis_totReturnN, lisIRR = \
ary2lis_totReturnN( ary = ele , nYear = nYear1)
lis_totReturnN2D.append(lis_totReturnN)
lisIRR2D.append(lisIRR)
#len(lis_totReturnN2D) = 3
#len(lisIRR2D) = 3
ary_totReturnN2D = np.array(lis_totReturnN2D)
#(3, 47)
aryIRR2D = np.array(lisIRR2D)
#(3, 47)
return ary_totReturnN2D, aryIRR2D, nYear1
ary_totReturnN2D, aryIRR2D, nYear1 \
= lisKinds2ary(lisKinds = lisLS_LV, nYear1 = 5)
“””
輸出兩個2D array
ary_totReturnN2D, aryIRR2D
參數nYear1 = 5,
array axis0 = 0,1,2分別代表大型,小型,大型價值股
array axis1 = 47,有47次滾動五年的總報酬率,IRR
“””
def aryIRR2D_premium(nYear2 = nYear1, kind=1, aryIRR2D=aryIRR2D,
baseIdx=0, lisCol=lisCol , aryYear = aryYear ):
“””
aryIRR2D: array axis0 = 0, 1, 2分別代表大型,小型,大型價值股
“””
ary_totReturnN2D, aryIRR2D, nYear2 \
= lisKinds2ary(lisKinds = lisLS_LV, nYear1 = nYear2)
aryBase = aryIRR2D[baseIdx] #大型股滾動五年IRR
#kind = 1
aryPremium = aryIRR2D[kind] #kind =1,小型股滾動五年IRR
dif = aryPremium – aryBase
aryBool = aryPremium – aryBase >= 0
#len(aryBool) = 47 #aryBool.shape = (47,)
tup = aryBase, aryPremium, dif, aryBool
aryBasePre = np.vstack( tup )
df = pd.DataFrame(aryBasePre).T
df.columns =[ lisCol[baseIdx+1], lisCol[kind+1],”差距”,”是否溢酬” ]
folder = r”P:\PythonExe\doc\premium”
fname = lisCol[kind+1] + “_premium_” + str(nYear2) + “.xlsx”
#別漏副檔名 “.xlsx”
fpath = os.path.join(folder, fname)
df.to_excel(fpath)
aryTrueIdx = aryBool.nonzero()[0]
#aryBool.nonzero() 是長度1的tuple
#aryBool.nonzero()[0]才是array #shape (27,)
#avgPreIRR = np.mean( aryPremium[aryTrueIdx.tolist()] )
cntPremium = len(aryTrueIdx) #cntPremium = 27
cntBase = len(aryBase) #47
prob = cntPremium/cntBase
print(“從%4d年初到%4d年底,共有%2d個完整年度,%2d個滾動%2d年,\n%s勝出%s %2d次,勝出機率%.2f%%\n”
%( aryYear[0], aryYear[-1], len(aryYear), cntBase, nYear2,
lisCol[kind+1],lisCol[baseIdx+1],cntPremium, prob*100) )
#lisCol[kind+1],因為lisCol多一欄year欄位
return None
lis_nYear = [3,5,10,15,20]
for n in lis_nYear:
aryIRR2D_premium(nYear2 = n, kind=1, aryIRR2D=aryIRR2D,
baseIdx=0, lisCol=lisCol , aryYear = aryYear )
近期留言