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))
Esempio n. 4
0
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)):
Esempio n. 6
0
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)
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 10
0
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]