ãã®èšäºã¯BASE Advent Calendar 2019ã®5æ¥ç®ã®èšäºã§ãã devblog.thebase.in ããã«ã¡ã¯ãBASEæ ªåŒäŒç€Ÿã§Owners GrowthããŒã ã®ãããŒãžã£ãŒãããŠããé è€ã§ãã Owners GrowthããŒã ã®ããã·ã§ã³ã¯ããBASEãã«ç»é²ããŠããã·ã§ããã®æé·ãæ¯æŽããããéå¶ã®ãµããŒããè¡ãããšã§ãBASEãã§ã®ã·ã§ããã®éèšã»éå¶ã®äœéšãåäžãããã·ã§ããããã«ç¶ç¶çã«ãå©çšããã ãããšã§ãã ä»åã¯ã¢ããã³ãã«ã¬ã³ããŒãšããããšã§ããã®ããã·ã§ã³ãéè¡ããããã«æ®æ®µã©ããªããšãè¡ãªã£ãŠããã®ããç¹ã«Owners GrowthããŒã ã§è¡ãªã£ãŠããæŠç¥ãæŠè¡ã決ããããã®ä»®èª¬æ€èšŒããã»ã¹ãç°¡åã«ã玹ä»ããããšæããŸãã ããããOwners Growthã£ãŠã©ããªããšãèããªããä»äºãããŠããã®ïŒãšããã©ããã£ãŠä»®èª¬ãæ€èšŒããªããæŠç¥ãäœãã®ïŒã£ãŠããçåã«çãããããããªèšäºã«ããããªãšæããŸããã ãã ãå®éã®ç€Ÿå
ããŒã¿ã¯çŽæ¥ãèŠãããšãã§ããªãã®ã§ã身è¿ã«ååšããåé¡ãæ¢ããçµæãæè³ãšããããŒãã顿ã«ããŠã¿ãŸããã ç®æšããèããKPIèšèšãšä»®èª¬æ€èšŒããã»ã¹ Iåã¯æè¿ãæ ªã«èå³ããã¡æè³ãå§ããããšæãç«ã¡ãŸããããã©ã®äŒç€Ÿã®æ ªãè²·ãã°ããã®ãããããæ©ãã§ããŸãã ããã§ã®Iåã®ç®æšã¯äœãã©ã®ãããè²·ãã®ããã€ãŸã æè³æ¹éãæ±ºããããš ã«ãªããŸãã ããã§Iåã¯ãã®ç®æšãéæããããã®èŠçŽ ãšããŠ æ ªäŸ¡ãäžãããããããš ãªã¹ã¯ãæããããããš ã®ïŒã€ãããããšã«æ°ã¥ãããŸãã¯ãã®æ ªäŸ¡ã®äžããããããšãªã¹ã¯ãå®éåããå¿
èŠããããšèããŸããã KPIèšèš äžãããããã¯éå»ã®æ ªäŸ¡ã®å€åçãšãããªã¹ã¯ãæ ªäŸ¡ã®æšæºåå·®ãšå®çŸ©ããŸãã ã€ãŸããéå»ã®æ ªäŸ¡ããã©ã¹ã«å€åããŠããéæã¯ä»åŸãäžããããããäžäžã®å€åã倧ããã£ãéæã¯ãªã¹ã¯ã倧ãããšèããã®ã§ãã ãããŠãã®å€åç(Return)ã倧ãããŠãªã¹ã¯ãäœããªããããªä»¥äžã®ãããªææšãäœã£ãŠKPIãšãããã®KPIãæå€§ã«ãªãããã«ããŸãã ITäŒæ¥ã«å€ããŠããIåã¯æè¿ããè³ã«ããA瀟ãšB瀟ã«çµã£ãŠãã©ã¡ãã«æè³ããããã倧ããªKPIãåŸãããã®ã調ã¹ãããšæããŸããã 仮説1ã®äœæ ããã§ã ã©ã¡ããKPIã®é«ãéæã«æè³ããããšãæè³å¹çãé«ã ãšãã仮説ãç«ãŠãŸãã ãã®ä»®èª¬ãæ€èšŒããããã«ãããããã®éæã®KPIææšãèšç®ããŠæ¯èŒããŠã¿ãããšæããŸãã æ€èšŒã®ããã®äžæºå ãŸã以äžã®ããã«ïŒç€Ÿã®æ ªäŸ¡ã®ååŸããŠcsvãã¡ã€ã«ã«ä¿åãããããªã¹ã¯ãªãããå®è¡ããŸããã getPrice.py #python from datetime import datetime from concurrent import futures import pandas as pd from pandas import DataFrame import pandas_datareader.data as web def download_stock(stock): try: print(stock) stock_df = web.DataReader(stock,"yahoo", start_time, now_time) stock_df['Name'] = stock output_name = stock + '_data.csv' stock_df.to_csv(output_name) except: bad_names.append(stock) print('bad: %s' % (stock)) if __name__ == '__main__': ticker_stocks = ["ticker_a","ticker_b"]#ticker array workers = len(ticker_stocks) with futures.ThreadPoolExecutor(workers) as executor: res=executor.map(download_stock, ticker_stocks) 仮説1ã®æ€èšŒ äžã®ã¹ã¯ãªãããå®è¡ããŠåŸãããcsvãã¡ã€ã«ã䜿ã£ãŠãããããã®éæãè©äŸ¡ããŠãããŸãã ãŸãKPIãç®åºããŠã¿ãŸãã getKpi.R #ãªã¿ãŒã³ãèšç®ãã a = read.csv("/Users/tsuyoshiendo/Documents/flask/stock/a_data.csv") b = read.csv("/Users/tsuyoshiendo/Documents/flask/stock/b_data.csv") colnames(a)[7] = "adjClose" colnames(b)[7] = "adjClose" a$ret = as.numeric(a$adjClose) / as.numeric(c(NA, a$adjClose[1:nrow(a)-1]))-1 b$ret = as.numeric(b$adjClose) / as.numeric(c(NA, b$adjClose[1:nrow(b)-1]))-1 #äœåãªããŒã¿ãåé€ a=a[!is.na(a$ret),c("Name", "Date", "ret")] b=b[!is.na(b$ret),c("Name", "Date", "ret")] #ãªã¿ãŒã³ ex_a = mean(a$ret) ex_b = mean(b$ret) #ãªã¹ã¯ sd_a = sd(a$ret) sd_b = sd(b$ret) #KPI kpi_a = ex_a/sd_ap#a瀟ã®KPI kpi_b = ex_b/sd_am#b瀟ã®KPI paste("a's KPI = ", kpi_a, ", b's KPI = ", kpi_b, sep="") å®è¡çµæ a's KPI = 0.0549560106863018, b's KPI = 0.081528997872345 aã®ã»ããKPIã®å€ãé«ãããªã¹ã¯ã«å¯ŸããŠçžå¯Ÿçã«ãªã¿ãŒã³ã倧ãããšãããŸãã æ€èšŒçµæã®æ·±æã ããããããã§åŸãããçµæã«åºã¥ã㊠B瀟ã ãã«æè³ããããšèããã®ã¯æé ã§ãã KPIãèšèšããéã«äœã£ããªã¹ã¯ææšã¯æšæºåå·®ãããªãã¡æ ªäŸ¡å€åã®å€§ããã衚ããŠããã®ã§ãããïŒç€Ÿã®æ ªäŸ¡ãå
šãåãããã«é£åããŠãããšã¯èãã¥ãããããããããã®çµã¿åããæ¹ã«ãã£ãŠã¯ãªã¹ã¯ãæããããå¯èœæ§ããããŸãã ãã®ãããïŒç€Ÿã®çµã¿åãããã¿ãŒã³ã«å¿ããKPIãç®åºããŠã¿ãã®ã次ã§ãã twoAssets.R #covariance cov_a_b <- cov(a$ret, b$ret) weight_patterns <- seq(from = 0, to = 1, length.out = 1000) two_assets <- data.table(wx = weight_patterns) two_assets[, wy := 1 - wx] two_assets[, ':=' (ex_p = wx * ex_a + wy * ex_b,sd_p = sqrt(wx^2 * sd_a^2 + wy^2 * sd_b^2 + 2 * wx * wy * cov_a_b))] two_assets <- two_assets[wx >= 0 & wy >= 0] two_assets[, ir := ex_p / sd_p] ggplot() + geom_point(data = two_assets, aes(x = sd_p, y = ex_p, color = ir)) + geom_point(data = data.table(sd = c(sd_a, sd_b), mean = c(ex_a, ex_b)), aes(x = sd, y = mean), color = "red", size = 3, shape = 18) + theme_bw() + ggtitle("efficient frontier") + xlab("Standard Deviation") + ylab("Expected Returns") + scale_y_continuous(label = percent) + scale_x_continuous(label = percent) + scale_color_gradientn(colors = c("blue", "red"), name = "ir ratio", labels = percent) + theme_gray (base_family = "HiraKakuPro-W3") + expand_limits(x = 0, y = 0) two_assets[ir == max(two_assets$ir)] ãã®çµæã以äžã®æ²ç·ã®ãããªå³ãåŸãããŸããã ãã®æ²ç·ã¯A瀟ãšB瀟ã®çµå
¥æ¯ç1,000éãã®ãã¿ãŒã³ã«å¯ŸããŠã瞊軞ã«ãªã¿ãŒã³ã暪軞ã«ãªã¹ã¯ããšã£ãŠãããããããã®ã§ãã ãããŠæ²ç·ã®äž¡ç«¯ãA瀟ãšB瀟ã®ïŒç€Ÿã«ããããåç¬ã«æè³ããå Žåã«ãªããŸãã 軞ã®åãæ¹ããå·Šäžã«è¡ãã»ã©KPIææšã®å€§ããªïŒïŒæé©ãªïŒçµã¿åããã§ãããšèšããŸããããããèŠããšäž¡ç«¯ã®ç¹ã§ã¯ãªããæ²ç·äžã®äžéå°ç¹ã®æ¹ãKPIã®å€ã倧ããããšãããããŸãã å®éã«æãé«ãKPIãšãªã£ãçµã¿åããã¯A瀟ã«24%ãB瀟ã«74%æè³ãããã¿ãŒã³ã§ãã®KPIææšã¯0.0832ãšãããããåç¬ã§æè³ãããå Žåã®0.055ãš0.082ããã倧ããã§ãã ãããæ€èšŒã®çµæã仮説ïŒã¯èª€ã£ãŠãã(æ£åŽããã)ãããªãã¡ã©ã¡ããã ãã«æè³ããã®ã§ã¯ãªãããªã¿ãŒã³ãšãªã¹ã¯ã«å¿ããŠæè³æ¯çãå€ããã¹ãã§ããããšãããããŸãã ããã§æ¬¡ã®çåãæ¹§ããŸãã è€æ°ã®äŒç€Ÿã«æè³ãããããšã§ KPIææšãããã«é«ããããšãã§ããã®ã§ã¯ãªãããã§ãã æåã®ä»®èª¬æ€èšŒããã»ã¹ã®çµæãKPIãããã«é«ããããã®æ¬¡ã®ä»®èª¬ãæ€èšŒããŠãããŸãã 仮説ïŒã®äœæ ãçµã¿åããæ¹ã«ãã£ãŠæãé«ãKPIãäºæž¬ããããšãã§ãããã 仮説ïŒã®æ€èšŒ Iåã¯ãã®ä»®èª¬ïŒãæ€èšŒãããããC瀟ãšD瀟ã«ãæè³ããŠã¿ãããšæããŸããã ãŸãC瀟ãåãããïŒç€Ÿã®ãã¿ãŒã³ã§å
ã»ã©ã®å³ãæããŠã¿ãŸãã threeAssets.R weight_patterns <- seq(from = 0, to = 1, length.out = 1000) #expected_return ex_a = mean(a$ret) ex_b = mean(b$ret) ex_c = mean(c$ret) ex_d = mean(d$ret) sd_a = sd(a$ret) sd_b = sd(b$ret) sd_c = sd(c$ret) sd_d = sd(d$ret) cov_b_a <- cov(a$ret, b$ret) cov_a_c <- cov(b$ret, c$ret) cov_c_b <- cov(c$ret, a$ret) three_assets <- data.table(wx = rep(weight_patterns, each = length(weight_patterns)),wy = rep(weight_patterns, length(weight_patterns))) three_assets[, wz := 1 - wx - wy] three_assets[, ':=' (ex_p = wx * ex_a + wy * ex_b + wz * ex_c, sd_p = sqrt(wx^2 * sd_a^2 + wy^2 * sd_b^2 + wz^2 * sd_c^2 + 2 * wx * wy * cov_b_a + 2 * wx * wz * cov_a_c + 2 * wy * wz * cov_c_b))] #four_assets[, ':=' (ex_p = ww*ex_a + wx*ex_b + wy*ex_c + wz*ex_d, sd_p = sqrt(ww^2 * sd_a^2 + wx^2 * sd_b^2 + wy^2 * sd_c^2 + wz^2*sd_d^2 +2 * ww * wx * cov_a_b + 2 * ww * wy * cov_a_c + 2 * ww * wz * cov_a_gg + 2 * wx * wy * cov_b_c + 2 * wx * wz * cov_b_gg + 2 * wy * wz * cov_c_gg))]#4è³ç£ä»¥äžã®å Žå three_assets <- three_assets[wx >= 0 & wy >= 0 & wz >= 0] three_assets[, ir := ex_p / sd_p] p = ggplot() + geom_point(data = three_assets, aes(x = sd_p, y = ex_p, color = ir)) + geom_point(data = data.table(sd = c(sd_a, sd_b, sd_c), mean = c(ex_a, ex_b, ex_c)), aes(x = sd, y = mean), color = "red", size = 3, shape = 18) + theme_bw() + ggtitle("frontier") + xlab("Standard Deviation") + ylab("Expected Returns") + scale_y_continuous(label = percent) + scale_x_continuous(label = percent) + scale_color_gradientn(colors = c("blue", "red"), name = "kpi", labels = percent) + theme_gray (base_family = "HiraKakuPro-W3") three_assets[ir == max(three_assets$ir)] çµæã¯ïŒç€Ÿã®æé©ãªçµã¿åããã®KPI=0.0845ãšãªããïŒç€Ÿã ãã®å Žåããããã«é«ããªããŸããã åæ§ã«D瀟ãå å³ããŠïŒç€Ÿã§è©ŠããšãKPI=0.0850ãšãªã£ãŠããã«é«ããªããŸãã ãã®å Žåãåœåæ²ç·ã ã£ãã°ã©ãã¯ä»¥äžã®ããã«ãåãããéžæè¢ãåºãã£ãåã ãå€ããªã£ãŠç·ããé¢ãšãªããŸãã ãã®äœæ¥ã®ç¹°ãè¿ãã«ãã£ãŠä»¥äžã®çµè«ãåŸãããŸãã ïŒç€Ÿã®å ŽåããïŒç€Ÿã®ã»ãã䌞ã³å¹
ãéæžããããã éææ°ãå€ããªãã»ã©KPIã¯é«ããªããã®ã®ãã®å€ã¯äžå®å€ã«åæãã ãšããå¯èœæ§ãæšæž¬ããããšãã§ããŸãã ãããã£ãŠã仮説ïŒã¯æ£ãããšèšããŸãã 仮説æ€èšŒã§åŸãããæŠç¥ã®å®è¡ãã©ã³ 仮説ïŒãšä»®èª¬ïŒã®æ€èšŒã«ãã£ãŠåŸãããç¥èŠãããæè³å¯Ÿè±¡ã®éæãå¢ããããšã«ãã£ãŠKPIææšã®æå€§åãå³ãããšãã§ãããã®ãšãã®æ ªåŒã®ä¿æå²åã¯äžã§å®æœãããããªæ¹æ³ã«ãã£ãŠç¥ãããšãã§ããŸãã ããããªãããå®éã®çŸå Žã§ã¯ããããŠåŸãããç¥èŠããã®ãŸãŸäœ¿ãããšã¯ããŸããã æé©è§£ãšããŠåŸãããä¿æå²åãäœã瀺ããŠããã®ãèããããŒã¿ã®è£ã«ããçå®ãæ¢ãå¿
èŠãããããã§ãã ããã§åŸãããçå®ãšã¯ãæ ªäŸ¡ïŒãªã¿ãŒã³ãšãªã¹ã¯ïŒã«ãã£ãŠåŸãããæé©ãªä¿æå²åã¯äžæã«æ±ºãŸããåççãªæè³å®¶ã§ããã°çãã®æ¯çãä¿æãããšæšæž¬ãããŸãã ãããã£ãŠãKPIã®èšèšãæ£ãããåžå Žåå è
ã®å€§éšåããã®KPIã«å¯ŸããŠåççã«æè³ãããšããåæã«ç«ãŠã°ãåæè³å®¶ãä»ååŸãããä¿ææ¯çã«å¿ããŠå£²è²·ããŠããããããã®çµæãšããŠäŸ¡æ Œåœ¢æãããçŸåšã®æ ªäŸ¡ïŒæ£ç¢ºã«ã¯æäŸ¡ç·é¡ïŒã¯ãã®æ¯çãåæ ãããŠããã¯ãã§ãã èšãæããã°ãæé©ãªä¿ææ¯çãã®ãã®ãæäŸ¡ç·é¡ã®æ¯çã«ãã£ãŠæ±ºå®ãããŠãããšèããããšãã§ããŸãã çµæçã«ãåœåç«ãŠãç®çãéæããããã«ã¯ãããå€ãã®éæãæäŸ¡ç·é¡ã®æ¯çã§éã¿ä»ããããææ°ïŒS&P500ãTOPIXã®ETFãªã©ïŒã«æè³ããå¿
èŠããããšããããã§ãã ãããã« ãããŸã§ãç®æšã«å¯ŸããŠKPIãèšèšããŠã¢ã¯ã·ã§ã³ã決å®ãããŸã§ã®ããã»ã¹ãã玹ä»ããŸããããå®éã®æ¥åã§ã¯ãã®ããã«åçŽãªåæã眮ãããšã¯ã§ããªãã®ã§ãä»®èª¬ãšæ€èšŒãç¹°ãè¿ããŠåŸãããçµæã®èåŸã«ããäºå®ãæ£ç¢ºã«æããªããæŠç¥ã®ç²ŸåºŠãé«ããŠããå¿
èŠããããŸãã ä»åã¯ã¢ããã³ãã«ã¬ã³ããŒãšããããšã§è¥å¹²ãã¯ãã«ã«ãªè©±ããããŠçã蟌ãã§ã¿ãŸããããå®éã®æ¥åã§ã¯ãããŸã§ã¹ã¯ãªãããæžããŠåæããæéã¯å€ããããŸããã ãããæå
ã«ããããŒã¿ãäºè±¡ããè«ççã«æŠç¥ã決ããã¡ã³ããŒãšã³ãã¥ãã±ãŒã·ã§ã³ãåããªããåæ»ã«ãããžã§ã¯ãã®ãã£ã¬ã¯ã·ã§ã³ãããããšãéèŠã§ãã ããããããä»äºã«èå³ãæã£ãŠããã ããããæ¡çšçªå£ããã®ãå¿åããé¡ãããããŸãã ãã²ãåŸ
ã¡ããŠãããŸãã