In [1]:
import numpy as np
import matplotlib.pyplot as plt
In [2]:
# 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
In [3]:
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))
In [4]:
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]]
In [5]:
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]]
In [6]:
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")