Exemple #1
0
def my_portfolio(start="2018-7-10", end="2018-10-16"):
    dates = pd.date_range(start, end)
    symbols = [
        'PHC', 'MBB', 'GEX', 'MBS', 'NDN', 'PNJ', 'STB', 'PVD', 'VRC', 'VIX'
    ]
    #    symbols = ['PHC','MBB','GEX', 'MBS']
    df_data = get_data(symbols, dates,
                       benchmark='^VNINDEX')  # get data for each symbol
    fill_missing_values(df_data)
    plot_normalized_data(df_data,
                         title=" Daily porfolio value with VNINDEX ",
                         xlabel="Date",
                         ylabel=" Normalized price ")
Exemple #2
0
def rebalancing_porfolio(symbols=None, bench='^VNINDEX'):

    start0 = "2015-1-2"
    end0 = "2017-1-2"
    allocations, cr, adr, sddr, sr = optimize_portfolio(sd=start0,
                                                        ed=end0,
                                                        syms=symbols,
                                                        benchmark=bench,
                                                        gen_plot=True)
    print("Optimize start Date:", start0)
    print("Optimize end Date:", end0)
    print("Optimize volatility (stdev of daily returns):", sddr)
    print("Optimize average Daily Return:", adr)
    print("Optimize cumulative Return:", cr)
    print(" -----------------------------------------------------")
    start_date_list = ["2017-1-3", "2017-7-3"]
    end_date_list = ["2017-7-2", "2018-4-1"]
    for start, end in zip(start_date_list, end_date_list):

        cr, adr, sddr, sr = compute_portfolio(sd=start,
                                              ed=end,
                                              syms=symbols,
                                              allocs=allocations,
                                              benchmark=bench,
                                              gen_plot=True)
        print("Start Date:", start)
        print("End Date:", end)
        print("Volatility (stdev of daily returns):", sddr)
        print("Average Daily Return:", adr)
        print("Cumulative Return:", cr)
        print(" -----------------------------------------------------")
        allocations, cr, adr, sddr, sr = optimize_portfolio(sd=start,
                                                            ed=end,
                                                            syms=symbols,
                                                            benchmark=bench,
                                                            gen_plot=False)
        print("Optimize volatility (stdev of daily returns):", sddr)
        print("Optimize average Daily Return:", adr)
        print("Optimize cumulative Return:", cr)
        print(" -----------------------------------------------------")

    # Out of sample testing optimisation algorithm

    end_date = "2018-9-27"
    start_date = "2018-4-2"

    cr, adr, sddr, sr = compute_portfolio(sd=start_date,
                                          ed=end_date,
                                          syms=symbols,
                                          allocs=allocations,
                                          benchmark=bench,
                                          gen_plot=True)
    print(
        "....................... Out of sample performance .................")
    print("Start Date:", start_date)
    print("End Date:", end_date)
    print("Volatility (stdev of daily returns):", sddr)
    print("Average Daily Return:", adr)
    print("Cumulative Return:", cr)
    # Assess the portfolio
    investment = 60E6
    df_result = pd.DataFrame(index=symbols)
    df_result['Opt allocs'] = allocations
    df_result['Cash'] = allocations * investment

    dates = pd.date_range(start_date, end_date)  # date range as index
    df_data = get_data(symbols, dates,
                       benchmark=bench)  # get data for each symbol

    df_high = get_data(symbols, dates, benchmark=bench, colname='<High>')
    df_low = get_data(symbols, dates, benchmark=bench, colname='<Low>')

    max_high = pd.Series(df_high.max(), name='MaxHigh')
    min_low = pd.Series(df_low.min(), name='MinLow')
    cpm = pd.Series(max_high / min_low, name='CPM')
    volatility = df_data[symbols].pct_change().std()

    # Fill missing values

    df_result['Close'] = df_data[symbols].iloc[-1, :].values
    df_result['CPM'] = cpm[symbols]
    df_result['Shares'] = round(
        df_result['Cash'] / df_result['Close'].values / 1000, 0)
    df_result['Volatility'] = volatility

    alpha_beta = analysis_alpha_beta(df_data, symbols, market=bench)
    df_result['Alpha'] = alpha_beta['Alpha']
    df_result['Beta'] = alpha_beta['Beta']

    relative_strength = 40*df_data[symbols].pct_change(periods = 63).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 126).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 189).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 252).fillna(0)

    df_result['RSW'] = relative_strength.iloc[-1, :].values

    return df_result
Exemple #3
0
def passive_strategy(start_date, end_date, market="^VNINDEX", symbols=None):

    if symbols == None:
        symbols = getliststocks(typestock=market)

    dates = pd.date_range(start_date, end_date)  # date range as index
    df_data = get_data(symbols, dates,
                       benchmark=market)  # get data for each symbol

    df_volume = get_data(symbols, dates, benchmark=market,
                         colname='<Volume>')  # get data for each symbol
    df_high = get_data(symbols, dates, benchmark=market, colname='<High>')
    df_low = get_data(symbols, dates, benchmark=market, colname='<Low>')

    #    covariance = numpy.cov(asset , SPY)[0][1]
    #    variance = numpy.var(asset)
    #
    #    beta = covariance / variance
    df_volume = df_volume.fillna(0)
    df_value = (df_volume * df_data).fillna(0)
    valueM30 = df_value.rolling(window=30).mean()

    vol_mean = pd.Series(df_volume.mean(), name='Volume')
    max_high = pd.Series(df_high.max(), name='MaxHigh')
    min_low = pd.Series(df_low.min(), name='MinLow')
    cpm = pd.Series(max_high / min_low, name='CPM')
    value_mean = pd.Series(df_value.mean(), name='ValueMean')

    # Fill missing values
    fill_missing_values(df_data)

    # Assess the portfolio

    allocations, cr, adr, sddr, sr = optimize_portfolio(sd=start_date,
                                                        ed=end_date,
                                                        syms=symbols,
                                                        benchmark=market,
                                                        gen_plot=True)

    # Print statistics
    print("Start Date:", start_date)
    print("End Date:", end_date)
    print("Symbols:", symbols)
    print("Optimal allocations:", allocations)
    print("Sharpe Ratio:", sr)
    print("Volatility (stdev of daily returns):", sddr)
    print("Average Daily Return:", adr)
    print("Cumulative Return:", cr)

    investment = 50000000
    df_result = pd.DataFrame(index=symbols)
    df_result['Opt allocs'] = allocations
    df_result['Cash'] = allocations * investment
    df_result['Close'] = df_data[symbols].iloc[-1, :].values
    df_result['PCT_Change'] = 100 * (df_data[symbols].iloc[-1, :].values -
                                     df_data[symbols].iloc[0, :].values
                                     ) / df_data[symbols].iloc[0, :].values
    df_result['Volume'] = df_volume[symbols].iloc[-1, :].values
    df_result['VolumeMean'] = vol_mean[symbols]
    df_result['Value'] = df_result['Close'] * df_result['Volume']
    df_result['ValueMean'] = value_mean[symbols]
    df_result['ValueMA30'] = valueM30[symbols].iloc[-1, :].values
    #    df_result['MaxH'] = max_high
    #    df_result['MinL'] = min_low
    df_result['CPM'] = cpm[symbols]
    df_result['Shares'] = round(
        df_result['Cash'] / df_result['Close'].values / 1000, 0)

    df_result['Volatility'] = df_data[symbols].pct_change().std()

    df_result['PCT_Change0D'] = df_data[symbols].pct_change().iloc[
        -1, :].values * 100
    df_result['PCT_Change1D'] = df_data[symbols].pct_change().iloc[
        -2, :].values * 100
    df_result['PCT_Change2D'] = df_data[symbols].pct_change().iloc[
        -3, :].values * 100

    alpha_beta = analysis_alpha_beta(df_data, symbols, market)
    df_result['Alpha'] = alpha_beta['Alpha']
    df_result['Beta'] = alpha_beta['Beta']

    relative_strength = 40*df_data[symbols].pct_change(periods = 63).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 126).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 189).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 252).fillna(0)

    relative_strength1M = 100 * df_data[symbols].pct_change(
        periods=21).fillna(0)
    relative_strength2M = 100 * df_data[symbols].pct_change(
        periods=42).fillna(0)

    df_result['RSW'] = relative_strength.iloc[-1, :].values

    df_result['RSW1M'] = relative_strength1M.iloc[-1, :].values
    df_result['RSW2M'] = relative_strength2M.iloc[-1, :].values

    marketVNI = df_data[symbols].pct_change()
    advances = marketVNI[marketVNI > 0]
    declines = marketVNI[marketVNI <= 0]
    dec = advances.isnull().sum(axis=1)
    adv = declines.isnull().sum(axis=1)

    df_market = pd.DataFrame(index=marketVNI.index)
    df_market[market + 'Volume'] = df_volume[market]
    df_market[market + 'PCT_Volume'] = df_volume[market].pct_change() * 100
    df_market[market + 'PCT_Index'] = df_data[market].pct_change() * 100
    #    df_market['Adv'] = adv
    #    df_market['Dec'] = dec
    df_market[market + 'Adv_Dec'] = adv - dec
    df_market[market + 'Dec/Adv'] = dec / adv
    strength = pd.Series(index=marketVNI.index)
    strength[(df_market[market + 'Adv_Dec'] > 0)
             & (df_market[market + 'PCT_Index'] > 0)] = 1
    strength[(df_market[market + 'Adv_Dec'] < 0)
             & (df_market[market + 'PCT_Index'] < 0)] = -1
    strength[(df_market[market + 'Adv_Dec'] < 0)
             & (df_market[market + 'PCT_Index'] > 0)] = 0
    df_market[market + 'Strength'] = strength
    #    np.where((df_data[symbols].pct_change() > 0), 1, -1)

    return df_result, df_data, df_market
Exemple #4
0
def passive_strategy(start_date,
                     end_date,
                     market=None,
                     symbols=None,
                     realtime=True,
                     source='yahoo'):

    if symbols == None:
        symbols = getliststocks(typestock=market)

    if realtime:
        end_date = datetime.datetime.today()

    dates = pd.date_range(start_date, end_date)  # date range as index
    df_data = get_data(symbols,
                       dates,
                       benchmark=market,
                       colname='Adj Close',
                       realtime=realtime,
                       source=source)  # get data for each symbol
    # Fill missing values
    fill_missing_values(df_data)
    df_volume = get_data(symbols,
                         dates,
                         benchmark=market,
                         colname='Volume',
                         realtime=realtime,
                         source=source)  # get data for each symbol
    df_rsi = get_RSI(symbols, df_data)
    df_volume = df_volume.fillna(0)

    df_result = pd.DataFrame(index=symbols)

    df_result['Ticker'] = symbols
    df_result['Close'] = df_data[symbols].iloc[-1, :].values
    df_result['PCT_C'] = 100 * (df_data[symbols].iloc[-1, :].values -
                                df_data[symbols].iloc[0, :].values
                                ) / df_data[symbols].iloc[0, :].values
    df_result['Volume'] = df_volume[symbols].iloc[
        -1, :].values + df_volume[symbols].iloc[-2, :].values

    df_result['Value'] = df_result['Close'] * df_result['Volume']

    df_result['Volatility'] = df_data[symbols].pct_change().std()

    df_result['PCT_3D'] = df_data[symbols].pct_change().iloc[
        -4, :].values * 100
    df_result['PCT_2D'] = df_data[symbols].pct_change().iloc[
        -3, :].values * 100
    df_result['PCT_1D'] = df_data[symbols].pct_change().iloc[
        -2, :].values * 100
    df_result['PCT_0D'] = df_data[symbols].pct_change().iloc[
        -1, :].values * 100


    relative_strength = 40*df_data[symbols].pct_change(periods = 63).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 126).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 189).fillna(0) \
                     + 20*df_data[symbols].pct_change(periods = 252).fillna(0)

    relative_strength1M = 100 * df_data[symbols].pct_change(
        periods=21).fillna(0)
    relative_strength2M = 100 * df_data[symbols].pct_change(
        periods=42).fillna(0)

    df_result['RSW'] = relative_strength.iloc[-1, :].values

    df_result['RSW1M'] = relative_strength1M.iloc[-1, :].values
    df_result['RSW2M'] = relative_strength2M.iloc[-1, :].values
    df_result['RSI'] = df_rsi[symbols].iloc[-1, :].values

    return df_result, df_data
Exemple #5
0
def compute_portvals_margin_vn(start,
                               end,
                               orders,
                               start_val=100000,
                               commission=0.0015,
                               tax=0.001,
                               impact=0.0,
                               market="^VNINDEX"):
    """Compute daily portfolio value given a dataframe of orders.

    Parameters
    ----------
        start_date: first date to track
        end_date: last date to track
        df:  read orders from dataframe
        start_val: total starting cash available

    Returns
    -------
        portvals: portfolio value for each trading day from start_date to end_date (inclusive)
    """
    #    if isinstance(df, pd.DataFrame):

    if isinstance(orders, str):
        df = pd.read_csv(orders, index_col='Date', parse_dates=True)
    else:
        df = orders

    # Get the first date and last date after reading file
    start_date = df.iloc[0].name
    end_date = df.iloc[-1].name
    print(" Start trading date :", start_date)
    print(" End trading date :", end_date)

    dates = pd.date_range(start, end)
    if (dates[0] > start_date) or (end_date > dates[-1]):
        raise ValueError(
            " Error on start date and end date. Must be in larger period as in order file! Check again!"
        )

#    symbols = []
#    for i, row in df.iterrows():
#        if row['Symbol'] not in symbols:
#            symbols.append(row['Symbol'])

    symbols = list(df['Symbol'].unique())  #ndarray to list of symbols in order

    prices_symbol = get_data(symbols,
                             pd.date_range(start, end),
                             benchmark=market)

    for symbol in symbols:
        prices_symbol[symbol + ' Shares'] = pd.Series(
            0, index=prices_symbol.index)
    prices_symbol['Port Val'] = pd.Series(start_val, index=prices_symbol.index)
    prices_symbol['Cash'] = pd.Series(start_val, index=prices_symbol.index)

    #    return prices_symbol

    for i, row in df.iterrows():
        symbol = row['Symbol']
        if row['Order'] == 'BUY':
            #            print(symbol)
            cash_out = (prices_symbol.loc[i, symbol] * (1 + impact) *
                        row['Shares'])
            current_cash = prices_symbol.loc[i, 'Cash']
            #            print(current_cash)
            if (2 * current_cash < cash_out):
                print("Over leverage (margin) 50%. Cannot BUY all shares. ")
                pass
            else:
                if (current_cash < cash_out):
                    print(" Using leverage margin 50%")
                prices_symbol.loc[i:, symbol + ' Shares'] = prices_symbol.loc[
                    i:, symbol + ' Shares'] + row['Shares']

                prices_symbol.loc[i:, 'Cash'] -= cash_out
                prices_symbol.loc[i:, 'Cash'] -= commission * cash_out
        if row['Order'] == 'SELL':
            current_shares = prices_symbol.loc[i, symbol + ' Shares']
            if (row['Shares'] > current_shares):
                print(" Not enough shares to SELL!", current_shares,
                      row['Shares'])
                pass
            else:
                prices_symbol.loc[i:, symbol + ' Shares'] = prices_symbol.loc[
                    i:, symbol + ' Shares'] - row['Shares']
                prices_symbol.loc[i:, 'Cash'] += cash_out
                prices_symbol.loc[i:, 'Cash'] -= (commission + tax) * cash_out
    for i, row in prices_symbol.iterrows():
        shares_val = 0
        for symbol in symbols:
            shares_val += prices_symbol.loc[i,
                                            symbol + ' Shares'] * row[symbol]
#            print(" Shares values :",  shares_val)
        prices_symbol.loc[i,
                          'Port Val'] = prices_symbol.loc[i,
                                                          'Cash'] + shares_val

    return prices_symbol
Exemple #6
0
def testcode():

    end_date = "2018-2-21"
    start_date = "2017-2-2"
    dates = pd.date_range(start_date, end_date)
    symbols = ['SHB']
    investment = 1000000
    ticker = 'SHB'
    data = get_data(symbols, dates, benchmark="^HASTC")
    #    data = defineData(start_date, end_date, symbols)

    #    return data
    plot_normalized_data(data)
    # get AAPL between the in-sample dates set as default
    data = get_data_trading(ticker, start_date, end_date)

    holdTime = 21  # in days
    smaWindow = 50
    smaIndicator = getSmaIndicator(data, smaWindow=smaWindow)
    smaThreshold = 0.012  #0.012 # optimized value on manual trading strategy 1
    # generate a buy signal (1) if price falls significantly below sma
    # generate a sell signal (-1) if prices rises significantly above sma
    smaSignal = 1 * (smaIndicator < -smaThreshold)  +  \
            -1 * (smaIndicator > smaThreshold)
    momWindow = 10
    momIndicator = getMomIndicator(data, momWindow=momWindow)
    momThreshold = 0.06  #0.055 # optimized value on manual trading strategy 1
    # generate a buy/sell signal if momentum is greatly positive/negative
    momSignal = -1 * (momIndicator < -momThreshold)  +  \
            1 * (momIndicator > momThreshold)

    bbWindow = 10  #48 NOT OPTIMIZED
    bbIndicator = getBbIndicator(data, bbWindow=bbWindow)
    bbThreshold = 0  #0.2 NOT OPTIMIZED
    # generate a buy/sell signal if indicator is below/above the lower/upper BB
    # and the indicator is rising/falling significantly
    bbSignal = -1 * ((bbIndicator > 1) & \
                     (standardize(data['Close']).diff(1) < -bbThreshold)) + \
                 1 * ((bbIndicator < -1) & \
                     (standardize(data['Close']).diff(1) > bbThreshold))
    crossWindow = 18
    crossIndicator = getCrossIndicator(data, crossWindow=crossWindow)
    crossThreshold = 0.08  #0.08 # optimized value on manual trading strategy 1
    # generate a buy/sell signal if indicator is close to 0.5/-0.5
    crossSignal = 1 * ( (crossIndicator - 0.5).abs() < crossThreshold) + \
            -1 * ( (crossIndicator + 0.5).abs() < crossThreshold )

    # Combine individual signals. bbSignal is neglected here since including it
    # with the other signals did not result in label-free trading using strategy 1
    signal = 1 * ( (smaSignal == 1) & (momSignal ==1 ) & (crossSignal == 1) ) \
        + -1 * ( (smaSignal == -1) & (momSignal == -1) & (crossSignal == -1) )

    order = tradingStrategy(signal, holdTime)
    df_orders = createOrderDf(order)
    prices_symbol = compute_portvals_margin_vn(start_date,
                                               end_date,
                                               df_orders,
                                               start_val=investment,
                                               market="^HASTC")

    #    return order

    portVals = prices_symbol['Port Val']
    #    print('Cumulative return [%]: ', round(cumReturn * 100, 4) )

    order_opt = bestPossibleStrategy(data)
    df_orders_opt = createOrderDf(order_opt)
    prices_symbol_opt = compute_portvals_margin_vn(start_date, end_date, df_orders_opt, start_val = investment, \
                                         market = "^HASTC")

    portVals_opt = prices_symbol_opt['Port Val']

    fig = plt.figure(figsize=(10, 10))
    ax1 = fig.add_subplot(3, 1, 1)
    #    ax1 = plt.subplot(311)
    plt.plot(data['Close'] / data['Close'].iloc[0],
             label='benchmark (market)',
             color='k')
    plt.plot(portVals / portVals[0], label='rule-based')
    plt.plot(portVals_opt / portVals_opt[0], label='optimal')
    #    plt.xticks(rotation=30)
    plotVline(order)
    plt.title('rule-based with sma + mom + crossover indicators')
    lg = plt.legend(loc='best')
    lg.draw_frame(False)
    plt.ylabel('normalized')

    #    ax2 = plt.subplot(312)
    ax2 = fig.add_subplot(3, 1, 2)
    plt.plot(smaSignal / 2, label='sma')
    plt.plot(momSignal / 1.3, '.', label='mom')
    plt.plot(crossSignal / 1.1, '.', label='crossover')
    plt.plot(signal, label='overall signal')
    #    plt.xticks(rotation=30)
    plt.ylabel('indicator signals [a.u.]')
    lg = plt.legend(loc='center right')
    lg.draw_frame(False)

    #    plt.subplot(313)
    ax3 = fig.add_subplot(3, 1, 3)
    plt.scatter(momIndicator[signal==0], crossIndicator[signal==0], \
                           color = 'k', label = 'hold')
    plt.scatter(momIndicator[signal==1], crossIndicator[signal==1], \
                           color = 'g', label = 'buy')
    plt.scatter(momIndicator[signal==-1], crossIndicator[signal==-1], \
                           color = 'r', label = 'sell')
    lg = plt.legend(loc='best')
    lg.draw_frame(True)
    plt.xlabel('Momentum Indicator')
    plt.ylabel('Crossover Indicator')

    plt.subplots_adjust(hspace=0)
    #    plt.setp([a.get_xticklabels() for a in plt.axes[:-1]], visible=False)
    return portVals_opt