def profit_analysis(): gross_profit = [r-o for r, o in zip(d.revenue, d.operating_expense)] period_expense = [] for i in range(len(d.selling_expense)): period_expense.append( sum([d.selling_expense[i], d.management_expense[i], d.financing_expense[i]])) print("二、利润表分析:") print("1.基本信息:") print(string + '营业收入:', [round(i, 2) for i in d.revenue]) print(string + '营业成本:', [round(i, 2) for i in d.operating_expense]) print(string + '营业成本增长率', f.percentageChange(d.operating_expense)) print(string + '营业利润', [round(no, 2) for no in d.operating_profit]) print(string + '营业利润变化', f.percentageChange(d.operating_profit)) print(string + '净利润', [round(no, 2) for no in d.net_profit]) print(string + '净利润变化', f.percentageChange(d.net_profit)) print(string + '销售费用', [round(no, 2) for no in d.selling_expense]) print(string + '管理费用', [round(no, 2) for no in d.management_expense]) print(string + '财务费用', [round(no, 2) for no in d.financing_expense]) print(string + '期间费用', [round(no, 2) for no in period_expense]) print(string + '期间费用变化', f.percentageChange(period_expense)) print(string + '三费占比', f.percentageOccupied(period_expense, d.revenue)) print("2. 利润结构分析数据:") print(string + '营业利润占比利润总额', f.percentageOccupied(d.operating_profit, d.overall_profit)) print(string + '毛利', gross_profit) print(string + '毛利率', f.ratio(gross_profit, d.revenue)) print(string + '毛利率变化', f.percentageChange(f.ratio(gross_profit, d.revenue)))
def cashflow_analysis(): print("三、现金流量表分析:") print("1. 基本信息:") print(string + '经营活动产生的现金流入小计', [round(i, 2) for i in d.operation_ttinflow]) print(string + '经营活动产生的现金流出小计', [round(i, 2) for i in d.operation_ttoutflow]) print(string + '经营活动产生的现金流量', [round(i, 2) for i in d.operation_cashflow]) print(string + '经营现金净流量增长率', f.percentageChange(d.operation_cashflow)) print(string + '投资活动产生的现金流入小计', [round(i, 2) for i in d.investment_ttinflow]) print(string + '投资活动产生的现金流出小计', [round(i, 2) for i in d.investment_ttoutflow]) print(string + '投资活动产生的现金流量', [round(i, 2) for i in d.investment_cashflow]) print(string + '投资活动产生的现金流量变化', f.percentageChange(d.investment_cashflow)) print(string + '筹资活动产生的现金流入小计', [round(i, 2) for i in d.financing_ttinflow]) print(string + '筹资活动产生的现金流出小计', [round(i, 2) for i in d.financing_ttoutflow]) print(string + '筹资活动产生的现金流量', [round(i, 2) for i in d.financing_cashflow]) print(string + '筹资活动产生的现金流量变化', f.percentageChange(d.financing_cashflow)) print("2. 企业销售利润、销售回款和创现能力(公司销售商品提供劳务收到的现金与购进劳务付出的现金比):", f.ratio(d.operation_inflow, d.operation_outflow)) print("3. 企业的主营业务与营销状况(销售商品提供劳务产生的现金流入于流入现金总额占比):", f.percentageOccupied(d.operation_inflow, d.operation_ttinflow)) print("4. 现金流入组成:", f.percentage_compostion([d.operation_ttinflow, d.investment_ttinflow, d.financing_ttinflow])) print("5. 现金流出组成:") print("6. 净现金流量总量分析:") print(string + "净现金流量总量 ", [round(i, 2) for i in d.total_cashflow]) print(string + "净现金流量总量变化率 ", f.percentageChange(d.total_cashflow)) print(string + "经营现金流量占比 ", f.percentageOccupied(d.operation_cashflow, d.total_cashflow)) print(string + "投资现金流量占比 ", f.percentageOccupied(d.investment_cashflow, d.total_cashflow)) print(string + "筹资先金流量占比 ", f.percentageOccupied(d.financing_cashflow, d.total_cashflow))
def ratio_analysis(): print("1. 短期偿债能力:") print(string + '流动比率', f.ratio(d.current_asset, d.current_liability)) print(string + '速动比率', f.ratio(d.quick_asset, d.current_liability)) print("2. 长期负债能力:") print(string + '资产负债率', f.percentageOccupied(d.total_liability, d.total_asset)) print(string + '股东权益比率', f.percentageOccupied(d.owner_equity, d.total_asset)) print(string + '权益乘数', f.percentageOccupied(d.total_asset, d.owner_equity)) print(string + '产权比率', f.percentageOccupied(d.total_liability, d.owner_equity)) print("3.发展能力:") print(string + '净资产增长率', f.percentageChange(d.owner_equity)) print(string + '销售增长率', f.percentageChange(d.revenue)) print(string + '总资产增长率', f.percentageChange(d.total_asset)) print("4. 盈利能力分析数据:") print(string + '销售净利率', f.percentageOccupied(d.net_profit, d.revenue)) print(string + '总资产收益率', f.percentageOccupied(d.net_profit, d.total_asset)) print(string + '净资产收益率', f.percentageOccupied(d.net_profit, d.owner_equity))
def optimization(weight_scheme): numberofday = 0 quarter_list = [] # Initialize matrix full of zeros resultMatrix = [[0 for x in range(len(ticker) + 5)] for y in range(len(timestamp) + 1)] # Change the first row of result matrix to show headers firstrow = resultMatrix[0] secondrow = resultMatrix[1] for i0 in range(len(firstrow)): if i0 == 0: firstrow[i0] = "" elif i0 < len(ticker) + 1: firstrow[i0] = ticker[i0 - 1] elif i0 == len(ticker) + 1: firstrow[i0] = "Daily Return" elif i0 == len(ticker) + 2: firstrow[i0] = "Cumulative" elif i0 == len(ticker) + 3: firstrow[i0] = "Stock Count" elif i0 == len(ticker) + 4: firstrow[i0] = "Portfolio" secondrow[i0] = initial_amount # Change the first column of result matrix to show time index for row in range(len(resultMatrix)): if row == 0: resultMatrix[row][0] = "" else: resultMatrix[row][0] = timestamp[row - 1] resultMatrix = np.array(resultMatrix) column_return = np.array(resultMatrix[:, -1][1:]) # Portfolio column_return = np.asfarray(column_return, float) column_return[0] = initial_amount # Loop through time index cash_amount = 0 for index in range(len(timestamp)): bool_quarter = False stockcount = 0 answer = 0 # search for index for weights month = int(timestamp[index].split("/")[1]) year = int(timestamp[index].split("/")[2]) if month < 7: quarter = "Q2" else: quarter = "Q4" current = str(year) + quarter # Q-2 quarter if month < 4: year -= 1 quarter = "Q2" elif month < 7: year -= 1 quarter = "Q4" elif month < 10: year -= 1 quarter = "Q4" else: quarter = "Q2" date = str(year) + quarter # Check if quarter is different from previous day's quarter quarter_list.append(current) if index == 0: store_index.append([index, current]) else: if quarter_list[index] != quarter_list[index - 1]: store_index.append([index, current]) if (index == 0) or (index != 0 and quarter_list[index] != quarter_list[index - 1]): bool_quarter = True # Search for index for weights for index2 in range(len(weight_scheme)): if date == weight_scheme[index2][0]: answer = index2 # Loop through stocks aggregate = 0 cash_hand = 100 for stock in range(len(ticker)): gain = functions.percentageChange( float(price[index - 1][stock + 1]), float(price[index][stock + 1])) if answer == 0: stockweight = 0 else: w = float(weight_scheme[answer][stock + 1]) stockweight = w / 100 if bool_quarter: # When quarter changes if index == 0: value = initial_amount * stockweight else: value = column_return[index - 1] * stockweight cash_hand -= w else: # When quarter does not change value = float( resultMatrix[index][stock + 1]) * (1 + gain / 100) resultMatrix[index + 1][ stock + 1] = value # Fill in the money allocation instead of percentage change aggregate += value # Calculate number of stocks to be invested if stockweight != 0 and float(price[index][stock + 1]) != 0: stockcount += 1 # Calculate cash in hand when remaining weight is not zero if bool_quarter and cash_hand < 100: cash_amount = cash_hand * column_return[index - 1] / 100 if bool_quarter and cash_hand == 100: cash_amount = 0 if aggregate == 0: aggregate = column_return[index - 1] if column_return[index - 1] == 0 or index == 0: aggregate = initial_amount aggregate += cash_amount column_return[index] = aggregate # Stock Count resultMatrix[index + 1][len(ticker) + 3] = stockcount numberofday += 1 resultMatrix[:, -1][1:] = column_return daily_return = functions.percentagelist(column_return) resultMatrix[:, -4][2:] = daily_return cumulative = functions.cumulative_list(daily_return) resultMatrix[:, -3][2:] = cumulative portfolio_list = column_return # Take the last index to get cumulative_return cumulative_return = cumulative[-1] # Final cumulative return list_cumulative.append(cumulative_return) # Calculate related stats sharpe_ratio = sharpe(daily_return) list_sharpe.append(sharpe_ratio) print(numberofday, "days;", round(cumulative_return, 4), "%, Sharpe = ", round(sharpe_ratio, 4)) return column_return
#timing = end - start #print(int(timing/60), " minutes and", round(timing-60*int(timing/60), 4), " seconds to plot graphs") #print("\n") ######################################################## print("Semiannually") # Calculate Quarterly Return (HK: semiannually) quarter_matrix = [[0 for x in range(len(store_index))] for y in range(5)] quarter_matrix[0][0] = "Semiannual Return" quarter_matrix[1][0] = "Pure Market Timing" quarter_matrix[2][0] = "Weight Scheme 1 + Market Timing" quarter_matrix[3][0] = "Weight Scheme 2 + Market Timing" quarter_matrix[4][0] = "Weight Optimized + Market Timing" for i in range(len(store_index) - 1): quarter_matrix[0][i + 1] = store_index[i][1] quarter_matrix[1][i + 1] = functions.percentageChange( portfolio_pure[store_index[i][0]], portfolio_pure[store_index[i + 1][0]]) quarter_matrix[2][i + 1] = functions.percentageChange( portfolio_weight1[store_index[i][0]], portfolio_weight1[store_index[i + 1][0]]) quarter_matrix[3][i + 1] = functions.percentageChange( portfolio_weight2[store_index[i][0]], portfolio_weight2[store_index[i + 1][0]]) quarter_matrix[4][i + 1] = functions.percentageChange( portfolio_weight_optimized[store_index[i][0]], portfolio_weight_optimized[store_index[i + 1][0]]) # Benchmark Quarter Return: HSCI quarter_list = [] store_index = [] quarter_benchmark = [] for index in range(len(date_index)):
def backtest(weight_scheme, number): numberofday = 0 quarter_list = [] # Initialize matrix full of zeros resultMatrix = [[0 for x in range(len(ticker) + 5)] for y in range(len(timestamp) + 1)] # Change the first row of result matrix to show headers firstrow = resultMatrix[0] secondrow = resultMatrix[1] for i0 in range(len(firstrow)): if i0 == 0: firstrow[i0] = "" elif i0 < len(ticker) + 1: firstrow[i0] = ticker[i0 - 1] elif i0 == len(ticker) + 1: firstrow[i0] = "Daily Return" elif i0 == len(ticker) + 2: firstrow[i0] = "Cumulative" elif i0 == len(ticker) + 3: firstrow[i0] = "Stock Count" elif i0 == len(ticker) + 4: firstrow[i0] = "Portfolio" secondrow[i0] = initial_amount # Change the first column of result matrix to show time index for row in range(len(resultMatrix)): if row == 0: resultMatrix[row][0] = "" else: resultMatrix[row][0] = timestamp[row - 1] resultMatrix = np.array(resultMatrix) column_return = np.array(resultMatrix[:, -1][1:]) # Portfolio column_return = np.asfarray(column_return, float) column_return[0] = initial_amount # Loop through time index for index in range(len(timestamp)): bool_quarter = False stockcount = 0 answer = 0 # search for index for weights month = int(timestamp[index].split("/")[1]) year = int(timestamp[index].split("/")[2]) if month < 7: quarter = "Q2" else: quarter = "Q4" current = str(year) + quarter # Q-2 quarter if month < 4: year -= 1 quarter = "Q2" elif month < 7: year -= 1 quarter = "Q4" elif month < 10: year -= 1 quarter = "Q4" else: quarter = "Q2" date = str(year) + quarter # Check if quarter is different from previous day's quarter quarter_list.append(current) if number == 1: if index == 0: store_index.append([index, current]) else: if quarter_list[index] != quarter_list[index - 1]: store_index.append([index, current]) if (index == 0) or (index != 0 and quarter_list[index] != quarter_list[index - 1]): bool_quarter = True # Search for index for weights for index2 in range(len(weight_scheme)): if date == weight_scheme[index2][0]: answer = index2 # Loop through stocks aggregate = 0 for stock in range(len(ticker)): gain = functions.percentageChange( float(price[index - 1][stock + 1]), float(price[index][stock + 1])) if answer == 0: stockweight = 0 else: stockweight = float(weight_scheme[answer][stock + 1]) / 100 if bool_quarter: # When quarter changes if index == 0: value = initial_amount * stockweight else: value = column_return[index - 1] * stockweight else: # When quarter does not change value = float( resultMatrix[index][stock + 1]) * (1 + gain / 100) resultMatrix[index + 1][ stock + 1] = value # Fill in the money allocation instead of percentage change aggregate += value # Calculate number of stocks to be invested if stockweight != 0 and float(price[index][stock + 1]) != 0: stockcount += 1 if aggregate == 0: aggregate = column_return[index - 1] if column_return[index - 1] == 0 or index == 0: aggregate = initial_amount column_return[index] = aggregate # Stock Count resultMatrix[index + 1][len(ticker) + 3] = stockcount numberofday += 1 resultMatrix[:, -1][1:] = column_return daily_return = functions.percentagelist(column_return) resultMatrix[:, -4][2:] = daily_return cumulative = functions.cumulative_list(daily_return) resultMatrix[:, -3][2:] = cumulative portfolio_list = column_return # Take the last index to get cumulative_return cumulative_return = cumulative[-1] # Final cumulative return # Calculate related stats head = "Weight Scheme " + str(number) print(head, ":") print(numberofday, "days;", round(cumulative_return, 4), "%") print("\n") print("Average Daily Return =", round(average(daily_return), 4), "%") print("SD of Daily Return =", round(SD(daily_return), 4), "%") annual_return = average(daily_return) * oneyear print("Annualized Return =", round(annual_return, 4), "%") annual_volatility = SD(daily_return) * (oneyear**(1 / 2)) print("Annualized Volatility =", round(annual_volatility, 4), "%") sharpe_ratio = sharpe(daily_return) print("Annual Sharpe Ratio: ", round(sharpe_ratio, 4)) print("Max Consecutive Loss = ", maxconsecutive(daily_return), "days") print("Win Rate:", round(winrate(daily_return), 4), "%") max_drawdown = functions.findMin(daily_return) print("Max Drawdown:", round(max_drawdown, 4), "%") print("\n") stats_line = [ head, cumulative_return, annual_return, annual_volatility, sharpe_ratio, max_drawdown ] stats_matrix.append(stats_line) if number == 2: # Calculate stats for market index daily_return_index = functions.percentagelist(price_index) cumulative_index = functions.percentageChange(price_index[0], price_index[-1]) print(market, "Index: ") print("Cumulative =", round(cumulative_index, 4), "%") print("Average Daily Return =", round(average(daily_return_index), 4), "%") print("SD of Daily Return =", round(SD(daily_return_index), 4), "%") annual_return = average(daily_return_index) * oneyear print("Annualized Return =", round(annual_return, 4), "%") annual_volatility = SD(daily_return_index) * (oneyear**(1 / 2)) print("Annualized Volatility =", round(annual_volatility, 4), "%") sharpe_ratio = sharpe(daily_return_index) print("Annual Sharpe Ratio: ", round(sharpe_ratio, 4)) print("Max Consecutive Loss = ", maxconsecutive(daily_return_index), "days") print("Win Rate:", round(winrate(daily_return_index), 4), "%") max_drawdown = functions.findMin(daily_return) print("Max Drawdown:", round(max_drawdown, 4), "%") stats_line = [ market, cumulative_index, annual_return, annual_volatility, sharpe_ratio, max_drawdown ] stats_matrix.append(stats_line) # Find correct date to match dates for market index and our portfolio correctdate = [] correctdate2 = [] for i in range(len(timestamp)): for j in range(len(date_index)): if date_index[j] == timestamp[i]: correctdate.append(i) correctdate2.append(j) # Prepare for a graph x_axis = date_index y = [] # Strategy Portfolio y_index = [] # Market Index Portfolio # Normalize to initial amount and fill up values for y-axis by searching for correct dates relative_portfolio = functions.relative(portfolio_list) for i in range(len(correctdate)): correctindex = correctdate[i] - 1 y.append(relative_portfolio[correctindex]) for j in range(len(correctdate2)): correctindex = correctdate2[j] y_index.append(price_index[correctindex]) y_index = functions.relative(y_index) # Plot a graph fig = plt.figure() # Create a figure ax = plt.axes() # Create axis if len(x_axis) == len(y): plt.plot(x_axis, y, label='Weight Scheme ' + str(number)) plt.plot(x_axis, y_index, label=market) ax.xaxis.set_major_locator( plt.MaxNLocator(5)) # Set Maximum number of x-axis values to show fig.autofmt_xdate() # Rotate values to see more clearly title = "Stock Selection: Growth of " + str( initial_amount / 1000000) + " million" plt.title(title) plt.ylabel("Cumulative Return") fig.savefig(directory + market + " Stock Selection Weight Scheme " + str(number) + ".png") plt.show() # Write csv file of result matrix inside result folder title = directory + 'weight scheme ' + str(number) with open(title + ' result.csv', "w") as output: writer = csv.writer(output, lineterminator='\n') for val in resultMatrix: writer.writerow(val)
df2 = pd.read_csv((directory + "weight scheme 2 result.csv"), header=None, low_memory=False) result2 = np.array(df2[1:]) # Skip First Row portfolio2 = result2[:, len(header)] # Last Column portfolio2 = portfolio2[1:] # Delete 'Start From Below' part # Calculate Quarterly Return (HK: semiannually) quarter_matrix = [[0 for x in range(len(store_index))] for y in range(3)] quarter_matrix[0][0] = "Semiannual Return" quarter_matrix[1][0] = "Weight Scheme 1" quarter_matrix[2][0] = "Weight Scheme 2" for i in range(len(store_index) - 1): quarter_matrix[0][i + 1] = store_index[i][1] quarter_matrix[1][i + 1] = functions.percentageChange( float(portfolio[store_index[i][0]]), float(portfolio[store_index[i + 1][0]])) quarter_matrix[2][i + 1] = functions.percentageChange( float(portfolio2[store_index[i][0]]), float(portfolio2[store_index[i + 1][0]])) Quarter = quarter_matrix[0][1:] Quarter_return1 = quarter_matrix[1][1:] Quarter_return2 = quarter_matrix[2][1:] # Draw quarterly return bar graphs fig = plt.figure() # Create a figure ax = plt.axes() # Create axis plt.bar(Quarter, Quarter_return1, align='center', alpha=0.5) # Draw Bar graph ax.xaxis.set_major_locator( plt.MaxNLocator(8)) # Set Maximum number of x-axis values to show
def combined_signal(stock, weight_scheme, stock_index): header = [ "Date", "Price", "Weight Signal", "Signal In", "Combined Signal", "Signal Out", "Position", "Trading Cost", "Return(%)", "Cumulative(%)" ] title = directory + functions.change_title(stock) with open(title + ' technical indicators.csv') as f: reader = csv.reader(f) original = [rows for rows in reader] original = np.array(original) signal_matrix = [[0 for x in range(len(header))] for y in range(len(original))] signal_matrix[0] = header signal_matrix = np.array(signal_matrix) signal_matrix[:, 0][1:] = original[:, 0][1:] # Date signal_matrix[:, 1][1:] = original[:, 1][1:] # Price signal_matrix[:, 3][1:] = original[:, 8][1:] # signal in signal_matrix[:, 5][1:] = original[:, 9][1:] # signal out # Import Weight Scheme with open('Stock Picking Result/' + weight_scheme + '.csv') as g: reader = csv.reader(g) weight = [rows for rows in reader] weight = np.array(weight) time_weight = weight[:, 0][1:] timestamp = signal_matrix[:, 0][1:] position = 0 portfolio = 1 for time in range(len(timestamp)): answer = 0 month = int(timestamp[time].split("/")[1]) year = int(timestamp[time].split("/")[2]) # Q-2 quarter if month < 4: # Q1 year -= 1 quarter = "Q2" elif month < 10: # Q2 and Q3 year -= 1 quarter = "Q4" else: # Q4 quarter = "Q2" date = str(year) + quarter # Search for index for weights for index in range(len(time_weight)): if date == time_weight[index]: answer = index if answer == 0: stockweight = 0 else: stockweight = float(weight[answer + 1][stock_index + 1]) / 100 # Fill in the weight signal in second column if stockweight == 0: signal_matrix[time + 1][2] = 0 weight_signal = 0 else: signal_matrix[time + 1][2] = 1 weight_signal = 1 # Combined signal = 1 if both signal is 1 technical_signal = int(signal_matrix[time + 1][3]) if weight_signal == 1 and technical_signal == 1: in_signal = 1 else: in_signal = 0 signal_matrix[time + 1][4] = in_signal # Combined signal # Position out_signal = int(signal_matrix[time + 1][5]) if in_signal == 1 and out_signal == 1: position = 0 elif in_signal == 1 and out_signal == 0: position = 1 elif in_signal == 0 and out_signal == 1: position = 0 if weight_signal == 0: position = 0 signal_matrix[time + 1][6] = position # Position # Trading Cost if time != 0 and signal_matrix[time + 1][6] != signal_matrix[time][6]: signal_matrix[time + 1][7] = trading_cost # Trading Cost # Return if time != 0: gain = functions.percentageChange( float(signal_matrix[time][1]), float(signal_matrix[time + 1][1])) gain *= int(signal_matrix[time][6]) # previous period's position profit = gain - float(signal_matrix[time + 1][7]) # return - cost signal_matrix[time + 1][8] = gain # return # Cumulative Return portfolio *= (1 + profit / 100) cumulative = (portfolio - 1) * 100 signal_matrix[time + 1][9] = cumulative # cumulative return # Write csv file of result matrix inside result folder title = directory + functions.change_title(stock) with open(title + ' combined signal ' + weight_scheme + '.csv', "w") as output: writer = csv.writer(output, lineterminator='\n') for val in signal_matrix: writer.writerow(val)
if sector[stock] == "Real Estate": signal = int(ranking[answer][9]) signals.append(signal) if sector[stock] == "Telecommunication Services": signal = int(ranking[answer][10]) signals.append(signal) if sector[stock] == "Utilities": signal = int(ranking[answer][11]) signals.append(signal) # Fill the result matrix with the return if signal = 1, otherwise zero if index == 0: # Skip the first row resultMatrix[index + 1][stock + 1] = 0 else: gain = functions.percentageChange( float(price[index - 1][stock + 1]), float(price[index][stock + 1])) resultMatrix[index + 1][stock + 1] = gain * signal # Calculate number of stocks to be invested if signal == 1 and float(price[index][stock + 1]) != 0: stockcount += 1 market_cap_value = float(market_cap[answer_marketcap][stock + 1]) market_cap_list.append(market_cap_value) market_cap_total += market_cap_value else: market_cap_list.append(0) # Calculate Daily Return for each loop row_to_calculate = resultMatrix[index + 1][1:len(ticker) + 1] # take the row
def market_timing(stock, pricelist, RSI_period, MACD_Fast, MACD_Slow, EMA_Slow, RSI_Low, RSI_High, MACD_Sig, EMA_Fast): header = [ "Date", "Price", "RSI", "MACD", "EMA", "RSI signal", "MACD Signal", "EMA Signal", "Signal In", "Signal Out", "Position", "Trading Cost (%)", "Return(%)", "Cumulative(%)" ] price_matrix = [[0 for x in range(len(header))] for y in range(len(timestamp) + 1)] delete = functions.findzero(pricelist) list_return = pricelist[:delete].tolist() pricelist = pricelist[delete:] RSI = rsi(pricelist, RSI_period) MACD = macd(pricelist, MACD_Fast, MACD_Slow) signal_line = ema(MACD, MACD_Sig) EMA = ema(pricelist, EMA_Slow) short_ema = ema(pricelist, EMA_Fast) # Count index index_macd = MACD_Slow - 1 + delete index_signal_line = MACD_Slow - 1 + MACD_Sig - 1 + delete index_ema = EMA_Slow - 1 + delete index_short_ema = EMA_Fast - 1 + delete index_rsi = RSI_period + delete index_signal = max(index_rsi, index_signal_line, index_ema) numberofday = len(price_matrix) - index_signal - 1 # Fill the headers firstrow = price_matrix[0] for integer in range(len(firstrow)): firstrow[integer] = header[integer] # Fill the rest of values position = 0 cumulative = 0 portfolio = 1 for integer in range(len(price_matrix) - 1): price_matrix[integer + 1][0] = timestamp[integer] if integer >= delete: signal_rsi = 0 signal_macd = 0 signal_ema = 0 price_matrix[integer + 1][1] = pricelist[integer - delete] # RSI if integer >= index_rsi: value_rsi = RSI[integer - index_rsi] price_matrix[integer + 1][2] = value_rsi if RSI_Low < value_rsi < RSI_High: signal_rsi = 1 else: signal_rsi = 0 price_matrix[integer + 1][5] = signal_rsi # MACD if integer >= index_macd: value_macd = MACD[integer - index_macd] price_matrix[integer + 1][3] = value_macd if integer >= index_signal_line: value_signal_line = signal_line[integer - index_signal_line] if value_macd > value_signal_line: signal_macd = 1 price_matrix[integer + 1][6] = signal_macd # EMA if integer >= index_short_ema: value_short_ema = short_ema[integer - index_short_ema] if integer >= index_ema: value_ema = EMA[integer - index_ema] price_matrix[integer + 1][4] = value_ema if value_ema < value_short_ema: signal_ema = 1 price_matrix[integer + 1][7] = signal_ema # Signals and Positions in_signal = 0 out_signal = 0 if integer >= index_signal: # Signal In if signal_rsi == 1 and signal_macd == 1 and signal_ema == 1: in_signal = 1 price_matrix[integer + 1][8] = in_signal # Signal Out if signal_ema == 0: out_signal = 1 price_matrix[integer + 1][9] = out_signal # Position if in_signal == 1 and out_signal == 1: position = 0 elif in_signal == 1 and out_signal == 0: position = 1 elif in_signal == 0 and out_signal == 1: position = 0 price_matrix[integer + 1][10] = position # Trading Cost if price_matrix[integer + 1][10] != price_matrix[integer][10]: price_matrix[integer + 1][11] = trading_cost # Return if integer > delete: gain = functions.percentageChange( pricelist[integer - delete - 1], pricelist[integer - delete]) gain *= int( price_matrix[integer][10]) # previous period's position profit = gain - price_matrix[integer + 1][11] # return - cost price_matrix[integer + 1][12] = gain list_return.append(profit) # Cumulative Return portfolio *= (1 + profit / 100) cumulative = (portfolio - 1) * 100 price_matrix[integer + 1][13] = cumulative # Annualized Sharpe and Return if numberofday != 0: list_return = list_return[-numberofday:] cumulative = cumulative * 252 / numberofday sharpe = functions.Sharpe(list_return) else: cumulative = 0 sharpe = 0 # Write csv file of result matrix inside result folder title = directory + functions.change_title(stock) with open(title + ' technical indicators.csv', "w") as output: writer = csv.writer(output, lineterminator='\n') for val in price_matrix: writer.writerow(val) return [sharpe, cumulative]