def recommend(user_input, line_bot_api, user_id): #### User Input #### extraPortfolio_ratio = user_input.extraPortfolio_ratio user_selectFunds = user_input.user_selectFunds user_selectFund_weights = user_input.user_selectFund_weights user_recommend_num = user_input.user_recommend_num #### Transform user_selectFund_weights to user_portfolio_weights_arr #### ## Description: Multiply (1-extraPortfolio_ratio) to user_selectFund_weights user_portfolio_weights_arr = ( 1 - extraPortfolio_ratio) * np.array(user_selectFund_weights) user_portfolio_weights = user_portfolio_weights_arr.tolist() #### Get the Funds' data #### ## Note: Has removed the funds that were closed or have few data message = TextSendMessage(text="讀取基金資料\U0010005E...") line_bot_api.push_message(user_id, message) df = readcsv.read_df(FUNDS_PREPROC_CSV_NAME) ## Check if user_selectFunds are in df.columns for fund in user_selectFunds: if not (fund in df.columns): return None, None #### Get the original_cluster_dict information #### original_cluster_dict = {} with open('original_cluster_dict' + '.pkl', 'rb') as f: original_cluster_dict = pickle.load(f) #### Get the bestFund_dict information #### bestFund_dict = {} new_bestFund_dict = {} with open('bestFund_dict' + '.pkl', 'rb') as f: bestFund_dict = pickle.load(f) #### Get the bestFund_dict excluding the groups that user_selectFund was in #### message = TextSendMessage(text="Pre-processing\U0010005E...") line_bot_api.push_message(user_id, message) new_bestFund_dict = calculate.cluster_preproc(original_cluster_dict, bestFund_dict, user_selectFunds) #### Pick the top 5 of bestFunds #### candidate_list = calculate.pick_candidate(new_bestFund_dict, candidate_num) #### Calculate the orginal protfolio #### portfolio_list = [] new_returns = calculate.newFund_return(df, user_selectFunds, user_selectFund_weights) orginal_q = calculate.index_q(new_returns, ivt_loop_num) co_risk = calculate.cal_co_risk(user_selectFunds, user_selectFund_weights, df, "downside") co_return = calculate.cal_co_return(user_selectFunds, user_selectFund_weights, df) # print(co_risk,co_return) orginal_protfolio = Portfolio(orginal_q, user_selectFunds, user_selectFund_weights, co_return / co_risk) portfolio_list.append(orginal_protfolio) #### Calculate protfolios with extra funds #### message = TextSendMessage(text="計算中(這可能會花點時間\U0010005E)...") line_bot_api.push_message(user_id, message) for i in range(1, user_recommend_num + 1): portfolio = calculate.portfolio_alloc(df, candidate_list, i, user_selectFunds, user_portfolio_weights, extraPortfolio_ratio, ivt_loop_num) if portfolio != None: portfolio_list.append(portfolio) recommend_portfolio = min(portfolio_list, key=attrgetter('index_q')) number_to_name = {} with open('label2name_dict' + '.pkl', 'rb') as f: number_to_name = pickle.load(f) temp_labels = [] for item in orginal_protfolio.labels: temp_labels.append( number_to_name.get(item, "Unkown name") + "(" + item + ")") orginal_protfolio.labels = temp_labels # ori = rec if len(orginal_protfolio.labels) == len(recommend_portfolio.labels): return orginal_protfolio, recommend_portfolio temp_labels = [] for item in recommend_portfolio.labels: temp_labels.append( number_to_name.get(item, "Unkown name") + "(" + item + ")") recommend_portfolio.labels = temp_labels return orginal_protfolio, recommend_portfolio