从功能+循环制作清单

时间:2019-03-25 16:08:05

标签: python

这是整个代码:我想做一个循环,每次我都从输入文件中跳过另外一行。

将熊猫作为pd导入
    将numpy导入为np     导入matplotlib.pyplot作为plt     将seaborn导入为sns     进口数量     导入scipy.optimize为sco     从pandas.plotting导入register_matplotlib_converters     register_matplotlib_converters()

mylist=[]

for i in range(0,4):
    table = pd.read_excel(r"Priser.xlsx",skiprows=i,usecols="b,c,d,e,f,g,h,i,j,k,l,m,n,o,p")
    table1 = np.array(table.values)

    returns = np.log(table) - np.log(table.shift(1))
    mean_returns = returns.mean()
    cov_matrix = returns.cov()
    num_portfolios = 1
    risk_free_rate = 0.0178

    def portfolio_annualised_performance(weights, mean_returns, cov_matrix):
        returns = np.sum(mean_returns*weights ) *252
        std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252)
        return std, returns

    def random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate):
        results = np.zeros((3,num_portfolios))
        weights_record = []
        for i in range(num_portfolios):
            weights = np.random.random(15)
            weights /= np.sum(weights)
            weights_record.append(weights)
            portfolio_std_dev, portfolio_return = portfolio_annualised_performance(weights, mean_returns, cov_matrix)
            results[0,i] = portfolio_std_dev
            results[1,i] = portfolio_return
            results[2,i] = (portfolio_return - risk_free_rate) / portfolio_std_dev
        return results, weights_record


    def neg_sharpe_ratio(weights, mean_returns, cov_matrix, risk_free_rate):
        p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, cov_matrix)
        return -(p_ret - risk_free_rate) / p_var

    def max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate):
        num_assets = len(mean_returns)
        args = (mean_returns, cov_matrix, risk_free_rate)
        constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
        bound = (0.0,1.0)
        bounds = tuple(bound for asset in range(num_assets))
        result = sco.minimize(neg_sharpe_ratio, num_assets*[1./num_assets,], args=args,
                            method='SLSQP', bounds=bounds, constraints=constraints)
        return result

    def portfolio_volatility(weights, mean_returns, cov_matrix):
        return portfolio_annualised_performance(weights, mean_returns, cov_matrix)[0]

    def min_variance(mean_returns, cov_matrix):
        num_assets = len(mean_returns)
        args = (mean_returns, cov_matrix)
        constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
        bound = (0.0,0.15)
        bounds = tuple(bound for asset in range(num_assets))

        result = sco.minimize(portfolio_volatility, num_assets*[1./num_assets,], args=args,
                            method='SLSQP', bounds=bounds, constraints=constraints)

        return result

    def efficient_return(mean_returns, cov_matrix, target):
        num_assets = len(mean_returns)
        args = (mean_returns, cov_matrix)

        def portfolio_return(weights):
            return portfolio_annualised_performance(weights, mean_returns, cov_matrix)[1]

        constraints = ({'type': 'eq', 'fun': lambda x: portfolio_return(x) - target},
                    {'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
        bounds = tuple((0,1) for asset in range(num_assets))
        result = sco.minimize(portfolio_volatility, num_assets*[1./num_assets,], args=args, method='SLSQP', bounds=bounds, constraints=constraints)
        return result


    def efficient_frontier(mean_returns, cov_matrix, returns_range):
        efficients = []
        for ret in returns_range:
            efficients.append(efficient_return(mean_returns, cov_matrix, ret))
        return efficients

    def display_calculated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate):
        results, _ = random_portfolios(num_portfolios,mean_returns, cov_matrix, risk_free_rate)

        max_sharpe = max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate)
        sdp, rp = portfolio_annualised_performance(max_sharpe['x'], mean_returns, cov_matrix)
        max_sharpe_allocation = pd.DataFrame(max_sharpe.x,index=table.columns,columns=['allocation'])
        max_sharpe_allocation.allocation = [round(i*100,2)for i in max_sharpe_allocation.allocation]
        max_sharpe_allocation = max_sharpe_allocation.T

        min_vol = min_variance(mean_returns, cov_matrix)
        sdp_min, rp_min = portfolio_annualised_performance(min_vol['x'], mean_returns, cov_matrix)
        min_vol_allocation = pd.DataFrame(min_vol.x,columns=['allocation'])
        min_vol_allocation.allocation = [round(i*100,2)for i in min_vol_allocation.allocation]
        min_vol_allocation = min_vol_allocation.T


        print (min_vol_allocation)
        mylist.append(min_vol_allocation)


        plt.figure(figsize=(10, 7))
        plt.scatter(results[0,:],results[1,:],c=results[2,:],cmap='YlGnBu', marker='o', s=10, alpha=0.3)
        plt.colorbar()
        plt.scatter(sdp,rp,marker='*',color='r',s=500, label='Maximum Sharpe ratio')
        plt.scatter(sdp_min,rp_min,marker='*',color='g',s=500, label='Minimum volatility')

        target = np.linspace(rp_min, 0.32, 50)
        efficient_portfolios = efficient_frontier(mean_returns, cov_matrix, target)
        plt.plot([p['fun'] for p in efficient_portfolios], target, linestyle='-.', color='black', label='efficient frontier')
        plt.title('Calculated Portfolio Optimization based on Efficient Frontier')
        plt.xlabel('annualised volatility')
        plt.ylabel('annualised returns')
        plt.legend(labelspacing=0.8)




display_calculated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate)

这将提供以下输出:

                 0     1     2    3     4      5     6     7     8     9     10    11    12    13   14
allocation  0.0  3.51  0.15  2.4  0.59  12.58  6.04  15.0  8.55  3.63  2.55  15.0  15.0  15.0  0.0

             0     1     2    3     4      5     6     7     8     9     10    11    12    13   14
allocation  0.0  3.51  0.15  2.4  0.59  12.58  6.04  15.0  8.55  3.63  2.55  15.0  15.0  15.0  0.0

             0     1     2    3     4      5     6     7     8     9     10    11    12    13   14
allocation  0.0  3.51  0.15  2.4  0.59  12.58  6.04  15.0  8.55  3.63  2.55  15.0  15.0  15.0  0.0

当代码循环运行时,我想将分配中的所有值保存到列表中。我不知道如何使用append函数。

2 个答案:

答案 0 :(得分:0)

我不确定您的问题100%。但是,您是否正在寻找类似的东西?

empty_list = []
# However you get each element in the z()
# say you calculate each element named as 'elem'
empty_list.append(elem)
# do this for each element

答案 1 :(得分:0)

我认为您的问题归结为在错误的时间做事。您当前的代码结构非常奇怪,函数定义位于一个循环中(因此它们会不断重新定义),但仅在循环结束后才调用:

my_list = []

for x in whatever():
    def foo(arg):
        my_list.append(arg)

foo(x)

那没有多大意义。该函数不依赖于x,该调用仅在最后一个x值(以及该函数的最后一个定义,那部分无关紧要,因为每个定义都相同)的情况下发生。 / p>

您应该重新安排事情。在循环外定义所有函数,然后从循环内调用它们:

my_list = []

def foo(arg):
    mylist.append(arg)

for x in whatever():
    foo(x)

这将为每个foo获得的值调用x(仅定义一次!)。该函数将每个追加到my_list(这非常简化,您的真实代码将进行大量处理,然后追加结果)。请注意,具有执行功能的功能可能并不理想。函数return的结果可能更有意义,然后让调用代码决定如何处理它。这种设计可以让您使用列表推导或map函数。