Coverage for src/scrilla/static/formats.py: 93%
71 statements
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-18 18:14 +0000
« prev ^ index » next coverage.py v6.4.2, created at 2022-07-18 18:14 +0000
1import argparse
3from scrilla.static import constants, definitions
4from scrilla.util.helper import significant_digits, exceeds_accuracy
6formats = {
7 'separator': '-',
8 'TAB': ' ',
9 'LINE_LENGTH': 100,
10 'BAR_WIDTH': 0.10,
11 'INDENT': 10,
12 'RISK_FREE_TITLE': "{} US Treasury",
13 'BINS': 20
14}
17def format_float_number(decimal: float) -> str:
18 if exceeds_accuracy(decimal):
19 return '0'
20 accuracy = f'.{constants.constants["ACCURACY"]}f'
21 sigfigs = format(significant_digits(
22 decimal, constants.constants["SIG_FIGS"]), accuracy)
23 return sigfigs.rstrip('0').rstrip('.')
26def format_float_percent(decimal: float) -> str:
27 if exceeds_accuracy(decimal):
28 return "0%"
29 accuracy = f'.{constants.constants["ACCURACY"]}f'
30 sigfigs = format(100*significant_digits(decimal,
31 constants.constants['SIG_FIGS']), accuracy)
32 return sigfigs.rstrip('0').rstrip('.') + '%'
35def format_dict_percent(this_dict: dict, which_key: str) -> dict:
36 buffer_dict = this_dict.copy()
37 buffer_dict[which_key] = format_float_percent(this_dict[which_key])
38 return buffer_dict
41def format_dict_number(this_dict: dict, which_key: str) -> dict:
42 buffer_dict = this_dict.copy()
43 buffer_dict[which_key] = format_float_number(this_dict[which_key])
44 return buffer_dict
47def format_allocation(allocation, portfolio, investment=None, latest_prices=None):
48 allocation_format = []
50 if investment is not None: 50 ↛ 51line 50 didn't jump to line 51, because the condition on line 50 was never true
51 shares = portfolio.calculate_approximate_shares(
52 x=allocation, total=investment, latest_prices=latest_prices)
53 total = portfolio.calculate_actual_total(
54 x=allocation, total=investment, latest_prices=latest_prices)
56 annual_volatility = portfolio.volatility_function(x=allocation)
57 annual_return = portfolio.return_function(x=allocation)
59 for j, item in enumerate(portfolio.tickers):
60 holding = {'ticker': item, 'allocation': round(allocation[j], constants.constants['ACCURACY']), 'annual_return': round(
61 portfolio.mean_return[j], constants.constants['ACCURACY']), 'annual_volatility': round(
62 portfolio.sample_vol[j], constants.constants['ACCURACY'])}
63 if investment is not None: 63 ↛ 64line 63 didn't jump to line 64, because the condition on line 63 was never true
64 holding['shares'] = float(shares[j])
65 allocation_format.append(holding)
67 json_format = {'holdings': allocation_format,
68 'portfolio_return': annual_return, 'portfolio_volatility': annual_volatility}
70 if investment is not None: 70 ↛ 71line 70 didn't jump to line 71, because the condition on line 70 was never true
71 json_format['total'] = float(total)
73 return json_format
76def format_frontier(portfolio, frontier, investment=None, latest_prices=None):
77 json_format = []
78 for item in frontier:
79 json_format.append(format_allocation(allocation=item, portfolio=portfolio,
80 investment=investment, latest_prices=latest_prices))
81 return json_format
84def format_correlation_matrix(tickers, correlation_matrix):
85 response = []
86 for i in range(0, len(tickers)-1):
87 subresponse = {}
88 for j in range(i+1, len(tickers)):
89 subresponse[f'{tickers[i]}_{tickers[j]}_correlation'] = correlation_matrix[j][i]
90 response.append(subresponse)
91 return response
94def format_args(args, default_estimation_method) -> argparse.Namespace:
95 parser = argparse.ArgumentParser()
97 choices = []
98 for func in definitions.FUNC_DICT:
99 choices.append(definitions.FUNC_DICT[func]['values'][0])
100 choices.append(definitions.FUNC_DICT[func]['values'][1])
102 parser.add_argument('function_arg', choices=choices)
104 groups = [parser.add_mutually_exclusive_group()
105 for _ in definitions.ARG_META_DICT['groups']]
107 for arg in definitions.ARG_DICT:
108 if definitions.ARG_DICT[arg]['format'] not in ('group', bool):
109 parser.add_argument(definitions.ARG_DICT[arg]['values'][0],
110 definitions.ARG_DICT[arg]['values'][1],
111 definitions.ARG_DICT[arg]['values'][2],
112 definitions.ARG_DICT[arg]['values'][3],
113 default=None,
114 type=definitions.ARG_DICT[arg]['format'],
115 dest=arg)
116 elif definitions.ARG_DICT[arg]['format'] == 'group':
117 group_index = definitions.ARG_META_DICT['groups'].index(
118 definitions.ARG_DICT[arg]['group'])
119 groups[group_index].add_argument(definitions.ARG_DICT[arg]['values'][0],
120 definitions.ARG_DICT[arg]['values'][1],
121 definitions.ARG_DICT[arg]['values'][2],
122 definitions.ARG_DICT[arg]['values'][3],
123 action='store_const',
124 dest=definitions.ARG_DICT[arg]['group'],
125 const=arg)
126 # NOTE: 'format' == group AND 'format' == bool => Empty Set, so only other alternative is
127 # 'format' == bool
128 else:
129 parser.add_argument(definitions.ARG_DICT[arg]['values'][0],
130 definitions.ARG_DICT[arg]['values'][1],
131 definitions.ARG_DICT[arg]['values'][2],
132 definitions.ARG_DICT[arg]['values'][3],
133 action='store_true',
134 dest=arg)
136 parser.set_defaults(estimation_method=default_estimation_method)
137 parser.add_argument('tickers', nargs='*', type=str)
138 return vars(parser.parse_args(args))