Browse Source

mmnode-ticker: display percent change columns in terms of non-USD assets

Any crypto or finance asset may be specified.

Examples:

    # Display percentage changes in relation to Bitcoin:
    $ mmnode-ticker --widest --pchg-unit=btc

    # In relation to Gold:
    $ mmnode-ticker --widest --pchg-unit=gc=f

    # In relation to Euros:
    $ mmnode-ticker --widest --pchg-unit=eurusd=x

    # In relation to the Nasdaq Index:
    $ mmnode-ticker --widest --pchg-unit=^ixic
The MMGen Project 1 month ago
parent
commit
84e8ea65d0

+ 27 - 2
mmgen_node_tools/Ticker.py

@@ -535,6 +535,10 @@ def gen_data(data):
 		'name': 'US Dollar',
 		'price_usd': Decimal(1),
 		'price_btc': Decimal(1) / btcusd,
+		'percent_change_24h': 0.0,
+		'percent_change_7d': 0.0,
+		'percent_change_30d': 0.0,
+		'percent_change_1y': 0.0,
 		'last_updated': None})
 
 def cache_data(data_src, no_overwrite=False):
@@ -742,7 +746,8 @@ def make_cfg(gcfg_arg):
 			{k: tuple(parse_asset_id(e) for e in v) for k, v in cfg_in.cfg['assets'].items()})
 		for hdr, data in (
 				('user_uniq', get_usr_assets()),
-				('portfolio_uniq', get_portfolio_assets())):
+				('portfolio_uniq', get_portfolio_assets()),
+				('pchg_unit_uniq', [pchg_unit] if pchg_unit else None)):
 			if data:
 				if uniq_data := tuple(gen_uniq(data, 'symbol', preload=rows)):
 					rows[hdr] = uniq_data
@@ -791,6 +796,7 @@ def make_cfg(gcfg_arg):
 		'portfolio',
 		'sort',
 		'percent_cols',
+		'pchg_unit',
 		'asset_limit',
 		'cached_data',
 		'elapsed',
@@ -833,6 +839,9 @@ def make_cfg(gcfg_arg):
 	if portfolio and asset_range:
 		die(1, '--portfolio not supported in market cap view')
 
+	pchg_unit = (lambda s: parse_asset_id(s, require_label=False) if s else None)(
+		get_cfg_var('pchg_unit'))
+
 	cfg = cfg_tuple(
 		rows        = create_rows(),
 		usr_rows    = usr_rows,
@@ -849,6 +858,7 @@ def make_cfg(gcfg_arg):
 		portfolio   = portfolio,
 		sort        = get_sort_opt(),
 		percent_cols    = parse_percent_cols(get_cfg_var('percent_cols')),
+		pchg_unit       = pchg_unit,
 		asset_limit     = get_cfg_var('asset_limit'),
 		cached_data     = get_cfg_var('cached_data'),
 		elapsed         = get_cfg_var('elapsed'),
@@ -890,7 +900,7 @@ class Ticker:
 
 		offer = None
 		to_asset = None
-		hidden_groups = ('extra',)
+		hidden_groups = ('extra', 'pchg_unit_uniq')
 
 		def __init__(self, data):
 
@@ -925,6 +935,14 @@ class Ticker:
 					cfg = cfg._replace(
 						portfolio = sorted(cfg.portfolio, key=pf_sort_func, reverse=reverse))
 
+			if cfg.pchg_unit:
+				self.pchg_data = self.data[self.get_id(cfg.pchg_unit)]
+				self.pchg_factors = {k: (self.pchg_data[k] / 100) + 1 for k in (
+					'percent_change_24h',
+					'percent_change_7d',
+					'percent_change_30d',
+					'percent_change_1y')}
+
 			self.col_usd_prices = {k: self.data[k]['price_usd'] for k in self.col_ids}
 			self.prices = {row.id: self.get_row_prices(row.id) for row in self.rows if row.id in data}
 			self.prices['usd-us-dollar'] = self.get_row_prices('usd-us-dollar')
@@ -995,6 +1013,11 @@ class Ticker:
 				text = sort_params[cfg.sort[0]].desc + ('' if cfg.sort[1] else ' [reversed]')
 				yield f'Sort order: {pink(text.upper())}'
 
+			if cfg.pchg_unit:
+				yield 'Percent change unit: {}'.format(orange('{} ({})'.format(
+					self.pchg_data['symbol'],
+					self.pchg_data['name'].upper())))
+
 			for asset in self.usr_col_assets:
 				if asset.symbol != 'USD':
 					usdprice = self.data[asset.id]['price_usd']
@@ -1085,6 +1108,8 @@ class Ticker:
 			def fmt_pct(d, key, wid=7):
 				if (n := d.get(key)) is None:
 					return gray('     --')
+				if cfg.pchg_unit:
+					n = ((((n / 100) + 1) / self.pchg_factors[key]) - 1) * 100
 				return (red, green)[n>=0](f'{n:+{wid}.2f}')
 
 			p = self.prices[d['id']]

+ 1 - 1
mmgen_node_tools/data/version

@@ -1 +1 @@
-3.6.dev8
+3.6.dev9

+ 2 - 0
mmgen_node_tools/main_ticker.py

@@ -63,6 +63,8 @@ opts_data = {
 -t, --testing         Print command(s) to be executed to stdout and exit
 -T, --thousands-comma Use comma as a thousands separator
 -u, --update-time     Include UPDATED (last update time) column
+-U, --pchg-unit=A     Use asset ‘A’ as unit of reference for percentage
+                      change columns (default: USD)
 -v, --verbose         Be more verbose
 -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)

+ 38 - 0
test/cmdtest_d/misc.py

@@ -98,6 +98,9 @@ class CmdTestScripts(CmdTestBase):
 		('ticker27', 'ticker [--sort=rp -r algo,ada]'),
 		('ticker28', 'ticker [--sort=d -r algo,ada]'),
 		('ticker29', 'ticker [--sort=y -r algo,ada]'),
+		('ticker30', 'ticker [--cached-data --wide --pchg-unit=btc --sort=d] (cf with config file)'),
+		('ticker31', 'ticker [--cached-data --wide --pchg-unit=usd] (cf with no USD)'),
+		('ticker32', 'ticker [--cached-data --wide --pchg-unit=gc=f]'),
 	)
 	}
 
@@ -438,3 +441,38 @@ class CmdTestScripts(CmdTestBase):
 			[],
 			['ETHEREUM', 'BITCOIN', 'MONERO', 'S&P', 'DOW', 'NASDAQ', 'CARDANO', 'ALGORAND'],
 			add_opts = ['--widest', '-s', 'y', '-r', 'ada,algo'])
+
+	def ticker30(self):
+		self.copy_file('ticker-cfg-sort-pchg.yaml', 'ticker-cfg.yaml')
+		t = self.ticker(add_opts=['--wide'])
+		chk1 = '\n'.join(t.read().splitlines()[5:-2])
+		self.rm_file('ticker-cfg.yaml')
+
+		self.copy_file('ticker-cfg-bad.yaml', 'ticker-cfg.yaml')
+		t = self.ticker(add_opts=['--wide', '--pchg-unit=btc', '--sort=d'], no_msg=True)
+		chk2 = '\n'.join(t.read().splitlines()[5:-2])
+		self.rm_file('ticker-cfg.yaml')
+
+		assert chk1 == chk2, f'\nOUTPUT 1\n{chk1}\n!= OUTPUT 2\n{chk2}\n'
+		return t
+
+	def ticker31(self):
+		t = self.ticker(add_opts=['--wide'])
+		chk1 = '\n'.join(t.read().splitlines()[5:-2])
+
+		t = self.ticker(add_opts=['--wide', '--pchg-unit=usd'], no_msg=True)
+		chk2 = '\n'.join(t.read().splitlines()[6:-2])
+
+		assert chk1 == chk2, f'\nOUTPUT 1\n{chk1}\n!= OUTPUT 2\n{chk2}\n'
+		return t
+
+	def ticker32(self):
+		return self.ticker(
+			[],
+			[
+				'BITCOIN', r'\+10.99', r'\+7.06', '-1.18', r'\+1.05',
+				'ETHEREUM',
+				'GOLD', r'\+0.00', r'\+0.00', r'\+0.00', r'\+0.00',
+				'SILVER'
+			],
+			add_opts = ['--widest', '--pchg-unit=gc=f'])

+ 14 - 0
test/ref/ticker/ticker-cfg-sort-pchg.yaml

@@ -0,0 +1,14 @@
+sort: d
+pchg_unit: btc
+
+assets:
+  coin1:
+    - btc-bitcoin
+    - ltc-litecoin
+    - eth-ethereum
+    - xmr-monero
+    - bad-badcoin
+  commodity:
+    - gc=f
+    - si=f
+    - bz=f