Variating portfolio by different categories¶

In [1]:
%load_ext autoreload
%autoreload 2
from import_src import *

from collections import OrderedDict

# TODO: import the portfolio for a single source

large_us_stocks = OrderedDict({"VTI": 0.5, "VTV": 0.285, "VNQ (REIT)": 0.215})

large_exus_stocks = OrderedDict({"EAFE": 1.0})

small_us_stocks = OrderedDict({"IJS": 1.0})

small_exus_stocks = OrderedDict({"EAFE Small-Cap": 1.0})

bonds = OrderedDict({"BND": 1.0})

fund_shares = [large_us_stocks, large_exus_stocks, small_us_stocks, small_exus_stocks, bonds]

Variate portfolio by Stock/Bond ratio¶

In [2]:
from src.domain.distribution import *
from src.distribution import create_distributions_from
from src.display.distribution import display_distributions

default_distribution = SharesDistribution(
    categories=SharesCategoriesDistribution(
        by_type=dict(zip((ShareType.Stock, ShareType.Bond), (0.75, 0.25))),
        by_region=dict(zip((Region.US, Region.ExUS), (0.7, 0.3))),
        by_cap=dict(zip((Cap.Large, Cap.Small), (0.6, 0.4))),
        by_term=dict(zip((Term.Long,), (1,))),
    ),
    shares=[FundsDistribution(x) for x in fund_shares],
)


def modify_distrib_by_type_ratio(distrib: SharesDistribution, stock_rate: float):
    if distrib.categories:
        bond_rate = 1 - stock_rate
        distrib.categories.by_type[ShareType.Stock] = stock_rate
        distrib.categories.by_type[ShareType.Bond] = bond_rate


distributions_rates = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
distributions_names = [f"{round(x * 100)}/{round((1 - x) * 100)}" for x in distributions_rates]
distributions = create_distributions_from(default_distribution, modify_distrib_by_type_ratio, distributions_rates)

display_distributions(distributions, names=distributions_names)
0/100 10/90 20/80 30/70 40/60 50/50 60/40 70/30 80/20 90/10 100/0
VTI 0.0% 2.1% 4.2% 6.3% 8.4% 10.5% 12.6% 14.7% 16.8% 18.9% 21.0%
VTV 0.0% 1.2% 2.39% 3.59% 4.79% 5.98% 7.18% 8.38% 9.58% 10.77% 11.97%
VNQ (REIT) 0.0% 0.9% 1.81% 2.71% 3.61% 4.51% 5.42% 6.32% 7.22% 8.13% 9.03%
EAFE 0.0% 1.8% 3.6% 5.4% 7.2% 9.0% 10.8% 12.6% 14.4% 16.2% 18.0%
IJS 0.0% 2.8% 5.6% 8.4% 11.2% 14.0% 16.8% 19.6% 22.4% 25.2% 28.0%
EAFE Small-Cap 0.0% 1.2% 2.4% 3.6% 4.8% 6.0% 7.2% 8.4% 9.6% 10.8% 12.0%
BND 100.0% 90.0% 80.0% 70.0% 60.0% 50.0% 40.0% 30.0% 20.0% 10.0% 0.0%
- - - - - - - - - - - -
Mean ret. 5.12 5.7 6.27 6.81 7.33 7.83 8.31 8.76 9.18 9.59 9.96
Std 3.69 3.71 4.3 5.27 6.46 7.76 9.13 10.54 11.97 13.42 14.89

Variate portfolio by Cap size ratio¶

In [3]:
from src.domain import *
from src.distribution import create_distributions_from
from src.display.distribution import display_distributions

default_distribution = SharesDistribution(
    categories=SharesCategoriesDistribution(
        by_type=dict(zip((ShareType.Stock, ShareType.Bond), (1, 0))),
        by_region=dict(zip((Region.US, Region.ExUS), (0.7, 0.3))),
        by_cap=dict(zip((Cap.Large, Cap.Small), (0.7, 0.3))),
        by_term=dict(zip((Term.Long,), (1,))),
    ),
    shares=[FundsDistribution(x) for x in fund_shares],
)


def modify_distrib_by_cap_ratio(distrib: SharesDistribution, large_cap: float):
    if distrib.categories:
        small_cap = 1 - large_cap
        distrib.categories.by_cap[Cap.Large] = large_cap
        distrib.categories.by_cap[Cap.Small] = small_cap


distributions_rates = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
distributions_names = [f"{round(x * 100)}/{round((1 - x) * 100)}" for x in distributions_rates]
distributions = create_distributions_from(default_distribution, modify_distrib_by_cap_ratio, distributions_rates)

display_distributions(distributions, names=distributions_names)
0/100 10/90 20/80 30/70 40/60 50/50 60/40 70/30 80/20 90/10 100/0
VTI 0.0% 3.5% 7.0% 10.5% 14.0% 17.5% 21.0% 24.5% 28.0% 31.5% 35.0%
VTV 0.0% 1.99% 3.99% 5.98% 7.98% 9.97% 11.97% 13.96% 15.96% 17.95% 19.95%
VNQ (REIT) 0.0% 1.5% 3.01% 4.51% 6.02% 7.52% 9.03% 10.53% 12.04% 13.54% 15.05%
EAFE 0.0% 3.0% 6.0% 9.0% 12.0% 15.0% 18.0% 21.0% 24.0% 27.0% 30.0%
IJS 70.0% 63.0% 56.0% 49.0% 42.0% 35.0% 28.0% 21.0% 14.0% 7.0% 0.0%
EAFE Small-Cap 30.0% 27.0% 24.0% 21.0% 18.0% 15.0% 12.0% 9.0% 6.0% 3.0% 0.0%
BND 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0%
- - - - - - - - - - - -
Mean ret. 10.96 10.81 10.65 10.49 10.32 10.14 9.96 9.78 9.58 9.39 9.18
Std 16.83 16.44 16.08 15.74 15.43 15.14 14.89 14.67 14.48 14.32 14.2

Variate portfolio by Region ratio¶

In [4]:
from src.domain.distribution import *
from src.distribution import create_distributions_from
from src.display.distribution import display_distributions

default_distribution = SharesDistribution(
    categories=SharesCategoriesDistribution(
        by_type=dict(zip((ShareType.Stock, ShareType.Bond), (1, 0))),
        by_region=dict(zip((Region.US, Region.ExUS), (0.7, 0.3))),
        by_cap=dict(zip((Cap.Large, Cap.Small), (0.6, 0.4))),
        by_term=dict(zip((Term.Long,), (1,))),
    ),
    shares=[FundsDistribution(x) for x in fund_shares],
)


def modify_distrib_by_region_ratio(distrib: SharesDistribution, us_rate: float):
    if distrib.categories:
        exUs_rate = 1 - us_rate
        distrib.categories.by_region[Region.US] = us_rate
        distrib.categories.by_region[Region.ExUS] = exUs_rate


distributions_rates = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]
distributions_names = [f"{round(x * 100)}/{round((1 - x) * 100)}" for x in distributions_rates]
distributions = create_distributions_from(default_distribution, modify_distrib_by_region_ratio, distributions_rates)

display_distributions(distributions, names=distributions_names)
0/100 10/90 20/80 30/70 40/60 50/50 60/40 70/30 80/20 90/10 100/0
VTI 0.0% 3.0% 6.0% 9.0% 12.0% 15.0% 18.0% 21.0% 24.0% 27.0% 30.0%
VTV 0.0% 1.71% 3.42% 5.13% 6.84% 8.55% 10.26% 11.97% 13.68% 15.39% 17.1%
VNQ (REIT) 0.0% 1.29% 2.58% 3.87% 5.16% 6.45% 7.74% 9.03% 10.32% 11.61% 12.9%
EAFE 60.0% 54.0% 48.0% 42.0% 36.0% 30.0% 24.0% 18.0% 12.0% 6.0% 0.0%
IJS 0.0% 4.0% 8.0% 12.0% 16.0% 20.0% 24.0% 28.0% 32.0% 36.0% 40.0%
EAFE Small-Cap 40.0% 36.0% 32.0% 28.0% 24.0% 20.0% 16.0% 12.0% 8.0% 4.0% 0.0%
BND 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 0.0%
- - - - - - - - - - - -
Mean ret. 6.45 6.98 7.5 8.01 8.51 9.0 9.49 9.96 10.43 10.89 11.34
Std 15.82 15.5 15.24 15.04 14.9 14.83 14.83 14.89 15.02 15.21 15.46