Skip to content

Commit

Permalink
feat: symbols_in_namespace() method in namespaces.py
Browse files Browse the repository at this point in the history
  • Loading branch information
chilango74 committed Jan 20, 2021
1 parent fe6cc53 commit 20292c6
Show file tree
Hide file tree
Showing 22 changed files with 1,222 additions and 1,005 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<img src="https://img.shields.io/badge/python-v3-brightgreen.svg"
alt="python"></a> &nbsp;
<a href="https://pypi.org/project/okama/">
<img src="https://img.shields.io/badge/pypi-v0.92-brightgreen.svg"
<img src="https://img.shields.io/badge/pypi-v0.93-brightgreen.svg"
alt="pypi"></a> &nbsp;
<a href="https://opensource.org/licenses/MIT">
<img src="https://img.shields.io/badge/license-MIT-brightgreen.svg"
Expand Down Expand Up @@ -84,10 +84,13 @@ x.wealth_indexes.plot()
![](../images/images/readmi03.jpg?raw=true)

### 2. Create a dividend stocks portfolio with base currency EUR

```python
import okama.portfolio

weights = [0.3, 0.2, 0.2, 0.2, 0.1]
assets = ['T.US', 'XOM.US', 'FRE.XETR', 'SNW.XETR', 'LKOH.MOEX']
pf = ok.Portfolio(assets, weights=weights, ccy='EUR')
pf = okama.portfolio.Portfolio(assets, weights=weights, ccy='EUR')
print(pf)
```
![](../images/images/readmi04.jpg?raw=true)
Expand Down
7 changes: 1 addition & 6 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import okama as ok
import pandas as pd

x = ok.Portfolio(symbols=['RUB.FX', 'MCFTR.INDX'], ccy='RUB',
first_date='2015-01', last_date='2020-01', inflation=True)
print(x.describe())
print('\n\n*******************')
print(pd.read_pickle('tests/data/portfolio_description.pkl'))
print(ok.symbols_in_namespace('CBR').info)
552 changes: 366 additions & 186 deletions notebooks/01 howto.ipynb

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions okama/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
"""

from okama.assets import Asset, AssetList, Portfolio
from okama.assets import Asset, AssetList
from okama.portfolio import Portfolio
from okama.macro import Inflation, Rate
from okama.frontier import EfficientFrontier
from okama.frontier_reb import EfficientFrontierReb
from okama.frontier.multi_period import EfficientFrontierReb
from okama.plots import Plots
from okama.data import QueryData, API, search, namespaces, assets_namespaces, macro_namespaces
from okama.api.data_queries import QueryData
from okama.api.search import search
from okama.api.api_methods import API
from okama.api.namespaces import namespaces, assets_namespaces, macro_namespaces, symbols_in_namespace
from okama.helpers import Float, Frame, Rebalance, Date
import okama.settings

__version__ = '0.92'
__version__ = '0.93'
Empty file added okama/api/__init__.py
Empty file.
133 changes: 5 additions & 128 deletions okama/data.py → okama/api/api_methods.py
Original file line number Diff line number Diff line change
@@ -1,128 +1,6 @@
from typing import Dict
from functools import lru_cache

from io import StringIO
import json

import requests
import pandas as pd
import numpy as np

from .settings import default_ticker


def search(search_string: str) -> json:
string_response = API.search(search_string)
return json.loads(string_response)


@lru_cache()
def get_namespaces():
string_response = API.get_namespaces()
return json.loads(string_response)


@lru_cache()
def get_assets_namespaces():
string_response = API.get_assets_namespaces()
return json.loads(string_response)


@lru_cache()
def get_macro_namespaces():
string_response = API.get_macro_namespaces()
return json.loads(string_response)


@lru_cache()
def no_dividends_namespaces():
string_response = API.get_no_dividends_namespaces()
return json.loads(string_response)


class QueryData:
"""
Set of methods to select a source and get_ts the data.
"""

@staticmethod
def get_symbol_info(symbol: str) -> Dict[str, str]:
json_input = API.get_symbol_info(symbol)
return json.loads(json_input)

@staticmethod
def csv_to_series(csv_input: str, period: str) -> pd.Series:
ts = pd.read_csv(StringIO(csv_input),
delimiter=',',
index_col=0,
parse_dates=[0],
dtype={1: np.float64},
engine='python')
if not ts.empty:
ts.index = ts.index.to_period(period.upper())
ts = ts.squeeze('columns')
return ts

@staticmethod
def get_macro_ts(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01') -> pd.Series:
"""
Requests API for Macroeconomic indicators time series (monthly data).
- Inflation time series
- Bank rates time series
"""
csv_input = API.get_macro(symbol=symbol, first_date=first_date, last_date=last_date)
return QueryData.csv_to_series(csv_input, period='M')

@staticmethod
def get_ror(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
Requests API for rate of return time series.
"""
csv_input = API.get_ror(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period)

@staticmethod
def get_nav(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
NAV time series for funds (works for PIF namespace only).
"""
csv_input = API.get_nav(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period=period)

@staticmethod
def get_close(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
Gets 'close' time series for a ticker.
"""
csv_input = API.get_close(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period)

@staticmethod
def get_adj_close(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
Gets 'adjusted close' time series for a ticker.
"""
csv_input = API.get_adjusted_close(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period)

@staticmethod
def get_dividends(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01',) -> pd.Series:
"""
Dividends time series daily data (dividend payment day should be considered).
"""
if symbol.split('.', 1)[-1] not in no_dividends_namespaces():
csv_input = API.get_dividends(symbol, first_date=first_date, last_date=last_date)
ts = QueryData.csv_to_series(csv_input, period='D')
else:
# make empty time series when no dividends
ts = pd.Series(dtype=float)
ts.rename(symbol, inplace=True)
return ts

@staticmethod
def get_live_price(symbol: str) -> float:
price = API.get_live_price(symbol)
return float(price)
from ..settings import default_ticker, default_namespace


class API:
Expand Down Expand Up @@ -240,6 +118,10 @@ def get_macro(cls,
def get_namespaces(cls):
return cls.connect(endpoint=cls.endpoint_namespaces, symbol='')

@classmethod
def get_symbols_in_namespace(cls, namespace: str = default_namespace):
return cls.connect(endpoint=cls.endpoint_namespaces, symbol=namespace)

@classmethod
def get_assets_namespaces(cls):
return cls.connect(endpoint=cls.endpoint_assets_namespaces, symbol='')
Expand All @@ -263,8 +145,3 @@ def search(cls, search_string: str):
@classmethod
def get_live_price(cls, symbol: str):
return cls.connect(endpoint=cls.endpoint_live_price, symbol=symbol)


namespaces = get_namespaces()
assets_namespaces = get_assets_namespaces()
macro_namespaces = get_macro_namespaces()
95 changes: 95 additions & 0 deletions okama/api/data_queries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from typing import Dict

from io import StringIO
import json

import pandas as pd
import numpy as np

from .api_methods import API
from .namespaces import no_dividends_namespaces


class QueryData:
"""
Set of methods to get symbols data from API.
"""

@staticmethod
def get_symbol_info(symbol: str) -> Dict[str, str]:
json_input = API.get_symbol_info(symbol)
return json.loads(json_input)

@staticmethod
def csv_to_series(csv_input: str, period: str) -> pd.Series:
ts = pd.read_csv(StringIO(csv_input),
delimiter=',',
index_col=0,
parse_dates=[0],
dtype={1: np.float64},
engine='python')
if not ts.empty:
ts.index = ts.index.to_period(period.upper())
ts = ts.squeeze('columns')
return ts

@staticmethod
def get_macro_ts(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01') -> pd.Series:
"""
Requests API for Macroeconomic indicators time series (monthly data).
- Inflation time series
- Bank rates time series
"""
csv_input = API.get_macro(symbol=symbol, first_date=first_date, last_date=last_date)
return QueryData.csv_to_series(csv_input, period='M')

@staticmethod
def get_ror(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
Requests API for rate of return time series.
"""
csv_input = API.get_ror(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period)

@staticmethod
def get_nav(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
NAV time series for funds (works for PIF namespace only).
"""
csv_input = API.get_nav(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period=period)

@staticmethod
def get_close(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
Gets 'close' time series for a ticker.
"""
csv_input = API.get_close(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period)

@staticmethod
def get_adj_close(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01', period='M') -> pd.Series:
"""
Gets 'adjusted close' time series for a ticker.
"""
csv_input = API.get_adjusted_close(symbol=symbol, first_date=first_date, last_date=last_date, period=period)
return QueryData.csv_to_series(csv_input, period)

@staticmethod
def get_dividends(symbol: str, first_date: str = '1913-01-01', last_date: str = '2100-01-01',) -> pd.Series:
"""
Dividends time series daily data (dividend payment day should be considered).
"""
if symbol.split('.', 1)[-1] not in no_dividends_namespaces():
csv_input = API.get_dividends(symbol, first_date=first_date, last_date=last_date)
ts = QueryData.csv_to_series(csv_input, period='D')
else:
# make empty time series when no dividends
ts = pd.Series(dtype=float)
ts.rename(symbol, inplace=True)
return ts

@staticmethod
def get_live_price(symbol: str) -> float:
price = API.get_live_price(symbol)
return float(price)
44 changes: 44 additions & 0 deletions okama/api/namespaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import json
from functools import lru_cache

import pandas as pd

from .api_methods import API
from ..settings import default_namespace


@lru_cache()
def get_namespaces():
string_response = API.get_namespaces()
return json.loads(string_response)


@lru_cache()
def symbols_in_namespace(namespace: str = default_namespace):
string_response = API.get_symbols_in_namespace(namespace.upper())
list_of_symbols = json.loads(string_response)
df = pd.DataFrame(list_of_symbols[1:], columns=list_of_symbols[0])
return df.astype('string', copy=False)


@lru_cache()
def get_assets_namespaces():
string_response = API.get_assets_namespaces()
return json.loads(string_response)


@lru_cache()
def get_macro_namespaces():
string_response = API.get_macro_namespaces()
return json.loads(string_response)


@lru_cache()
def no_dividends_namespaces():
string_response = API.get_no_dividends_namespaces()
return json.loads(string_response)


namespaces = get_namespaces()
assets_namespaces = get_assets_namespaces()
macro_namespaces = get_macro_namespaces()
8 changes: 8 additions & 0 deletions okama/api/search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import json

from .api_methods import API


def search(search_string: str) -> json:
string_response = API.search(search_string)
return json.loads(string_response)
Loading

0 comments on commit 20292c6

Please sign in to comment.