Beispiel #1
0
 def func(t):
     data = read_ETF(t)
     if data.index[0] < start:
         data = data[start:end]
         a, b = get_alpha_beta(data.Close, ret_type='simple', dspl=False)
         df.at[t, 'alpha'] = a
         df.at[t, 'beta'] = b
Beispiel #2
0
def show_dividend(ticker, start=None, end=None):
    """
    Show annual dividend yield
    input:  ticker  ticker of the stock/ETF
            start   start date, default '2000-01-01'
            end     end date, default current
    Return a DataFrame
    """
    from invest.useful import convert_time
    from invest.get_data import read_ETF
    from invest.calculation import add_dividend, get_dividend_yield
    start, end = convert_time(start, end)
    data = read_ETF(ticker)[start:end]
    add_dividend(data, price='Close', adj='Adj Close', out='Div')
    div = get_dividend_yield(data, price='Close', div='Div', style='simple')

    plt.figure(figsize=(14, 4))
    plt.bar(div.index, div * 100)

    ret = data.Div[data.Div > 0].tail(6).to_frame()
    ret.index = ret.index.date

    print(ret)
    plt.show()
    return ret.T
Beispiel #3
0
def investment_performance(ticker, price, quantity, start, end=None):
    """
    Calculate performance of given stock/ETF.
    input:  ticker  ticker of the stock/ETF
            start   start date
            end     end date, default current
    """
    from invest.useful import convert_time
    from invest.get_data import read_ETF
    from invest.plot import plot_day_price
    from invest.calculation import add_dividend, get_return_vol
    from time_series.functions import resample
    start, end = convert_time(start, end)
    data = read_ETF(ticker)[start:end]
    plot_day_price(data)
    plt.plot([start], [price], 'ro')
    plt.show()
    add_dividend(data, price='Close', adj='Adj Close', out='Dividend')
    temp = data[['Dividend']][data.Dividend != 0].copy()
    temp.index = temp.index.date
    display(temp.T)
    weekly = resample(data, style='week', method='close')
    rv = get_return_vol(weekly[['Close', 'Adj Close']],
                        scale=52,
                        ret=False,
                        plotit=False)
    rv['Total Return'] = data[['Close', 'Adj Close']].iloc[-1, :] / data[
        ['Close', 'Adj Close']].iloc[0, :] - 1
    rv = rv * 100
    rv['Gain'] = np.round(price * quantity * rv['Total Return'] / 100, 2)
    display(rv)
    print("Actual gain without reinvest: {:.2f}".format(
        (data.Close[-1] - price) * quantity))
    print("Dividend gain: {:.2f}".format(data.Dividend.sum() * quantity))
Beispiel #4
0
def show_yield(ticker, start=None, end=None, weeks=52):
    """
    Calculate annualized return. Simple return is calculated
    input:  ticker  ticker of the stock/ETF
            start   start date, default '2000-01-01'
            end     end date, default current
            weeks   number of weeks for each calculation, default 52
    Return a DataFrame with three rows: Adj Close, Dividend, Close
    """
    from invest.useful import convert_time
    from invest.get_data import read_ETF
    from invest.calculation import add_dividend, get_returns
    from time_series.functions import resample
    start, end = convert_time(start, end)
    data = read_ETF(ticker)[start:end]
    add_dividend(data, price='Close', adj='Adj Close', out='Dividend')
    data['Dividend'] = np.cumsum(data.Dividend)
    weekly = resample(data, style='week', method='close')
    weekly = weekly[(weekly.shape[0] - 1) % weeks::weeks]
    df = get_returns(weekly[['Adj Close', 'Dividend', 'Close']], 'simple')
    df['Dividend'] = (weekly.Dividend.diff() / weekly.Close.shift(1))
    df = df * 100 * 52 / weeks
    from datetime import timedelta
    ds = df.index
    xlim = [
        ds[0] - timedelta(days=3 * weeks), ds[-1] + timedelta(days=3 * weeks)
    ]
    plt.figure(figsize=(14, 3))
    plt.title("Annualized Return")
    plt.hlines(xmin=xlim[0], xmax=xlim[1], y=0)
    plt.hlines(xmin=xlim[0],
               xmax=xlim[1],
               y=df['Adj Close'].mean(),
               linestyle='--',
               color='#1f77b4')
    plt.hlines(xmin=xlim[0],
               xmax=xlim[1],
               y=df.Dividend.mean(),
               linestyle='--',
               color='#ff7f0e')
    plt.bar(ds, df.Close, width=5 * weeks, label='Yield')
    plt.bar(ds,
            df.Dividend,
            bottom=df.Close,
            width=5 * weeks,
            label='Div_Yield')
    plt.plot(ds, df['Adj Close'], 'o-', label='Adj_Yield')
    plt.xlabel("Date to sell")
    plt.xlim(xlim)
    plt.ylim([np.min(df.values) - 0.2, np.max(df.values) + 0.2])
    plt.legend(bbox_to_anchor=(1.01, 0.9), loc='upper left')
    plt.grid()
    df.index = df.index.date

    print(np.round(df, 2))
    plt.show()
    return np.round(df, 2).T
Beispiel #5
0
def show_trend(ticker, start=None, end=None):
    """
    Plot price change, return and volatility
    input:  ticker  ticker of the stock/ETF
            start   start date, default '2000-01-01'
            end     end date, default current
    Return correlation between return and volatility
    """
    from invest.useful import convert_time
    from invest.get_data import read_ETF
    from invest.calculation import get_returns
    from time_series.functions import moving_agg, resample
    from basic.mathe import covariance, correlation
    start, end = convert_time(start, end)
    data = read_ETF(ticker)[start:end]

    fig = plt.figure(figsize=(14,6))
    fig.add_axes([0.05,0.68,0.94,0.3])
    for c in ['Close','Adj Close']:
        plt.plot(data.index, data[c], label=c)
    plt.xlim(data.index[0],data.index[-1])
    plt.xticks([])
    plt.ylabel("Price ($)")
    plt.legend(loc='best')

    weekly = resample(data, style='week', method='close')
    df = get_returns(weekly.Close, 'simple')

    fig.add_axes([0.05,0.38,0.94,0.3])
    m = moving_agg(df, window=52, step=1, func=np.sum)
    plt.plot(df.index[51:], m*100)
    plt.hlines(xmin=data.index[0], xmax=data.index[-1], y=0, linestyle='--')
    plt.xlim(data.index[0],data.index[-1])
    plt.xticks([])
    plt.ylabel("Annual Return (%)")
    plt.legend(loc='best')

    fig.add_axes([0.05,0.08,0.94,0.3])
    v = moving_agg(df, window=52, step=1, func=covariance)
    v = np.sqrt(v*52)
    plt.plot(df.index[51:], v*100)
    plt.xlim(data.index[0],data.index[-1])
    plt.ylabel("Volatility (%)")
    plt.gca().set_ylim(bottom=0)
    plt.legend(loc='best')

    corr = correlation(m, v)
    print("Correlation between return and volatility:", corr)
    plt.show()
    return corr
Beispiel #6
0
def generate(tickers, features):
    """
    input:  tickers     a list of tickers of stocks/ETFs
            features    a list of feature names to be calculated
    Return a pandas DataFrame
    """
    from invest.get_data import read_ETF
    from time_series.functions import resample
    from invest.calculation import get_returns
    data = pd.DataFrame()
    for t in tickers:
        etf = read_ETF(t)
        weekly = resample(etf, style='week', method='close')
        ret = get_returns(weekly, style='simple')
        rv = get_return_vol(ret, scale=52, ret=True, plotit=False)
 def set_benchmark(self):
     ticker = self.benchmark.get().upper()
     if ticker == "":
         self._logger_.info("Remove benchmark")
         self._data_['benchmark'] = 0
     else:
         self._logger_.info("Set benchmark as {}".format(ticker))
         try:
             data = read_ETF(ticker, file_dir=path + "\\data_temp")
         except:
             self._logger_.error("Cannot load benchmark {}".format(ticker))
         else:
             self._data_['benchmark'] = get_returns(resample(
                 data.Close, column=None, style="week", method='close'),
                                                    style='simple',
                                                    fillna=False)
     self.update_plot()
Beispiel #8
0
    def main_frame(self):
        holdings = pd.read_csv(file_dir + '\\data\\holdings.csv',
                               index_col=None,
                               parse_dates=[0]).dropna()
        data = {}
        for t in holdings.Ticker.unique():
            data[t] = read_ETF(t)
            if (data[t].index[-1].date() !=
                    date.today()) and (date.today().weekday() < 5):
                self._logger_.debug("Latest date is {}. Update local data for ticker {}"\
                    .format(data[t].index[-1].date(), t))
                update_ETF_data([t],
                                dt="2000-01-01",
                                file_dir=file_dir + '\\data\\')
            add_dividend(data[t],
                         price='Close',
                         adj='Adj Close',
                         out='Dividend')

        def pop_up():
            self._logger_.info("Popup window")
            frame = tk.Tk()
            self.transactions(frame)
            frame.mainloop()

        tk.Button(self, text='Add Transactions',
                  command=pop_up).pack(anchor=tk.E)

        fig = plot_embed(self)
        fig.pack()
        table = tk.Frame(self)
        table.pack()
        for i, text in enumerate([
                "Ticker", "Buy Date", "Buy Price", "Current Price",
                "Buy Shares", "Reinvested Shares", "Capital Gain",
                "Dividend Gain", "Total Gain"
        ]):
            tk.Label(table, text=text).grid(row=0, column=i, padx=5, pady=5)
        total_gain = 0
        for loc, i in enumerate(holdings.index):
            t = holdings.Ticker[i]
            d = holdings.Date[i]
            p = holdings.Price[i]
            s = holdings.Shares[i]
            r = (date.today() - d.date()).days / 365
            print(r)
            vals = [
                t, "{}".format(d.date()), "{:.2f}".format(p),
                "{:.2f}".format(data[t].iloc[-1, :].Close), "{:.0f}".format(s)
            ]
            current_share = data[t].loc[d,
                                        'Close'] / data[t].loc[d,
                                                               'Adj Close'] * s
            vals.append("{:.4f}".format(current_share - s))
            vals.append("{:.2f} ({:.2%})".format(
                (data[t].iloc[-1, :].Close - p) * s,
                (data[t].iloc[-1, :].Close / p - 1) / r))
            vals.append("{:.2f} ({:.2%})".format(
                data[t].loc[d:, 'Dividend'].sum() * s,
                data[t].loc[d:, 'Dividend'].sum() / p / r))
            gain = data[t].iloc[-1, :].Close * current_share - p * s
            total_gain += gain
            vals.append("{:.2f} ({:.2%})".format(gain, gain / p / s / r))
            for j, text in enumerate(vals):
                tk.Label(table, text=text).grid(row=loc + 1,
                                                column=j,
                                                padx=5,
                                                pady=5)
        tk.Label(table, text="Total gain is: {:.2f}".format(total_gain))\
            .grid(row=holdings.shape[0]+1, column=0, columnspan=3)
Beispiel #9
0
def show_performance(ticker, current=None):
    """
    Calculate total return and effective annual return for different starting point.
    Simple return is calculated
    input:  ticker  ticker of the stock/ETF
            current the date to be calculated
    Return a DataFrame with two rows: Total Return, Annual Return
    """
    from datetime import date, timedelta
    from invest.get_data import read_ETF
    from time_series.functions import change_month
    data = read_ETF(ticker)[['Close', 'Adj Close']]
    if current is None:
        current = data.index[-1]
    else:
        current = data[:current].index[-1]
    mns = np.array([1, 3, 6, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120])
    dates = [change_month(current, -x) for x in mns]
    df = pd.DataFrame(columns=['Close', 'Adj Close'])
    dates = np.array(dates)
    dates = dates[np.where(dates >= data.index[0].date())]
    for d in dates:
        vals = data[:d]
        if vals.empty:
            break
        df.loc[vals.index[-1].date(), :] = 100 * (
            data.loc[current, :] / vals.iloc[-1, :] - 1)
    df['label'] = [
        '1M', '3M', '6M', '1Y', '2Y', '3Y', '4Y', '5Y', '6Y', '7Y', '8Y', '9Y',
        '10Y'
    ][:df.shape[0]]
    df['years'] = mns[:df.shape[0]] / 12
    result = pd.DataFrame(index=df.index)
    result['Total Return'] = df.Close
    result['Annual Return'] = df.Close / df.years
    result['Adjusted Total Return'] = df['Adj Close']
    result['Adjusted Annual Return'] = df['Adj Close'] / df.years

    plt.figure(figsize=(14, 8))
    plt.subplot(2, 1, 1)
    plt.title("Performance for close price (not adjusted)")
    plt.bar(df.index.map(lambda x: x - timedelta(days=12)),
            df.Close,
            width=24,
            label='Total Return')
    plt.bar(df.index.map(lambda x: x + timedelta(days=12)),
            df.Close / df.years,
            width=24,
            label='Annual Return')
    plt.hlines(xmin=df.index[-1] - timedelta(days=24), xmax=current, y=0)
    plt.xticks(df.index, df.label)
    plt.xlim(df.index[-1] - timedelta(days=24), current)
    plt.ylim(max(-10,
                 np.min(result.values) - 1), min(20,
                                                 np.max(result.values) + 1))
    plt.legend(loc='best')
    plt.grid()
    plt.subplot(2, 1, 2)
    plt.title("Performance for close price (adjusted)")
    plt.bar(df.index.map(lambda x: x - timedelta(days=12)),
            df['Adj Close'],
            width=24,
            label='Total Return')
    plt.bar(df.index.map(lambda x: x + timedelta(days=12)),
            df['Adj Close'] / df.years,
            width=24,
            label='Annual Return')
    plt.hlines(xmin=df.index[-1] - timedelta(days=24), xmax=current, y=0)
    plt.xticks(df.index, df.label)
    plt.xlim(df.index[-1] - timedelta(days=24), current)
    plt.ylim(max(-10,
                 np.min(result.values) - 1), min(20,
                                                 np.max(result.values) + 1))
    plt.legend(loc='best')
    plt.grid()

    print(np.round(result[::-1].astype(float), 2))
    plt.show()
    return np.round(result[::-1].astype(float), 2).T