Skip to content

Commit

Permalink
Merge pull request #205 from bocabitlabs/develop
Browse files Browse the repository at this point in the history
v1.0.4
  • Loading branch information
renefs committed Sep 4, 2024
2 parents 001f678 + 0ea3bef commit 6db5c95
Show file tree
Hide file tree
Showing 54 changed files with 1,374 additions and 3,372 deletions.
6 changes: 0 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,6 @@ coverage.xml
*.cover
.hypothesis/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery
celerybeat-schedule.*

Expand Down
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
8 changes: 4 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM python:3.10-slim

WORKDIR /usr/src/app
WORKDIR /usr/src/

ENV PYTHONPATH "${PYTHONPATH}:/usr/src"
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
Expand All @@ -10,8 +10,8 @@ ENV PYTHONUNBUFFERED 1
ENV POETRY_VERSION 1.5.0
ENV POETRY_HOME /opt/poetry
ENV POETRY_VIRTUALENVS_IN_PROJECT true
ENV POETRY_CACHE_DIR ${WORKDIR}/.cache
ENV VIRTUAL_ENVIRONMENT_PATH ${WORKDIR}/.venv
ENV POETRY_CACHE_DIR /usr/src/.cache
ENV VIRTUAL_ENVIRONMENT_PATH /usr/src/.venv

LABEL org.opencontainers.image.authors='[email protected]' \
org.opencontainers.image.url='https://github.com/bocabitlabs/buho-stocks/pkgs/container/buho-stocks' \
Expand All @@ -31,7 +31,7 @@ COPY poetry.lock ./
# Using Poetry to install dependencies without requiring the project main files to be present
RUN pip install poetry==${POETRY_VERSION} && poetry install --only main --no-root --no-directory

COPY ./backend $WORKDIR
COPY ./backend /usr/src/app
COPY ./etc /usr/src/etc

RUN chmod +x /usr/src/etc/entrypoint.sh
Expand Down
137 changes: 30 additions & 107 deletions backend/companies/data_calculators_closed.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,29 +64,17 @@ def calculate_accumulated_investment_until_year(self, year: int) -> Decimal:
total: Decimal = Decimal(0)

# Any year after the last sell transaction year
if (
int(year) >= self.last_transaction.transaction_date.year
and year != settings.YEAR_FOR_ALL
):
if int(year) >= self.last_transaction.transaction_date.year:
return Decimal(0)
# YEAR_FOR_ALL
if (
int(year) == settings.YEAR_FOR_ALL
or int(year) < self.last_transaction.transaction_date.year
):
total = self.shares_calculator.calculate_accumulated_investment_until_year_excluding_last_sale( # noqa
year
)
return total

# Years before the last sell transaction
if int(year) < self.last_transaction.transaction_date.year:
total += self.shares_calculator.calculate_accumulated_investment_until_year(
year
)
total += self.rights_calculator.calculate_accumulated_investment_until_year(
year
)
logger.debug(f"Total accum on year {year}: {total}")
total += self.shares_calculator.calculate_accumulated_investment_until_year(
year
)
total += self.rights_calculator.calculate_accumulated_investment_until_year(
year
)
logger.debug(f"Total accum on year {year}: {total}")

return total

Expand All @@ -109,36 +97,6 @@ def calculate_company_value_on_year(self, year: int) -> Decimal:
if int(year) < self.last_transaction.transaction_date.year:
logger.debug("Year is before last sell")
return super().calculate_company_value_on_year(year)
# year > last_transaction and != YEAR_FOR_ALL
# 0
elif (
int(year) > self.last_transaction.transaction_date.year
and year != settings.YEAR_FOR_ALL
):
logger.debug("Year is after last sell and not ALL")
return Decimal(0)

# year > last_transaction and == YEAR_FOR_ALL
# or year == last_transaction
# get the value from last sell * exchange rate
elif (
int(year) > self.last_transaction.transaction_date.year
and year == settings.YEAR_FOR_ALL
) or (int(year) == self.last_transaction.transaction_date.year):
logger.debug("Year is the same as last sell or ALL")
exchange_rates_fetcher = ExchangeRateFetcher()
datetime_from_date = datetime.datetime.combine(
self.last_transaction.transaction_date, datetime.datetime.min.time()
)
exchange_rate = exchange_rates_fetcher.get_exchange_rate_for_date(
self.company.base_currency,
self.company.portfolio.base_currency,
datetime_from_date,
)
if exchange_rate:
total = self.last_transaction.total_amount.amount * Decimal(
exchange_rate.exchange_rate
)

return total

Expand Down Expand Up @@ -181,26 +139,18 @@ def calculate_return_on_year(self, year: int) -> Decimal:
if int(year) < self.last_transaction.transaction_date.year:
logger.debug("Year is before last sell")
return super().calculate_return_on_year(year)
# year > last_transaction and != YEAR_FOR_ALL
# 0
elif (
int(year) > self.last_transaction.transaction_date.year
and year != settings.YEAR_FOR_ALL
):
logger.debug("Year is after last sell and not ALL")
return Decimal(0)

elif (
int(year) > self.last_transaction.transaction_date.year
and year == settings.YEAR_FOR_ALL
) or (int(year) == self.last_transaction.transaction_date.year):
accum_investment = self.shares_calculator.calculate_accumulated_investment_until_year_excluding_last_sale( # noqa
year
)
investments = self.shares_calculator.calculate_total_investments_until_year(
year
)
# Commissions from all the transactions
commissions = self.shares_calculator.calculate_total_commissions_until_year(
year
)

company_value = self.calculate_company_value_on_year(year)
sales = self.shares_calculator.calculate_total_sales_until_year(year)

total = company_value - accum_investment
total = sales - investments - commissions

return total

Expand All @@ -210,58 +160,31 @@ def calculate_return_with_dividends_on_year(self, year: int) -> Decimal:
if int(year) < self.last_transaction.transaction_date.year:
logger.debug("Year is before last sell")
return super().calculate_return_with_dividends_on_year(year)
# year > last_transaction and != YEAR_FOR_ALL
# 0
elif (
int(year) > self.last_transaction.transaction_date.year
and year != settings.YEAR_FOR_ALL
):
logger.debug("Year is after last sell and not ALL")
return Decimal(0)

elif (
int(year) > self.last_transaction.transaction_date.year
and year == settings.YEAR_FOR_ALL
) or (int(year) == self.last_transaction.transaction_date.year):
accum_investment = self.shares_calculator.calculate_accumulated_investment_until_year_excluding_last_sale( # noqa
year
)

company_value = self.calculate_company_value_on_year(year)
accumulated_dividends = self.calculate_accumulated_dividends_until_year(
year
)
return_year = self.calculate_return_on_year(year)
accumulated_dividends = self.calculate_accumulated_dividends_until_year(year)

return company_value - accum_investment + accumulated_dividends
return return_year + accumulated_dividends

def calculate_return_yield_on_year(self, year: int) -> Decimal:

return_value = self.calculate_return_on_year(year)

if (
int(year) == self.last_transaction.transaction_date.year
or year == settings.YEAR_FOR_ALL
) or (int(year) == self.last_transaction.transaction_date.year):
total_invested = self.shares_calculator.calculate_accumulated_investment_until_year_excluding_last_sale( # noqa
year
)
else:
total_invested = self.calculate_accumulated_investment_until_year(year)
# Years before the last sell transaction
total_invested = Decimal(0)
total_invested = self.shares_calculator.calculate_total_investments_until_year(
year
)

if total_invested != 0:
return (return_value / total_invested) * 100
return Decimal(0)

def calculate_return_yield_with_dividends_on_year(self, year: int) -> Decimal:
return_with_dividends = self.calculate_return_with_dividends_on_year(year)
if (
int(year) == self.last_transaction.transaction_date.year
or year == settings.YEAR_FOR_ALL
) or (int(year) == self.last_transaction.transaction_date.year):
total_invested = self.shares_calculator.calculate_accumulated_investment_until_year_excluding_last_sale( # noqa
year
)
else:
total_invested = self.calculate_accumulated_investment_until_year(year)
total_invested = self.shares_calculator.calculate_total_investments_until_year(
year
)

if total_invested != 0:
return (return_with_dividends / total_invested) * 100
Expand Down
9 changes: 7 additions & 2 deletions backend/companies/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,14 @@ def get_dividends_currency(self, obj):

def get_logo(self, obj):
request = self.context.get("request")
photo_url = obj.fingerprint.url
if request:
return request.build_absolute_uri(photo_url)
photo_url = obj.fingerprint.url
logo_url = (
request.build_absolute_uri(photo_url)
.replace("http://", "//")
.replace("https://", "//")
)
return logo_url
return None

def get_first_year(self, obj):
Expand Down
3 changes: 0 additions & 3 deletions backend/dividends_transactions/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ def perform_destroy(self, instance):
self.delete_dividends_update_company_stats(instance, company)

def add_dividends_update_company_stats(self, serializer, company):
logger.debug(f"Updating company stats for {company.name} after adding dividend")
transaction_date = datetime.strptime(
serializer.data.get("transaction_date"), "%Y-%m-%d"
)
Expand All @@ -67,8 +66,6 @@ def add_dividends_update_company_stats(self, serializer, company):
)

def delete_dividends_update_company_stats(self, instance, company):
logger.debug(f"Updating company stats for {company.name} after adding dividend")

update_portfolio = self.request.query_params.get("updatePortfolio", False)

if update_portfolio == "true":
Expand Down
6 changes: 3 additions & 3 deletions backend/portfolios/calculators.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@


def get_portfolio_first_year(portfolio_id):
query = SharesTransaction.objects.filter(
company__portfolio=portfolio_id, company__is_closed=False
).order_by("transaction_date")
query = SharesTransaction.objects.filter(company__portfolio=portfolio_id).order_by(
"transaction_date"
)
if query.exists():
return query[0].transaction_date.year
return None
2 changes: 1 addition & 1 deletion backend/portfolios/data_calculators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def __init__(self, portfolio_id: int, use_portfolio_currency: bool = True):

def get_portfolio_first_year(self) -> int | None:
query = SharesTransaction.objects.filter(
company__portfolio=self.portfolio.id, company__is_closed=False
company__portfolio=self.portfolio.id
).order_by("transaction_date")
if query.exists():
transaction = query[0]
Expand Down
6 changes: 3 additions & 3 deletions backend/portfolios/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ def get_base_currency(self, obj):
return serialized_currency.data

def get_first_year(self, obj):
query = SharesTransaction.objects.filter(
company__portfolio=obj.id, company__is_closed=False
).order_by("transaction_date")
query = SharesTransaction.objects.filter(company__portfolio=obj.id).order_by(
"transaction_date"
)
if query.exists():
return query[0].transaction_date.year
return None
20 changes: 12 additions & 8 deletions backend/rights_transactions/calculators.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,28 @@ def calculate_invested_on_year(self, year: int) -> Decimal:
query = self._get_multiple_buy_transactions_query(year)

transactions_calculator = TransactionCalculator()
total = transactions_calculator.calculate_transactions_amount(
total = transactions_calculator.calculate_investments(
query, use_portfolio_currency=self.use_portfolio_currency
)
return total

def calculate_accumulated_investment_until_year(self, year: int) -> Decimal:
"""Get the total amount invested until a given year (included)
Returns:
[type]: [description]
"""
total: Decimal = Decimal(0)
# BUY
query = self._get_multiple_buy_transactions_query(year, use_accumulated=True)

transactions_calculator = TransactionCalculator()
total = transactions_calculator.calculate_transactions_amount(
buy_total = transactions_calculator.calculate_investments(
query, use_portfolio_currency=self.use_portfolio_currency
)
# SELL
query = self._get_multiple_sell_transactions_query(year, use_accumulated=True)
transactions_calculator = TransactionCalculator()
sell_total = transactions_calculator.calculate_investments(
query, use_portfolio_currency=self.use_portfolio_currency
)

total = buy_total - sell_total

return total

def get_accumulated_investment_until_current_year(self) -> Decimal:
Expand Down
Loading

0 comments on commit 6db5c95

Please sign in to comment.