연속 최적화로 포트폴리오를 풀어 보자.

소개



연속 최적화로 포트폴리오를 풀어 보자.
  • 3개의 유명 상표(A,B,C)에 대해 각각 365개의 데이터가 있습니다.
  • 각 유명 상표 사이에는 상관 관계가 있습니다.
  • 오늘의 구입 가격은, 모두 99엔으로 합니다.
  • 위험을 최소화하는 포트폴리오 (종목 비율)를 찾아 보겠습니다
  • 수수료는 무시합니다.

  • 사고방식



    365개의 데이터를 365개의 시나리오로 설정합니다.
    구입한 유명 상표를 판매할 때 365가지 판매 가격이 될 수 있다고 가정합니다.
    일반적인 위험은 편차를 보지만, 그렇게 하면 비선형이 되고 해결하기가 어렵습니다.
    여기에서는 시나리오에서 최악의 경우의 반환을 극대화하는 것을 고려합니다.

    파이썬에서 실행해보십시오.



    먼저 난수 데이터를 만듭니다.

    python3
    %matplotlib inline
    import numpy as np, matplotlib.pyplot as plt
    from pulp import *
    from ortoolpy import addvars
    plt.rcParams['figure.figsize'] = 16, 4
    plt.rcParams['font.family'] = 'IPAexGothic'
    N = 365
    np.random.seed(1)
    # 乱数でデータ作成
    a = np.random.multivariate_normal([100, 100, 100],
        [[1, 0.5, -0.5],[0.5, 1, 0.2], [-0.5, -0.1, 1]], N)
    a.mean(axis=0)
    >>>
    array([  99.99327092,  100.06971451,  100.03864796])
    

    평균을 보면 작지만 유명 상표 B가 가장 높습니다.
    상관관계를 살펴보자.

    python3
    plt.subplot(131)
    plt.title('銘柄間の相関(A-B)')
    plt.scatter(a[:, 0], a[:, 1])
    plt.subplot(132)
    plt.title('銘柄間の相関(A-C)')
    plt.scatter(a[:, 0], a[:, 2])
    plt.subplot(133)
    plt.title('銘柄間の相関(B-C)')
    plt.scatter(a[:, 1], a[:, 2]);
    


  • A와 B는 양의 상관 관계
  • A와 C는 음의 상관 관계
  • B와 C는 거의 상관되지 않습니다

  • 최적화 문제를 해결하는 함수 solve를 정의합니다.
    별도 확인해, 임계치(최악 케이스의 보증치)의 최대는, 98.58이었습니다.
    그 때의 결과를 보자.

    python3
    def solve(a, th):
        m = LpProblem()
        x = addvars(3)
        m += lpSum(x) == 1
        for e in a * np.array(x):
            m += lpSum(e) >= th
        m.solve()
        return m.status, [value(i) for i in x]
    r = solve(a, 98.58)
    r
    >>>
    (1, [0.4815265, 0.00026221562, 0.51821129])
    

    첫 번째는 "최적 솔루션"을, 다음 배열은 각 주식의 구매 비율을 나타냅니다.

    평균은 B가 높기 때문에 B만 구매하는 경우(수익 최대)와 방금 해결한 케이스(최소 최대)의 시나리오별 히스토그램을 살펴보겠습니다.

    python3
    plt.rcParams['figure.figsize'] = 6, 4
    plt.title('目的別の利益のヒストグラム')
    plt.hist(a.dot([0,1,0]), bins=12, range=(97, 103), alpha=0.5, label='収益最大')
    plt.hist(a.dot(r[1]), bins=12, range=(97, 103), alpha=0.5, label='最小最大')
    plt.legend();
    



    1종목만 구입하는 것보다, 역상관의 종목을 조합하는 것이, 값 움직임의 편차를 억제할 수 있습니다.

    그래프에서 보더라도 "최소 최대"케이스에서 분포의 폭이 작아지는 것을 알 수 있습니다.

    임계값을 변경했을 때의 포트폴리오도 살펴보겠습니다.

    python3
    x = np.linspace(97, 98.58, 10)
    y = np.array([solve(a, th)[1] for th in x])
    plt.title('しきい値の変化に対する割合')
    plt.plot(x, y)
    plt.legend(['A','B','C']);
    



    평균적으로 보면 B가 최상이므로 위험을 무시하면 B만이 최상입니다.
    위험을 최대한으로 평가하면 A와 C가 역 상관이므로 A와 C를 조합하는 것이 좋습니다.
    이와 같이 B의 비율이 1에서 0까지 변화하고 있는 것을 알 수 있습니다.

    이상

    좋은 웹페이지 즐겨찾기