Esempio n. 1
0
            y.append(original[i])
            y_max.append(max_cumulative[i])
            y_min.append(min_cumulative[i])
            y_max_sharpe.append(max_sharpe[i])
            y_min_sharpe.append(min_sharpe[i])
            y_index.append(price_index[j])

# Draw Graphs
fig = plt.figure(figsize=(15, 6))  # Create a figure
title = "Piotroski Optimization: Growth of " + str(
    initial_amount / 1000000) + " million"
plt.suptitle(title, fontsize=18)
# Cumulative Return
ax1 = plt.subplot(1, 2, 1)  # Create axis
ax1.plot(x_axis,
         functions.relative(y_max),
         label=max_name[:-4] + ': Max Cumulative Return')
ax1.plot(x_axis,
         functions.relative(y_min),
         label=min_name[:-4] + ': Min Cumulative Return')
ax1.plot(x_axis, functions.relative(y), label='original weight')
ax1.plot(x_axis, functions.relative(y_index), label=market)
ax1.xaxis.set_major_locator(
    plt.MaxNLocator(5))  # Set Maximum number of x-axis values to show
ax1.legend(loc='best')
ax1.grid(True)
plt.title("Max Cumulative Return", fontsize=12)
plt.ylabel("Cumulative Return", fontsize=8)
# Sharpe Ratio
ax2 = plt.subplot(1, 2, 2)  # Create axis
ax2.plot(x_axis,
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 = []
y = []  # Pure Market Trending
strategy1 = []  # Weight Scheme 1
strategy2 = []  # Weight Scheme 2
strategy3 = []  # Weight Optimized
y_index = []  # Market Index Portfolio

# Normalize to initial amount and fill up values for y-axis by searching for correct dates
portfolio_pure = functions.relative(portfolio_pure)
portfolio_weight1 = functions.relative(portfolio_weight1)
portfolio_weight2 = functions.relative(portfolio_weight2)
portfolio_weight_optimized = functions.relative(portfolio_weight_optimized)
for i in range(len(correctdate)):
    correctindex = correctdate[i]
    y.append(portfolio_pure[correctindex])
    strategy1.append(portfolio_weight1[correctindex])
    strategy2.append(portfolio_weight2[correctindex])
    strategy3.append(portfolio_weight_optimized[correctindex])
for j in range(len(correctdate2)):
    correctindex = correctdate2[j]
    y_index.append(price_index[correctindex])
    x_axis.append(date_index[correctindex])

title_stats = [
Esempio n. 3
0
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
y1 = []  # Weight Scheme1 Portfolio
y2 = []  # Weight Scheme2 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)
relative_portfolio2 = functions.relative(portfolio2)
for i in range(len(correctdate)):
    correctindex = correctdate[i]
    y1.append(relative_portfolio[correctindex])
    y2.append(relative_portfolio2[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
plt.plot(x_axis, y1, label='Weight Scheme 1')
Esempio n. 4
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)
# 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='Strategy')
    plt.plot(x_axis, y_index, label=market)
    ax.xaxis.set_major_locator(