基于Python的指數基金量化投資 - 指數投資技巧(一)定期定額

指數投資方式中有四種基本的方法烫映,分別是定期定額沼本、定期不定額、不定期定額和不定期不定額锭沟,這四種方式投資效果不同抽兆,對投資者的要求也不同辫红,定期定額最簡單祝辣,但收益不算高蝙斜,不定期不定額最復雜孕荠,對投資者的要求最高,特別是對情緒的要求非常高底循,同時收益也是最好的熙涤。

這里先介紹第一種定期定額的情況祠挫,下面會通過量化的過程來反應投資的整體過程等舔。

定期定額就是按日、按周或者按月進行投資甚牲,每次投資的資金是一樣的蝶柿,比如每周買入1000塊的滬深300基金,這種方式是不管指數漲跌雏赦,到點就買芙扎;

假設每次投入的資金是1000塊戒洼,按周定投,下面是通過量化的過程跑出來的情況(源碼附在后面)敷矫,這里既然是定期定額就不考慮賣出。數據是通過中證全指(指數代碼1000002)進行計算的蠕搜。

上半部分的圖中藍線是中證全指的走勢圖轨蛤,紅點是每周定投的位置祥山,下半部分的圖中藍線是累計投入的資金缝呕,紅線是持有基金的市值斧散,整個過程投入的總資金是500000鸡捐,最終的基金總市值是680424.75栈暇,最后獲得的收益是36.08%,從下半部分圖中可以很清晰的看出源祈,當指數下跌的過程,基金市值會低于投入的資金香缺,這個過程收益為負,隨著指數的上漲脚草,基金市值上漲的幅度會高于投入的資金,然后在某些點超過投入資金的總值馏慨,這個過程收益就會轉負為正埂淮,這就是在低點積累的份額更多造成的。

整體來說定期定額的投資效果并不是很好写隶,接下來還會分享定期不定額倔撞、不定期定額和不定期不定額來進行比較。

源碼


import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import math as math


name_index = 'lxr_1000002'

name_index_g = 'g_lxr'

all_data_index =pd.read_csv('./exportfile/indexDataAll/' + name_index + '.csv')

all_data_index_g =pd.read_csv('./importfile/indexSeries/indexValuation/g/' + name_index_g +'.csv')


calc_range = 2500

calc_gap = 5

data_index_p = all_data_index['close'].values[len(all_data_index['close'])- calc_range:len(all_data_index['close']):calc_gap]

data_index_g =all_data_index_g['pe'].values[len(all_data_index_g['pe']) -calc_range:len(all_data_index_g['pe']):calc_gap]

val_percentage_list = list()


sell_flag_no_regular_no_quota = [0, 0]

sell_flag_regular_quota = 0

sell_flag_regular_no_quota = 0

sell_flag_no_regular_quota = 0



def RegularQuota(val_percentage,val_data_p, buy_cnt, buy_total_share):

???global sell_flag_regular_quota

???if val_percentage <= 1:

???????sell_flag_regular_quota = 0

???????buy_each_regular_quota = 1000

???????buy_each_share = buy_each_regular_quota / val_data_p

???????buy_total_share = buy_total_share + buy_each_share

???????buy_cnt = buy_cnt + 1

???????plot_y = val_data_p

???????plot_x = i

???????plot_flag = 1

???else:

???????if sell_flag_regular_quota == 0:

???????????sell_flag_regular_quota = 1

???????????buy_each_share = -buy_total_share

???????????buy_total_share = 0

???????????plot_y = val_data_p

???????????plot_x = i

???????????plot_flag = -1

???????else:

???????????buy_each_share = 0

???????????plot_y = val_data_p

???????????plot_x = i

???????????plot_flag = 0


???return buy_each_share, buy_cnt, [plot_flag, plot_x, plot_y],buy_total_share


gap = 5?# invest each week

cnt = 0


buy_each_share_regular_quota =np.zeros((len(data_index_p), 1))

buy_total_share_list_regular_quota =np.zeros((len(data_index_p), 1))

buy_total_money_list_regular_quota =np.zeros((len(data_index_p), 1))

buy_cnt_regular_quota = 0

plot_regular_quota =np.zeros((len(data_index_p), 3))


buy_each_share_regular_no_quota =np.zeros((len(data_index_p), 1))

buy_total_share_list_regular_no_quota =np.zeros((len(data_index_p), 1))

buy_total_money_list_regular_no_quota =np.zeros((len(data_index_p), 1))

buy_cnt_regular_no_quota = 0

plot_regular_no_quota =np.zeros((len(data_index_p), 3))


buy_each_share_no_regular_quota =np.zeros((len(data_index_p), 1))

buy_total_share_list_no_regular_quota =np.zeros((len(data_index_p), 1))

buy_total_money_list_no_regular_quota =np.zeros((len(data_index_p), 1))

buy_cnt_no_regular_quota = 0

plot_no_regular_quota =np.zeros((len(data_index_p), 3))


buy_each_share_no_regular_no_quota =np.zeros((len(data_index_p), 1))

buy_total_share_list_no_regular_no_quota =np.zeros((len(data_index_p), 1))

buy_total_money_list_no_regular_no_quota =np.zeros((len(data_index_p), 1))

buy_cnt_no_regular_no_quota = 0

plot_no_regular_no_quota =np.zeros((len(data_index_p), 3))


# idx_start = 974 #2011-1-4

idx_start = 1

for i in range(len(data_index_p)):

???valuation_len =all_data_index_g['pe'].values[len(all_data_index['close']) -calc_range-500:len(all_data_index['close']) - calc_range+i*calc_gap:calc_gap]

???val_loc = np.where(valuation_len < data_index_g[i])

???val_percentage = len(val_loc[0]) / (len(valuation_len))

???val_percentage_list.append(val_percentage)


???buy_each_regular_quota = 1000

???buy_each_share_regular_quota[i], buy_cnt_regular_quota,plot_regular_quota[i], buy_total_share_regular_quota\

???????= RegularQuota(val_percentage, data_index_p[i], buy_cnt_regular_quota,sum(buy_each_share_regular_quota))

???buy_total_share_list_regular_quota[i] =sum(buy_each_share_regular_quota) * data_index_p[i]

???buy_total_money_list_regular_quota[i] = buy_cnt_regular_quota *buy_each_regular_quota


earn_total_money_no_regular_quota =np.zeros((len(data_index_p), 1))

money_sell_no_regular_quota = 0

for i in range(len(data_index_p)):

???if buy_each_share_no_regular_quota[i] < 0:

???????money_sell_no_regular_quota = money_sell_no_regular_quota -buy_each_share_no_regular_quota[i] * data_index_p[i]

???earn_total_money_no_regular_quota[i] =sum(buy_each_share_no_regular_quota[0:i+1]) * data_index_p[i] +money_sell_no_regular_quota


earn_total_money_regular_no_quota =np.zeros((len(data_index_p), 1))

money_sell_regular_no_quota = 0

for i in range(len(data_index_p)):

???if buy_each_share_regular_no_quota[i] < 0:

???????money_sell_regular_no_quota = money_sell_regular_no_quota -buy_each_share_regular_no_quota[i] * data_index_p[i]

???earn_total_money_regular_no_quota[i] = sum(buy_each_share_regular_no_quota[0:i+1])* data_index_p[i] + money_sell_regular_no_quota


earn_total_money_regular_quota =np.zeros((len(data_index_p), 1))

money_sell_regular_quota = 0

for i in range(len(data_index_p)):

???if buy_each_share_regular_quota[i] < 0:

???????money_sell_regular_quota = money_sell_regular_quota -buy_each_share_regular_quota[i] * data_index_p[i]

???????print('')

???earn_total_money_regular_quota[i] =sum(buy_each_share_regular_quota[0:i+1]) * data_index_p[i] +money_sell_regular_quota

???print('')


earn_total_money_no_regular_no_quota =np.zeros((len(data_index_p), 1))

money_sell_no_regular_no_quota = 0

for i in range(len(data_index_p)):

???if buy_each_share_no_regular_no_quota[i] < 0:

???????money_sell_no_regular_no_quota = money_sell_no_regular_no_quota -buy_each_share_no_regular_no_quota[i] * data_index_p[i]

???earn_total_money_no_regular_no_quota[i] =sum(buy_each_share_no_regular_no_quota[0:i+1]) * data_index_p[i] +money_sell_no_regular_no_quota


plt_gap = 10

size_title = 28

size_label = 15

size_line = 3

size_rotation = 15

size_buy_plot = 5


#------------------------------------------------------------- #


plt.figure()

plt.rcParams["axes.grid"] = True

plt.rcParams['font.sans-serif'] =['Microsoft YaHei']

plt.rcParams['axes.unicode_minus'] = False

plt.rcParams["grid.linestyle"] =(3, 5)

plt.subplot(211)


income = 100 *(earn_total_money_regular_quota[-1][0] -buy_total_money_list_regular_quota[-1][0]) /buy_total_money_list_regular_quota[-1][0]

plt.title('定期定額 | 投資收益= ' + str("{:.2f}".format(income)) + '%',size=15)


v_max = max(data_index_p)

v_min = min(data_index_p)


for i in range(len(plot_regular_quota)):

???if plot_regular_quota[i][0] == 1:

???????plt.plot(plot_regular_quota[i][1], plot_regular_quota[i][2],color='tomato',marker='o',ms=(size_buy_plot*v_max/plot_regular_quota[i][2]))

???elif plot_regular_quota[i][0] == -1:

???????plt.plot(plot_regular_quota[i][1], plot_regular_quota[i][2],color='purple', marker='o',ms=10)

plt.plot(data_index_p)

plt_xticks =all_data_index['date'].values[len(all_data_index['close']) -calc_range:len(all_data_index['close']):calc_gap].tolist()

plt.xticks(range(len(plt_xticks),0,-math.floor(len(plt_xticks)/plt_gap)),plt_xticks[len(plt_xticks):0:-math.floor(len(plt_xticks)/plt_gap)],rotation=size_rotation)

plt.tick_params(labelsize=size_label)


plt.subplot(212)

plt.plot(buy_total_share_list_regular_quota,color='tomato')

font = {'size': 15, 'color': 'tomato','weight': 'black'}

plt.text(len(buy_total_share_list_regular_quota),buy_total_share_list_regular_quota[-1][0], str("{:.2f}".format(buy_total_share_list_regular_quota[-1][0])),fontdict=font)

plt.plot(len(buy_total_share_list_regular_quota)-1,buy_total_share_list_regular_quota[-1][0],color='tomato', marker='o')


plt.plot(buy_total_money_list_regular_quota,color='cornflowerblue')

font = {'size': 15, 'color':'cornflowerblue', 'weight': 'black'}

plt.text(len(buy_total_money_list_regular_quota),buy_total_money_list_regular_quota[-1][0],str("{:.2f}".format(buy_total_money_list_regular_quota[-1][0])),fontdict=font)

plt.plot(len(buy_total_money_list_regular_quota)-1,buy_total_money_list_regular_quota[-1][0],color='cornflowerblue', marker='o')


plt.plot(earn_total_money_regular_quota,color='red')

font = {'size': 15, 'color': 'red','weight': 'black'}

plt.text(len(earn_total_money_regular_quota),earn_total_money_regular_quota[-1][0],str("{:.2f}".format(earn_total_money_regular_quota[-1][0])),fontdict=font)

plt.plot(len(earn_total_money_regular_quota)-1,earn_total_money_regular_quota[-1][0],color='red', marker='o')


plt_xticks =all_data_index['date'].values[len(all_data_index['close']) -calc_range:len(all_data_index['close']):calc_gap].tolist()

plt.xticks(range(len(plt_xticks),0,-math.floor(len(plt_xticks)/plt_gap)),plt_xticks[len(plt_xticks):0:-math.floor(len(plt_xticks)/plt_gap)],rotation=size_rotation)

plt.tick_params(labelsize=size_label)


#----------------------------------------------------------------- #


plt.show()

文中用到的兩個文件鏈接: https://pan.baidu.com/s/13alPKvTP7Rw061UMcgtMXQ?pwd=s6dr 提取碼: s6dr

程序中用到的數據如果有問題,大家可以留言獲取帝际,歡迎大家一起交流溝通^_^

課程參考:網易云課堂? 基于Python的量化指數基金投資

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蹲诀,隨后出現的幾起案子斑粱,更是在濱河造成了極大的恐慌,老刑警劉巖脯爪,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件则北,死亡現場離奇詭異,居然都是意外死亡披粟,警方通過查閱死者的電腦和手機咒锻,發(fā)現死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來守屉,“玉大人惑艇,你說我怎么就攤上這事∧捶海” “怎么了滨巴?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長俺叭。 經常有香客問我恭取,道長,這世上最難降的妖魔是什么熄守? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任蜈垮,我火速辦了婚禮,結果婚禮上裕照,老公的妹妹穿的比我還像新娘攒发。我一直安慰自己,他們只是感情好晋南,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布惠猿。 她就那樣靜靜地躺著,像睡著了一般负间。 火紅的嫁衣襯著肌膚如雪偶妖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天政溃,我揣著相機與錄音趾访,去河邊找鬼。 笑死董虱,一個胖子當著我的面吹牛腹缩,可吹牛的內容都是我干的。 我是一名探鬼主播空扎,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼藏鹊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了转锈?” 一聲冷哼從身側響起盘寡,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撮慨,沒想到半個月后竿痰,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡砌溺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年影涉,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片规伐。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蟹倾,死狀恐怖,靈堂內的尸體忽然破棺而出猖闪,到底是詐尸還是另有隱情鲜棠,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布培慌,位于F島的核電站豁陆,受9級特大地震影響,放射性物質發(fā)生泄漏吵护。R本人自食惡果不足惜盒音,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馅而。 院中可真熱鬧祥诽,春花似錦、人聲如沸用爪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽偎血。三九已至诸衔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間颇玷,已是汗流浹背笨农。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留帖渠,地道東北人谒亦。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親份招。 傳聞我的和親對象是個殘疾皇子切揭,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容