示例#1
0
def assign_strategy(filtered_stocks: pd.DataFrame, algo: str,
                    n_stocks: int) -> tuple:
    filtered_stocks = filtered_stocks.sample(n=n_stocks, axis=1)
    returns = returns_from_prices(filtered_stocks, log_returns=False)
    mu = mean_historical_return(filtered_stocks)
    assert len(mu) == n_stocks
    s = CovarianceShrinkage(filtered_stocks).ledoit_wolf()

    if algo == "hrp":
        return (hrp_strategy, "Hierarchical Risk Parity", {
            'returns': returns
        }, mu, s)
    elif algo == "ef-sharpe":
        return (ef_sharpe_strategy, "Efficient Frontier - max. sharpe", {
            'returns': mu,
            'cov_matrix': s
        }, mu, s)
    elif algo == "ef-risk":
        return (ef_risk_strategy, "Efficient Frontier - efficient risk", {
            'returns': mu,
            'cov_matrix': s,
            'target_volatility': 5.0
        }, mu, s)
    elif algo == "ef-minvol":
        return (ef_minvol_strategy, "Efficient Frontier - minimum volatility",
                {
                    'returns': mu,
                    'cov_matrix': s
                }, mu, s)
    else:
        assert False
示例#2
0
def get_mean_variance_share_allocation():
    dates, ticker_to_closing_prices = get_ticker_to_closing_prices(
        START_DATE, TEST_START_DATE - timedelta(days=1))

    tickers = ticker_to_closing_prices.keys()
    prices = list(
        zip(*[ticker_to_closing_prices[ticker] for ticker in tickers]))
    df = pd.DataFrame(
        prices,
        index=dates,
        columns=tickers,
    )

    mu = mean_historical_return(df)
    S = CovarianceShrinkage(df).ledoit_wolf()

    ef = EfficientFrontier(mu, S)
    weights = ef.max_sharpe()

    _, ticker_to_closing_prices_at_test_start = get_ticker_to_closing_prices(
        TEST_START_DATE, TEST_END_DATE)
    prices_at_test_start = pd.Series([
        float(ticker_to_closing_prices_at_test_start[ticker][0])
        for ticker in tickers
    ],
                                     index=tickers)
    da = DiscreteAllocation(weights,
                            prices_at_test_start,
                            total_portfolio_value=INITIAL_PORTFOLIO_VAL)
    allocation, leftover = da.lp_portfolio()
    for ticker in tickers:
        if ticker not in allocation:
            allocation[ticker] = 0

    return allocation
def run_allocation(date, duration):
    df = pd.DataFrame(columns=symbols)
    for symbol in symbols:
        try:
            data = get_all_binance(symbol, date, duration, save=False)
            df[symbol] = data["close"]

        except BinanceAPIException:
            print("Symbol was : " + symbol)

    df = df.apply(pd.to_numeric)
    df.fillna(0)
    print(df)
    mu = mean_historical_return(df)
    S = CovarianceShrinkage(df).ledoit_wolf()

    ef = EfficientFrontier(mu, S)

    weights = ef.max_sharpe()

    #aws, graphql, table'a ekle

    cleaned_weights = ef.clean_weights()
    print(ef.portfolio_performance(verbose=True))
    lists = sorted(weights.items())  # sorted by key, return a list of tuples
    lists = {x: y for x, y in lists if y > 0}

    f = open("Coin" + duration + ".txt", "w")
    f.write(str(lists))
    f.close()
    print(weights)
    s3 = boto3.client('s3')
    with open("Coin" + duration + ".txt", "rb") as f:
        s3.upload_fileobj(f, "model-predictions", "Coin" + duration + ".txt")
示例#4
0
def run_iteration(
    ld: LazyDictionary,
    strategy,
    first_prices,
    latest_prices,
    filtered_stocks,
    **kwargs,
):
    assert ld is not None
    strategy(ld, **kwargs)

    ld["optimizer_performance"] = lambda ld: portfolio_performance(ld)
    ld["allocator"] = lambda ld: DiscreteAllocation(
        ld["raw_weights"],
        first_prices,
        total_portfolio_value=ld["total_portfolio_value"],
    )
    ld["portfolio"] = lambda ld: ld["allocator"].greedy_portfolio(
    )  # greedy_portfolio returns (dict, float) tuple
    ld["cleaned_weights"] = lambda ld: clean_weights(ld["raw_weights"], ld[
        "portfolio"][0], first_prices, latest_prices)
    ld["latest_prices"] = latest_prices
    ld["len_latest_prices"] = lambda ld: len(ld["latest_prices"])

    # only plot covmatrix/corr for significant holdings to ensure readability
    ld["m"] = lambda ld: CovarianceShrinkage(filtered_stocks[list(ld[
        "cleaned_weights"].keys())[:30]]).ledoit_wolf()
示例#5
0
 def calculate(self, date, universe):
     prices = universe.pricing['price'].unstack()[self.assets].iloc[-self.window:]
     mu = mean_historical_return(prices)
     S = CovarianceShrinkage(prices).ledoit_wolf()
     ef = EfficientFrontier(mu, S)
     weights = ef.min_volatility()
     weights = pd.Series(weights, index=self.assets)
     return weights
示例#6
0
 def __init__(self, prices, risk_free=0.00):
     self.prices = prices
     self.assets = prices.columns
     self.num_of_assets = len(prices.columns)
     self.e_returns = expected_returns.mean_historical_return(prices)
     self.returns = prices.pct_change().dropna()
     self.cum_returns = ((1 + self.returns).cumprod() - 1)
     self.correlation = self.returns.corr('pearson')
     self.covariance = CovarianceShrinkage(prices).ledoit_wolf()
     self.rf = risk_free
    def wf(self,
           train,
           optimizer,
           test,
           test_months,
           annual_risk_free_rate=0.02):
        """Walk-Forward backtesting method

        Args:
            train (pandas.Series): training data
            optimizer (str): portfolio optimizer for PyPortfolioOpt
            test (pandas.Series): test data
            test_months (int): number of testing months
            annual_risk_free_rate (float, optional): annual risk free rate used in calculating Sharpe ratio. Defaults to 0.02.

        Returns:
            [pandas.Series, float]: expected and realised asset performance
        """

        if optimizer == "hrp":
            returns = train.pct_change().dropna()
            hrp = HRPOpt(returns)
            weights = hrp.optimize()
            weights = pd.Series(weights)
            performance = hrp.portfolio_performance(verbose=True)

            realised_annual_return = sum(
                weights *
                ((test.iloc[-1] / test.iloc[0])**(12 / test_months) - 1))
            realised_annual_volatility = sum(
                weights * np.std(test.pct_change().dropna()) * np.sqrt(251))
            realised_sharpe_ratio = (
                realised_annual_return -
                annual_risk_free_rate) / realised_annual_volatility

            return weights, performance, realised_annual_return, realised_annual_volatility, realised_sharpe_ratio
        else:
            mu = mean_historical_return(train)
            S = CovarianceShrinkage(train).ledoit_wolf()
            ef = EfficientFrontier(mu, S)
            weights = ef.max_sharpe(
            ) if optimizer == "msr" else ef.min_volatility()
            weights = pd.Series(weights)
            performance = ef.portfolio_performance()

            realised_annual_return = sum(
                weights *
                ((test.iloc[-1] / test.iloc[0])**(12 / test_months) - 1))
            realised_annual_volatility = sum(
                weights * np.std(test.pct_change().dropna()) * np.sqrt(251))
            realised_sharpe_ratio = (
                realised_annual_return -
                annual_risk_free_rate) / realised_annual_volatility

            return weights, performance, realised_annual_return, realised_annual_volatility, realised_sharpe_ratio
def approximated_max_kelly(data):
    """Find a approximated solution of the portofolio based on kelly criterion."""
    returns_data = data.pct_change().dropna()
    sigma = CovarianceShrinkage(data).shrunk_covariance(delta=1e-2)
    mu = returns_data.mean(axis=0)
    A = 0.5 * sigma
    A = np.hstack((A, np.ones((sigma.shape[0], 1))))
    A = np.vstack((A, np.ones((1, sigma.shape[0] + 1))))
    A[-1, -1] = 0.0
    B = np.hstack((mu, [1]))
    w = np.dot(np.linalg.inv(A), B)
    return pd.DataFrame([w[:-1]], columns=data.columns)
def get_portfolio(universe, df_tr, port_value, cutoff, df_m):
    '''create a portfolio using the stocks from the universe and the closing
    prices from df_tr with a given portfolio value and a weight cutoff value
    using the value of a momemntum indicator to limit the quantity of the stocks'''
    df_t = select_columns(df_tr, universe)
    mu = capm_returns(df_t)
    S = CovarianceShrinkage(df_t).ledoit_wolf()
    # Optimize the portfolio for min volatility
    ef = EfficientFrontier(mu, S)  # Use regularization (gamma=1)
    weights = ef.min_volatility()
    #weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights(cutoff=cutoff)
    # Allocate
    latest_prices = get_latest_prices(df_t)
    da = DiscreteAllocation(cleaned_weights,
                            latest_prices,
                            total_portfolio_value=port_value)
    allocation = da.greedy_portfolio()[0]
    non_trading_cash = da.greedy_portfolio()[1]
    # Put the stocks and the number of shares from the portfolio into a df
    symbol_list = []
    mom = []
    w = []
    num_shares_list = []
    l_price = []
    tot_cash = []
    for symbol, num_shares in allocation.items():
        symbol_list.append(symbol)
        mom.append(df_m[df_m['stock'] == symbol].values[0])
        w.append(round(cleaned_weights[symbol], 4))
        num_shares_list.append(num_shares)
        l_price.append(latest_prices[symbol])
        tot_cash.append(num_shares * latest_prices[symbol])

    df_buy = pd.DataFrame()
    df_buy['stock'] = symbol_list
    df_buy['momentum'] = mom
    df_buy['weights'] = w
    df_buy['shares'] = num_shares_list
    df_buy['price'] = l_price
    df_buy['value'] = tot_cash
    df_buy = df_buy.append(
        {
            'stock': 'CASH',
            'momentum': 0,
            'weights': round(1 - df_buy['weights'].sum(), 4),
            'shares': 1,
            'price': round(non_trading_cash, 2),
            'value': round(non_trading_cash, 2)
        },
        ignore_index=True)
    df_buy = df_buy.set_index('stock')
    return df_buy, non_trading_cash
def get_portfolio_weights(df, clean=False, req_return=0.02):
    """
    Returns the portfolio weights, following Markowitz's
    Modern Portfolio Theory to maximize sharpe ratio.
    """
    mu = mean_historical_return(df)
    S = CovarianceShrinkage(df).ledoit_wolf()
    ef = EfficientFrontier(mu, S)
    weights = ef.max_sharpe(risk_free_rate=req_return)
    if clean:
        weights = ef.clean_weights()
    # weights = _fix_weights(weights)
    return weights
示例#11
0
 def __init__(self, weights, prices, risk_free=0.00):
     self.weights = weights
     self.prices = prices
     self.assets = prices.columns
     self.num_of_assets = len(prices.columns)
     self.returns = prices.pct_change().dropna()
     self.e_returns = expected_returns.mean_historical_return(prices)
     self.allocation = pd.DataFrame.from_dict(self.weights,
                                              orient='index',
                                              columns=['portfolio'])
     self.port_returns = self.returns.dot(self.allocation)
     self.port_cum_returns = ((1 + self.port_returns).cumprod() - 1)
     self.covariance = CovarianceShrinkage(prices).ledoit_wolf()
     self.rf = risk_free
示例#12
0
def assign_strategy(ld: LazyDictionary, algo: str) -> tuple:
    assert ld is not None
    # use of black-litterman is based on https://github.com/robertmartin8/PyPortfolioOpt/blob/master/cookbook/4-Black-Litterman-Allocation.ipynb
    # print(market_prices)
    ld["s"] = CovarianceShrinkage(ld["filtered_stocks"]).ledoit_wolf()
    ld["delta"] = market_implied_risk_aversion(ld["market_prices"])

    # use BlackLitterman model to compute returns - hopefully better estimate of returns than extrapolation of historical prices
    # market_prior = market_implied_prior_returns(ld["market_caps"], delta, ld["s"])
    ld["bl"] = lambda ld: BlackLittermanModel(
        ld["s"],
        pi="market",
        market_caps=ld["market_caps"],
        risk_aversion=abs(ld["delta"]),
        absolute_views={},
    )
    ld["posterior_total_returns"] = lambda ld: ld["bl"].bl_returns()
    ld["posterior_s"] = lambda ld: ld["bl"].bl_cov()
    ld["mu"] = lambda ld: mean_historical_return(ld["filtered_stocks"])
    ld["returns_from_prices"] = lambda ld: returns_from_prices(ld[
        "filtered_stocks"])

    use_bl = ld["returns_by"] != "by_prices"
    kwargs = ({
        "returns": ld["mu"]
    } if use_bl else {
        "returns": ld["posterior_total_returns"]
    })
    if algo != "hrp":
        kwargs["cov_matrix"] = ld["s"] if not use_bl else ld["posterior_s"]
    else:
        # algo is HRP
        kwargs = {"returns": ld["returns_from_prices"]}

    if algo == "hrp":
        ld["title"] = "Hierarchical Risk Parity"
        return (hrp_strategy, kwargs)
    elif algo == "ef-sharpe":
        ld["title"] = "Efficient Frontier - max. sharpe"
        return (ef_sharpe_strategy, kwargs)
    elif algo == "ef-risk":
        ld["title"] = "Efficient Frontier - efficient risk"
        kwargs["target_volatility"] = 5.0
        return (ef_risk_strategy, kwargs)
    elif algo == "ef-minvol":
        ld["title"] = "Efficient Frontier - minimum volatility"
        return (ef_minvol_strategy, kwargs)
    else:
        assert False
def get_result(l):
    data = yf.download(tickers=l,
                       period="max",
                       interval="1d",
                       auto_adjust=True)
    data = data['Close']
    mu = expected_returns.mean_historical_return(data)
    S = CovarianceShrinkage(data).ledoit_wolf()
    ef = EfficientFrontier(mu, S)
    raw_weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    data = []
    for x in cleaned_weights.keys():
        if cleaned_weights[x] != 0:
            data.append({'name': x, 'y': cleaned_weights[x]})
    answer = {'data': data, 'performance': ef.portfolio_performance()}
    return answer
示例#14
0
def construct_price_df():
    dates, ticker_to_closing_prices = get_ticker_to_closing_prices(
        TEST_START_DATE, TEST_END_DATE)

    tickers = ticker_to_closing_prices.keys()
    prices = list(
        zip(*[ticker_to_closing_prices[ticker] for ticker in tickers]))
    df = pd.DataFrame(
        prices,
        index=dates,
        columns=tickers,
    )

    mu = mean_historical_return(df)
    S = CovarianceShrinkage(df).ledoit_wolf()

    ef = EfficientFrontier(mu, S)
    weights = ef.max_sharpe()
    cleaned_weights = ef.clean_weights()
    ef.portfolio_performance(verbose=True)
示例#15
0
def call_portfolios(trading_days, start_time, end_time, test_start_time = "", test_end_time = "", add_index=False):
    
    total_portfolio = []
    portfolio_weights = []
    portfolio_invests = []
    performances = []
    
    # Getting the S&P500 (benchmark)
    sp500 = pdr.DataReader('^GSPC', 'yahoo', start_time, end_time)['Close']
    sp500 = sp500.rename('SP500')
    sp500 = sp500.to_frame()
    
    for i in range(0, len(stock_list.columns)): 
    #for i in range(0, 1):
        
        stock = []
        stock = stock_list.iloc[:,i].tolist() ### !!! Important: change the number to get the portfolio of interest (first one is 50% percentile, etc.)
        stock = [x for x in stock if str(x) != 'nan']
        
        portfolio_name = stock_list.columns[i]
        
        # Getting stock data (maybe re-do to for loop, if there be problems with memory)
        temp = pdr.DataReader(stock, 'yahoo', start_time, end_time)['Close']
        data = sp500.join(temp)
        del temp
        
        # Main dataset with all tickers and without S&P
        stocks = data.drop('SP500', 1)
        
        # Drop stocks where are less than 50% of data points available, if applicable
        if filter_recent_stocks[i]:
            stocks = stocks.loc[:, (stocks.count() >= stocks.count().max()/2)]
        
        risk_free_rate = 0.0085 # !!! Risk-free rate, 10Y US treasury bond, could be adjusted
        weight_bounds = weight_bounds_tuple[i]  # taken from the tuple each iteration, defined at the beginning
        
        # !!! Different approaches could be taken from here
        mu = mean_historical_return(stocks) # Getting returns
        S = CovarianceShrinkage(stocks).ledoit_wolf() # Getting cov matrix
        
        current_weights = [0] * len(stocks.columns)
        
        # Main function to find optimal portfolio, determining optimal weights
        ef = EfficientFrontier(mu, S, weight_bounds=weight_bounds)
        ef.add_objective(objective_functions.transaction_cost, w_prev=current_weights, k=0.005)
        ef.add_objective(objective_functions.L2_reg, gamma=gamma) 
        weights = ef.max_sharpe(risk_free_rate=risk_free_rate) # using max sharpe optimization
        cleaned_weights = ef.clean_weights() # weights with pretty formatting
        print(cleaned_weights)
        
        # Printing info on returns, variance & sharpe
        temp_tuple = ef.portfolio_performance(verbose=True)
        
        temp_dict = {}
        temp_dict['Portfolio'] = portfolio_name
        temp_dict['Return'] = "{:.4f}".format(temp_tuple[0])
        temp_dict['Risk'] = "{:.4f}".format(temp_tuple[1])
        temp_dict['Sharpe'] = "{:.4f}".format(temp_tuple[2])
        performances.append(temp_dict)
        
        # Putting weights into pandas df
        max_sharpe_allocation = pd.DataFrame.from_dict(cleaned_weights, orient='index')
        max_sharpe_allocation.columns =['allocation_weight']    
        
        ### This function would change the weights to a number of shares based on the last price in the observable interval
        latest_prices = get_latest_prices(stocks)
        if add_index == False:
            da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=total_portfolio_value)    
            if discrete_algo_lp[i] == True:
                allocation, leftover = da.lp_portfolio()
            else: allocation, leftover = da.greedy_portfolio()
            
            print(allocation)
            print("Money left: " + str(leftover))
            print(da._allocation_rmse_error())
            
            # Adding discrete allocation to portfolio dataframe
            allocation = pd.DataFrame.from_dict(allocation, orient='index')
            allocation.columns =['allocation_discrete']   
            max_sharpe_allocation = max_sharpe_allocation.join(allocation)
                
            
        # Add some plots
        plot_covariance(S)
        plot_weights(weights)
        
        
        start_of_investment = str(latest_prices.name)
        if add_index == True:
            if np.any(start_of_investment in trading_days.values) ==  True:
                start_of_investment = trading_days[trading_days.index[trading_days == start_of_investment].tolist()[0] + 1]
            
            ### Function to crete a portfolio and test it on the new data
            portfolio, data_new = load_data(max_sharpe_allocation, test_start_time, test_end_time)
            tmp = create_index(test_start_time, test_end_time, start_of_investment, portfolio_name, portfolio, data_new)
            
            # Add all results to list
            total_portfolio.append(tmp[0])
            portfolio_weights.append(tmp[1])
            
            with open(p+'/portfolios/performance_index.txt', 'w') as outFile:
                for d in performances:
                    line =  str(i) + ": " + " ".join([str(key)+' : '+str(value) for key,value in d.items()]) + '\n'
                    outFile.write(line)
            
            
        else:
            if np.any(start_of_investment in trading_days.values) ==  False:
                start_of_investment = trading_days[trading_days.index[trading_days == start_of_investment].tolist()[0] + 1]
        
            portfolio, data_new = load_data(max_sharpe_allocation, test_end_time, test_end_time)
            tmp2 = create_portfolio(start_of_investment, portfolio_name, portfolio, data_new)
            
            # Add all results to list
            portfolio_invests.append(tmp2)
            
            with open(p+'/portfolios/performance_investment.txt', 'w') as outFile:
                for d in performances:
                    line =  str(i) + ": " + " ".join([str(key)+' : '+str(value) for key,value in d.items()]) + '\n'
                    outFile.write(line)
    
        
    return total_portfolio, portfolio_weights, portfolio_invests 
示例#16
0
import pandas as pd
import numpy as np
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt.objective_functions import negative_cvar
from pypfopt.risk_models import CovarianceShrinkage

##Importar série de dados
df = pd.read_excel(r'C:\Users\Jhona\OneDrive\Área de Trabalho\PRBR11.xlsx', index_col='Data')

##Obter os retornos dos ativos
returns = pd.DataFrame()
for i in df:
    returns[i] = df[i].pct_change().dropna()

##Criar a matrix de covariância eficiente
covMatrix = CovarianceShrinkage(df)
e_cov = covMatrix.ledoit_wolf()

##Fronteira
ef = EfficientFrontier(None, e_cov)

##Encontrando o CVaR 95% minimizando 
optimal_weights = ef.custom_objective(negative_cvar, returns)
print(optimal_weights)
示例#17
0
a = tod - d
backtest_type = "wf"

tickers = ['BA', 'AMD', 'AAPL']
start = dt.datetime(2021, 3, 1)
end = dt.datetime(2021, 3, 30)
ohlc = yf.download(tickers, start=start, end=end)
prices = ohlc["Adj Close"].dropna(how="all")
df = prices


from pypfopt.expected_returns import mean_historical_return
from pypfopt.risk_models import CovarianceShrinkage

mu = mean_historical_return(df)
S = CovarianceShrinkage(df).ledoit_wolf()
from pypfopt.efficient_frontier import EfficientFrontier

ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe()
cleaned_weights = ef.clean_weights()
# ef.save_weights_to_file("weights.txt")  # saves to file
print(cleaned_weights)

ef.portfolio_performance(verbose=True);

#####################################################################################
# an example from pyportfolioopt

# if you already have expected returns and risk model
from pypfopt.efficient_frontier import EfficientFrontier
def rebalnce_portfolios():

    p = abspath(getsourcefile(lambda: 0))
    p = p.rsplit('/', 1)[0]
    os.chdir(p)
    print('Working Directory is: %s' % os.getcwd())

    file_path = p + '/results_2015-2019/'  # !!! Editable Folder with files with weights
    start_time = '2015-01-01'  # !!! start date, editable
    end_time = (datetime.today() - timedelta(days=1)).strftime(
        '%Y-%m-%d')  # last day = day before today

    # Lists of files with portfolio weights
    files = [f for f in listdir(file_path) if isfile(join(file_path, f))]
    files = [f for f in files if f.startswith('portfolio_investment')]
    files = [file_path + f for f in files]
    files = sorted(files)

    weight_bounds_tuple = (
        (0.0, 0.1), (0.0, 0.1), (0.0, 0.15), (0.0, 0.05), (0.0, 0.05), (0.01,
                                                                        0.1)
    )  # !!! Weights to be adjusted for every iteration by arbitrary value
    gamma = 0.05

    total_portfolio_value = 20000

    for i in range(0, len(files)):

        portfolio = pd.read_csv(files[i], index_col=0).iloc[:, 0:6]

        tickers = portfolio.iloc[:, 2].tolist(
        )  # tickers inside portfolio (they will be updated)

        # Getting stock data (maybe re-do to for loop, if there be problems with memory)
        temp = pdr.DataReader(tickers, 'yahoo', start_time, end_time)['Close']

        current_weights = portfolio['allocation_weight'].to_list()

        risk_free_rate = 0.0085  # !!! Risk-free rate, 10Y US treasury bond, could be adjusted
        weight_bounds = weight_bounds_tuple[
            i]  # taken from the tuple each iteration, defined at the beginning

        # !!! Different approaches could be taken from here
        mu = mean_historical_return(temp)  # Getting returns
        S = CovarianceShrinkage(temp).ledoit_wolf()  # Getting cov matrix

        # Main function to find optimal portfolio, determining optimal weights
        ef = EfficientFrontier(mu, S, weight_bounds=weight_bounds)
        ef.add_objective(objective_functions.transaction_cost,
                         w_prev=current_weights,
                         k=0.005)
        ef.add_objective(objective_functions.L2_reg, gamma=gamma)
        weights = ef.max_sharpe(
            risk_free_rate=risk_free_rate)  # using max sharpe optimization
        cleaned_weights = ef.clean_weights()  # weights with pretty formatting
        print(cleaned_weights)

        # Printing info on returns, variance & sharpe
        ef.portfolio_performance(verbose=True)

        ### This function would change the weights to a number of shares based on the last price in the observable interval
        latest_prices = get_latest_prices(temp)
        da = DiscreteAllocation(weights,
                                latest_prices,
                                total_portfolio_value=total_portfolio_value)
        allocation, leftover = da.lp_portfolio()
        print(allocation)
        print("Money left: " + str(leftover))
        print(da._allocation_rmse_error())

        allocation = pd.DataFrame.from_dict(allocation, orient='index')
        allocation.columns = ['allocation_discrete']

        weights = pd.DataFrame.from_dict(weights, orient='index')
        weights.columns = ['allocation_weight']

        latest_prices = pd.DataFrame(latest_prices)
        latest_prices.columns = ['buy_price']

        tickers = pd.DataFrame(tickers)
        tickers.columns = ['ticker']
        tickers.index = tickers['ticker']

        result = pd.concat([weights, allocation, tickers, latest_prices],
                           axis=1)

        result['buy_investment'] = result['allocation_discrete'] * result[
            'buy_price']
        result['actual_allocation'] = result['buy_investment'] / result[
            'buy_investment'].sum()

        # Get paths & filenames for saving with replacing old csv files
        n = files[i].split('_')[-1]
        s = file_path + 'portfolio_ticker_' + n

        result.to_csv(s)
    def cv(self,
           back_test_months,
           data,
           optimizer,
           test_months,
           annual_risk_free_rate=0.02):
        """Cross-Validation backtesting method

        Args:
            back_test_months (int): number of backtesting months
            data (pandas.Series): data that includes both training and testing data
            optimizer (str): portfolio optimizer for PyPortfolioOpt
            test_months (int): number of testing months
            annual_risk_free_rate (float, optional): annual risk free rate used in calculating Sharpe ratio. Defaults to 0.02.

        Returns:
            [pandas.Series, float]: expected and realised asset performance
        """

        embargo = np.round_(0.01 * len(data), decimals=0)
        all_weights = np.zeros((back_test_months, np.shape(data)[1]))
        all_realised_annual_return = np.zeros(back_test_months)
        all_realised_annual_volatility = np.zeros(back_test_months)
        all_realised_sharpe_ratio = np.zeros(back_test_months)

        for i in range(back_test_months):

            test_start = i * len(data) / back_test_months
            test_end = test_start + len(data) / back_test_months - 1
            test = data.iloc[int(test_start):int(test_end), :]
            train = data.iloc[np.r_[0:int(test_start),
                                    int(test_end) + int(embargo):len(data)], :]

            if optimizer == "hrp":
                train_returns = train.pct_change().dropna()
                hrp = HRPOpt(train_returns)
                weights = hrp.optimize()
                weights = pd.Series(weights)
                all_weights[i] = weights
                performance = hrp.portfolio_performance(verbose=True)
            else:
                mu = mean_historical_return(train)
                S = CovarianceShrinkage(train).ledoit_wolf()
                ef = EfficientFrontier(mu, S)
                weights = ef.max_sharpe(
                ) if optimizer == "msr" else ef.min_volatility()
                weights = pd.Series(weights)
                all_weights[i] = weights
                performance = ef.portfolio_performance()

            all_realised_annual_return[i] = sum(all_weights[i] * ((test.iloc[
                (len(test) - 1)] / test.iloc[0])**(12 / test_months) - 1))
            all_realised_annual_volatility[i] = sum(
                all_weights[i] * np.std(test.pct_change().dropna()) *
                np.sqrt(251))
            all_realised_sharpe_ratio = (
                all_realised_annual_return[i] -
                annual_risk_free_rate) / all_realised_annual_volatility[i]

        weights = np.mean(all_weights)
        realised_annual_return = np.mean(all_realised_annual_return)
        realised_annual_volatility = np.mean(all_realised_annual_volatility)
        realised_sharpe_ratio = np.mean(all_realised_sharpe_ratio)

        return weights, performance, realised_annual_return, realised_annual_volatility, realised_sharpe_ratio
示例#20
0
def main():

    dashboard = st.sidebar.selectbox('Which Dashboard to open?',
                                     ('All Stocks', 'Strategies', 'Analysis',
                                      'Portfolio', 'Pattern', 'Update Stocks'))
    cursor = connection.cursor()
    if dashboard == 'All Stocks':
        st.title(dashboard)
        print(f'Inside dashboard : {dashboard}')

        cursor.execute('''select symbol from stock''')
        stocks_symbols = cursor.fetchall()
        stocks = [item for t in stocks_symbols for item in t]
        symbol_search = st.sidebar.text_input("Stock name ")
        symbol = st.sidebar.selectbox("Select the Stock", stocks)
        if symbol_search != "":
            symbol = symbol_search
        result = get_quote(symbol)
        #data = json.loads(result['data'][0])
        #df = pd.json_normalize(data['data'])
        st.dataframe(pd.DataFrame(result['data']))

    # elif dashboard == 'Pattern':
    #     stocks= {}
    #     print(f'Inside dashboard : {dashboard}')
    #     st.title(dashboard)
    #     cursor.execute('''select symbol from stock''')
    #     stocks_symbols = cursor.fetchall()
    #     stocks = [item for t in stocks_symbols for item in t]
    #     symbol = st.sidebar.selectbox("Select the Stock",stocks)
    #     df = pd.read_sql("select open,high,low,close,symbol from stock_price where symbol ='"+symbol+"'", connection)
    #     cursor.execute('''select key,name from patterns''')
    #     patterns = cursor.fetchall()
    #     # patterns = [item for t in patterns for item in t]
    #     for pattern in patterns:
    #         pattern_function = getattr(tb,pattern[0])
    #         result = pattern_function(df['Open'],df['High'],df['Low'],df['Close'])
    #         last = result.tail(1).values[0]
    #         if last>0:
    #             st.write("Patter name : "+pattern[1])
    #             st.write("BULLISH")
    #         elif last<0:
    #             st.write("Patter name : "+pattern[1])
    #             st.write("BEARISH")

    elif dashboard == 'Strategies':
        print(f'Inside dashboard : {dashboard}')
        st.title(dashboard)
        cursor.execute('''select name from strategy''')
        strategies = cursor.fetchall()
        strategies = [item for t in strategies for item in t]
        strategy = st.sidebar.selectbox("Select the Strategy", strategies)
        cursor.execute('''select name from sectors''')
        sectors = cursor.fetchall()
        sectors = [item for t in sectors for item in t]
        sector = st.sidebar.selectbox("Select the Sector", sectors)
        if sector == 'All':
            cursor.execute('''select symbol from stock''')
            stocks = cursor.fetchall()
            stock_in_sector = [item for t in stocks for item in t]
        else:
            df = pd.read_csv("nifty Sectors/" + sector + ".csv")
            stock_in_sector = pd.Series(df['Symbol'])
            st.header("Strategy selected: " + strategy)
        if strategy == 'TTM Squeeze':
            if sector != "":
                my_bar = st.progress(0)
                percent_complete = 1
                i = 1
                for stock in stock_in_sector:
                    percent_complete = int((i / len(stock_in_sector)) * 100)
                    i = i + 1
                    df = pd.read_sql(
                        "select * from stock_price where symbol= '" + stock +
                        "'", connection)
                    if df.empty:
                        continue
                # st.dataframe(df)
                #if len(df.squeeze_on.tail()) > 3:
                    if df.iloc[-3]['squeeze_on'] and not df.iloc[-1][
                            'squeeze_on'] and (df.iloc[-1]['OBV'] *
                                               2) > df.iloc[-1]['OBV_EMA']:
                        mess = "{} is coming out of squeezer".format(stock)
                        st.subheader(mess)
                        st.dataframe(
                            df.sort_values(by=['Date'], ascending=False))
                        newdf = df
                        candlestick = go.Candlestick(x=newdf['Date'],
                                                     open=newdf['Open'],
                                                     high=newdf['High'],
                                                     low=newdf['Low'],
                                                     close=newdf['Close'])
                        upper_band = go.Scatter(x=newdf['Date'],
                                                y=newdf['upper_band'],
                                                name='Upper Bollinger Band',
                                                line={'color': 'red'})
                        lower_band = go.Scatter(x=newdf['Date'],
                                                y=newdf['lower_band'],
                                                name='Lower Bollinger Band',
                                                line={'color': 'red'})
                        upper_keltner = go.Scatter(
                            x=newdf['Date'],
                            y=newdf['upper_keltner'],
                            name='Upper Keltner Channel',
                            line={'color': 'blue'})
                        lower_keltner = go.Scatter(
                            x=newdf['Date'],
                            y=newdf['lower_keltner'],
                            name='Lower Keltner Channel',
                            line={'color': 'blue'})
                        OBV = go.Scatter(x=newdf['Date'],
                                         y=newdf['OBV'],
                                         name='On Balace Volume',
                                         line={'color': 'black'})
                        OBV_EMA = go.Scatter(x=newdf['Date'],
                                             y=newdf['OBV_EMA'],
                                             name='On Balace Volume EMA',
                                             line={'color': 'green'})

                        fig_vol = go.Figure(data=[OBV, OBV_EMA])
                        fig = go.Figure(data=[
                            candlestick, upper_band, lower_band, upper_keltner,
                            lower_keltner
                        ])
                        fig.layout.xaxis.type = 'category'
                        fig.layout.xaxis.rangeslider.visible = False
                        first, last = st.beta_columns(2)
                        first.plotly_chart(fig)
                        last.plotly_chart(fig_vol)
                    my_bar.progress(percent_complete)
                    if percent_complete == 100:
                        st.balloons()
        elif strategy == 'On Balance Volume(OBV)':
            if sector != "":
                my_bar = st.progress(0)
                percent_complete = 1
                i = 1
                for stock in stock_in_sector:
                    percent_complete = int((i / len(stock_in_sector)) * 100)
                    i = i + 1
                    df = pd.read_sql(
                        "select * from stock_price where symbol= '" + stock +
                        "'", connection)
                    if df.empty:
                        continue
                    newdf = df
                    if newdf.iloc[-1]['OBV'] > newdf.iloc[-1][
                            'OBV_EMA'] and newdf.iloc[-1]['Close'] > newdf.iloc[
                                -1]['21ema'] and newdf.iloc[-1][
                                    'Close'] > newdf.iloc[-1]['VWAP']:
                        mess = "{}  is above OBV, 20EMA and VWAP ".format(
                            stock)
                        st.subheader(mess)
                        candlestick = go.Candlestick(x=newdf['Date'],
                                                     open=newdf['Open'],
                                                     high=newdf['High'],
                                                     low=newdf['Low'],
                                                     close=newdf['Close'])
                        OBV = go.Scatter(x=newdf['Date'],
                                         y=newdf['OBV'],
                                         name='Volume',
                                         line={'color': 'yellow'})
                        OBV_EMA = go.Scatter(x=newdf['Date'],
                                             y=newdf['OBV_EMA'],
                                             name='Volume EMA',
                                             line={'color': 'green'})
                        fig = go.Figure(data=[OBV, OBV_EMA])
                        fig.layout.xaxis.type = 'category'
                        fig.layout.xaxis.rangeslider.visible = False
                        figPrice = go.Figure(data=[candlestick])
                        figPrice.layout.xaxis.type = 'category'
                        figPrice.layout.xaxis.rangeslider.visible = False
                        first, last = st.beta_columns(2)
                        first.plotly_chart(fig)
                        last.plotly_chart(figPrice)

                        my_bar.progress(percent_complete)
                if percent_complete == 100:
                    st.balloons()
        elif strategy == 'SuperTrend':
            if sector != "":
                my_bar = st.progress(0)
                percent_complete = 1
                i = 1
                for stock in stock_in_sector[:3]:
                    st.subheader(stock)
                    percent_complete = int((i / len(stock_in_sector)) * 100)
                    i = i + 1
                    df = pd.read_sql(
                        "select * from stock_price where symbol= '" + stock +
                        "'", connection)
                    if df.empty:
                        continue
                    df = supertrend.run_supertrend(df, 10, 3)
                    df['in_uptrend'] = True
                    for current in range(1, len(df.Close)):
                        previous = current - 1

                        if df['Close'][current] > df['upperband'][previous]:
                            df['in_uptrend'][current] = True
                        elif df['Close'][current] < df['Lowerband'][previous]:
                            df['in_uptrend'][current] = False
                        else:
                            df['in_uptrend'][current] = df['in_uptrend'][
                                previous]

                            if df['in_uptrend'][current] and df['Lowerband'][
                                    current] < df['Lowerband'][previous]:
                                df['Lowerband'][current] = df['Lowerband'][
                                    previous]

                            if not df['in_uptrend'][
                                    current] and df['upperband'][current] > df[
                                        'upperband'][previous]:
                                df['upperband'][current] = df['upperband'][
                                    previous]

                    candlestick = go.Candlestick(x=df['Date'],
                                                 open=df['Open'],
                                                 high=df['High'],
                                                 low=df['Low'],
                                                 close=df['Close'])
                    upper_band = go.Scatter(x=df['Date'],
                                            y=df['upperband'],
                                            name='Upper  Band',
                                            line={'color': 'red'})
                    lower_band = go.Scatter(x=df['Date'],
                                            y=df['Lowerband'],
                                            name='Lower  Band',
                                            line={'color': 'red'})
                    fig = go.Figure(data=[candlestick, upper_band, lower_band])
                    fig.layout.xaxis.type = 'category'
                    fig.layout.xaxis.rangeslider.visible = False
                    st.plotly_chart(fig)

                    my_bar.progress(percent_complete)
                    if percent_complete == 100:
                        st.balloons()

        elif strategy == 'Support & Resistence':
            if sector != "":
                my_bar = st.progress(0)
                percent_complete = 1
                i = 1
                for stock in stock_in_sector:
                    percent_complete = int((i / len(stock_in_sector)) * 100)
                    i = i + 1
                    df = pd.read_sql(
                        "select * from stock_price where symbol= '" + stock +
                        "'", connection)
                    if df.empty:
                        continue
                    s = np.mean(df['High'] - df['Low'])
                    df['Date'] = pd.to_datetime(df.index)
                    df['Date'] = df['Date'].apply(mpl_dates.date2num)
                    df = df.loc[:, ['Date', 'Open', 'High', 'Low', 'Close']]

                    def isFarFromLevel(l):
                        return np.sum([abs(l - x) < s for x in levels]) == 0

                    levels = []

                    def isSupport(df, i):
                        support = df['Low'][i] < df['Low'][
                            i - 1] and df['Low'][i] < df['Low'][
                                i + 1] and df['Low'][i + 1] < df['Low'][
                                    i + 2] and df['Low'][i - 1] < df['Low'][i -
                                                                            2]

                        return support

                    def isResistance(df, i):
                        resistance = df['High'][i] > df['High'][i - 1] and df[
                            'High'][i] > df['High'][i + 1] and df['High'][
                                i + 1] > df['High'][i + 2] and df['High'][
                                    i - 1] > df['High'][i - 2]

                        return resistance

                    for i in range(2, df.shape[0] - 2):
                        if isSupport(df, i):
                            l = df['Low'][i]

                            if isFarFromLevel(l):
                                levels.append((i, l))

                        elif isResistance(df, i):
                            l = df['High'][i]

                            if isFarFromLevel(l):
                                levels.append((i, l))

        elif strategy == 'Breakout':
            if sector != "":
                my_bar = st.progress(0)
                percent_complete = 1
                i = 1

                def is_consolidating(df, percentage=2):
                    recent_candlesticks = df[-15:]

                    max_close = recent_candlesticks['Close'].max()
                    min_close = recent_candlesticks['Close'].min()

                    threshold = 1 - (percentage / 100)
                    if min_close > (max_close * threshold):
                        return True

                    return False

                def is_breaking_out(df, percentage=2.5):
                    last_close = df[-1:]['Close'].values[0]

                    if is_consolidating(df[:-1], percentage=percentage):
                        recent_closes = df[-16:-1]

                        if last_close > recent_closes['Close'].max():
                            return True

                    return False

                percentage = st.slider('Slide me to select percentage',
                                       min_value=1,
                                       max_value=10)

                for stock in stock_in_sector:
                    percent_complete = int((i / len(stock_in_sector)) * 100)
                    i = i + 1
                    df = pd.read_sql(
                        "select * from stock_price where symbol= '" + stock +
                        "'", connection)
                    if df.empty:
                        continue
                    if is_breaking_out(df, percentage):
                        newdf = df
                        st.subheader(f'{stock} is breaking out...')
                        candlestick = go.Candlestick(x=newdf['Date'],
                                                     open=newdf['Open'],
                                                     high=newdf['High'],
                                                     low=newdf['Low'],
                                                     close=newdf['Close'])
                        OBV = go.Scatter(x=newdf['Date'],
                                         y=newdf['OBV'],
                                         name='On Balace Volume',
                                         line={'color': 'black'})
                        OBV_EMA = go.Scatter(x=newdf['Date'],
                                             y=newdf['OBV_EMA'],
                                             name='On Balace Volume EMA',
                                             line={'color': 'green'})
                        fig_vol = go.Figure(data=[OBV, OBV_EMA])
                        fig = go.Figure(data=[candlestick])
                        fig.layout.xaxis.type = 'category'
                        fig.layout.xaxis.rangeslider.visible = False
                        first, last = st.beta_columns(2)
                        first.plotly_chart(fig)
                        last.plotly_chart(fig_vol)

                    my_bar.progress(percent_complete)
                    if percent_complete == 100:
                        st.balloons()

    elif dashboard == 'Portfolio':
        print(f'Inside dashboard : {dashboard}')
        st.title(dashboard)
        cursor.execute('''select name from sectors''')
        sectors = cursor.fetchall()
        sectors = [item for t in sectors for item in t]
        sector = st.sidebar.selectbox("Select the Sector", sectors)
        alldf = pd.read_sql("select * from stock_price", connection)
        if sector == 'All':
            cursor.execute('''select symbol from stock''')
            stocks = cursor.fetchall()
            stock_in_sector = [item for t in stocks for item in t]
            alldf = alldf.loc[alldf['Symbol'].isin(stock_in_sector)]
        else:
            df = pd.read_csv("nifty Sectors/" + sector + ".csv")
            alldf = alldf.loc[alldf['Symbol'].isin(df['Symbol'])]

        #alldf = alldf.set_index(pd.DatetimeIndex(df['Date'].values))
        #alldf.drop(columns = ['Date'], axis =1, inplace=True)
        assets = alldf.Symbol.unique()
        alldf = alldf.set_index('Date')
        alldf = alldf.pivot_table(index='Date',
                                  columns=['Symbol'],
                                  values='Close')
        alldf = alldf.set_index(pd.DatetimeIndex(alldf.index.values))
        alldf = alldf.dropna(axis=1)
        #medals.reindex_axis(['Gold', 'Silver', 'Bronze'], axis=1)
        st.subheader("Stocks")
        st.write(alldf)
        #mu = expected_returns.mean_historical_return(alldf)
        #s = risk_models.sample_cov(alldf)
        span = st.slider('Slide me to select span', min_value=1, max_value=500)
        mu = expected_returns.ema_historical_return(alldf, span=span)
        st.subheader("Returns")
        st.write(mu)
        s = CovarianceShrinkage(alldf).shrunk_covariance()
        ef = EfficientFrontier(mu, s)
        weight = ef.max_sharpe()
        clean_weight = ef.clean_weights()
        expectedreturn, volatility, Sharperatio = ef.portfolio_performance(
            verbose=False)
        st.subheader("Expected annual return: " +
                     str(round(expectedreturn, 2) * 100) + '%')
        st.subheader("Annual volatility: " + str(round(volatility, 2) * 100) +
                     '%')
        st.subheader("Sharpe Ratio: " + str(round(Sharperatio, 2)))
        funds = st.slider('PortFolio Value:',
                          min_value=50000,
                          max_value=500000)
        latest_prices = get_latest_prices(alldf)
        weights = clean_weight

        da = DiscreteAllocation(weights,
                                latest_prices,
                                total_portfolio_value=funds)
        allocation, leftover = da.lp_portfolio()
        st.subheader("Weight")
        st.write(pd.DataFrame(weights, columns=weights.keys(), index=[0]))
        st.subheader("Discreate Allocation")
        st.write(pd.DataFrame(allocation, columns=allocation.keys(),
                              index=[0]))
        st.subheader("Funds Reamaning:" + str(round(leftover, 2)))

    elif dashboard == 'Update Stocks':
        print(f'Inside dashboard : {dashboard}')
        st.title(dashboard)
        icon('update')
        if st.button('Update Tables'):
            status = nse.updateTableList(connection)
            if status == 'Success':
                st.balloons()
        if st.button('Update Stocks Price'):
            status = update_stock.updateStockPrice(st, connection)
            if status == 'Success':
                st.balloons()
        if st.button('Create Stocks Tables'):
            status = update_stock.updateTables(connection)
            if status == 'Success':
                st.balloons()
示例#21
0
#           "FB", "AAPL", "COST", "WMT", "KR", "JPM",
#           "BAC", "HSBC"]

# portfolio = combine_stocks(stocks)

# portfolio.to_csv("portfolio.csv", index=False)

portfolio = pd.read_csv("portfolio.csv")
print(portfolio.head())

from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt.expected_returns import mean_historical_return
from pypfopt.risk_models import CovarianceShrinkage

mu = mean_historical_return(portfolio)
S = CovarianceShrinkage(portfolio).ledoit_wolf()

ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe()

cleaned_weights = ef.clean_weights()
print(dict(cleaned_weights))

ef.portfolio_performance(verbose=True)

from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices

latest_prices = get_latest_prices(portfolio)

da = DiscreteAllocation(cleaned_weights,
                        latest_prices,
df_m = df_m.sort_values(by='momentum', ascending=False)
if len(df_m[(df_m['momentum'] > minimum_momentum - 0.5 * dev) & (
        df_m['momentum'] < minimum_momentum + 1.9 * dev)]) < portfolio_size:
    df_m = df_m.head(portfolio_size)
else:
    df_m = df_m[(df_m['momentum'] > minimum_momentum - 0.5 * dev) & (
        df_m['momentum'] < minimum_momentum + 1.9 * dev)].head(portfolio_size)
# Set the universe to the top momentum stocks for the period
universe = df_m['stock'].tolist()
# Create a df with just the stocks from the universe
df_t = select_columns(df_tr, universe)

# -----Χαρτοφυλάκιο Νο1 γενικό
# Calculate portofolio mu and S
mu = capm_returns(df_t)
S = CovarianceShrinkage(df_t).ledoit_wolf()
# Optimise the portfolio for maximal Sharpe ratio
ef = EfficientFrontier(mu, S)  # Use regularization (gamma=1)
weights = ef.min_volatility()
cleaned_weights = ef.clean_weights(cutoff=cutoff, rounding=3)
ef.portfolio_performance()

st.subheader('Βελτιστοποιημένο Χαρτοφυλάκιο')
st.write(
    'Το προτεινόμενο χαρτοφυλάκιο από τις ιστορικές τιμές των επιλεγμένων μετοχών έχει τα παρακάτω χαρακτηριστικά'
)
st.write('Αρχική Αξία Χαρτοφυλακίου : ' + str(port_value) + '€')
st.write('Sharpe Ratio: ' + str(round(ef.portfolio_performance()[2], 2)))
st.write('Απόδοση Χαρτοφυλακίου: ' +
         str(round(ef.portfolio_performance()[0] * 100, 2)) + '%')
st.write('Μεταβλητότητα Χαρτοφυλακίου: ' +
示例#23
0
response = table.scan(FilterExpression=Attr('date').gt(prev))
items = response['Items']
while 'LastEvaluatedKey' in response:
    response = table.scan(ExclusiveStartKey=response['LastEvaluatedKey'])
    items.extend(response['Items'])
dfitems = pd.DataFrame(items, columns=['code', 'date', 'price'])

f = dfitems.drop_duplicates(subset=['date', 'code'], keep='last')
filtered = dfitems.pivot(index='date', columns='code', values='price')

cols = filtered.columns
filtered[cols] = filtered[cols].apply(pd.to_numeric, errors='coerce')
filtered = filtered.dropna()
print(filtered)
mu = mean_historical_return(filtered)
S = CovarianceShrinkage(filtered).ledoit_wolf()
ef = EfficientFrontier(mu, S)
max_sharpe = ef.max_sharpe()
max_sharpe_performance = ef.portfolio_performance()

minVolFrontier = EfficientFrontier(mu, S)
min_volatility = minVolFrontier.min_volatility()
min_vol_performance = minVolFrontier.portfolio_performance()

print(max_sharpe_performance, "MAX SHARPE PERFORMANCE")
print(min_vol_performance, "MIN VOL PERFORMANCE")

addModelPrediction("max_sharpe_ratio", max_sharpe_performance[2],
                   max_sharpe_performance[0], max_sharpe_performance[1],
                   max_sharpe)
addModelPrediction("min_volatility", min_vol_performance[2],
示例#24
0
def portfolio_all(df):

    coins = ['ripple','bitcoin','ethereum','litecoin','iota','bitcoin_cash']
    #coins = ['bitcoin']

    stocks = df.dropna()[coins]

    log_ret = np.log(stocks/stocks.shift(1))

    np.random.seed(42)
    num_ports = 6000
    all_weights = np.zeros((num_ports, len(stocks.columns)))
    ret_arr = np.zeros(num_ports)
    vol_arr = np.zeros(num_ports)
    sharpe_arr = np.zeros(num_ports)

    for x in range(num_ports):
        # Weights
        weights = np.array(np.random.random(len(stocks.columns)))
        weights = weights/np.sum(weights)

        # Save weights
        all_weights[x,:] = weights

        # Expected return
        ret_arr[x] = np.sum( (log_ret.mean() * weights * int(252)))

        # Expected volatility
        vol_arr[x] = np.sqrt(np.dot(weights.T, np.dot(log_ret.cov()*int(252), weights)))

        # Sharpe Ratio
        sharpe_arr[x] = ret_arr[x]/vol_arr[x]

    max_sr_ret = ret_arr[sharpe_arr.argmax()]
    max_sr_vol = vol_arr[sharpe_arr.argmax()]
    logging.info(vol_arr)
    logging.info(ret_arr)

    fig = go.Figure(data=go.Scatter(x=vol_arr, y=ret_arr,
        mode='markers',
        marker=dict(
            size=8,
            color=sharpe_arr, #set color equal to a variable
            colorscale='Viridis', # one of plotly colorscales
            showscale=True
        )
    ))

    fig.add_trace(
        go.Scatter(
            mode='markers',
            x=[max_sr_vol],
            y=[max_sr_ret],
            marker=dict(
                color='Red',
                size=10
            ),
            showlegend=False
        )
    )

    logging.info("Saving portfolio graph...")
    plio.write_html(fig,'/appdata/portgraphstatic.html', include_plotlyjs=True)

    logging.info("Getting portfolio info")
    mu = mean_historical_return(stocks,frequency=int(252))
    S = CovarianceShrinkage(stocks).ledoit_wolf()

    ef = EfficientFrontier(mu, S)
    weights = ef.max_sharpe()
    logging.info(weights)
    perf = ef.portfolio_performance(verbose=True)
    portinfo={'weights':weights, 'performance':{'Return':perf[0],'Volatility':perf[1],'Sharpe Ratio':perf[2]}}
    logging.info(type(portinfo))
    with open('/appdata/portinfo.json', 'w') as f:
        json.dump(portinfo, f)
示例#25
0
        plt.xlabel('Year', fontsize=14)
        plt.grid(which="major", color='k', linestyle='-.', linewidth=0.5)
        plt.show()

    #plot()
    return data


df = multi_stock()

from pypfopt.expected_returns import mean_historical_return
from pypfopt.risk_models import CovarianceShrinkage

mu = mean_historical_return(
    df)  # pandas series of estimated expected returns for each asset
S = CovarianceShrinkage(df).ledoit_wolf()  #estimated covariance matrix
print(mu)
print(S)

# define a loop to iterate through all the different objective functions
from pypfopt import objective_functions as objfunc

print()
print('max sharpe')
from pypfopt.efficient_frontier import EfficientFrontier
ef = EfficientFrontier(mu, S)
ef.add_objective(
    objfunc.L2_reg,
    gamma=0.1)  # incentivize optimizer to choose non zero  weights
weights = ef.max_sharpe()
x = ef.portfolio_performance(verbose=True)
    def port_rets(cls, list):
        global weightedreturns
        global Stock_data_frames
        global Portfolio
        global Portfolio_returns
        cls.weight = list
        #Create panel for stocks returns
        cls.Stock_data_frames = pd.concat(FinancialInfo.frames, axis=1)
        cls.Stock_data_frames.dropna(inplace=True)

        #Create panel for stocks' close price
        cls.Stock_close_prices = pd.concat(FinancialInfo.prices, axis=1)
        cls.Stock_close_prices.dropna(inplace=True)

        # Compute the annualized average historical return
        cls.mean_returns_avg = mean_historical_return(cls.Stock_close_prices,
                                                      frequency=252)

        # Calculate the portfolio annual simple return
        cls.simple_returns_annual = np.sum(
            cls.Stock_data_frames.mean() * cls.weight) * 252
        # Calculate the log returns

        cls.log_returns = np.log(cls.Stock_close_prices /
                                 cls.Stock_close_prices.shift(1))
        cls.log_returns.dropna(inplace=True)

        # Calculate the annualized log returns and covariance
        cls.log_returns_annualized = cls.log_returns.mean() * 252
        cls.log_returns_covariance = cls.log_returns.cov() * 252

        #Create panel for stocks return multipled by their weights in portfolio
        cls.weightedreturns = FinancialInfo.Stock_data_frames.mul(
            FinancialInfo.weight, axis=1)

        cls.cummulativereturns = (
            (1 + FinancialInfo.weightedreturns.sum(axis=1)).cumprod() - 1)
        # cummulativereturns = weightedreturns.sum(axis = 1)
        portfolio_weights_ew = np.repeat(1 / FinancialInfo.num_stocks,
                                         FinancialInfo.num_stocks)
        # cummulativereturns_ew = FinancialInfo.Stock_data_frames.iloc[:,0:FinancialInfo.num_stocks].mul(portfolio_weights_ew, axis = 1).sum(axis =1)

        # FinancialInfo.cummulativereturns.plot(color = 'Red')
        # cummulativereturns_ew.plot(color = 'Blue')

        #Calculate portfolio volatility
        cls.cov_mat = FinancialInfo.Stock_data_frames.cov()
        cls.cov_mat_annual = cls.cov_mat * 252
        cls.portfolio_weights = np.array(FinancialInfo.weight)
        cls.portfolio_volatility = np.sqrt(
            np.dot(cls.portfolio_weights.T,
                   np.dot(cls.cov_mat_annual, cls.portfolio_weights)))
        # print (f'The volatility of this portfoliois:  {portfolio_volatility}')
        FinancialInfo.vol_list.append(cls.portfolio_volatility)
        cls.pfvol = pd.DataFrame(FinancialInfo.vol_list)

        # Create the covariance shrinkage instance variable
        cls.cov_shrinkage = CovarianceShrinkage(cls.Stock_close_prices)
        cls.e_cov = cls.cov_shrinkage.ledoit_wolf()

        #Create the sum of returns of portfolio's stocks
        cls.Portfolio_returns = FinancialInfo.weightedreturns.sum(axis=1,
                                                                  skipna=True)
        cls.Portfolio = pd.DataFrame(data=cls.Portfolio_returns,
                                     columns=['Portfolio'])
        cls.Portfolio.drop(cls.Portfolio.index[0], inplace=True)

        # Annualized portfolio volatility 30-day windows
        cls.returns_windowed = cls.Portfolio_returns.rolling(30)
        cls.volatility_series = cls.returns_windowed.std() * np.sqrt(252)

        #Create a total accmulative returns
        cls.total_returns = cls.Portfolio_returns.sum()

        #Calculate sharpe ratio
        cls.Portfolio_sharpe = (cls.total_returns - FinancialInfo.risk_free
                                ) / cls.portfolio_volatility
        # print (f'The total returns for this portfolio is: {total_returns}')
        FinancialInfo.returns_list.append(cls.total_returns)
        cls.pfreturns = pd.DataFrame(FinancialInfo.returns_list)
        FinancialInfo.sharpe_list.append(cls.Portfolio_sharpe)
        cls.pfsharpe = pd.DataFrame(FinancialInfo.sharpe_list)

        #Create a dataframe with total returns, sharpe ratio, and volatility
        FinancialInfo.wList.append(cls.weight)
        cls.df = pd.DataFrame(np.array(FinancialInfo.wList),
                              columns=FinancialInfo.symbol_list)
        cls.df.insert(FinancialInfo.num_stocks, 'Returns', cls.pfreturns)
        cls.df.insert(FinancialInfo.num_stocks + 1, 'Volatility', cls.pfvol)
        cls.df.insert(FinancialInfo.num_stocks + 2, 'Sharpe', cls.pfsharpe)

        #Sorting the dataframe by Sharpe ratio
        cls.df_sorted = cls.df.sort_values(by=['Sharpe'], ascending=False)
        cls.MSR_weights = cls.df_sorted.iloc[0, 0:FinancialInfo.num_stocks]
        cls.MSR_weights_array = np.array(cls.MSR_weights)
        cls.MSRreturns = FinancialInfo.Stock_data_frames.iloc[:,
                                                              0:FinancialInfo.
                                                              num_stocks].mul(
                                                                  cls.
                                                                  MSR_weights_array,
                                                                  axis=1).sum(
                                                                      axis=1)
        # cls.MSRreturns.plot(color = 'Orange')

        #Sorting the dataframe by volatility
        cls.df_vol_sorted = cls.df.sort_values(by=['Volatility'],
                                               ascending=True)
        cls.GMV_weights = cls.df_vol_sorted.iloc[0, 0:FinancialInfo.num_stocks]
        cls.GMV_weights_array = np.array(cls.GMV_weights)
        cls.GMVreturns = FinancialInfo.Stock_data_frames.iloc[:,
                                                              0:FinancialInfo.
                                                              num_stocks].mul(
                                                                  cls.
                                                                  GMV_weights_array,
                                                                  axis=1).sum(
                                                                      axis=1)
weightsmo = st.sidebar.checkbox(
    'Επιλεγμένο επιλέγει τον υπολογισμό των βαρών με βάση τον μέγιστο Sharpe Ratio αλλιώς με την ελάχιστη διακύμανση.',
    value=True)
allocmo = st.sidebar.checkbox(
    'Επιλεγμένο επιλέγει τον υπολογισμό του μοντέλου του greedy_portfolio αλλιώς επιλέγει το lp_portfolio.',
    value=True)
cutoff = st.sidebar.slider(
    'Ελάχιστο Ποσοστό Συμμετοχής μιας Μετοχής στο Χαρτοφυλάκιο.', 0.01, 0.30,
    0.10)

c1, c2, c3, c4 = st.beta_columns((1, 1, 1, 1))
#-----Χαρτοφυλάκιο Νο1 γενικό
#Calculate portofolio mu and S
mu = expected_returns.mean_historical_return(df_t)
if riskmo:
    S = CovarianceShrinkage(df_t).ledoit_wolf()
else:
    S = risk_models.sample_cov(df_t)
# Optimise the portfolio
ef = EfficientFrontier(mu, S, gamma=2)  # Use regularization (gamma=1)
if weightsmo:
    weights = ef.max_sharpe()
else:
    weights = ef.min_volatility()
cleaned_weights = ef.clean_weights(cutoff=cutoff, rounding=3)
ef.portfolio_performance()

c1.subheader('Χαρτοφυλάκιο Νο1')
c1.write(
    'Το προτινόμενο χαρτοφυλάκιο από τις ιστορικές τιμές των επιλεγμένων μετοχών έχει τα παρακάτω χαρακτηριστικά'
)
    def next(self):
        # Pass counter_period days to compute return
        if self.counter < self.counter_period:
            self.counter += 1
        else:
            # Get data to dataframe in order to feed Pyopt
            appended_data = []
            for i, d in enumerate(self.datas):
                dt, dn = self.datetime.date(), d._name
                get = lambda mydata: mydata.get(0, self.counter_period)
                time = [d.num2date(x) for x in get(d.datetime)]
                df = pd.DataFrame({dn: get(d.close)}, index=time)
                appended_data.append(df)
            df = pd.concat(appended_data,
                           axis=1)  # df is dataframe of n assets

            for i, d in enumerate(self.datas):
                dt, dn = self.datetime.date(), d._name
                if d.close[0] > self.inds[d]['sma_50'][0] and self.inds[d][
                        'sma_50'][0] > self.inds[d]['sma_200']:
                    if dn in self.selected_assets:
                        pass
                    else:
                        self.selected_assets.append(dn)
                else:
                    if dn in self.selected_assets:
                        self.selected_assets.remove(dn)

            # Create dataframe of selected_assets portfolio
            portfolio_today = df[self.selected_assets]

            # Because there are some days having no assets in portfolio may cause error
            if strategy == 'Risk_parity':
                x_t = [0.25, 0.25, 0.25, 0.25]

                cons = ({
                    'type': 'eq',
                    'fun': total_weight_constraint
                }, {
                    'type': 'ineq',
                    'fun': long_only_constraint
                })

                res = minimize(risk_budget_objective,
                               w0,
                               args=[V, x_t],
                               method='SLSQP',
                               constraints=cons,
                               options={'disp': True})

                w_rb = np.asmatrix(res.x)
            elif strategy == 'M_Max_sharpe':
                try:
                    mu = mean_historical_return(portfolio_today)
                    S = CovarianceShrinkage(portfolio_today).ledoit_wolf()
                    ef = EfficientFrontier(mu, S)
                    weights = ef.max_sharpe()
                    cleaned_weights = ef.clean_weights()

                    # Rebalance monthly
                    if self.day_counter % 24 == 0:
                        for key, value in cleaned_weights.items():
                            self.order_target_percent(key, target=value)
                            print(
                                'on {} asset of portfolio is {} with value {}'.
                                format(self.datetime.date(), key, value))
                    self.day_counter += 1
                except:
                    pass
# In[75]:

# The average historical return is usually available as a proxy for expected returns, but is not always accurate--a more
# thorough estimate of expected returns requires an assumption about the return distribution, which we'll discuss in the context
# of Loss Distributions later in the course.

# In[76]:

df4.head(10)

# In[77]:

# Import the CovarianceShrinkage object, it reduces/shrinks the errors/residuals while calculating the covariance matrix

# Create the CovarianceShrinkage instance variable
cs = CovarianceShrinkage(df4)

# In[78]:

# Difference in calculating covariance matrix through covariance shrinkage and through sample cov() method
# Compute the sample covariance matrix of returns
sample_cov = df4.pct_change().cov() * 252

# Compute the efficient covariance matrix of returns
e_cov = cs.ledoit_wolf()

# Display both the sample covariance_matrix and the efficient e_cov estimate
print("Sample Covariance Matrix\n", sample_cov, "\n")
print("Efficient Covariance Matrix\n", e_cov, "\n")

# In[79]:
# path2 = r"D:\TimerSeriesAnalysis\AMZN.csv"
path2 = r"D:\TimerSeriesAnalysis"
with changepath(path2):
    df = pd.read_csv("AMZN.csv", parse_dates=True, index_col="Date")

# Compute the annualized average historical return
mu = mean_historical_return(assets, frequency=252)

# Plot the annualized average historical return
plt.plot(mu, linestyle='None', marker='o')
plt.show()

# Create the CovarianceShrinkage instance variable
# this is bette, because it shrinks the errors, and give annualized covariance
cs = CovarianceShrinkage(assets).ledoit_wolf()

# Compute the sample covariance matrix of returns
sample_covariance = assets.pct_change().cov() * 252

# Create the EfficientFrontier instance variable
ef = EfficientFrontier(mu, cs)

# Compute the Weights portfolio that maximises the Sharpe ratio
weights = ef.max_sharpe()

# clean_weights() method truncates tiny weights to zero and rounds others
cw = ef.clean_weights()

with changepath(path):
    ef.save_weights_to_file("weights.txt")  # saves to file