Browse Source

mmnode-ticker: use coinpaprika `tickers` API call

The MMGen Project 6 months ago
parent
commit
77d8ffb7b9

+ 17 - 11
mmgen_node_tools/Ticker.py

@@ -12,14 +12,14 @@
 mmgen_node_tools.Ticker: Display price information for cryptocurrency and other assets
 """
 
-# We use deprecated coinpaprika ‘ticker’ API for now because it returns ~45% less data.
+# v3.2.dev4: switch to new coinpaprika ‘tickers’ API call (supports ‘limit’ parameter, more historical data)
 # Old ‘ticker’ API  (/v1/ticker):  data['BTC']['price_usd']
 # New ‘tickers’ API (/v1/tickers): data['BTC']['quotes']['USD']['price']
 
 # Possible alternatives:
 # - https://min-api.cryptocompare.com/data/pricemultifull?fsyms=BTC,LTC&tsyms=USD,EUR
 
-import sys,os,re,time,json,yaml,random
+import sys,os,re,time,datetime,json,yaml,random
 from subprocess import run,PIPE,CalledProcessError
 from decimal import Decimal
 from collections import namedtuple
@@ -159,6 +159,10 @@ class DataSource:
 		btc_ratelimit = 10
 		net_data_type = 'json'
 		has_verbose = True
+		dfl_asset_limit = 2000
+
+		def __init__(self):
+			self.asset_limit = int(gcfg.asset_limit or self.dfl_asset_limit)
 
 		def rate_limit_errmsg(self,elapsed):
 			return (
@@ -168,7 +172,10 @@ class DataSource:
 
 		@property
 		def api_url(self):
-			return f'https://{self.api_host}/v1/ticker' + ('/btc-bitcoin' if cfg.btc_only else '')
+			return (
+				f'https://{self.api_host}/v1/tickers/btc-bitcoin' if cfg.btc_only else
+				f'https://{self.api_host}/v1/tickers?limit={self.asset_limit}' if self.asset_limit else
+				f'https://{self.api_host}/v1/tickers' )
 
 		@property
 		def json_fn(self):
@@ -352,7 +359,7 @@ def gen_data(data):
 
 	for d in data['cc']:
 		if d['id'] == 'btc-bitcoin':
-			btcusd = Decimal(d['price_usd'])
+			btcusd = Decimal(str(d['quotes']['USD']['price']))
 			break
 
 	get_id = src_cls['fi'].get_id
@@ -378,13 +385,12 @@ def gen_data(data):
 				if d[k] in wants[k]:
 					if d[k] in found[k]:
 						die(1,dup_sym_errmsg(d[k]))
-					if not d.get('_converted'):
-						d['price_usd'] = Decimal(d['price_usd'])
-						d['price_btc'] = Decimal(d['price_btc'])
-						d['percent_change_7d'] = Decimal(d['percent_change_7d'])
-						d['percent_change_24h'] = Decimal(d['percent_change_24h'])
-						d['last_updated'] = int(d['last_updated'])
-						d['_converted'] = True
+					if not 'price_usd' in d:
+						d['price_usd'] = Decimal(str(d['quotes']['USD']['price']))
+						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['last_updated'] = int(datetime.datetime.fromisoformat(d['last_updated']).timestamp())
 					yield (d['id'],d)
 					found[k].add(d[k])
 					wants[k].remove(d[k])

+ 13 - 7
mmgen_node_tools/main_ticker.py

@@ -25,6 +25,9 @@ opts_data = {
 		'options': """
 -h, --help            Print this help message
 --, --longhelp        Print help message for long options (common options)
+-a, --asset-limit=N   Retrieve data for top ‘N’ cryptocurrencies by market
+                      cap (default: {al}).  To retrieve all available data,
+                      specify a value of zero.
 -A, --adjust=P        Adjust prices by percentage ‘P’.  In ‘trading’ mode,
                       spot and adjusted prices are shown in separate columns.
 -b, --btc             Fetch and display data for Bitcoin only
@@ -137,13 +140,14 @@ Financial data is obtained from {fi.desc}, which currently allows Tor.
 
                              RATE LIMITING NOTE
 
-To protect user privacy, all filtering and processing of cryptocurrency data
-is performed client side so that the remote server does not know which assets
-are being examined.  This means that data for ALL available crypto assets
-(currently over 8000) is fetched with each invocation of the script.  A rate
-limit of {cc.ratelimit} seconds between calls is thus imposed to prevent abuse of the
-remote server.  When the --btc option is in effect, this limit is reduced to
-{cc.btc_ratelimit} seconds.  To bypass the rate limit entirely, use --cached-data.
+To protect user privacy, filtering and processing of cryptocurrency data is
+performed client side so that the remote server does not know which assets
+are being examined.  This is done by fetching data for the top {al} crypto
+assets by market cap (configurable via the --asset-limit option) with each
+invocation of the script.  A rate limit of {cc.ratelimit} seconds between calls is thus
+imposed to prevent abuse of the remote server.  When the --btc option is in
+effect, this limit is reduced to {cc.btc_ratelimit} seconds.  To bypass the rate limit
+entirely, use --cached-data.
 
 Note that financial data obtained from {fi.api_host} is filtered in the
 request, which has privacy implications.  The rate limit for financial data
@@ -201,11 +205,13 @@ To add a portfolio, edit the file
 		'options': lambda s: s.format(
 			dfl_cachedir = os.path.relpath(dfl_cachedir,start=homedir),
 			ds           = fmt_dict(DataSource.get_sources(),fmt='equal_compact'),
+			al           = DataSource.coinpaprika.dfl_asset_limit,
 		),
 		'notes': lambda s: s.format(
 			assets = fmt_list(assets_list_gen(cfg_in),fmt='col',indent='  '),
 			cfg    = os.path.relpath(cfg_in.cfg_file,start=homedir),
 			pf_cfg = os.path.relpath(cfg_in.portfolio_file,start=homedir),
+			al     = DataSource.coinpaprika.dfl_asset_limit,
 			cc     = src_cls['cc'](),
 			fi     = src_cls['fi'](),
 		)

+ 1 - 1
setup.cfg

@@ -19,7 +19,7 @@ classifiers  =
 	Operating System :: Microsoft :: Windows
 
 [options]
-python_requires = >=3.7
+python_requires = >=3.8
 include_package_data = True
 
 install_requires =

+ 6 - 6
test/cmdtest_py_d/ct_misc.py

@@ -132,7 +132,7 @@ class CmdTestScripts(CmdTestBase):
 			[],
 			[
 				'USD BTC',
-				'BTC 23250.77 1.00000000 ETH 1659.66 0.07146397'
+				'BTC 23250.77 1.00000000 ETH 1659.66 0.07138094'
 			])
 
 
@@ -144,8 +144,8 @@ class CmdTestScripts(CmdTestBase):
 				r'INR \(INDIAN RUPEE\) = 0.012579 USD',
 				'USD EURUSD=X INR BTC CHG_7d CHG_24h UPDATED',
 				'BITCOIN',
-				r'ETHEREUM 1,659.66 1,559.5846 131,943.14 0.07146397 \+21.42 \+1.82',
-				r'MONERO 158.97 149.3870 12,638.36 0.00684527 \+7.28 \+1.21 2022-08-02 18:25:59',
+				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 -- --',
 			])
 
@@ -156,8 +156,8 @@ class CmdTestScripts(CmdTestBase):
 			[
 				'Adjusting prices by -0.77%',
 				'USD BTC CHG_7d CHG_24h UPDATED',
-				r'LITECOIN 58.56 0.00252162 \+12.79 \+0.40 2022-08-02 18:25:59',
-				r'MONERO 157.76 0.00679284 \+7.28 \+1.21'
+				r'LITECOIN 58.56 0.00251869 \+12.79 \+0.40 2022-08-02 18:25:59',
+				r'MONERO 157.76 0.00678495 \+7.28 \+1.21'
 			])
 		os.unlink(os.path.join(self.nt_datadir,'ticker-cfg.yaml'))
 		return t
@@ -174,7 +174,7 @@ class CmdTestScripts(CmdTestBase):
 			['--wide','--portfolio'],
 			[
 				'USD BTC CHG_7d CHG_24h UPDATED',
-				r'ETHEREUM 1,659.66 0.07146397 \+21.42 \+1.82 2022-08-02 18:25:59',
+				r'ETHEREUM 1,659.66 0.07138094 \+21.42 \+1.82 2022-08-02 18:25:59',
 				'CARDANO','ALGORAND',
 				'PORTFOLIO','BITCOIN','ETHEREUM','MONERO','CARDANO','ALGORAND','TOTAL'
 			])

+ 1 - 1
test/ref/ticker/ticker-btc.json

@@ -1 +1 @@
-{"id":"btc-bitcoin","name":"Bitcoin","symbol":"BTC","rank":"1","price_usd":"23368.859557988893","price_btc":"1","volume_24h_usd":"24116251608.791744","market_cap_usd":"446560795287","circulating_supply":"19109225","total_supply":"19109231","max_supply":"21000000","percent_change_1h":"-0.23","percent_change_24h":"-1.87","percent_change_7d":"6.05","last_updated":"1659346445"}
+{"id":"btc-bitcoin","name":"Bitcoin","symbol":"BTC","rank":"1","circulating_supply":"19109225","total_supply":"19109231","max_supply":"21000000","last_updated":"2022-08-01T09:34:05Z","quotes":{"USD":{"price":23368.859557988893,"percent_change_1h":-0.23,"percent_change_6h":-1.4960000000000002,"percent_change_24h":-1.87,"percent_change_7d":6.05,"percent_change_30d":8.469999999999999,"percent_change_1y":10.285,"volume_24h":24116251608.791744,"market_cap":446560795287}}}

File diff suppressed because it is too large
+ 0 - 0
test/ref/ticker/ticker.json


Some files were not shown because too many files changed in this diff