import numpy as np
import matplotlib.pyplot as plt
# Algorithm: universal portfolio
# Input: a sequence of market vectors X_{i,t}, i from m assets, t from n periods
# Output: Krichevsky-Trofimov mixture forecaster to build universal portfolio
def log_wealth_factor_rebalance(Q, X):
# m, n = np.shape(X)
# Nsim, m = np.shape(Q)
lnW = np.log(np.matmul(Q, X))
lnWcum = np.cumsum(lnW, axis = 1)
return lnWcum
def universal_portfolio(X, Nsim = 1e5):
m, n = np.shape(X)
alpha = 0.5 * np.ones(m)
Q = np.random.dirichlet(alpha, int(Nsim))
lnWcum = log_wealth_factor_rebalance(Q, X)
P_un_normalized = np.matmul(np.transpose(Q), np.exp(lnWcum-np.log(Nsim)))
norm_Const = np.sum(np.exp(lnWcum-np.log(Nsim)), axis = 0, keepdims=True)
return P_un_normalized/norm_Const
# Algorithm: exponentiated gradient portfolio
def expGrad_portfolio(X, eta = 0.1):
m, n = np.shape(X)
P = np.ones((m, n+1))/m
for t in range(n):
w = np.sum(P[:, t]*X[:, t])
P_un_normalized = P[:, t]*np.exp(eta*X[:, t]/w)
P[:, t+1] = P_un_normalized/np.sum(P_un_normalized)
return P
m, n = 20, 20
# X = np.exp(np.random.normal(0,0.25,size=(m, n)))
X = np.random.uniform(0.1,2,size=(m, n))
Q_UP = universal_portfolio(X, Nsim=1e6)
print(Q_UP)
[[0.05358333 0.05386971 0.05324782 0.0546439 0.05044583 0.0508351 0.0555285 0.05412654 0.05572843 0.05969239 0.0547849 0.05031963 0.0486998 0.05070765 0.05194647 0.05249798 0.05151254 0.0536416 0.04959511 0.04940863] [0.04706959 0.04862282 0.04659059 0.0462117 0.04919089 0.04568242 0.04615195 0.04731384 0.04710579 0.04969403 0.0491533 0.04805424 0.04942334 0.04967831 0.0522896 0.05319649 0.05048379 0.04966273 0.04982016 0.04836016] [0.05525134 0.05608737 0.05716099 0.05981118 0.05990668 0.05436343 0.05441673 0.05249108 0.05344123 0.05197062 0.05049635 0.05217363 0.05104338 0.04840713 0.04519029 0.04820485 0.04646317 0.04676606 0.04746325 0.04776729] [0.04720704 0.04537094 0.04207271 0.04038839 0.0413559 0.04269035 0.04138228 0.03957036 0.03690617 0.03622926 0.0354121 0.03778773 0.0375808 0.03566734 0.03690601 0.03532943 0.03678188 0.03654419 0.03744014 0.03840182] [0.04805939 0.05002027 0.05239279 0.05620013 0.05330014 0.05347435 0.05448904 0.05185124 0.05434385 0.05023561 0.04912711 0.04662004 0.0439649 0.0419747 0.0427956 0.04225669 0.03955497 0.04077544 0.03887494 0.04102799] [0.05335607 0.05335161 0.04883674 0.0514175 0.05341479 0.0543525 0.05412791 0.05379566 0.05444774 0.05677924 0.05993105 0.05945407 0.06129184 0.06650283 0.06886348 0.07399304 0.07754658 0.07488462 0.07977743 0.07547997] [0.05466265 0.05027032 0.05236832 0.04855538 0.04998162 0.05355581 0.05588578 0.05814635 0.05609513 0.05162108 0.05578547 0.06032708 0.06326051 0.06924708 0.06579128 0.06374793 0.0643988 0.06438153 0.06632349 0.0608427 ] [0.04765343 0.04984367 0.04919998 0.05026697 0.04668932 0.04728435 0.04679482 0.04965174 0.05069534 0.0535623 0.05434512 0.05053777 0.05035864 0.05433344 0.05486887 0.05129253 0.05294565 0.05140612 0.04712467 0.04538918] [0.04603706 0.04457173 0.04336749 0.04049463 0.04182661 0.04270559 0.04466347 0.04379469 0.04556944 0.04274543 0.04506205 0.04212302 0.03925783 0.03672455 0.03581516 0.03601909 0.03426304 0.03350482 0.03353443 0.03299953] [0.05296541 0.05325775 0.05166813 0.04763076 0.04758724 0.04946042 0.04668305 0.04803441 0.04855522 0.05141334 0.04782989 0.04767266 0.04666861 0.04574114 0.04614058 0.04869099 0.04602964 0.04569697 0.04334677 0.04726265] [0.04965929 0.04944861 0.05015208 0.04642114 0.04691909 0.04777167 0.04837264 0.04859136 0.05085364 0.05296266 0.0576932 0.06305542 0.06311639 0.06126169 0.06204761 0.05812535 0.05469527 0.05241303 0.05324552 0.05292545] [0.04719314 0.04423355 0.04544249 0.04833245 0.04747764 0.05055134 0.05053319 0.04767094 0.0490344 0.04874667 0.04676228 0.04951296 0.05149748 0.05424941 0.05015509 0.05181223 0.04866212 0.05059933 0.05160716 0.05311292] [0.04669759 0.04441381 0.04336944 0.04392623 0.04423621 0.04166354 0.04045077 0.04309701 0.04006743 0.04014681 0.03808382 0.03607926 0.03399736 0.03359258 0.03419279 0.03287626 0.0314311 0.0320916 0.03105142 0.02968054] [0.04933056 0.05208559 0.05199415 0.0557571 0.05625356 0.05134032 0.04846715 0.04618653 0.04829703 0.04599894 0.0492003 0.05380918 0.05598042 0.05130923 0.05056833 0.05306503 0.05140269 0.04910847 0.05013478 0.0502028 ] [0.04848283 0.04943529 0.05161008 0.05183244 0.0551057 0.05360802 0.05674368 0.05747484 0.05299704 0.04921475 0.05188963 0.05505615 0.05395669 0.05361116 0.05732539 0.05384199 0.05748383 0.06043852 0.06246692 0.06358656] [0.04633495 0.04775843 0.04437547 0.04278781 0.04209878 0.04310596 0.041418 0.04244567 0.04033974 0.03932266 0.03739053 0.03519075 0.03648673 0.03547681 0.0347505 0.03572721 0.03764336 0.03929097 0.03984489 0.04041731] [0.04612967 0.04640461 0.0472908 0.04529953 0.04722985 0.04391853 0.04342563 0.04190999 0.04282892 0.04280442 0.04435154 0.04122728 0.04063971 0.03920811 0.04145233 0.04251355 0.04254182 0.0436933 0.04051354 0.04015502] [0.0543329 0.05718162 0.06003188 0.05823481 0.05378511 0.05772215 0.06245499 0.06468664 0.06721258 0.06624122 0.06449217 0.06043617 0.06336096 0.06732444 0.06202493 0.06646394 0.06968753 0.06743041 0.07033275 0.07192613] [0.0518355 0.05190538 0.05432477 0.0569145 0.05707682 0.06007518 0.05540938 0.05957509 0.05591162 0.05830267 0.05737214 0.05802779 0.05814314 0.05748528 0.06070238 0.05698278 0.06099846 0.06238099 0.06437333 0.06665404] [0.05415825 0.05186689 0.05450327 0.05487345 0.05611822 0.05583898 0.05260105 0.04958601 0.04956926 0.05231589 0.05083704 0.05253518 0.05127149 0.04749714 0.04617331 0.04336263 0.04547378 0.04528931 0.04312929 0.04439931]]
Q_EG = expGrad_portfolio(X, eta = np.power(n, -0.5))
print(Q_EG)
[[0.05 0.0590545 0.05957238 0.05768062 0.06074799 0.05045877 0.05112722 0.06354867 0.05966428 0.06373659 0.07448579 0.06157452 0.05013604 0.04596597 0.05010834 0.05318897 0.05444586 0.0515772 0.05740086 0.04771258 0.04726896] [0.05 0.04287675 0.04654831 0.04161425 0.04039652 0.0480342 0.03964226 0.04033657 0.04284625 0.04205667 0.04819332 0.04659209 0.04339156 0.04612752 0.04584984 0.05283036 0.05463852 0.04811072 0.04614391 0.04580369 0.04230949] [0.05 0.06403233 0.06600216 0.06852004 0.0752254 0.07511275 0.06102928 0.06066427 0.05549551 0.05773128 0.05375843 0.04973672 0.0532484 0.0502631 0.0438836 0.03660167 0.04381203 0.03952029 0.04022374 0.04128044 0.04206263] [0.05 0.04305672 0.03876366 0.03173538 0.02808098 0.0302162 0.03300406 0.02999529 0.02625766 0.0212713 0.01988847 0.01834012 0.02264872 0.02211281 0.01864754 0.02108172 0.01811665 0.02052786 0.02012513 0.02151131 0.02342842] [0.05 0.04488936 0.04960851 0.05525411 0.06497215 0.05743318 0.05738683 0.05949999 0.0528505 0.05909348 0.04916015 0.04617004 0.04008918 0.03437303 0.03002021 0.03174578 0.03045286 0.02515191 0.02782532 0.02402826 0.02884419] [0.05 0.0580419 0.05776225 0.04725003 0.05338312 0.05868551 0.06075583 0.05964159 0.05843695 0.05973616 0.06558255 0.07369094 0.07167728 0.0759351 0.08847188 0.09507568 0.10941815 0.11819147 0.1107774 0.1228241 0.11081959] [0.05 0.06213533 0.05142745 0.05662791 0.04727317 0.05097423 0.06091964 0.06699938 0.07315187 0.06724693 0.05562378 0.06752526 0.08076507 0.08897883 0.10576106 0.0947673 0.08814936 0.08940524 0.08923037 0.0942569 0.07858144] [0.05 0.04383578 0.04915512 0.04729614 0.04945177 0.04118525 0.04228582 0.04081719 0.04770085 0.04995046 0.05708809 0.05849209 0.04897402 0.04815611 0.05701692 0.05840889 0.04980218 0.05334743 0.04964733 0.04039264 0.0364207 ] [0.05 0.04062574 0.03717282 0.03428549 0.02828678 0.03132012 0.03307931 0.03730578 0.03517169 0.03909148 0.03277331 0.03821819 0.03175504 0.0260346 0.02124241 0.01953173 0.01973832 0.01661701 0.01534149 0.01517856 0.01427033] [0.05 0.05720957 0.05768671 0.05353646 0.04411492 0.0439356 0.04849983 0.04187604 0.04504395 0.04594212 0.05307896 0.04436231 0.04337333 0.04083305 0.03832251 0.03919454 0.04508626 0.03903083 0.03823583 0.03312519 0.04329894] [0.05 0.0482112 0.04750888 0.04883871 0.04043436 0.04156312 0.04336634 0.04447695 0.04478541 0.05003544 0.05492406 0.06749144 0.08169284 0.08129105 0.07561106 0.07766349 0.06730068 0.05872577 0.05299464 0.05433264 0.05334933] [0.05 0.04285151 0.03628018 0.03875952 0.04540441 0.04326143 0.05093125 0.05044289 0.04360456 0.04667767 0.04555826 0.04075107 0.04687169 0.05125252 0.05693722 0.04712134 0.05092359 0.04366901 0.04859383 0.05043286 0.0543255 ] [0.05 0.04204078 0.03684914 0.03431543 0.03521564 0.03588128 0.03025405 0.02757095 0.03325286 0.02705616 0.0270167 0.02294086 0.01919687 0.01580371 0.01491975 0.01602384 0.01384392 0.01177309 0.01284452 0.01127565 0.00947004] [0.05 0.04774998 0.05465357 0.05404386 0.06348273 0.06457591 0.05243639 0.04543298 0.04001347 0.04493442 0.03947513 0.04727449 0.05911042 0.0643596 0.05272531 0.05074695 0.05714186 0.05244365 0.04670281 0.04869762 0.04885431] [0.05 0.04564379 0.04778162 0.05285555 0.05295106 0.06171857 0.05744304 0.06513795 0.06664004 0.05579807 0.04669728 0.05334743 0.06113143 0.05803435 0.05616164 0.06662876 0.05739034 0.06643513 0.07511583 0.07970343 0.08265602] [0.05 0.04112121 0.044423 0.03681574 0.03312508 0.03158136 0.03359478 0.02984421 0.03191498 0.02750929 0.02532354 0.02160891 0.01767175 0.01972269 0.01783395 0.01662159 0.01818117 0.02141443 0.02482552 0.02552722 0.02675043] [0.05 0.04075766 0.04125045 0.04298177 0.0382747 0.04304059 0.03543953 0.03404531 0.03067643 0.03247267 0.03211797 0.03547398 0.02897628 0.02754755 0.02446851 0.02949153 0.0315361 0.03116609 0.03380586 0.02750336 0.02672578] [0.05 0.06111134 0.06870179 0.07621348 0.07109381 0.05957673 0.07057173 0.08403452 0.09014838 0.0972603 0.09391389 0.0882741 0.07660897 0.0840179 0.09388784 0.07926469 0.09200362 0.10020815 0.09383662 0.10053865 0.10505293] [0.05 0.05414023 0.05412081 0.06002108 0.06633239 0.06649962 0.07436292 0.06262575 0.07397643 0.06435607 0.07057917 0.06743204 0.06826873 0.06806445 0.06556896 0.07464864 0.06478116 0.07512139 0.07916089 0.08328662 0.08988948] [0.05 0.0606143 0.05473119 0.06135444 0.06175302 0.06494558 0.0638699 0.05570373 0.04836792 0.04804345 0.05476115 0.0507034 0.05441239 0.05112606 0.04256145 0.03936254 0.03323738 0.03756332 0.03716811 0.03258828 0.03562149]]
Q_RB = np.ones((m, n))/m
logW = lambda Q, X : np.cumsum(np.log(np.sum(Q * X, axis = 0)))
plt.plot(range(n), logW(Q_RB, X), label='ReB')
plt.plot(range(n), logW(Q_EG[:,0:n], X), label='ExpGrad')
plt.plot(range(n), logW(Q_UP, X), label='UnivPort')
plt.legend()
plt.savefig("Lecture-4-Portfolios.pdf")