python投資分析

python投資分析

1. 資產組合的收益與風險

蒐集三支股票不少於100個交易日的收盤價,據此計算其收益率與協方差,
並在此基礎上計算等權重條件下的組合收益與風險。
未做,以下爲例子

import numpy as np


def portstats(ExpReturn, ExpCovariance, PortWts):
    PortRisk = 0
    for i in range(len(PortWts)):
        for j in range(len(PortWts)):
            PortRisk += PortWts[i] * PortWts[j] * ExpCovariance[i * 3 + j]
    PortReturn = np.sum(ExpReturn * np.array(PortWts))
    return np.sqrt(PortRisk), PortReturn


# 組合中每種證券的預期收益率
ExpReturn = [0.000540, 0.000275, 0.000236]
# 組合中證券的協方差矩陣
ExpCovariance = 0.0001 * np.array([5.27, 2.80, 1.74,
                                   2.80, 4.26, 1.67,
                                   1.74, 1.67, 2.90])
ExpCovariance = ExpCovariance.tolist()
# 組合中每種證券的初始權重(初始投資金額)/初始總金額
PortWts = 1.0 / 3 * np.array([1, 1, 1])
PortWts = PortWts.tolist()
# 調用 portstats 函數
PortRisk, PortReturn = portstats(ExpReturn, ExpCovariance, PortWts)
print(PortRisk, PortReturn)
# 計算結果
# 風險(標準差)
# PortRisk = 0.016617
# 組合收益率
# PortReturn = 3.5033e-004

2. 有效前沿與隨機模擬收益

利用之前下載的三支股票的收益率、協方差和相關係數等數據計算該三支股票的
有效前沿並給出其他可行集的收益——風險模擬。
未做,以下爲例子

import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as sco


def frontcon(ExpReturn, ExpCovariance, NumPorts):
    noa = len(ExpReturn)

    def statistics(weights):
        weights = np.array(weights)
        z = np.dot(ExpCovariance, weights)
        x = np.dot(weights, z)
        port_returns = (np.sum(ExpReturn * weights.T))
        port_variance = np.sqrt(x)
        num1 = port_returns / port_variance
        return np.array([port_returns, port_variance, num1])

    # 定義一個函數對方差進行最小化
    def min_variance(weights):
        return statistics(weights)[1]

    bnds = tuple((0, 1) for x in range(noa))
    # 在不同目標收益率水平(target_returns)循環時,最小化的一個約束條件會變化
    target_returns = np.linspace(min(ExpReturn), max(ExpReturn), NumPorts)
    target_variance = []
    PortsWts = []
    for tar in target_returns:
        # 在最優化時採用兩個約束:1.給定目標收益率;2.投資組合權重和爲1
        cons = ({'type': 'eq', 'fun': lambda x: statistics(x)[0] - tar},
                {'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
        res = sco.minimize(min_variance, noa * [1. / noa, ], method='SLSQP', bounds=bnds, constraints=cons)
        target_variance.append(res['fun'])
        PortsWts.append(res['x'])
    target_variance = np.array(target_variance)
    return [target_variance, target_returns, PortsWts]


ExpReturn = np.array([0.00540, 0.00275, 0.00236])
ExpCovariance = 0.0001 * np.array([[5.27, 2.80, 1.74],
                                   [2.80, 4.26, 1.67],
                                   [1.74, 1.67, 2.90]])
NumPorts = 10
[target_variance, target_returns, PortWts] = frontcon(ExpReturn, ExpCovariance, NumPorts)
plt.plot(target_variance, target_returns)
plt.title("Mean-Variance-Efficient Frontier")
plt.xlabel("Risk(Standard Deviation)")
plt.ylabel("Expected Retrun")
plt.show()

3. 單個資產的收益與風險

下載一隻股票不少於100個交易日的收盤價,然後據此計算其收益率和風險。(分別用期望和方差表示)
未做,以下爲例子

# NumAssets = 3       # 資產數量3個
# PVal = 1            # 配置比例,100%表示滿倉配置,若80%,則設PVal=0.8;AssetMin=0各資產最低配置
# # 將各類約束合併到ConSet中
# ConSet = portcons(PVal, NumAssets)


import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as sco

noa = 3
ExpReturn = np.array([0.000540, 0.000275, 0.000236])
ExpCovariance = 0.0001 * np.array([[5.27, 2.80, 1.74],
                                   [2.80, 4.26, 1.67],
                                   [1.74, 1.67, 2.90]])


def statistics(weights):
    weights = np.array(weights)
    z = np.dot(ExpCovariance, weights)
    x = np.dot(weights, z)
    port_returns = (np.sum(ExpReturn * weights.T))
    port_variance = np.sqrt(x)
    # port_variance = np.array(port_variance)
    num1 = port_returns / port_variance
    # arr2 = np.ravel(arr1)
    return np.array([port_returns, port_variance, num1])

# 定義一個函數對方差進行最小化


def min_variance(weights):
    return statistics(weights)[1]


# 在最優化時採用兩個約束:1.給定目標收益率;2.投資組合權重和爲1
bnds = tuple((0, 1) for x in range(noa))
# 在不同目標收益率水平(target_returns)循環時,最小化的一個約束條件會變化
target_returns = np.linspace(min(ExpReturn), max(ExpReturn), 10)
target_variance = []
print(target_returns)
for tar in target_returns:
    cons = ({'type': 'eq', 'fun': lambda x: statistics(x)[0] - tar},
            {'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    res = sco.minimize(min_variance, noa * [1. / noa, ], method='SLSQP', bounds=bnds, constraints=cons)
    target_variance.append(res['fun'])
    print(res['x'])
target_variance = np.array(target_variance)
print(target_variance)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章