minor cleanups
This commit is contained in:
parent
015de30cdd
commit
3fd9c971bf
4 changed files with 86 additions and 56 deletions
23
README.md
23
README.md
|
|
@ -12,10 +12,10 @@ First, install [MMGen][6].
|
|||
|
||||
Then,
|
||||
|
||||
$ git clone https://github.com/mmgen/mmgen-node-tools
|
||||
$ cd mmgen-node-tools
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --user dist/*.whl
|
||||
$ git clone https://github.com/mmgen/mmgen-node-tools
|
||||
$ cd mmgen-node-tools
|
||||
$ python3 -m build --no-isolation
|
||||
$ python3 -m pip install --user dist/*.whl
|
||||
|
||||
Also make sure that `~/.local/bin` is in `PATH`.
|
||||
|
||||
|
|
@ -24,9 +24,18 @@ Also make sure that `~/.local/bin` is in `PATH`.
|
|||
*NOTE: the tests require that the MMGen and MMGen Node Tools repositories be
|
||||
located in the same directory.*
|
||||
|
||||
$ test/init.sh
|
||||
$ test/test-release.sh -A # BTC-only testing
|
||||
$ test/test-release.sh # Full testing
|
||||
Initialize the test framework (must be run at least once after cloning, and
|
||||
possibly again after a pull if tests have been updated):
|
||||
|
||||
$ test/init.sh
|
||||
|
||||
BTC-only testing:
|
||||
|
||||
$ test/test-release.sh -A
|
||||
|
||||
Full testing:
|
||||
|
||||
$ test/test-release.sh
|
||||
|
||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
|
|
|||
|
|
@ -87,11 +87,11 @@ def gen_data(data):
|
|||
usr_wants = {
|
||||
'id': (
|
||||
{a.id for a in usr_assets if a.id} -
|
||||
{a.id for a in usr_assets if a.amount and a.id} - {'usd-us-dollar'} )
|
||||
{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 if a.amount} - {'USD'} ),
|
||||
{a.symbol for a in usr_assets if a.rate} - {'USD'} ),
|
||||
}
|
||||
|
||||
found = { 'id': set(), 'symbol': set() }
|
||||
|
|
@ -114,7 +114,7 @@ def gen_data(data):
|
|||
break
|
||||
|
||||
for asset in (cfg.usr_rows + cfg.usr_columns):
|
||||
if asset.amount:
|
||||
if asset.rate:
|
||||
"""
|
||||
User-supplied rate overrides rate from source data.
|
||||
"""
|
||||
|
|
@ -122,8 +122,8 @@ def gen_data(data):
|
|||
yield ( _id, {
|
||||
'symbol': asset.symbol,
|
||||
'id': _id,
|
||||
'price_usd': str(Decimal(1/asset.amount)),
|
||||
'price_btc': str(Decimal(1/asset.amount/btcusd)),
|
||||
'price_usd': str(Decimal(1/asset.rate)),
|
||||
'price_btc': str(Decimal(1/asset.rate/btcusd)),
|
||||
'last_updated': int(now),
|
||||
})
|
||||
|
||||
|
|
@ -280,47 +280,62 @@ def main(cfg_parm,cfg_in_parm):
|
|||
def make_cfg(cmd_args,cfg_in):
|
||||
|
||||
def get_rows_from_cfg(add_data=None):
|
||||
def create_row(e):
|
||||
return asset_tuple(e.split('-')[0].upper(),e)
|
||||
def gen():
|
||||
for n,(k,v) in enumerate(cfg_in.cfg['assets'].items()):
|
||||
yield(k)
|
||||
if add_data and k in add_data:
|
||||
v += tuple(add_data[k])
|
||||
for e in v:
|
||||
yield(create_row(e))
|
||||
yield parse_asset_id(e,True)
|
||||
return tuple(gen())
|
||||
|
||||
def parse_asset_tuple(s):
|
||||
sym,id = (s.split('-')[0],s) if '-' in s else (s,None)
|
||||
return asset_tuple( sym.upper(), id.lower() if id else None )
|
||||
|
||||
def parse_asset_triplet(s,reverse_ok=False):
|
||||
ss = s.split(':')
|
||||
return asset_triplet(
|
||||
*parse_asset_tuple(s if len(ss) == 1 else ss[0]),
|
||||
(
|
||||
None if len(ss) == 1 else
|
||||
1 / Decimal(ss[1][:-1]) if reverse_ok and ss[1].lower().endswith('r') else
|
||||
Decimal(ss[1])
|
||||
))
|
||||
def parse_asset_id(s,require_label=False):
|
||||
sym,label = (*s.split('-',1),None)[:2]
|
||||
if require_label and not label:
|
||||
die(1,f'{s!r}: asset label is missing')
|
||||
return asset_tuple( sym.upper(), (s.lower() if label else None) )
|
||||
|
||||
def parse_usr_asset_arg(s):
|
||||
return tuple(parse_asset_triplet(ss,reverse_ok=True) for ss in s.split(',')) if s else ()
|
||||
"""
|
||||
asset_id[:rate]
|
||||
"""
|
||||
def parse_parm(s):
|
||||
ss = s.split(':')
|
||||
assert len(ss) in (1,2), f'{s}: malformed argument'
|
||||
asset_id,rate = (*ss,None)[:2]
|
||||
parsed_id = parse_asset_id(asset_id)
|
||||
|
||||
return asset_data(
|
||||
symbol = parsed_id.symbol,
|
||||
id = parsed_id.id,
|
||||
amount = None,
|
||||
rate = (
|
||||
None if rate is None else
|
||||
1 / Decimal(rate[:-1]) if rate.lower().endswith('r') else
|
||||
Decimal(rate) ))
|
||||
|
||||
return tuple(parse_parm(s2) for s2 in s.split(',')) if s else ()
|
||||
|
||||
def parse_query_arg(s):
|
||||
"""
|
||||
asset_id:amount[:to_asset_id[:to_amount]]
|
||||
"""
|
||||
def parse_query_asset(asset_id,amount):
|
||||
parsed_id = parse_asset_id(asset_id)
|
||||
return asset_data(
|
||||
symbol = parsed_id.symbol,
|
||||
id = parsed_id.id,
|
||||
amount = None if amount is None else Decimal(amount),
|
||||
rate = None )
|
||||
|
||||
ss = s.split(':')
|
||||
if len(ss) == 2:
|
||||
return query_tuple(
|
||||
asset = parse_asset_triplet(s),
|
||||
to_asset = None )
|
||||
elif len(ss) in (3,4):
|
||||
return query_tuple(
|
||||
asset = parse_asset_triplet(':'.join(ss[:2])),
|
||||
to_asset = parse_asset_triplet(':'.join(ss[2:])),
|
||||
)
|
||||
else:
|
||||
die(1,f'{s}: malformed argument')
|
||||
assert len(ss) in (2,3,4), f'{s}: malformed argument'
|
||||
asset_id,amount,to_asset_id,to_amount = (*ss,None,None)[:4]
|
||||
|
||||
return query_tuple(
|
||||
asset = parse_query_asset(asset_id,amount),
|
||||
to_asset = parse_query_asset(to_asset_id,to_amount) if to_asset_id else None
|
||||
)
|
||||
|
||||
def gen_uniq(obj_list,key,preload=None):
|
||||
found = set([getattr(obj,key) for obj in preload if hasattr(obj,key)] if preload else ())
|
||||
|
|
@ -339,7 +354,7 @@ def make_cfg(cmd_args,cfg_in):
|
|||
|
||||
def get_portfolio_assets(ret=()):
|
||||
if cfg_in.portfolio and opt.portfolio:
|
||||
ret = tuple( asset_tuple(e.split('-')[0].upper(),e) for e in cfg_in.portfolio )
|
||||
ret = (parse_asset_id(e,True) for e in cfg_in.portfolio)
|
||||
return ( 'portfolio', tuple(e for e in ret if (not opt.btc) or e.symbol == 'BTC') )
|
||||
|
||||
def get_portfolio():
|
||||
|
|
@ -357,7 +372,7 @@ def make_cfg(cmd_args,cfg_in):
|
|||
def create_rows():
|
||||
rows = (
|
||||
('trade_pair',) + query if (query and query.to_asset) else
|
||||
('bitcoin',parse_asset_tuple('btc-bitcoin')) if opt.btc else
|
||||
('bitcoin',parse_asset_id('btc-bitcoin')) if opt.btc else
|
||||
get_rows_from_cfg( add_data={'fiat':['usd-us-dollar']} if opt.add_columns else None )
|
||||
)
|
||||
|
||||
|
|
@ -385,7 +400,7 @@ def make_cfg(cmd_args,cfg_in):
|
|||
'portfolio' ])
|
||||
|
||||
query_tuple = namedtuple('query',['asset','to_asset'])
|
||||
asset_triplet = namedtuple('asset_triplet',['symbol','id','amount'])
|
||||
asset_data = namedtuple('asset_data',['symbol','id','amount','rate'])
|
||||
asset_tuple = namedtuple('asset_tuple',['symbol','id'])
|
||||
|
||||
usr_rows = parse_usr_asset_arg(opt.add_rows)
|
||||
|
|
|
|||
|
|
@ -67,22 +67,28 @@ user’s portfolio, while trading mode displays the price of a given quantity
|
|||
of an asset in relation to other assets, optionally comparing an offered
|
||||
price to the spot price.
|
||||
|
||||
ASSETS consist of either a symbol (e.g. ‘xmr’) or full ID consisting of
|
||||
symbol plus label (e.g. ‘xmr-monero’). In cases where the symbol is
|
||||
ambiguous, the full ID must be used. Examples:
|
||||
ASSETS consist of either a symbol (e.g. ‘xmr’) or full ID (see --list-ids)
|
||||
consisting of symbol plus label (e.g. ‘xmr-monero’). In cases where the
|
||||
symbol is ambiguous, the full ID must be used. Examples:
|
||||
|
||||
chf - specify asset by symbol
|
||||
chf-swiss-franc-token - same as above, but use full ID instead of symbol
|
||||
|
||||
ASSET SPECIFIERS consist of an ASSET followed by an optional colon and USD
|
||||
rate. If the asset is not in the source data (see --list-ids), the label
|
||||
part of the ID may be arbitrarily chosen by the user. When the letter ‘r’
|
||||
is appended to the USD rate, the rate is reversed, i.e. treated as ‘USD per
|
||||
asset’ instead of ‘asset per USD’. Asset specifier examples:
|
||||
ASSET SPECIFIERS have the following format:
|
||||
|
||||
inr:79.5 - INR is not in the source data, so supply USD rate
|
||||
inr-indian-rupee:79.5 - same as above, but add an arbitrary label
|
||||
omr-omani-rial:2.59r - OMR is pegged to USD with fixed value of 2.59 USD
|
||||
ASSET[:RATE]
|
||||
|
||||
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:
|
||||
|
||||
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
|
||||
|
||||
A TRADE_SPECIFIER is a single argument in the format:
|
||||
|
||||
|
|
@ -137,7 +143,7 @@ $ mmnode-ticker
|
|||
# Display BTC price only:
|
||||
$ mmnode-ticker --btc
|
||||
|
||||
# Wide display, add EUR and OMR columns, OMRUSD rate, extra precision and
|
||||
# Wide display, add EUR and OMR columns, OMR/USD rate, extra precision and
|
||||
# proxy:
|
||||
$ mmnode-ticker -w -c eur,omr-omani-rial:2.59r -e2 -x http://vpnhost:8118
|
||||
|
||||
|
|
|
|||
|
|
@ -280,6 +280,6 @@ class TestSuiteScripts(TestSuiteBase):
|
|||
r'EUR \(EURO TOKEN\) = 1.0186 USD ' +
|
||||
r'OMR \(OMANI RIAL\) = 2.5900 USD',
|
||||
'USD EUR OMR BTC CHG_7d CHG_24h UPDATED',
|
||||
'BITCOIN',
|
||||
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'
|
||||
])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue