mmnode-ticker: add year and month percentage change columns

This commit is contained in:
The MMGen Project 2023-11-05 13:40:23 +00:00
commit 545bc044c6
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
3 changed files with 56 additions and 18 deletions

View file

@ -34,6 +34,13 @@ portfolio_fn = 'ticker-portfolio.yaml'
asset_tuple = namedtuple('asset_tuple',['symbol','id','source'])
last_api_host = None
percent_cols = {
'd': 'day',
'w': 'week',
'm': 'month',
'y': 'year',
}
class DataSource:
source_groups = [
@ -390,6 +397,8 @@ def gen_data(data):
d['price_btc'] = Decimal(str(d['quotes']['USD']['price'])) / btcusd
d['percent_change_24h'] = d['quotes']['USD']['percent_change_24h']
d['percent_change_7d'] = d['quotes']['USD']['percent_change_7d']
d['percent_change_30d'] = d['quotes']['USD']['percent_change_30d']
d['percent_change_1y'] = d['quotes']['USD']['percent_change_1y']
d['last_updated'] = int(datetime.datetime.fromisoformat(d['last_updated']).timestamp())
yield (d['id'],d)
found[k].add(d[k])
@ -497,6 +506,15 @@ def make_cfg(gcfg_arg):
yield parse_asset_id(e,require_label=True)
return tuple(gen())
def parse_percent_cols(arg):
if arg is None:
return []
res = arg.lower().split(',')
for s in res:
if s not in percent_cols:
die(1,f'{arg!r}: invalid --percent-cols parameter (valid letters: {fmt_list(percent_cols)})')
return res
def parse_usr_asset_arg(key,use_cf_file=False):
"""
asset_id[:rate[:rate_asset]]
@ -606,7 +624,8 @@ def make_cfg(gcfg_arg):
'cachedir',
'proxy',
'proxy2',
'portfolio' ])
'portfolio',
'percent_cols' ])
global gcfg,cfg_in,src_cls,cfg
@ -645,7 +664,8 @@ def make_cfg(gcfg_arg):
cachedir = gcfg.cachedir or cfg_in.cfg.get('cachedir') or dfl_cachedir,
proxy = proxy,
proxy2 = None if proxy2 == 'none' else '' if proxy2 == '' else (proxy2 or proxy),
portfolio = get_portfolio() if cfg_in.portfolio and gcfg.portfolio and not query else None
portfolio = get_portfolio() if cfg_in.portfolio and gcfg.portfolio and not query else None,
percent_cols = parse_percent_cols(gcfg.percent_cols)
)
def get_cfg_in():
@ -802,7 +822,7 @@ class Ticker:
yield '-' * self.hl_wid
if not cfg.btc_only:
yield self.fs_num.format(
lbl = 'TOTAL', pc1='', pc2='', upd='', amt='',
lbl = 'TOTAL', pc3='', pc4='', pc1='', pc2='', upd='', amt='',
**{ k.replace('-','_'): v for k,v in self.prices['total'].items() }
)
@ -851,6 +871,8 @@ class Ticker:
lbl = (self.create_label(d['id']) if gcfg.name_labels else d['symbol']),
pc1 = fmt_pct(d.get('percent_change_7d')),
pc2 = fmt_pct(d.get('percent_change_24h')),
pc3 = fmt_pct(d.get('percent_change_1y')),
pc4 = fmt_pct(d.get('percent_change_30d')),
upd = d.get('last_updated_fmt'),
amt = amt_fmt,
**{ k.replace('-','_'): v * (1 if amt is None else amt) for k,v in p.items() }
@ -873,8 +895,10 @@ class Ticker:
col_fs_data = {
'label': fd(f'{{lbl:{self.col1_wid}}}',f'{{lbl:{self.col1_wid}}}',self.col1_wid),
'pct7d': fd(' {pc1:7}', ' {pc1:7}', 8),
'pct24h': fd(' {pc2:7}', ' {pc2:7}', 8),
'pct1y': fd(' {pc3:7}', ' {pc3:7}', 8),
'pct1m': fd(' {pc4:7}', ' {pc4:7}', 8),
'pct1w': fd(' {pc1:7}', ' {pc1:7}', 8),
'pct1d': fd(' {pc2:7}', ' {pc2:7}', 8),
'update_time': fd(' {upd}', ' {upd}', max((19 if cfg.portfolio else 0),self.upd_w) + 2),
'amt': fd(' {amt}', ' {amt}', 21),
}
@ -891,8 +915,10 @@ class Ticker:
[asset.id for asset in self.usr_col_assets] +
[a for a,b in (
( 'btc-bitcoin', not cfg.btc_only ),
( 'pct7d', gcfg.percent_change ),
( 'pct24h', gcfg.percent_change ),
( 'pct1y', 'y' in cfg.percent_cols ),
( 'pct1m', 'm' in cfg.percent_cols ),
( 'pct1w', 'w' in cfg.percent_cols ),
( 'pct1d', 'd' in cfg.percent_cols ),
( 'update_time', gcfg.update_time ),
) if b]
)
@ -915,6 +941,8 @@ class Ticker:
lbl = '',
pc1 = ' CHG_7d',
pc2 = 'CHG_24h',
pc3 = 'CHG_1y',
pc4 = 'CHG_30d',
upd = 'UPDATED',
amt = ' AMOUNT',
usd_us_dollar = 'USD',

View file

@ -14,7 +14,11 @@ mmnode-ticker: Display price information for cryptocurrency and other assets
opts_data = {
'sets': [
('wide', True, 'percent_change', True),
('widest', True, 'percent_cols', 'd,w,m,y'),
('widest', True, 'name_labels', True),
('widest', True, 'thousands_comma', True),
('widest', True, 'update_time', True),
('wide', True, 'percent_cols', 'd,w'),
('wide', True, 'name_labels', True),
('wide', True, 'thousands_comma', True),
('wide', True, 'update_time', True),
@ -45,7 +49,9 @@ opts_data = {
-F, --portfolio Display portfolio data
-l, --list-ids List IDs of all available assets
-n, --name-labels Label rows with asset names rather than symbols
-p, --percent-change Add percentage change columns
-p, --percent-cols=C Add daily, weekly, monthly, or yearly percentage change
columns C (specify with comma-separated letters
{pc})
-P, --pager Pipe the output to a pager
-r, --add-rows=LIST Add rows for asset specifiers in LIST (comma-separated,
see ASSET SPECIFIERS below). Can also be used to supply
@ -54,7 +60,8 @@ opts_data = {
-T, --thousands-comma Use comma as a thousands separator
-u, --update-time Include UPDATED (last update time) column
-v, --verbose Be more verbose
-w, --wide Display all optional columns (equivalent to -punT)
-w, --wide Display most optional columns (same as -unT -p d,w)
-W, --widest Display all optional columns (same as -unT -p d,w,m,y)
-x, --proxy=P Connect via proxy P. Set to the empty string to
completely disable or none to allow override from
environment. Consult the curl manpage for --proxy usage.
@ -169,9 +176,10 @@ $ mmnode-ticker -w -c eurusd=x,omr-omani-rial:2.59r -e2 -x http://vpnhost:8118
# Wide display, elapsed update time, add EUR, BGN columns and BGN/EUR rate:
$ mmnode-ticker -wE -c eurusd=x,bgn-bulgarian-lev:0.5113r:eurusd=x
# Wide display, use cached data from previous network query, show portfolio
# (see above), pipe output to pager, add DOGE row:
$ mmnode-ticker -wCFP -r doge
# Widest display with all percentage change columns, use cached data from
# previous network query, show portfolio (see above), pipe output to pager,
# add DOGE row:
$ mmnode-ticker -WCFP -r doge
# Display 17.234 XMR priced in all configured assets (‘trading’ mode):
$ mmnode-ticker xmr:17.234
@ -206,6 +214,7 @@ To add a portfolio, edit the file
dfl_cachedir = os.path.relpath(dfl_cachedir,start=homedir),
ds = fmt_dict(DataSource.get_sources(),fmt='equal_compact'),
al = DataSource.coinpaprika.dfl_asset_limit,
pc = fmt_list(Ticker.percent_cols,fmt='bare'),
),
'notes': lambda s: s.format(
assets = fmt_list(assets_list_gen(cfg_in),fmt='col',indent=' '),

View file

@ -138,15 +138,16 @@ class CmdTestScripts(CmdTestBase):
def ticker4(self):
return self.ticker(
['--wide','--add-columns=eurusd=x,inr-indian-rupee:79.5'],
['--widest','--add-columns=eurusd=x,inr-indian-rupee:79.5'],
[
r'EURUSD=X \(EUR/USD\) = 1.0642 USD ' +
r'INR \(INDIAN RUPEE\) = 0.012579 USD',
'USD EURUSD=X INR BTC CHG_7d CHG_24h UPDATED',
'USD EURUSD=X INR BTC CHG_1y CHG_30d CHG_7d CHG_24h UPDATED',
'BITCOIN',
r'ETHEREUM 1,659.66 1,559.5846 131,943.14 0.07138094 \+21.42 \+1.82',
r'MONERO 158.97 149.3870 12,638.36 0.00683732 \+7.28 \+1.21 2022-08-02 18:25:59',
r'INDIAN RUPEE 0.01 0.0118 1.00 0.00000054 -- --',
r'ETHEREUM 1,659.66 1,559.5846 131,943.14 0.07138094 \+36.41 \+29.99 \+21.42 \+1.82',
r'MONERO 158.97 149.3870 12,638.36 0.00683732 \+12.38 \+10.19 \+7.28 \+1.21 2022-08-02 18:25:59',
r'S&P 500 4,320.06 4,059.5604 343,444.77 0.18580285 -- -- -- -0.23',
r'INDIAN RUPEE 0.01 0.0118 1.00 0.00000054 -- -- -- --',
])
def ticker5(self):