Skip to content

Commit e8da056

Browse files
committed
Add main function to use the library and update example
1 parent 464e329 commit e8da056

File tree

6 files changed

+134
-76
lines changed

6 files changed

+134
-76
lines changed

allokation/__init__.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,8 @@
1-
from .functions import (
2-
get_closing_price_from_yahoo,
3-
map_columns_without_suffix,
4-
transpose_prices,
5-
calculate_multiplier,
6-
calculate_amount,
7-
calculate_total_for_each_ticker,
8-
calculate_percentage_of_each_ticker
1+
from .allokate import (
2+
allocate_money
93
)
104

5+
116
__all__ = [
12-
'get_closing_price_from_yahoo',
13-
'map_columns_without_suffix',
14-
'transpose_prices',
15-
'calculate_multiplier',
16-
'calculate_amount',
17-
'calculate_total_for_each_ticker',
18-
'calculate_percentage_of_each_ticker'
7+
'allocate_money',
198
]

allokation/allokate.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from allokation.utils import (calculate_amount, calculate_multiplier,
2+
calculate_percentage_of_each_ticker,
3+
calculate_total_for_each_ticker,
4+
get_closing_price_from_yahoo, get_target_date,
5+
map_columns_without_suffix, transpose_prices)
6+
7+
8+
def allocate_money(available_money, tickers):
9+
# import ipdb; ipdb.set_trace()
10+
target_date = get_target_date()
11+
prices = get_closing_price_from_yahoo(tickers=tickers, date=target_date)
12+
renamed_columns = map_columns_without_suffix(tickers)
13+
prices.rename(columns=renamed_columns, inplace=True)
14+
df = transpose_prices(prices)
15+
multiplier = calculate_multiplier(df, number_of_tickers=len(tickers), available_money=available_money)
16+
17+
df['amount'] = calculate_amount(df, multiplier)
18+
df['total'] = calculate_total_for_each_ticker(df)
19+
df['percentage'] = calculate_percentage_of_each_ticker(df)
20+
21+
result = {}
22+
result['allocations'] = df.set_index('symbol').T.to_dict()
23+
result['total_value'] = df["total"].sum()
24+
25+
return result

allokation/functions.py renamed to allokation/utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,30 @@
1+
from datetime import date, timedelta
2+
13
import pandas as pd
24
from pandas_datareader import data as web
35

46

7+
def get_target_date(base_date=date.today()):
8+
weekdays = [
9+
'monday',
10+
'tuesday',
11+
'wednesday',
12+
'thursday',
13+
'friday',
14+
'saturday',
15+
'sunday',
16+
]
17+
18+
target_date = base_date
19+
weekday = weekdays[target_date.weekday()]
20+
if weekday == 'saturday':
21+
target_date = target_date - timedelta(days=1)
22+
elif weekday == 'sunday':
23+
target_date = target_date - timedelta(days=2)
24+
25+
return target_date
26+
27+
528
def get_closing_price_from_yahoo(tickers, date):
629
result = web.get_data_yahoo(tickers, date)
730
return result['Adj Close']

example/example.py

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
1-
from datetime import date, timedelta
1+
from pprint import pp
22

3-
from allokation import (
4-
get_closing_price_from_yahoo,
5-
map_columns_without_suffix,
6-
transpose_prices,
7-
calculate_multiplier,
8-
calculate_amount,
9-
calculate_total_for_each_ticker,
10-
calculate_percentage_of_each_ticker
11-
)
3+
from allokation import allocate_money
124

135
AVAILABLE_MONEY = 1000
146

@@ -20,41 +12,5 @@
2012
'VVAR3.SA',
2113
]
2214

23-
weekdays = [
24-
'monday',
25-
'tuesday',
26-
'wednesday',
27-
'thursday',
28-
'friday',
29-
'saturday',
30-
'sunday',
31-
]
32-
33-
target_date = date.today()
34-
weekday = weekdays[target_date.weekday()]
35-
if weekday == 'saturday':
36-
target_date = target_date - timedelta(days=1)
37-
elif weekday == 'sunday':
38-
target_date = target_date - timedelta(days=2)
39-
40-
prices = get_closing_price_from_yahoo(tickers=tickers, date=date.today()-timedelta(days=2))
41-
42-
renamed_columns = map_columns_without_suffix(tickers)
43-
44-
prices.rename(columns=renamed_columns, inplace=True)
45-
46-
df = transpose_prices(prices)
47-
48-
multiplier = calculate_multiplier(df, number_of_tickers=len(tickers), available_money=AVAILABLE_MONEY)
49-
50-
df['amount'] = calculate_amount(df, multiplier)
51-
df['total'] = calculate_total_for_each_ticker(df)
52-
df['percentage'] = calculate_percentage_of_each_ticker(df)
53-
54-
print(df)
55-
print(f'multiplier = {multiplier}')
56-
57-
total_sum = df["total"].sum()
58-
print(f'MONEY = {AVAILABLE_MONEY}')
59-
print(f'TOTAL = {total_sum}')
60-
print(f'DIFF = {AVAILABLE_MONEY - total_sum}')
15+
result = allocate_money(available_money=AVAILABLE_MONEY, tickers=tickers)
16+
pp(result)

tests/test_allokate.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from datetime import date
2+
3+
import requests_cache
4+
from pandas_datareader import data as web
5+
6+
from allokation.allokate import allocate_money
7+
8+
9+
def test_allocate_money(mocker):
10+
"""
11+
The get_closing_price_from_yahoo() calls get_data_yahoo from pandas_datareader, which returns a pandas dataframe.
12+
For this reason, some data for test purposes were saved in a sqlite cache.
13+
In this test, the cache is used to return this data.
14+
"""
15+
tickers = [
16+
'B3SA3.SA',
17+
'BBDC4.SA',
18+
'MGLU3.SA',
19+
'PETR4.SA',
20+
'VVAR3.SA',
21+
]
22+
target_date = date(year=2020, month=9, day=4)
23+
cache_session = requests_cache.CachedSession(
24+
cache_name='tests/data/data_from_yahoo',
25+
backend='sqlite',
26+
expires_after=None
27+
)
28+
cached_df = web.DataReader(tickers, 'yahoo', session=cache_session, start=target_date, end=target_date)
29+
30+
mock_result = cached_df['Adj Close']
31+
32+
mocker.patch('allokation.allokate.get_closing_price_from_yahoo', lambda tickers, date: mock_result.copy())
33+
result = allocate_money(1000, tickers)
34+
35+
assert result.get('allocations', None)
36+
assert result.get('total_value', None)
37+
assert result['allocations'].get('B3SA3', None)
38+
assert result['allocations'].get('BBDC4', None)
39+
assert result['allocations'].get('MGLU3', None)
40+
assert result['allocations'].get('PETR4', None)
41+
assert result['allocations'].get('VVAR3', None)

tests/test_functions.py renamed to tests/test_utils.py

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,47 @@
1-
import requests_cache
21
import os
2+
from datetime import date, timedelta
3+
34
import pandas as pd
45
import pytest
6+
import requests_cache
57
from pandas_datareader import data as web
6-
from datetime import date
7-
8-
from allokation import (
9-
get_closing_price_from_yahoo,
10-
map_columns_without_suffix,
11-
transpose_prices,
12-
calculate_multiplier,
13-
calculate_amount,
14-
calculate_total_for_each_ticker,
15-
calculate_percentage_of_each_ticker
16-
)
8+
9+
from allokation.utils import (calculate_amount, calculate_multiplier,
10+
calculate_percentage_of_each_ticker,
11+
calculate_total_for_each_ticker,
12+
get_closing_price_from_yahoo, get_target_date,
13+
map_columns_without_suffix, transpose_prices)
1714

1815
STOCKS_DATA_FILEPATH = os.path.join(os.path.dirname(__file__), './data/stocks.csv')
1916

2017

18+
def test_get_target_date_when_today_is_a_weekday():
19+
base_date = date(year=2020, month=9, day=4)
20+
expected = base_date
21+
22+
result = get_target_date(base_date=base_date)
23+
24+
assert result == expected
25+
26+
27+
def test_get_target_date_when_today_is_saturday():
28+
base_date = date(year=2020, month=9, day=5)
29+
expected = base_date - timedelta(days=1)
30+
31+
result = get_target_date(base_date=base_date)
32+
33+
assert result == expected
34+
35+
36+
def test_get_target_date_when_today_is_sunday():
37+
base_date = date(year=2020, month=9, day=6)
38+
expected = base_date - timedelta(days=2)
39+
40+
result = get_target_date(base_date=base_date)
41+
42+
assert result == expected
43+
44+
2145
def test_get_closing_price_from_yahoo(mocker):
2246
"""
2347
The get_closing_price_from_yahoo() calls get_data_yahoo from pandas_datareader, which returns a pandas dataframe.
@@ -45,7 +69,7 @@ def test_get_closing_price_from_yahoo(mocker):
4569

4670
expected = cached_df['Adj Close']
4771

48-
mocker.patch('allokation.functions.web.get_data_yahoo', lambda tickers, date: cached_df)
72+
mocker.patch('allokation.utils.web.get_data_yahoo', lambda tickers, date: cached_df)
4973
result = get_closing_price_from_yahoo(tickers, target_date)
5074

5175
assert result.equals(expected)

0 commit comments

Comments
 (0)