Skip to content

Commit

Permalink
Changed test, changed name of base files, added mean_variance as a pa…
Browse files Browse the repository at this point in the history
…rt of library
  • Loading branch information
Divasco committed Sep 18, 2024
1 parent c4e0373 commit e8cc466
Show file tree
Hide file tree
Showing 13 changed files with 45 additions and 97 deletions.
85 changes: 1 addition & 84 deletions garpar/core/portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,89 +55,6 @@ def _as_float_array(arr):
class Portfolio:
"""
Represents a financial portfolio with utilities for analysis and manipulation.
Attributes
----------
_prices_df : pd.DataFrame
DataFrame containing the prices of the assets.
_weights : np.ndarray
Array of asset weights in the portfolio.
_entropy : np.ndarray
Array of entropy values associated with the assets.
_window_size : int or None
Window size for rolling calculations, if applicable.
_metadata : Bunch
Additional metadata related to the portfolio.
plot : PortfolioPlotter
Accessor for plotting portfolio data.
prices : PricesAccessor
Accessor for price-related operations.
ereturns : ExpectedReturnsAccessor
Accessor for expected returns calculations.
covariance : CovarianceAccessor
Accessor for covariance matrix calculations.
correlation : CorrelationAccessor
Accessor for correlation matrix calculations.
risk : RiskAccessor
Accessor for risk-related operations.
utilities : UtilitiesAccessor
Accessor for utility-related operations.
diversification : DiversificationAccessor
Accessor for diversification-related operations.
Methods
-------
__attrs_post_init__()
Initialize additional attributes and performs validation.
from_dfkws(prices, weights=None, entropy=None, window_size=None, stocks=None, **metadata)
Alternative constructor to create a Portfolio instance from various inputs.
__len__()
Return the number of days in the price DataFrame.
__eq__(other)
Check equality with another Portfolio instance.
__ne__(other)
Check inequality with another Portfolio instance.
__getitem__(key)
Slice the Portfolio by the given key.
weights()
Return the weights as a pandas Series.
entropy()
Return the entropy values as a pandas Series.
stocks()
Return the stocks in the portfolio.
stocks_number()
Return the number of stocks in the portfolio.
metadata()
Return the metadata as a Bunch object.
window_size()
Return the window size for rolling calculations.
delisted()
Return a Series indicating if a stock has been delisted.
shape()
Return the shape of the price DataFrame.
copy(prices=None, weights=None, entropy=None, window_size=None, stocks=None, preserve_old_metadata=True, **metadata)
Create a copy of the Portfolio with optional modifications.
to_hdf5(stream_or_buff, **kwargs)
Save the Portfolio to an HDF5 file.
to_dataframe()
Convert the Portfolio to a pandas DataFrame.
as_returns(**kwargs)
Convert the price DataFrame to returns.
as_prices()
Return a copy of the price DataFrame.
weights_prune(threshold=1e-4)
Prune the Portfolio by removing assets with weights below the threshold.
delisted_prune()
Prune the Portfolio by removing delisted assets.
scale_weights(scaler="proportion")
Scale the weights to a range of [0, 1].
refresh_entropy(entropy="shannon", entropy_kws=None)
Recalculate the entropy values for the Portfolio.
__repr__()
Return a string representation of the Portfolio.
_repr_html_()
Return an HTML representation of the Portfolio for IPython notebooks.
"""

_prices_df = attr.ib(validator=vldt.instance_of(pd.DataFrame))
Expand Down Expand Up @@ -703,7 +620,7 @@ def scale_weights(self, *, scaler="proportion"):
return self.copy(weights=scaled_weights)

# CALCULATE ENTROPY =======================================================
# TODO
# TODO Risso
def refresh_entropy(self, *, entropy="shannon", entropy_kws=None):
"""Refresh entropy values using a specified entropy calculation method.
Expand Down
2 changes: 1 addition & 1 deletion garpar/datasets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

"""Different utilities to create or load portfolios."""

from .base import PortfolioMakerABC, RandomEntropyPortfolioMakerABC
from .ds_base import PortfolioMakerABC, RandomEntropyPortfolioMakerABC
from .data import load_MERVAL
from .multisector import MultiSector, make_multisector
from .risso import (
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion garpar/datasets/multisector.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import pandas as pd

from .base import PortfolioMakerABC
from .ds_base import PortfolioMakerABC
from ..core.portfolio import Portfolio
from ..utils import Bunch, mabc, unique_names

Expand Down
2 changes: 1 addition & 1 deletion garpar/datasets/risso.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

import scipy.stats

from .base import RandomEntropyPortfolioMakerABC
from .ds_base import RandomEntropyPortfolioMakerABC
from ..utils import mabc


Expand Down
2 changes: 1 addition & 1 deletion garpar/optimize/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@

from . import mean_variance

__all__ = [ "mean_variance"]
__all__ = [ "mean_variance" ]
4 changes: 2 additions & 2 deletions garpar/optimize/mean_variance.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import attr

from .base import OptimizerABC, MeanVarianceFamilyMixin
from .opt_base import OptimizerABC, MeanVarianceFamilyMixin

from ..utils import mabc

Expand Down Expand Up @@ -83,7 +83,7 @@ def _calculate_weights(self, pf):

return optimization_methods[method](optimizer, pf)

def _min_volatiliy(self, optimizer, pf):
def _min_volatility(self, optimizer, pf):
weights_dict = optimizer.min_volatility()
weights = [weights_dict[stock] for stock in pf.stocks]
return weights, {"name": "min_volatility"}
Expand Down
File renamed without changes.
12 changes: 11 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
[tool.black]
line-length = 80
target-version = ['py38', 'py39', 'py310', 'py311']
target-version = ['py38', 'py39', 'py310', 'py311', 'py312']

[tool.pytest.ini_options]
markers = [
"slow: marks tests that require significant execution time (deselect with '-m \"not slow\"')",
"plot: marks tests related to matplotlib integration (deselect with '-m \"not plot\"')",
]
testpaths = [
"tests",
]
addopts = "-m 'not slow' -n auto"
20 changes: 20 additions & 0 deletions tests/core/test_plot_acc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

import seaborn as sns

@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("returns", [True, False])
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
Expand All @@ -30,6 +32,8 @@ def test_PortFolioPlotter_line(risso_portfolio, fig_test, fig_ref, returns, pric
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("returns", [True, False])
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
Expand All @@ -46,6 +50,8 @@ def test_PortFolioPlotter_heatmap(risso_portfolio, fig_test, fig_ref, returns, p
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
def test_PortFolioPlotter_wheatmap(risso_portfolio, fig_test, fig_ref, price_distribution):
Expand All @@ -62,6 +68,8 @@ def test_PortFolioPlotter_wheatmap(risso_portfolio, fig_test, fig_ref, price_dis
ax_ref.set_xlabel("Stocks")


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("returns", [True, False])
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
Expand All @@ -78,6 +86,8 @@ def test_PortFolioPlotter_hist(risso_portfolio, fig_test, fig_ref, returns, pric
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
def test_PortFolioPlotter_whist(risso_portfolio, fig_test, fig_ref, price_distribution):
Expand All @@ -93,6 +103,8 @@ def test_PortFolioPlotter_whist(risso_portfolio, fig_test, fig_ref, price_distri
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("returns", [True, False])
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
Expand All @@ -109,6 +121,8 @@ def test_PortFolioPlotter_box(risso_portfolio, fig_test, fig_ref, returns, price
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
def test_PortFolioPlotter_wbox(risso_portfolio, fig_test, fig_ref, price_distribution):
Expand All @@ -124,6 +138,8 @@ def test_PortFolioPlotter_wbox(risso_portfolio, fig_test, fig_ref, price_distrib
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("returns", [True, False])
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
Expand All @@ -140,6 +156,8 @@ def test_PortFolioPlotter_kde(risso_portfolio, fig_test, fig_ref, returns, price
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
def test_PortFolioPlotter_wkde(risso_portfolio, fig_test, fig_ref, price_distribution):
Expand All @@ -155,6 +173,8 @@ def test_PortFolioPlotter_wkde(risso_portfolio, fig_test, fig_ref, price_distrib
ax_ref.set_title(title)


@pytest.mark.slow
@pytest.mark.plot
@check_figures_equal()
@pytest.mark.parametrize("returns", [True, False])
@pytest.mark.parametrize("price_distribution", pytest.DISTRIBUTIONS)
Expand Down
2 changes: 1 addition & 1 deletion tests/optimize/test_base_optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from garpar import Portfolio

from garpar.optimize import base
from garpar.optimize import opt_base as base

import numpy as np

Expand Down
2 changes: 1 addition & 1 deletion tests/optimize/test_mean_variance.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import pytest

# =============================================================================
# MARKOWITS TEST
# MARKOWITZ TEST
# =============================================================================

def test_Markowitz_optimize():
Expand Down
9 changes: 5 additions & 4 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ envlist =
py39,
py310,
py311,
#py312, no funca en arch (?) FIXME
py312,
coverage,


Expand All @@ -22,7 +22,7 @@ usedevelop = False
deps = flake8
flake8-import-order
flake8-black
#flake8-builtins
flake8-builtins
commands =
flake8 setup.py garpar/ tests/ {posargs}

Expand Down Expand Up @@ -60,8 +60,9 @@ usedevelop = True
deps =
ipdb
pytest
pytest-xdist
commands =
pytest tests/ {posargs}
pytest tests/ -vm '' {posargs}

[testenv:coverage]
usedevelop = True
Expand All @@ -71,5 +72,5 @@ deps =
pytest-cov
commands =
- coverage erase # - => Segui en el que sigue
pytest -v tests/ --cov garpar --cov-fail-under 80 --cov-report term-missing --ignore=tests/core/test_plot_acc.py
pytest tests/ -m '' --cov garpar --cov-fail-under 91 --cov-report term-missing

0 comments on commit e8cc466

Please sign in to comment.