Pengoptimalan Portofolio dengan Python dan PyPortfolioOpt

Teori Portofolio Markowitz

Teori portofolio Markowitz (selanjutnya disebut PTM) (Modern portfolio theory) adalah metodologi untuk pembentukan portofolio investasi, yang dikembangkan oleh Harry Markowitz, yang ditujukan pada pilihan aset yang optimal, berdasarkan rasio pengembalian / risiko yang diperlukan. Ide-ide yang dia rumuskan pada tahun 1950-an menjadi dasar teori portofolio modern.





Ketentuan utama teori portofolio dirumuskan oleh Garry Markowitz ketika sedang mempersiapkan disertasi doktoralnya pada tahun 1950-1951.





Kelahiran teori portofolio Markowitz dianggap sebagai artikel β€œSeleksi Portofolio” yang diterbitkan dalam Jurnal Keuangan pada tahun 1952. Di dalamnya, ia pertama kali mengusulkan model matematika untuk pembentukan portofolio optimal dan menyajikan metode untuk membangun portofolio dalam kondisi tertentu. Kelebihan utama Markowitz adalah dalam mengusulkan formalisasi probabilistik dari konsep "profitabilitas" dan "risiko", yang memungkinkan untuk menerjemahkan masalah memilih portofolio optimal ke dalam bahasa matematika formal. Perlu dicatat bahwa selama bertahun-tahun pembuatan teori, Markowitz bekerja di RAND Corp., bersama dengan salah satu pendiri optimasi linier dan nonlinier, George Danzig, dan dia sendiri berpartisipasi dalam memecahkan masalah ini. Oleh karena itu, teori saya sendiri, setelah formalisasi yang diperlukan, cocok dengan arah yang ditunjukkan.





Markowitz terus meningkatkan teorinya dan pada tahun 1959 menerbitkan monografi khusus pertama "Seleksi Portofolio: Diversifikasi Investasi yang Efektif".





Basis model

1.  Portofolio Pengembalian yang Diharapkan





Pengembalian yang diharapkan pada portofolio akan tergantung pada pengembalian yang diharapkan pada setiap aset yang termasuk di dalamnya. Pendekatan ini memungkinkan Anda untuk mengurangi risiko melalui diversifikasi dan pada saat yang sama memaksimalkan pendapatan investor, karena kerugian pada satu investasi akan diimbangi dengan pendapatan pada investasi lainnya.





Pengembalian yang diharapkan atas portofolio adalah total pengembalian yang diharapkan atas sekuritas penyusunnya, yang ditimbang berdasarkan bagiannya dalam portofolio.





E (R_ {p}) = \ sum_ {i = 1} ^ nw_ {i} E (R_ {i})

2. Varians Portofolio





β€” , , . , , , , .





\ sigma_ {p} ^ {2} = \ sum_ {i} ^ {} \ omega_ {i} ^ {2} \ sigma_ {i} ^ {2} + \ sum_ {i} ^ {} \ sum_ {j \ neq i} ^ {} \ omega_ {i} ^ {} \ omega_ {j} ^ {} \ sigma_ {i} ^ {} \ sigma_ {j} ^ {} \ rho_ {ij}

3. (Sharpe Ratio)





\ frac {R_ {p} - R_ {f}} {\ sigma_ {p}}

4.  (The Efficient Frontier)





:





(. Efficient frontier) β€” , . , , , . 1952 .





«», ( ). , , . () , .





, , , ( ) . , .





Python





:





import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pandas_datareader as web
from matplotlib.ticker import FuncFormatter
      
      



PyPortfolioOpt. , .





!pip install PyPortfolioOpt
      
      



:





from pypfopt.efficient_frontier import EfficientFrontier 
from pypfopt import risk_models 
from pypfopt import expected_returns
from pypfopt.cla import CLA
import pypfopt.plotting as pplt
from matplotlib.ticker import FuncFormatter
      
      







, . yahoo.





, β€” .





nullin_df = pd.DataFrame(df_stocks,columns=tickers)
print(nullin_df.isnull().sum())
      
      







. .





# 
mu = expected_returns.mean_historical_return(df_stocks) 
# 
Sigma = risk_models.sample_cov(df_stocks)
#  
ef = EfficientFrontier(mu, Sigma, weight_bounds=(0,1)) #weight bounds in negative allows shorting of stocks
sharpe_pfolio=ef.max_sharpe() #May use add objective to ensure minimum zero weighting to individual stocks
sharpe_pwt=ef.clean_weights()
print(sharpe_pwt)

OrderedDict([('AFLT.ME', 0.0), ('DSKY.ME', 0.22606), ('GMKN.ME', 0.48796), ('IRAO.ME', 0.0), ('LKOH.ME', 0.0), ('MTSS.ME', 0.02953), ('NKNC.ME', 0.25645), ('SBER.ME', 0.0)])
      
      



, weight_bounds=(0,1) weight_bounds=(-1,1), .





.





ef.portfolio_performance(verbose=True)

Expected annual return: 37.1%
Annual volatility: 20.7%
Sharpe Ratio: 1.70
(0.37123023494063007, 0.20717177784552962, 1.695357536597058)
      
      



, :





ef1 = EfficientFrontier(mu, Sigma, weight_bounds=(0,1)) 
minvol=ef1.min_volatility()
minvol_pwt=ef1.clean_weights()
print(minvol_pwt)

OrderedDict([('AFLT.ME', 0.02876), ('DSKY.ME', 0.24503), ('GMKN.ME', 0.10403), ('IRAO.ME', 0.0938), ('LKOH.ME', 0.01168), ('MTSS.ME', 0.41967), ('NKNC.ME', 0.09704), ('SBER.ME', 0.0)])

ef1.portfolio_performance(verbose=True, risk_free_rate = 0.27)

Expected annual return: 24.0%
Annual volatility: 16.9%
Sharpe Ratio: -0.18(0.239915644698749, 0.16885732511472468, -0.17816434839774456)
      
      







.





100 000 .





cl_obj = CLA(mu, Sigma)
ax = pplt.plot_efficient_frontier(cl_obj, showfig = False)
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: '{:.0%}'.format(x)))
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y)))
      
      



:





latest_prices = get_latest_prices(df_stocks)
allocation_minv, rem_minv = DiscreteAllocation(minvol_pwt, latest_prices, total_portfolio_value=100000).lp_portfolio() 
print(allocation_minv)
print("         - {:.2f} ".format(rem_minv))
print()

{'AFLT.ME': 41, 'DSKY.ME': 181, 'IRAO.ME': 1765, 'LKOH.ME': 1, 'MTSS.ME': 127, 'NKNC.ME': 107}
         - 6152.03 
      
      



:





latest_prices1 = get_latest_prices(df_stocks)
allocation_shp, rem_shp = DiscreteAllocation(sharpe_pwt, latest_prices1, total_portfolio_value=100000).lp_portfolio() 
print(allocation_shp)
print("          {:.2f} ".format(rem_shp))

{'DSKY.ME': 167, 'GMKN.ME': 2, 'MTSS.ME': 9, 'NKNC.ME': 283} 
          1319.05 
      
      



167 , 2 , 9 283 . 1319 .





, , .








All Articles