コード例 #1
0
def testPolicy(symbol="JPM",
               sd=dt.datetime(2008, 1, 1),
               ed=dt.datetime(2009, 12, 31),
               sv=100000):

    # Retrieve prices on the symbol to be traded
    policy_frame = id.get_prices([symbol], sd, ed)

    # Calculate daily returns
    policy_frame['Daily Rets'] = id.get_daily_returns(policy_frame)

    # Calculate positions based on the next day's daily returns
    policy_frame['Positions'] = policy_frame['Daily Rets'].shift(-1)
    policy_frame['Positions'] = np.where(policy_frame['Positions'] > 0, 1,
                                         policy_frame['Positions'])
    policy_frame['Positions'] = np.where(policy_frame['Positions'] < 0, -1,
                                         policy_frame['Positions'])

    # Calculate trades based on positions
    policy_frame['Trades'] = policy_frame['Positions'].shift(1)
    policy_frame['Trades'][0] = 0
    policy_frame['Trades'] = (policy_frame['Positions'] -
                              policy_frame['Trades']) * 1000
    policy_frame['Trades'][-1] = 0
    return policy_frame['Trades']
コード例 #2
0
    def get_indicators(self, prices, window = 10, band_size = 2):
        """
        Computes indicators for a symbol, given prices.

        Parameters:
        prices: array of prices
        window: time-window in days
        band_size: band_size for the Bollinger(R) Bands

        Returns:
        Tuple of indicators for price/SMA, momentum, BB
        """
        self.window = window
        sma, price_to_sma = ind.get_simple_moving_average(prices, window = window)
        momentum = ind.get_momentum(prices, window = window)
        upper, lower, bb_val = ind.get_bollinger_bands(prices, window = window, band_size = band_size)
        return price_to_sma, momentum, bb_val
コード例 #3
0
 def _build_tech_ind(dfs: dict) -> dict:
     """
     Build technical indicators and append them to the DataFrames as columns.
     :param dfs: Dict containing DataFrames by symbol containing all stock data as provided by group_by_stockname()
     :return: dict: {stock_name:string -> stock_data:DataFrame} with additional feature columns
     """
     result = {}
     for symbol, stock_df in dfs.items():
         pmas = TechnicalIndicators.sma(stock_df,
                                        5,
                                        'PMA_S',
                                        col=ADJ_CLOSE_COL)
         pmal = TechnicalIndicators.sma(stock_df,
                                        20,
                                        'PMA_L',
                                        col=ADJ_CLOSE_COL)
         vmas = TechnicalIndicators.sma(stock_df,
                                        5,
                                        'VMA_S',
                                        col=ADJ_VOL_COL)
         vmal = TechnicalIndicators.sma(stock_df,
                                        20,
                                        'VMA_L',
                                        col=ADJ_VOL_COL)
         rsi = TechnicalIndicators.rsi(stock_df, 14, col=ADJ_CLOSE_COL)
         sto = TechnicalIndicators.sto(stock_df,
                                       14,
                                       3,
                                       col=ADJ_CLOSE_COL,
                                       col_low=ADJ_LOW_COL,
                                       col_high=ADJ_HIGH_COL)
         bb = TechnicalIndicators.bbands(stock_df, 8, 2, col=ADJ_CLOSE_COL)
         result[symbol] = pd.concat(
             [stock_df, pmas, pmal, vmas, vmal, rsi, sto, bb], axis=1)
     return result
コード例 #4
0
def main_optimal():

    # Set-up initial parameters for simulation
    symbol = "JPM"
    sd = dt.datetime(2008, 1, 2)
    ed = dt.datetime(2009, 12, 31)
    sv = 100000
    commission = 0
    impact = 0

    # Calculate optimal portfolio values
    optimal_trades = testPolicy(symbol=symbol, sd=sd, ed=ed, sv=sv)
    optimal_trades = process_trades_df(optimal_trades, "JPM")
    optimal_port_vals = ms.compute_portvals(optimal_trades,
                                            start_val=sv,
                                            commission=commission,
                                            impact=impact)
    optimal_port_vals = optimal_port_vals / optimal_port_vals.iloc[0, :]

    # Calculate benchmark portfolio values
    benchmark_trades = pd.DataFrame(data=[["JPM", "BUY", 1000]],
                                    index=[sd, ed],
                                    columns=["Symbol", "Order", "Shares"])
    benchmark_port_vals = ms.compute_portvals(benchmark_trades,
                                              start_val=sv,
                                              commission=commission,
                                              impact=impact)
    benchmark_port_vals = benchmark_port_vals / benchmark_port_vals.iloc[0, :]

    # Plot optimal strategy
    plt.plot(benchmark_port_vals, color='g', linewidth=0.7)
    plt.plot(optimal_port_vals, color='r', linewidth=0.7)
    plt.legend(["Benchmark", "Optimal"])
    plt.title("Portfolio Values: Benchmark vs. Optimal", fontsize=10)
    plt.ylabel("Normalized Values", fontsize=8)
    plt.xlabel("Date Range", fontsize=8)
    plt.savefig('Optimal.png')

    ocr, oadr, osddr, osr = id.calculate_portfolio_metrics(optimal_port_vals)
    bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(benchmark_port_vals)
    print("Optimal: ", ocr, oadr, osddr, osr)
    print("Benchmark:", bcr, badr, bsddr, bsr)
コード例 #5
0
def build_tech_ind(dfs: dict) -> dict:
    """
    Build technical indicators and append them to the DataFrames as columns.
    :param dfs: Dict containing DataFrames by symbol containing all stock data as provided by group_by_stockname()
    :return: dict: {stock_name:string -> stock_data:DataFrame} with additional feature columns
    """
    result = {}
    for symbol, stock_df in dfs.items():
        close_col = 'adj_close' if 'adj_close' in stock_df else 'close'
        open_col  = 'adj_open'  if 'adj_open'  in stock_df else 'open'
        low_col   = 'adj_low'   if 'adj_low'   in stock_df else 'low'
        high_col  = 'adj_high'  if 'adj_high'  in stock_df else 'high'
        pmas = TechnicalIndicators.sma(stock_df, 10, 'PMA_S', col=close_col)
        pmal = TechnicalIndicators.sma(stock_df, 21, 'PMA_L', col=close_col)
        vmas = TechnicalIndicators.sma(stock_df, 10, 'VMA_S', col=vol_col)
        vmal = TechnicalIndicators.sma(stock_df, 21, 'VMA_L', col=vol_col)
        rsi = TechnicalIndicators.rsi(stock_df, 14, col=close_col)
        sto = TechnicalIndicators.sto(stock_df, 14, 3, col=close_col, col_low=low_col, col_high=high_col)
        bb = TechnicalIndicators.bbands(stock_df, 8, 2, col=close_col)
        result[symbol] = pd.concat([stock_df, pmas, pmal, vmas, vmal, rsi, sto, bb], axis=1)
    return result
コード例 #6
0
def testPolicy(symbol="JPM", sd=dt.datetime(2008, 1, 1), ed=dt.datetime(2009, 12, 31), sv=100000, bb_threshold=1, sma_threshold=0.06, momentum_threshold = 0.4):
    '''
    Generates a dataframe of trades based on the manual strategy policy.
	The policy is described in the attached report.
	
	Parameters:
	symbol (string) - The symbol with which to trade.
	sd (datetime) - Trading period start date.
	ed (datetime) - Trading period end date.
	sv (int) - Starting cash value.
	bb_threshold (float) - Threshold at which to trigger indicator.
	sma_threshold (float) - Threshold at which to trigger indicator.
	momentum_threshold(float) - Threshold at which to trigger indicator.
    '''
    window = 10;
    prices = id.get_prices([symbol], sd, ed)
    indicators = id.get_indicators(prices, [symbol], window = window)

    position = 0;
    holdings = 0;

    df_trades = pd.DataFrame(index = indicators.index);
    df_trades["Symbol"] = symbol
    df_trades["Order"] = "NONE"
    df_trades["Shares"] = 0

    for day in indicators.iloc[window-1:].index:
        bb = indicators["Normal BB"][day]
        sma = indicators["Price/SMA"][day]
        momentum = indicators["Momentum"][day]

        # Short Positions:
        # Stock is above upper Bollinger Band 
        # Price/SMA ratio is above 1.
        # Momentum is smaller than lower threshold
        if (bb > bb_threshold or sma > 1+sma_threshold) or momentum < -momentum_threshold:
            position = -1
        # Long Positions:
        # Price is below lower Bollinger Band
        # Price/SMA ratio is below 1.
        # Momentum is larger than upper threshold
        elif (bb < -bb_threshold or sma < 1-sma_threshold) or momentum > momentum_threshold:
            position = 1
        # Otherwise, maintain position.
        else:
            position = 0

        # Calculate needed shares to trade based on position.
        if position == -1:
            shares_to_trade = -1000-holdings
            holdings = -1000
        elif position == 1:
            shares_to_trade = 1000-holdings
            holdings = 1000
        else:
            shares_to_trade = 0

        if shares_to_trade<0:
            df_trades.loc[day, "Order"] = "SELL"
            df_trades.loc[day, "Shares"]= -shares_to_trade
        elif shares_to_trade>0:
            df_trades.loc[day, "Order"] = "BUY"
            df_trades.loc[day, "Shares"] = shares_to_trade

    df_trades = df_trades[df_trades.Order != "NONE"]
    return df_trades
コード例 #7
0
    port_vals.fillna(method = 'ffill', inplace=True)

    # Plot optimal strategy
    plt.gcf().subplots_adjust(bottom=0.2)
    plt.plot(port_vals["Benchmark"], color = 'g', linewidth = 0.7)
    plt.plot(port_vals["Manual"], color = 'r', linewidth = 0.7)
    if out_file == "Manual_In.png":
        print("In-sample")
        for day in manual_trades.index:
            if manual_trades.loc[day, "Order"] == "BUY":
                plt.axvline(day, color = 'b')
            else:
                plt.axvline(day, color = 'k')
    plt.legend(["Benchmark", "Manual Strategy"])
    plt.title("Portfolio Values: Benchmark vs. Manual Strategy\n"+out_subtitle, fontsize = 10)
    plt.ylabel("Normalized Values", fontsize = 8)
    plt.xlabel("Date Range", fontsize = 8)
    plt.xticks(rotation = 45)
    plt.savefig(out_file)
    #plt.show()

    mcr, madr, msddr, msr = id.calculate_portfolio_metrics(manual_port_vals)
    bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(benchmark_port_vals)
    print("Manual Strategy: ",  mcr, madr, msddr, msr)
    print("Benchmark:", bcr, badr, bsddr, bsr)

if __name__ == "__main__":
    main_manual(out_file = "Manual_In.png", out_subtitle = "In Sample")
    plt.figure()
    main_manual(sd = dt.datetime(2010, 1, 4), ed = dt.datetime(2011, 12, 30), out_file = "Manual_Out.png", out_subtitle = "Out of Sample")
コード例 #8
0

def test_ti():

    data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    df = pd.DataFrame(data=data)
    #print("dataframe before: ")
    #print(df)
    #df_out = ti.calculate_cci(df, 3)
    #print("dataframe after: ")
    #print(df_out)

    df.plot()
    plt.show()
    plt.savefig(code_path + "plot.png")


if __name__ == "__main__":

    test_ti()

    # build dataframe
    df_price, df_price_nonan = build_dataframe_price()
    df_dr = ti.calculate_daily_returns(df_price)
    df_sr = ti.calculate_sharpe_ratio(df_dr)
    print(df_sr)

    #print(df_price["btc"])
    #df_price["btc"].plot()
    ##plt.show()
    #plt.savefig(code_path + "plot.png")
コード例 #9
0
def experiment_2_helper(symbol,
                        start_train,
                        end_train,
                        start_test,
                        end_test,
                        sv=100000,
                        commission=0.0,
                        impact=0.0):

    np.random.seed(1000)
    random.seed(1000)

    slearner = sl.StrategyLearner(impact=impact)
    slearner.addEvidence(symbol=symbol, sd=start_train, ed=end_train, sv=sv)

    # In-Sample Experiment 1
    # Calculate manual strategy portfolio values
    manual_trades = man.testPolicy(symbol=symbol,
                                   sd=start_test,
                                   ed=end_test,
                                   sv=sv)
    manual_port_vals = ms.compute_portvals(manual_trades,
                                           start_val=sv,
                                           commission=commission,
                                           impact=impact)
    manual_port_vals = manual_port_vals / manual_port_vals.iloc[0, :]
    manual_port_vals.rename(columns={"Portfolio Value": "Manual"},
                            inplace=True)

    # Calculate benchmark portfolio values
    dates = pd.date_range(start_test, end_test)
    syms = [symbol]
    price_range = get_data(syms, dates)  # automatically adds SPY
    benchmark_trades = pd.DataFrame(
        data=[[symbol, "BUY", 1000]],
        index=[price_range.index[0], price_range.index[-1]],
        columns=["Symbol", "Order", "Shares"])
    bench_port_vals = ms.compute_portvals(benchmark_trades,
                                          start_val=sv,
                                          commission=commission,
                                          impact=impact)
    bench_port_vals = bench_port_vals / bench_port_vals.iloc[0, :]
    bench_port_vals.rename(columns={"Portfolio Value": "Benchmark"},
                           inplace=True)

    # Calculate strategy learner portfolio values
    temp_strategylearner_trades = slearner.testPolicy(symbol=symbol,
                                                      sd=start_test,
                                                      ed=end_test,
                                                      sv=sv)
    strategylearner_trades = pd.DataFrame(
        columns=['Order', 'Symbol', 'Shares'])
    for row_idx in temp_strategylearner_trades.index:
        nshares = temp_strategylearner_trades.loc[row_idx][0]
        if nshares == 0:
            continue
        order = 'SELL' if nshares < 0 else 'BUY'
        new_row = pd.DataFrame([
            [order, symbol, abs(nshares)],
        ],
                               columns=['Order', 'Symbol', 'Shares'],
                               index=[
                                   row_idx,
                               ])
        strategylearner_trades = strategylearner_trades.append(new_row)

    strategylearner_port_vals = ms.compute_portvals(strategylearner_trades,
                                                    start_val=sv,
                                                    commission=commission,
                                                    impact=impact)
    strategylearner_port_vals = strategylearner_port_vals / strategylearner_port_vals.iloc[
        0, :]
    strategylearner_port_vals.rename(columns={"Portfolio Value": "Strategy"},
                                     inplace=True)

    port_vals = pd.DataFrame(bench_port_vals["Benchmark"],
                             index=bench_port_vals.index)
    port_vals["Manual"] = manual_port_vals["Manual"]
    port_vals["Strategy"] = strategylearner_port_vals["Strategy"]
    port_vals.fillna(method='ffill', inplace=True)

    mcr, madr, msddr, msr = id.calculate_portfolio_metrics(manual_port_vals)
    bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(bench_port_vals)
    scr, sadr, ssddr, ssr = id.calculate_portfolio_metrics(
        strategylearner_port_vals)
    return mcr, madr, msddr, msr, bcr, badr, bsddr, bsr, scr, sadr, ssddr, ssr
コード例 #10
0
def run_experiment_1(symbol,
                     start_train,
                     end_train,
                     start_test,
                     end_test,
                     sv=100000,
                     commission=0.0,
                     impact=0.0,
                     output="default.png"):

    np.random.seed(1000)
    random.seed(1000)

    slearner = sl.StrategyLearner(impact=impact)
    slearner.addEvidence(symbol=symbol, sd=start_train, ed=end_train, sv=sv)

    # In-Sample Experiment 1
    # Calculate manual strategy portfolio values
    manual_trades = man.testPolicy(symbol=symbol,
                                   sd=start_test,
                                   ed=end_test,
                                   sv=sv)
    manual_port_vals = ms.compute_portvals(manual_trades,
                                           start_val=sv,
                                           commission=commission,
                                           impact=impact)
    manual_port_vals = manual_port_vals / manual_port_vals.iloc[0, :]
    manual_port_vals.rename(columns={"Portfolio Value": "Manual"},
                            inplace=True)

    # Calculate benchmark portfolio values
    dates = pd.date_range(start_test, end_test)
    syms = [symbol]
    price_range = get_data(syms, dates)  # automatically adds SPY
    benchmark_trades = pd.DataFrame(
        data=[[symbol, "BUY", 1000]],
        index=[price_range.index[0], price_range.index[-1]],
        columns=["Symbol", "Order", "Shares"])
    bench_port_vals = ms.compute_portvals(benchmark_trades,
                                          start_val=sv,
                                          commission=commission,
                                          impact=impact)
    bench_port_vals = bench_port_vals / bench_port_vals.iloc[0, :]
    bench_port_vals.rename(columns={"Portfolio Value": "Benchmark"},
                           inplace=True)

    # Calculate strategy learner portfolio values
    temp_strategylearner_trades = slearner.testPolicy(symbol=symbol,
                                                      sd=start_test,
                                                      ed=end_test,
                                                      sv=sv)
    strategylearner_trades = pd.DataFrame(
        columns=['Order', 'Symbol', 'Shares'])
    for row_idx in temp_strategylearner_trades.index:
        nshares = temp_strategylearner_trades.loc[row_idx][0]
        if nshares == 0:
            continue
        order = 'SELL' if nshares < 0 else 'BUY'
        new_row = pd.DataFrame([
            [order, symbol, abs(nshares)],
        ],
                               columns=['Order', 'Symbol', 'Shares'],
                               index=[
                                   row_idx,
                               ])
        strategylearner_trades = strategylearner_trades.append(new_row)

    strategylearner_port_vals = ms.compute_portvals(strategylearner_trades,
                                                    start_val=sv,
                                                    commission=commission,
                                                    impact=impact)
    strategylearner_port_vals = strategylearner_port_vals / strategylearner_port_vals.iloc[
        0, :]
    strategylearner_port_vals.rename(columns={"Portfolio Value": "Strategy"},
                                     inplace=True)

    port_vals = pd.DataFrame(bench_port_vals["Benchmark"],
                             index=bench_port_vals.index)
    port_vals["Manual"] = manual_port_vals["Manual"]
    port_vals["Strategy"] = strategylearner_port_vals["Strategy"]
    port_vals.fillna(method='ffill', inplace=True)

    # Plot in-sample strategy
    plt.figure()
    plt.gcf().subplots_adjust(bottom=0.2)
    plt.plot(port_vals["Benchmark"], color='g', linewidth=0.7)
    plt.plot(port_vals["Manual"], color='r', linewidth=0.7)
    plt.plot(port_vals["Strategy"], color='b', linewidth=0.7)
    plt.legend(["Benchmark", "Manual", "StrategyLearner"])
    plt.title(
        "Portfolio Values: Benchmark vs. Manual Strategy vs. StrategyLearner\n",
        fontsize=10)
    plt.ylabel("Normalized Values", fontsize=8)
    plt.xlabel("Date Range", fontsize=8)
    plt.xticks(rotation=45)
    plt.savefig(output)

    mcr, madr, msddr, msr = id.calculate_portfolio_metrics(manual_port_vals)
    bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(bench_port_vals)
    scr, sadr, ssddr, ssr = id.calculate_portfolio_metrics(
        strategylearner_port_vals)
    print("--------------------Manual Strategy--------------------")
    print("Cumulative Return:", mcr)
    print("Average Daily Return:", madr)
    print("Stdev Daily Return:", msddr)
    print("Sharpe Ratio:", msr)
    print("--------------------Benchmark Strategy-----------------")
    print("Cumulative Return:", bcr)
    print("Average Daily Return:", badr)
    print("Stdev Daily Return:", bsddr)
    print("Sharpe Ratio:", bsr)
    print("--------------------StrategyLearner---------------------")
    print("Cumulative Return:", scr)
    print("Average Daily Return:", sadr)
    print("Stdev Daily Return:", ssddr)
    print("Sharpe Ratio:", ssr)