基于蒙特卡洛随机最优化的投资组合模型

from numpy import *
import scipy.optimize as sco
import pandas as pd
import matplotlib.pyplot as plt
from tqdm import *
import numpy as np
import cufflinks as cf
cf.set_config_file(
    offline=True,
    dimensions=((900, 400)),
    theme='ggplot')
import plotly.express as px
px.defaults.width = 1000
px.defaults.height = 800
import warnings
warnings.filterwarnings('ignore')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

r = np.array([0.28, 0.21, 0.23, 0.25])
p = np.array([0.01, 0.02, 0.045, 0.065])
c = r - p
q = np.array([0.025, 0.015, 0.055, 0.026])

def rate_sharp(weights):
    returns = weights * c
    risk = [weights] * q
    # print(returns.flatten())
    # returns = returns.flatten()
    # risk = risk.flatten()
    norisk = 0.05
    # print(risk)
    sharp = (returns.sum() - norisk)/max(risk.flatten())
    # print(sharp)
    return -sharp

def main():
    weights_history = []
    sharp_history = []
    returns_history = []
    risk_history = []
    opt_sharp_history = []
    opt_weights_history = []
    numofasset = len(r)
    for i in tqdm(range(10000)):
        weights = np.random.dirichlet(np.ones(numofasset), size=1)
        weights = array(weights)
        cons = ({'type': 'eq', 'fun': lambda x: sum(x * (1 + p)) - 1})
        bnds = np.asarray([[0,1],[0,1],[0,1],[0,1]])
        # 用最优化module求解最大夏普比率,opt_sharpe(目标函数, 入参, 优化方法, 边界条件, 约束条件)
        opt_sharpe = sco.minimize(rate_sharp, weights, method='SLSQP',
                                  bounds=bnds, constraints=cons, options={'maxiter':1000})
        opt_sharp_history.append(-opt_sharpe.fun)
        opt_weights = opt_sharpe.x
        returns = opt_weights * c
        risk = [opt_weights] * q
        returns_history.append(returns.sum())
        risk_history.append(max(risk.flatten()))
        opt_weights_history.append(opt_sharpe.x)
        sharp_history.append(rate_sharp(weights.flatten()))
    k = np.argmax(array(opt_sharp_history))
    print(opt_sharp_history[k])
    print(returns_history[k],risk_history[k])
    print(opt_weights_history[k])
    ef_port = pd.DataFrame({
        'targetrets': np.array(returns_history).flatten(),
        'targetvols': np.array(risk_history).flatten(),
        'targetsharp': np.array(opt_sharp_history).flatten()
    })
    ef_port.head()
    fig = px.scatter(
        ef_port, x='targetvols', y='targetrets', color='targetsharp',
        labels={'targetrets': '收益率', 'targetvols': '总体风险率',
                'targetsharp': '类夏普比率'},
        title='投资组合蒙特卡洛随机最优'
    ).update_traces(mode='markers', marker=dict(symbol='circle'))
    fig.update_xaxes(showspikes=True)
    fig.update_yaxes(showspikes=True)
    fig.show()
if __name__ == '__main__':
    main()




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值