mmnode-ticker: support rate asset in asset specifier
This feature adds convenience for users whose native currencies are pegged to
assets other than the US Dollar.
Example:
# Add a column for Bulgarian Lev, which is pegged to the Euro at 0.5113 EUR:
$ mmnode-ticker -wE -c eur,bgn-bulgarian-lev:0.5113r:eur
Testing / demo:
$ test/test.py -e scripts.ticker
This commit is contained in:
parent
3fd9c971bf
commit
f9ba7b89c8
4 changed files with 54 additions and 16 deletions
|
|
@ -83,18 +83,24 @@ def gen_data(data):
|
|||
'id': {r.id for r in cfg.rows if getattr(r,'id',None)} - {'usd-us-dollar'},
|
||||
'symbol': {r.symbol for r in cfg.rows if isinstance(r,tuple) and r.id is None} - {'USD'},
|
||||
}
|
||||
usr_rate_assets = tuple(u.rate_asset for u in cfg.usr_rows + cfg.usr_columns if u.rate_asset)
|
||||
usr_rate_assets_want = {
|
||||
'id': {a.id for a in usr_rate_assets if a.id},
|
||||
'symbol': {a.symbol for a in usr_rate_assets if not a.id}
|
||||
}
|
||||
usr_assets = cfg.usr_rows + cfg.usr_columns + tuple(c for c in (cfg.query or ()) if c)
|
||||
usr_wants = {
|
||||
'id': (
|
||||
{a.id for a in usr_assets if a.id} -
|
||||
{a.id for a in usr_assets + usr_rate_assets if a.id} -
|
||||
{a.id for a in usr_assets if a.rate and a.id} - {'usd-us-dollar'} )
|
||||
,
|
||||
'symbol': (
|
||||
{a.symbol for a in usr_assets if not a.id} -
|
||||
{a.symbol for a in usr_assets + usr_rate_assets if not a.id} -
|
||||
{a.symbol for a in usr_assets if a.rate} - {'USD'} ),
|
||||
}
|
||||
|
||||
found = { 'id': set(), 'symbol': set() }
|
||||
rate_assets = {}
|
||||
|
||||
for k in ['id','symbol']:
|
||||
wants = rows_want[k] | usr_wants[k]
|
||||
|
|
@ -105,6 +111,8 @@ def gen_data(data):
|
|||
die(1,dup_sym_errmsg(d[k]))
|
||||
yield (d['id'],d)
|
||||
found[k].add(d[k])
|
||||
if d[k] in usr_rate_assets_want[k]:
|
||||
rate_assets[d['symbol']] = d # NB: using symbol instead of ID
|
||||
if k == 'id' and len(found[k]) == len(wants):
|
||||
break
|
||||
|
||||
|
|
@ -119,11 +127,12 @@ def gen_data(data):
|
|||
User-supplied rate overrides rate from source data.
|
||||
"""
|
||||
_id = asset.id or f'{asset.symbol}-user-asset-{asset.symbol}'.lower()
|
||||
ra_rate = Decimal(rate_assets[asset.rate_asset.symbol]['price_usd']) if asset.rate_asset else 1
|
||||
yield ( _id, {
|
||||
'symbol': asset.symbol,
|
||||
'id': _id,
|
||||
'price_usd': str(Decimal(1/asset.rate)),
|
||||
'price_btc': str(Decimal(1/asset.rate/btcusd)),
|
||||
'price_usd': str(Decimal(ra_rate/asset.rate)),
|
||||
'price_btc': str(Decimal(ra_rate/asset.rate/btcusd)),
|
||||
'last_updated': int(now),
|
||||
})
|
||||
|
||||
|
|
@ -297,12 +306,12 @@ def make_cfg(cmd_args,cfg_in):
|
|||
|
||||
def parse_usr_asset_arg(s):
|
||||
"""
|
||||
asset_id[:rate]
|
||||
asset_id[:rate[:rate_asset]]
|
||||
"""
|
||||
def parse_parm(s):
|
||||
ss = s.split(':')
|
||||
assert len(ss) in (1,2), f'{s}: malformed argument'
|
||||
asset_id,rate = (*ss,None)[:2]
|
||||
assert len(ss) in (1,2,3), f'{s}: malformed argument'
|
||||
asset_id,rate,rate_asset = (*ss,None,None)[:3]
|
||||
parsed_id = parse_asset_id(asset_id)
|
||||
|
||||
return asset_data(
|
||||
|
|
@ -312,7 +321,8 @@ def make_cfg(cmd_args,cfg_in):
|
|||
rate = (
|
||||
None if rate is None else
|
||||
1 / Decimal(rate[:-1]) if rate.lower().endswith('r') else
|
||||
Decimal(rate) ))
|
||||
Decimal(rate) ),
|
||||
rate_asset = parse_asset_id(rate_asset) if rate_asset else None )
|
||||
|
||||
return tuple(parse_parm(s2) for s2 in s.split(',')) if s else ()
|
||||
|
||||
|
|
@ -326,7 +336,8 @@ def make_cfg(cmd_args,cfg_in):
|
|||
symbol = parsed_id.symbol,
|
||||
id = parsed_id.id,
|
||||
amount = None if amount is None else Decimal(amount),
|
||||
rate = None )
|
||||
rate = None,
|
||||
rate_asset = None )
|
||||
|
||||
ss = s.split(':')
|
||||
assert len(ss) in (2,3,4), f'{s}: malformed argument'
|
||||
|
|
@ -400,7 +411,7 @@ def make_cfg(cmd_args,cfg_in):
|
|||
'portfolio' ])
|
||||
|
||||
query_tuple = namedtuple('query',['asset','to_asset'])
|
||||
asset_data = namedtuple('asset_data',['symbol','id','amount','rate'])
|
||||
asset_data = namedtuple('asset_data',['symbol','id','amount','rate','rate_asset'])
|
||||
asset_tuple = namedtuple('asset_tuple',['symbol','id'])
|
||||
|
||||
usr_rows = parse_usr_asset_arg(opt.add_rows)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
3.1.dev5
|
||||
3.1.dev6
|
||||
|
|
|
|||
|
|
@ -76,19 +76,20 @@ symbol is ambiguous, the full ID must be used. Examples:
|
|||
|
||||
ASSET SPECIFIERS have the following format:
|
||||
|
||||
ASSET[:RATE]
|
||||
ASSET[:RATE[:RATE_ASSET]]
|
||||
|
||||
If the asset referred to by ASSET is not in the source data (see --list-ids),
|
||||
an arbitrarily chosen label may be used. RATE is the USD exchange rate of
|
||||
the asset. When RATE is postfixed with the letter ‘r’, its meaning is
|
||||
reversed, i.e. interpreted as ‘ASSET/USD’ instead of ‘USD/ASSET’. Asset
|
||||
specifier examples:
|
||||
an arbitrarily chosen label may be used. RATE is the exchange rate of the
|
||||
asset in relation to RATE_ASSET, if present, otherwise USD. When RATE is
|
||||
postfixed with the letter ‘r’, its meaning is reversed, i.e. interpreted as
|
||||
‘ASSET/RATE_ASSET’ instead of ‘RATE_ASSET/ASSET’. Asset specifier examples:
|
||||
|
||||
inr:79.5 - INR is not in the source data, so supply rate of
|
||||
79.5 INR to the Dollar (USD/INR)
|
||||
inr:0.01257r - same as above, but use reverse rate (INR/USD)
|
||||
inr-indian-rupee:79.5 - same as first example, but add an arbitrary label
|
||||
omr-omani-rial:2.59r - Omani Rial is pegged to the Dollar at 2.59 USD
|
||||
bgn-bg-lev:0.5113r:eur - Bulgarian Lev is pegged to the Euro at 0.5113 EUR
|
||||
|
||||
A TRADE_SPECIFIER is a single argument in the format:
|
||||
|
||||
|
|
@ -147,6 +148,9 @@ $ mmnode-ticker --btc
|
|||
# proxy:
|
||||
$ mmnode-ticker -w -c eur,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 eur,bgn-bulgarian-lev:0.5113r:eur
|
||||
|
||||
# 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
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ class TestSuiteScripts(TestSuiteBase):
|
|||
('ticker14', 'ticker [--cached-data --wide --btc]'),
|
||||
('ticker15', 'ticker [--cached-data --wide --btc btc:2:usd:45000]'),
|
||||
('ticker16', 'ticker [--cached-data --wide --elapsed -c eur,omr-omani-rial:2.59r'),
|
||||
('ticker17', 'ticker [--cached-data --wide --elapsed -c bgn-bulgarian-lev:0.5113r:eur'),
|
||||
('ticker18', 'ticker [--cached-data --wide --elapsed -c eur,bgn-bulgarian-lev:0.5113r:eur-euro-token'),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -283,3 +285,24 @@ class TestSuiteScripts(TestSuiteBase):
|
|||
r'BITCOIN 23,250.77 22,826.6890 8,977.1328 1.00000000 \+11.15 \+0.89 10 minutes ago',
|
||||
'OMANI RIAL 2.59 2.5428 1.0000 0.00011139 -- -- just now'
|
||||
])
|
||||
|
||||
def ticker17(self):
|
||||
# BGN pegged at 0.5113 EUR
|
||||
return self.ticker(
|
||||
['--wide','--elapsed','-c','bgn-bulgarian-lev:0.5113r:eur'],
|
||||
[
|
||||
r'BGN \(BULGARIAN LEV\) = 0.52080 USD',
|
||||
'USD BGN BTC CHG_7d CHG_24h UPDATED',
|
||||
'BITCOIN 23,250.77 44,644.414 1.00000000',
|
||||
'BULGARIAN LEV 0.52 1.000 0.00002240',
|
||||
])
|
||||
|
||||
def ticker18(self):
|
||||
return self.ticker(
|
||||
['--wide','--elapsed','-c','eur,bgn-bulgarian-lev:0.5113r:eur-euro-token'],
|
||||
[
|
||||
r'BGN \(BULGARIAN LEV\) = 0.52080 USD',
|
||||
'USD EUR BGN BTC CHG_7d CHG_24h UPDATED',
|
||||
'BITCOIN 23,250.77 22,826.6890 44,644.414 1.00000000',
|
||||
'BULGARIAN LEV 0.52 0.5113 1.000 0.00002240',
|
||||
])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue