Bitquery feature branch (#1016)

* Add separate view for finbrain for crypto curreny sentiment analysis

* Move json with symbols to separate directory, little refactoring, update readme

* Add screenshot of finbrain for PolkaDot

* Add bitquery model and view

* Move bitquery to onchain module

* Bitquery added to onchain controller

* Apply long number formatting for big numbers in bitquery commands

* Update README with bitquery API key

* Add error handling for cases when there is no token found, or dextrades response is empty. Use os library to take care of paths to files

* Add helper method to extract dexTrades object from bitquery response. Add timout exception to request function. Add mapping for DECENTRALIZED_EXCHANGES to support lowercase choices:

* Refactor bitquery model and views, prettify column names, remove redundant columns, change command names. Add test for api key

* Update website docs for bitquery

* Add difflib implementation for exchanges in bitquery ttcp command

* Remove menu() from code

* Remove tokens with less than 3 trades (doesn't make sense to show them, as most of them are scams). Add difflib for -coin parameter in baas command
This commit is contained in:
jp
2021-12-10 00:52:58 +01:00
committed by GitHub
parent 67e1ecf986
commit 072c413ac0
15 changed files with 6964 additions and 4 deletions

2
README.md vendored
View File

@@ -312,6 +312,7 @@ These are the ones where a key is necessary:
- Whale Alert API: <https://docs.whale-alert.io/>
- Ethplorer API: <https://github.com/EverexIO/Ethplorer/wiki/Ethplorer-API>
- Cryptopanic API: <https://cryptopanic.com/developers/api/>
- BitQuery API: <https://bitquery.io/pricing>
- Glassnode API: <https://docs.glassnode.com/basic-api/api-key#how-to-get-an-api-key>
- Coinglass API: <https://coinglass.github.io/API-Reference/#api-key>
@@ -342,6 +343,7 @@ Alternatively, you can also set them to the following environment variables:
| [Cryptopanic](https://cryptopanic.com/developers/api/) | GT_API_CRYPTO_PANIC_KEY |
| [Glassnode](https://docs.glassnode.com/basic-api/api-key#how-to-get-an-api-key) | GT_API_GLASSNODE_KEY |
| [Coinglass](https://coinglass.github.io/API-Reference/#api-key) | GT_API_COINGLASS_KEY |
| [BitQuery](https://bitquery.io/pricing) | GT_API_BITQUERY_KEY |
Example:

View File

@@ -111,3 +111,6 @@ API_ETHPLORER_KEY = os.getenv("GT_API_ETHPLORER_KEY") or "freekey"
# https://cryptopanic.com/developers/api/
API_CRYPTO_PANIC_KEY = os.getenv("GT_API_CRYPTO_PANIC_KEY") or "REPLACE_ME"
# https://bitquery.io/pricing
API_BITQUERY_KEY = os.getenv("GT_API_BITQUERY_KEY") or "REPLACE_ME"

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,7 @@
"""Dataframe helpers"""
__docformat__ = "numpy"
import re
from typing import Union, Any
import textwrap
import pandas as pd
@@ -118,3 +119,21 @@ def very_long_number_formatter(num: Union[str, int, float]) -> str:
return f'{formatted_num}{["", "K", "M", "B", "T"][magnitude]}'
return num
def prettify_column_names(columns: list) -> list:
"""Helper method that change column names into more human readable format. E.g.
- tradeAmount => Trade amount,
- tokenValue => Token value
- mediumGasPrice => Medium Gas Price
Parameters
----------
columns: list
list of column names
Returns
-------
list with reformatted columns
"""
return [" ".join(re.findall(".[^A-Z]*", val)).capitalize() for val in columns]

View File

@@ -0,0 +1,667 @@
"""BitQuery model"""
__docformat__ = "numpy"
import datetime
import json
import os
from typing import Optional
import numpy as np
from requests.exceptions import HTTPError
from requests.adapters import HTTPAdapter
import requests
import pandas as pd
from gamestonk_terminal import config_terminal as cfg
class BitQueryApiKeyException(Exception):
"""Bit Query Api Key Exception object"""
def __init__(self, message: str):
super().__init__(message)
self.message = message
def __str__(self) -> str:
return f"BitQueryApiKeyException: {self.message}"
class BitQueryTimeoutException(Exception):
"""BitQuery Timeout Exception class"""
BQ_URL = "https://graphql.bitquery.io"
CURRENCIES = ["ETH", "USD", "BTC", "USDT"]
DECENTRALIZED_EXCHANGES = [
"1inch",
"AfroDex",
"AirSwap",
"Amplbitcratic",
"Balancer",
"BestSwap",
"Bitox",
"CellSwap",
"Cellswap",
"Cofix",
"Coinchangex",
"Curve",
"DDEX",
"DUBIex",
"DecentrEx",
"DeversiFi",
"Dodo",
"ETHERCExchange",
"EtherBlockchain",
"EtherDelta",
"Ethernext",
"Ethfinex",
"FEGex",
"FFFSwap",
"Fordex",
"GUDecks",
"GUDeks",
"HiSwap",
"IDEX",
"LedgerDex",
"Matcha",
"Miniswap",
"Mooniswap",
"Oasis",
"OpenRelay",
"S.Finance",
"SakeSwap",
"SeedDex",
"SingularX",
"StarBitEx",
"SushiSwap",
"SwapX",
"SwitchDex",
"TacoSwap",
"TokenJar",
"TokenStore",
"TokenTrove",
"Tokenlon",
"TradexOne",
"Uniswap",
"ZeusSwap",
"dYdX",
"dex.blue",
]
DECENTRALIZED_EXCHANGES_MAP = {e.lower(): e for e in DECENTRALIZED_EXCHANGES}
NETWORKS = ["bsc", "ethereum", "matic"]
def _extract_dex_trades(data: dict) -> pd.DataFrame:
"""Helper method that extracts from bitquery api response data from nested dictionary:
response = {'ethereum' : {'dexTrades' : <data>}}. If 'dexTrades' is None, raises Exception.
Parameters
----------
data: dict
response data from bitquery api.
Returns
-------
pd.DataFrame
normalized pandas data frame with data
"""
dex_trades = data["ethereum"]["dexTrades"]
if not dex_trades:
raise ValueError("No data was returned in request response\n")
return pd.json_normalize(dex_trades)
def query_graph(url: str, query: str) -> dict:
"""Helper methods for querying graphql api. [Source: https://bitquery.io/]
Parameters
----------
url: str
Endpoint url
query: str
Graphql query
Returns
-------
dict:
Dictionary with response data
"""
session = requests.Session()
session.mount("https://", HTTPAdapter(max_retries=5))
headers = {"x-api-key": cfg.API_BITQUERY_KEY}
timeout = 30
try:
response = session.post(
url, json={"query": query}, headers=headers, timeout=timeout
)
except requests.Timeout as e:
raise BitQueryTimeoutException(
f"BitQuery API didn't respond within {timeout} seconds.\n"
) from e
if response.status_code == 500:
raise HTTPError(f"Internal sever error {response.reason}")
if not 200 <= response.status_code < 300:
raise BitQueryApiKeyException(
f"Invalid Authentication: {response.status_code}. "
f"Please visit https://bitquery.io/pricing and generate you free api key\n"
)
try:
data = response.json()
if "error" in data:
raise ValueError(f"Invalid Response: {data['error']}\n")
except Exception as e:
raise ValueError(f"Invalid Response: {response.text}\n") from e
return data["data"]
def get_erc20_tokens() -> pd.DataFrame:
"""Helper method that loads ~1500 most traded erc20 token.
[Source: json file]
Returns
-------
pd.DataFrame
ERC20 tokens with address, symbol and name
"""
file_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "..", "data", "erc20_coins.json"
)
with open(file_path) as f:
data = json.load(f)
df = pd.json_normalize(data)
df.columns = ["count", "address", "symbol", "name"]
df = df[~df["symbol"].isin(["", None, np.NaN])]
return df[["name", "symbol", "address", "count"]]
def find_token_address(token: str) -> Optional[str]:
"""Helper methods that search for ERC20 coin base on provided symbol or token address.
If erc20 token address is provided, then function checks if it's proper address and returns it back.
In other case mapping data is loaded from file (or cache), and function lookup for belonging token address.
Parameters
----------
token: str
ERC20 token symbol e.g. UNI, SUSHI, ETH, WBTC or token address e.g. 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Returns
-------
str or None
ERC20 token address, or None if nothing found.
"""
if token.startswith("0x") and len(token) >= 38:
return token
if token == "ETH":
return token
token = "WBTC" if token == "BTC" else token
tokens_map: pd.DataFrame = get_erc20_tokens()
found_token = tokens_map.loc[tokens_map["symbol"] == token]
if found_token.empty:
return None
if len(found_token) > 1:
return found_token.sort_values(by="count", ascending=False).iloc[0]["address"]
return found_token.iloc[0]["address"]
def get_dex_trades_by_exchange(
trade_amount_currency: str = "USD", limit: int = 90
) -> pd.DataFrame:
"""Get trades on Decentralized Exchanges aggregated by DEX [Source: https://graphql.bitquery.io/]
Parameters
----------
trade_amount_currency: str
Currency of displayed trade amount. Default: USD
limit: int
Last n days to query data. Maximum 365 (bigger numbers can cause timeouts
on server side)
Returns
-------
pd.DataFrame
Trades on Decentralized Exchanges aggregated by DEX
"""
dt = (datetime.date.today() - datetime.timedelta(min(limit, 365))).strftime(
"%Y-%m-%d"
)
if trade_amount_currency not in CURRENCIES:
trade_amount_currency = "USD"
query = f"""
{{
ethereum {{
dexTrades(options: {{limit: 40, desc: ["count"]}}
date: {{since: "{dt}"}}
) {{
exchange {{
name
}}
count
tradeAmount(in: {trade_amount_currency})
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
df = _extract_dex_trades(data)
df.columns = ["trades", "tradeAmount", "exchange"]
df = df[~df["exchange"].isin([None, np.NaN, ""])]
return df[["exchange", "trades", "tradeAmount"]].sort_values(
by="tradeAmount", ascending=True
)
def get_dex_trades_monthly(
trade_amount_currency: str = "USD", limit: int = 90
) -> pd.DataFrame:
"""Get list of trades on Decentralized Exchanges monthly aggregated. [Source: https://graphql.bitquery.io/]
Parameters
----------
trade_amount_currency: str
Currency of displayed trade amount. Default: USD
limit: int
Last n days to query data. Maximum 365 (bigger numbers can cause timeouts
on server side)
Returns
-------
pd.DataFrame
Trades on Decentralized Exchanges monthly aggregated
"""
if trade_amount_currency not in CURRENCIES:
trade_amount_currency = "USD"
dt = (datetime.date.today() - datetime.timedelta(min(limit, 365))).strftime(
"%Y-%m-%d"
)
query = f"""
{{
ethereum {{
dexTrades(
options: {{desc: ["date.year", "date.month", "count"]}}
date: {{since: "{dt}"}}
) {{
count
date {{
month
year
}}
tradeAmount(in: {trade_amount_currency})
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
if not data:
return pd.DataFrame()
df = _extract_dex_trades(data)
df["date"] = df.apply(
lambda x: datetime.date(int(x["date.year"]), int(x["date.month"]), 1), axis=1
)
df.rename(columns={"count": "trades"}, inplace=True)
return df[["date", "trades", "tradeAmount"]]
def get_daily_dex_volume_for_given_pair(
limit: int = 100,
token: str = "UNI",
vs: str = "USDT",
) -> pd.DataFrame:
"""Get daily volume for given pair [Source: https://graphql.bitquery.io/]
Parameters
-------
limit: int
Last n days to query data
token: str
ERC20 token symbol
vs: str
Quote currency.
Returns
-------
pd.DataFrame
Daily volume for given pair
"""
dt = (datetime.date.today() - datetime.timedelta(min(limit, 365))).strftime(
"%Y-%m-%d"
)
base, quote = find_token_address(token), find_token_address(vs)
if not base or not quote:
raise ValueError("Provided coin or quote currency doesn't exist\n")
query = f"""
{{
ethereum(network: ethereum) {{
dexTrades(
options: {{desc: ["timeInterval.day", "trades"]}}
baseCurrency: {{is: "{base}"}}
quoteCurrency: {{is: "{quote}"}}
date: {{since: "{dt}" }}
) {{
timeInterval {{
day(count: 1)
}}
baseCurrency {{
symbol
}}
quoteCurrency {{
symbol
}}
exchange {{
fullName
}}
trades: count
tradeAmount(in: USD)
quotePrice
maximum_price: quotePrice(calculate: maximum)
minimum_price: quotePrice(calculate: minimum)
open_price: minimum(of: block, get: quote_price)
close_price: maximum(of: block, get: quote_price)
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
if not data:
return pd.DataFrame()
df = _extract_dex_trades(data)
df.columns = [
"trades",
"tradeAmount",
"price",
"high",
"low",
"open",
"close",
"date",
"base",
"quote",
"exchange",
]
return df[
[
"date",
"exchange",
"base",
"quote",
"open",
"high",
"low",
"close",
"tradeAmount",
"trades",
]
].sort_values(by="date", ascending=False)
def get_token_volume_on_dexes(
token: str = "UNI",
trade_amount_currency: str = "USD",
) -> pd.DataFrame:
"""Get token volume on different Decentralized Exchanges. [Source: https://graphql.bitquery.io/]
Parameters
----------
token: str
ERC20 token symbol.
trade_amount_currency: str
Currency to display trade amount in.
Returns
-------
pd.DataFrame
Token volume on Decentralized Exchanges
"""
if trade_amount_currency not in CURRENCIES:
trade_amount_currency = "USD"
token_address = find_token_address(token)
if token_address is None:
raise ValueError(f"Couldn't find token with symbol {token}\n")
query = f"""
{{
ethereum {{
dexTrades(
baseCurrency: {{is:"{token_address}"}}
) {{
baseCurrency{{
symbol
}}
exchange {{
name
fullName
}}
count
tradeAmount(in: {trade_amount_currency})
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
if not data:
return pd.DataFrame()
df = _extract_dex_trades(data)[["exchange.fullName", "tradeAmount", "count"]]
df.columns = ["exchange", "tradeAmount", "trades"]
return df[~df["exchange"].str.startswith("<")].sort_values(
by="tradeAmount", ascending=False
)
def get_ethereum_unique_senders(interval: str = "day", limit: int = 90) -> pd.DataFrame:
"""Get number of unique ethereum addresses which made a transaction in given time interval.
Parameters
----------
interval: str
Time interval in which count unique ethereum addresses which made transaction. day, month or week.
limit: int
Number of records for data query.
Returns
-------
pd.DataFrame
Unique ethereum addresses which made a transaction
"""
intervals = {
"day": 1,
"month": 30,
"week": 7,
}
if interval not in intervals.keys():
interval = "day"
days = min(limit * intervals[interval], 90)
dt = (datetime.date.today() - datetime.timedelta(days)).strftime("%Y-%m-%d")
query = f"""
{{
ethereum(network: ethereum) {{
transactions(options: {{desc: "date.date"}}, date: {{since: "{dt}"}}) {{
uniqueSenders: count(uniq: senders)
date {{
date:startOfInterval(unit: {interval})
}}
averageGasPrice: gasPrice(calculate: average)
mediumGasPrice: gasPrice(calculate: median)
maximumGasPrice: gasPrice(calculate: maximum)
transactions: count
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
if not data:
return pd.DataFrame()
df = pd.DataFrame(data["ethereum"]["transactions"])
df["date"] = df["date"].apply(lambda x: x["date"])
return df[
[
"date",
"uniqueSenders",
"transactions",
"averageGasPrice",
"mediumGasPrice",
"maximumGasPrice",
]
]
def get_most_traded_pairs(
network: str = "ethereum", exchange: str = "Uniswap", limit: int = 90
) -> pd.DataFrame:
"""Get most traded crypto pairs on given decentralized exchange in chosen time period.
[Source: https://graphql.bitquery.io/]
Parameters
----------
network: str
EVM network. One from list: bsc (binance smart chain), ethereum or matic
exchange:
Decentralized exchange name
limit:
Number of days taken into calculation account.
Returns
-------
"""
dt = (datetime.date.today() - datetime.timedelta(limit)).strftime("%Y-%m-%d")
exchange = DECENTRALIZED_EXCHANGES_MAP.get(exchange, "Uniswap")
query = f"""
{{
ethereum(network: {network}){{
dexTrades(options: {{limit: 100, desc: "tradeAmount"}},
exchangeName: {{is: "{exchange}"}}
date: {{since: "{dt}"}}) {{
buyCurrency {{
symbol
}}
sellCurrency{{
symbol
}}
trades: count
tradeAmount(in: USD)
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
if not data:
return pd.DataFrame()
df = _extract_dex_trades(data)
df.columns = ["trades", "tradeAmount", "base", "quoted"]
return df[["base", "quoted", "trades", "tradeAmount"]]
def get_spread_for_crypto_pair(
token: str = "WETH", vs: str = "USDT", limit: int = 30
) -> pd.DataFrame:
"""Get an average bid and ask prices, average spread for given crypto pair for chosen time period.
[Source: https://graphql.bitquery.io/]
Parameters
----------
limit: int
Last n days to query data
token: str
ERC20 token symbol
vs: str
Quoted currency.
Returns
-------
pd.DataFrame
Average bid and ask prices, spread for given crypto pair for chosen time period
"""
dt = (datetime.date.today() - datetime.timedelta(limit)).strftime("%Y-%m-%d")
base, quote = find_token_address(token), find_token_address(vs)
if not base or not quote:
raise ValueError("Provided coin or quote currency doesn't exist\n")
query = f"""
{{
ethereum(network: ethereum){{
dexTrades(
date: {{since:"{dt}"}}
baseCurrency: {{is: "{base}"}},
quoteCurrency: {{is: "{quote}"}}) {{
date {{date}}
baseCurrency {{symbol}}
baseAmount
quoteCurrency {{
symbol
}}
quoteAmount
trades: count
quotePrice
side
}}
}}
}}
"""
data = query_graph(BQ_URL, query)
if not data:
return pd.DataFrame()
df = _extract_dex_trades(data)
columns = ["quotePrice", "date.date", "baseCurrency.symbol", "quoteCurrency.symbol"]
bids = df.query("side == 'SELL'")[columns]
asks = df.query("side == 'BUY'")[columns]
bids.columns = ["averageBidPrice", "date", "baseCurrency", "quoteCurrency"]
asks.columns = ["averageAskPrice", "date", "baseCurrency", "quoteCurrency"]
daily_spread = pd.merge(asks, bids, on=["date", "baseCurrency", "quoteCurrency"])
daily_spread["dailySpread"] = abs(
daily_spread["averageBidPrice"] - daily_spread["averageAskPrice"]
)
return daily_spread[
[
"date",
"baseCurrency",
"quoteCurrency",
"dailySpread",
"averageBidPrice",
"averageAskPrice",
]
].sort_values(by="date", ascending=True)
POSSIBLE_CRYPTOS = list(get_erc20_tokens()["symbol"].unique())

View File

@@ -0,0 +1,398 @@
"""The BitQuery view"""
__docformat__ = "numpy"
import os
from tabulate import tabulate
from gamestonk_terminal.cryptocurrency.dataframe_helpers import (
very_long_number_formatter,
prettify_column_names,
)
from gamestonk_terminal.cryptocurrency.onchain import bitquery_model
from gamestonk_terminal.helper_funcs import export_data
from gamestonk_terminal import feature_flags as gtff
def display_dex_trades(
trade_amount_currency: str = "USD",
kind: str = "dex",
top: int = 20,
days: int = 90,
sortby: str = "tradeAmount",
descend: bool = False,
export: str = "",
) -> None:
"""Trades on Decentralized Exchanges aggregated by DEX or Month [Source: https://graphql.bitquery.io/]
Parameters
----------
kind: str
Aggregate trades by dex or time
trade_amount_currency: str
Currency of displayed trade amount. Default: USD
top: int
Number of records to display
sortby: str
Key by which to sort data
descend: bool
Flag to sort data descending
days: int
Last n days to query data. Maximum 365 (bigger numbers can cause timeouts
on server side)
export : str
Export dataframe data to csv,json,xlsx file
"""
if kind == "time":
df = bitquery_model.get_dex_trades_monthly(trade_amount_currency, days)
df = df.sort_values(by="date", ascending=descend)
else:
df = bitquery_model.get_dex_trades_by_exchange(trade_amount_currency, days)
df = df.sort_values(by=sortby, ascending=descend)
df_data = df.copy()
df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap(
lambda x: very_long_number_formatter(x)
)
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df.head(top),
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
),
"\n",
)
else:
print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"lt",
df_data,
)
def display_daily_volume_for_given_pair(
token: str = "WBTC",
vs: str = "USDT",
top: int = 20,
sortby: str = "date",
descend: bool = False,
export: str = "",
) -> None:
"""Display daily volume for given pair
[Source: https://graphql.bitquery.io/]
Parameters
----------
token: str
ERC20 token symbol or address
vs: str
Quote currency.
top: int
Number of records to display
sortby: str
Key by which to sort data
descend: bool
Flag to sort data descending
export : str
Export dataframe data to csv,json,xlsx file
Returns
-------
pd.DataFrame
Token volume on different decentralized exchanges
"""
df = bitquery_model.get_daily_dex_volume_for_given_pair(
token=token,
vs=vs,
limit=top,
)
if df.empty:
return
df = df.sort_values(by=sortby, ascending=descend)
df_data = df.copy()
df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap(
lambda x: very_long_number_formatter(x)
)
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df.head(top),
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
),
"\n",
)
else:
print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"dvcp",
df_data,
)
def display_dex_volume_for_token(
token: str = "WBTC",
trade_amount_currency: str = "USD",
top: int = 10,
sortby: str = "tradeAmount",
descend: bool = False,
export: str = "",
) -> None:
"""Display token volume on different Decentralized Exchanges. [Source: https://graphql.bitquery.io/]
Parameters
----------
token: str
ERC20 token symbol or address
trade_amount_currency: str
Currency of displayed trade amount. Default: USD
top: int
Number of records to display
sortby: str
Key by which to sort data
descend: bool
Flag to sort data descending
export : str
Export dataframe data to csv,json,xlsx file
Returns
-------
pd.DataFrame
Token volume on different decentralized exchanges
"""
df = bitquery_model.get_token_volume_on_dexes(
token=token,
trade_amount_currency=trade_amount_currency,
).sort_values(by=sortby, ascending=descend)
df_data = df.copy()
df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap(
lambda x: very_long_number_formatter(x)
)
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df.head(top),
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
),
"\n",
)
else:
print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"tv",
df_data,
)
def display_ethereum_unique_senders(
interval: str = "days",
limit: int = 10,
sortby: str = "date",
descend: bool = False,
export: str = "",
) -> None:
"""Display number of unique ethereum addresses which made a transaction in given time interval
[Source: https://graphql.bitquery.io/]
Parameters
----------
interval: str
Time interval in which ethereum address made transaction. month, week or day
limit: int
Number of records to display. It's calculated base on provided interval.
If interval is month then calculation is made in the way: limit * 30 = time period,
in case if interval is set to week, then time period is calculated as limit * 7.
For better user experience maximum time period in days is equal to 90.
sortby: str
Key by which to sort data
descend: bool
Flag to sort data descending
export : str
Export dataframe data to csv,json,xlsx file
Returns
-------
pd.DataFrame
Number of unique ethereum addresses which made a transaction in given time interval
"""
df = bitquery_model.get_ethereum_unique_senders(interval, limit).sort_values(
by=sortby, ascending=descend
)
df[["uniqueSenders", "transactions", "maximumGasPrice"]] = df[
["uniqueSenders", "transactions", "maximumGasPrice"]
].applymap(lambda x: very_long_number_formatter(x))
df_data = df.copy()
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df,
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
),
"\n",
)
else:
print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"ueat",
df_data,
)
def display_most_traded_pairs(
exchange="Uniswap",
days: int = 10,
top: int = 10,
sortby: str = "tradeAmount",
descend: bool = False,
export: str = "",
) -> None:
"""Display most traded crypto pairs on given decentralized exchange in chosen time period.
[Source: https://graphql.bitquery.io/]
Parameters
----------
exchange:
Decentralized exchange name
days:
Number of days taken into calculation account.
sortby: str
Key by which to sort data
descend: bool
Flag to sort data descending
export : str
Export dataframe data to csv,json,xlsx file
Returns
-------
pd.DataFrame
Most traded crypto pairs on given decentralized exchange in chosen time period.
"""
df = bitquery_model.get_most_traded_pairs(
exchange=exchange, limit=days
).sort_values(by=sortby, ascending=descend)
df_data = df.copy()
df[["tradeAmount", "trades"]] = df[["tradeAmount", "trades"]].applymap(
lambda x: very_long_number_formatter(x)
)
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df.head(top),
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
),
"\n",
)
else:
print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"ttcp",
df_data,
)
def display_spread_for_crypto_pair(
token="ETH",
vs="USDC",
days: int = 10,
sortby: str = "date",
descend: bool = False,
export: str = "",
) -> None:
"""Display an average bid and ask prices, average spread for given crypto pair for chosen time period.
[Source: https://graphql.bitquery.io/]
Parameters
----------
days: int
Last n days to query data
token: str
ERC20 token symbol
vs: str
Quoted currency.
sortby: str
Key by which to sort data
descend: bool
Flag to sort data descending
export : str
Export dataframe data to csv,json,xlsx file
Returns
-------
pd.DataFrame
Average bid and ask prices, spread for given crypto pair for chosen time period
"""
df = bitquery_model.get_spread_for_crypto_pair(
token=token, vs=vs, limit=days
).sort_values(by=sortby, ascending=descend)
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
print(
tabulate(
df,
headers=df.columns,
floatfmt=".2f",
showindex=False,
tablefmt="fancy_grid",
),
"\n",
)
else:
print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"baas",
df,
)

View File

@@ -4,6 +4,7 @@ __docformat__ = "numpy"
# pylint: disable=C0302
import argparse
import difflib
from typing import List
from prompt_toolkit.completion import NestedCompleter
@@ -17,12 +18,15 @@ from gamestonk_terminal.helper_funcs import (
check_int_range,
try_except,
system_clear,
EXPORT_ONLY_RAW_DATA_ALLOWED,
)
from gamestonk_terminal.cryptocurrency.onchain import (
ethgasstation_view,
whale_alert_view,
ethplorer_view,
bitquery_view,
bitquery_model,
)
@@ -64,6 +68,12 @@ class OnchainController:
"prices",
"address",
"active",
"lt",
"dvcp",
"tv",
"ueat",
"ttcp",
"baas",
]
CHOICES += CHOICES_COMMANDS
@@ -205,6 +215,7 @@ class OnchainController:
"to",
],
)
parser.add_argument(
"--descend",
action="store_false",
@@ -366,6 +377,7 @@ class OnchainController:
"tokenSymbol",
],
)
parser.add_argument(
"--descend",
action="store_false",
@@ -431,6 +443,7 @@ class OnchainController:
default="timestamp",
choices=["timestamp", "transactionHash", "token", "value"],
)
parser.add_argument(
"--descend",
action="store_false",
@@ -499,6 +512,7 @@ class OnchainController:
"share",
],
)
parser.add_argument(
"--descend",
action="store_false",
@@ -682,6 +696,7 @@ class OnchainController:
"value",
],
)
parser.add_argument(
"--descend",
action="store_false",
@@ -801,6 +816,7 @@ class OnchainController:
"low",
],
)
parser.add_argument(
"--descend",
action="store_false",
@@ -835,6 +851,585 @@ class OnchainController:
except Exception as e:
print(e)
def call_lt(self, other_args: List[str]):
"""Process lt command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="lt",
description="""
Display Trades on Decentralized Exchanges aggregated by DEX or Month
[Source: https://graphql.bitquery.io/]
""",
)
parser.add_argument(
"-k",
"--kind",
dest="kind",
type=str,
help="Aggregate trades by dex or time Default: dex",
default="dex",
choices=["dex", "time"],
)
parser.add_argument(
"-vs",
"--vs",
dest="vs",
type=str,
help="Currency of displayed trade amount.",
default="USD",
choices=bitquery_model.CURRENCIES,
)
parser.add_argument(
"-t",
"--top",
dest="top",
type=check_positive,
help="top N number records",
default=10,
)
parser.add_argument(
"-d",
"--days",
dest="days",
type=check_positive,
help="Number of days to display data for.",
default=90,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column. Default: tradeAmount. For monthly trades date.",
default="tradeAmount",
choices=["trades", "tradeAmount", "exchange"],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
try:
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if not ns_parser:
return
bitquery_view.display_dex_trades(
kind=ns_parser.kind,
trade_amount_currency=ns_parser.vs,
top=ns_parser.top,
days=ns_parser.days,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
except Exception as e:
print(e)
def call_dvcp(self, other_args: List[str]):
"""Process dvcp command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="dvcp",
description="""
Display daily volume for given crypto pair
[Source: https://graphql.bitquery.io/]
""",
)
parser.add_argument(
"-c",
"--coin",
dest="coin",
type=str,
help="ERC20 token symbol or address.",
required="-h" not in other_args,
)
parser.add_argument(
"-t",
"--top",
dest="top",
type=check_positive,
help="top N number records",
default=10,
)
parser.add_argument(
"-vs", "--vs", dest="vs", type=str, help="Quote currency", default="USDT"
)
parser.add_argument(
"-d",
"--days",
dest="days",
type=check_positive,
help="Number of days to display data for.",
default=10,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column.",
default="date",
choices=[
"date",
"exchange",
"base",
"quote",
"open",
"high",
"low",
"close",
"tradeAmount",
"trades",
],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
try:
if other_args:
if not other_args[0][0] == "-":
other_args.insert(0, "-c")
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if not ns_parser:
return
bitquery_view.display_daily_volume_for_given_pair(
token=ns_parser.coin,
vs=ns_parser.vs,
top=ns_parser.days,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
except Exception as e:
print(e)
def call_tv(self, other_args: List[str]):
"""Process tv command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="tv",
description="""
Display token volume on different Decentralized Exchanges.
[Source: https://graphql.bitquery.io/]
""",
)
parser.add_argument(
"-c",
"--coin",
dest="coin",
type=str,
help="ERC20 token symbol or address.",
required="-h" not in other_args,
)
parser.add_argument(
"-vs",
"--vs",
dest="vs",
type=str,
help="Currency of displayed trade amount.",
default="USD",
choices=bitquery_model.CURRENCIES,
)
parser.add_argument(
"-t",
"--top",
dest="top",
type=check_positive,
help="top N number records",
default=10,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column.",
default="trades",
choices=["exchange", "tradeAmount", "trades"],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
try:
if other_args:
if not other_args[0][0] == "-":
other_args.insert(0, "-c")
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if not ns_parser:
return
bitquery_view.display_dex_volume_for_token(
token=ns_parser.coin,
trade_amount_currency=ns_parser.vs,
top=ns_parser.top,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
except Exception as e:
print(e)
def call_ueat(self, other_args: List[str]):
"""Process ueat command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="ueat",
description="""
Display number of unique ethereum addresses which made a transaction in given time interval,
[Source: https://graphql.bitquery.io/]
""",
)
parser.add_argument(
"-t",
"--top",
dest="top",
type=check_positive,
help="top N number records. (Maximum available time period is 90 days."
"Depending on chosen time period, top N records will be recalculated. E.g."
"For interval: month, and top: 10, period of calculation equals to 300, "
"but because of max days limit: 90, it will only return last 3 months (3 records). ",
default=10,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column.",
default="date",
choices=[
"date",
"uniqueSenders",
"transactions",
"averageGasPrice",
"mediumGasPrice",
"maximumGasPrice",
],
)
parser.add_argument(
"-i",
"--interval",
dest="interval",
type=str,
help="Time interval in which ethereum address made transaction. month, week or day. "
"Maximum time period is 90 days (3 months, 14 weeks)",
default="day",
choices=["day", "month", "week"],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
try:
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if not ns_parser:
return
bitquery_view.display_ethereum_unique_senders(
interval=ns_parser.interval,
limit=ns_parser.top,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
except Exception as e:
print(e)
def call_ttcp(self, other_args: List[str]):
"""Process ttcp command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="ttcp",
description="""
Display most traded crypto pairs on given decentralized exchange in chosen time period.
[Source: https://graphql.bitquery.io/]
""",
)
parser.add_argument(
"-t",
"--top",
dest="top",
type=check_positive,
help="top N number records",
default=10,
)
parser.add_argument(
"-e",
"--exchange",
dest="exchange",
type=str,
help="Decentralized exchange name.",
)
parser.add_argument(
"-d",
"--days",
dest="days",
type=check_positive,
help="Number of days to display data for.",
default=30,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column.",
default="tradeAmount",
choices=["base", "quoted", "trades", "tradeAmount"],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
if other_args:
if "-" not in other_args[0]:
other_args.insert(0, "-e")
try:
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if not ns_parser:
return
exchange = "Uniswap"
if ns_parser.exchange:
if ns_parser.exchange in bitquery_model.DECENTRALIZED_EXCHANGES:
exchange = ns_parser.exchange
else:
similar_cmd = difflib.get_close_matches(
ns_parser.exchange,
bitquery_model.DECENTRALIZED_EXCHANGES,
n=1,
cutoff=0.75,
)
if similar_cmd:
print(f"Replacing by '{similar_cmd[0]}'")
exchange = similar_cmd[0]
else:
similar_cmd = difflib.get_close_matches(
ns_parser.exchange,
bitquery_model.DECENTRALIZED_EXCHANGES,
n=1,
cutoff=0.5,
)
if similar_cmd:
print(f"Did you mean '{similar_cmd[0]}'?")
return
print(
f"Couldn't find any exchange with provided name: {ns_parser.exchange}. "
f"Please choose one from list: {bitquery_model.DECENTRALIZED_EXCHANGES}\n"
)
return
else:
print("Exchange not provided setting default to Uniswap.\n")
bitquery_view.display_most_traded_pairs(
days=ns_parser.days,
top=ns_parser.top,
exchange=exchange,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
except Exception as e:
print(e)
def call_baas(self, other_args: List[str]):
"""Process baas command"""
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="baas",
description="""
Display average bid, ask prices, spread for given crypto pair for chosen time period
[Source: https://graphql.bitquery.io/]
""",
)
parser.add_argument(
"-c",
"--coin",
dest="coin",
type=str,
help="ERC20 token symbol or address.",
)
parser.add_argument(
"-vs", "--vs", dest="vs", type=str, help="Quote currency", default="USDT"
)
parser.add_argument(
"-d",
"--days",
dest="days",
type=check_positive,
help="Number of days to display data for.",
default=10,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column.",
default="date",
choices=[
"date",
"baseCurrency",
"quoteCurrency",
"dailySpread",
"averageBidPrice",
"averageAskPrice",
],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
try:
if other_args:
if not other_args[0][0] == "-":
other_args.insert(0, "-c")
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if not ns_parser:
return
if ns_parser.coin:
if ns_parser.coin in bitquery_model.POSSIBLE_CRYPTOS:
bitquery_view.display_spread_for_crypto_pair(
token=ns_parser.coin,
vs=ns_parser.vs,
days=ns_parser.days,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
else:
print(f"Coin '{ns_parser.coin}' does not exist.")
if ns_parser.coin.upper() == "BTC":
token = "WBTC"
else:
similar_cmd = difflib.get_close_matches(
ns_parser.coin,
bitquery_model.POSSIBLE_CRYPTOS,
n=1,
cutoff=0.75,
)
token = similar_cmd[0]
if similar_cmd[0]:
print(f"Replacing by '{token}'")
bitquery_view.display_spread_for_crypto_pair(
token=token,
vs=ns_parser.vs,
days=ns_parser.days,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
export=ns_parser.export,
)
else:
similar_cmd = difflib.get_close_matches(
ns_parser.coin,
bitquery_model.POSSIBLE_CRYPTOS,
n=1,
cutoff=0.5,
)
if similar_cmd:
print(f"Did you mean '{similar_cmd[0]}'?")
else:
print("You didn't provide coin symbol.\n")
return
except Exception as e:
print(e)
def print_help(self):
"""Print help"""
help_text = """
@@ -849,6 +1444,14 @@ Eth Gas Station:
Whale Alert:
whales check crypto wales transactions
BitQuery:
lt last trades by dex or month
dvcp daily volume for crypto pair
tv token volume on DEXes
ueat unique ethereum addresses which made a transaction
ttcp top traded crypto pairs on given decentralized exchange
baas bid, ask prices, average spread for given crypto pair
"""
help_text += f"\nEthereum address: {self.address if self.address else '?'}"
help_text += (
@@ -887,9 +1490,15 @@ def menu():
while True:
# Get input command from user
if session and gtff.USE_PROMPT_TOOLKIT:
completer = NestedCompleter.from_nested_dict(
{c: None for c in onchain_controller.CHOICES}
)
choices: dict = {c: {} for c in onchain_controller.CHOICES}
choices["ttcp"] = {c: None for c in bitquery_model.DECENTRALIZED_EXCHANGES}
choices["baas"]["-c"] = {c: None for c in bitquery_model.POSSIBLE_CRYPTOS}
choices["baas"]["--coin"] = {
c: None for c in bitquery_model.POSSIBLE_CRYPTOS
}
completer = NestedCompleter.from_nested_dict(choices)
an_input = session.prompt(
f"{get_flair()} (crypto)>(onchain)> ",
completer=completer,

View File

@@ -240,7 +240,27 @@ def check_api_keys():
key_dict["BINANCE"] = "Not defined"
else:
key_dict["BINANCE"] = "defined, not tested"
# BitQuery keys
bitquery = cfg.API_BITQUERY_KEY
if "REPLACE_ME" in bitquery:
key_dict["BITQUERY"] = "Not defined"
else:
headers = {"x-api-key": cfg.API_BITQUERY_KEY}
query = """
{
ethereum {
dexTrades(options: {limit: 10, desc: "count"}) {
count
protocol
}}}
"""
r = requests.post(
"https://graphql.bitquery.io", json={"query": query}, headers=headers
)
if r.status_code == 200:
key_dict["BITQUERY"] = "defined, test passed"
else:
key_dict["BITQUERY"] = "defined, test failed"
# SentimentInvestor keys
si_keys = [cfg.API_SENTIMENTINVESTOR_KEY, cfg.API_SENTIMENTINVESTOR_TOKEN]
if "REPLACE_ME" in si_keys:

View File

@@ -0,0 +1,23 @@
```
usage: baas [-c COIN] [-t TOP] [-vs VS] [-d DAYS]
[-s {date,baseCurrency,quoteCurrency,dailySpread,averageBidPrice,averageAskPrice}]
[--descend] [-h] [--export {csv,json,xlsx}]
```
Display average bid, ask prices, spread for given crypto pair for chosen time
period [Source: https://graphql.bitquery.io/]
```
optional arguments:
-c COIN, --coin COIN ERC20 token symbol or address. (default: None)
-t TOP, --top TOP top N number records (default: 10)
-vs VS, --vs VS Quote currency (default: USDT)
-d DAYS, --days DAYS Number of days to display data for. (default: 10)
-s {date,baseCurrency,quoteCurrency,dailySpread,averageBidPrice,averageAskPrice}, --sort {date,baseCurrency,quoteCurrency,dailySpread,averageBidPrice,averageAskPrice}
Sort by given column. (default: date)
--descend Flag to sort in descending order (lowest first)
(default: False)
-h, --help show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -0,0 +1,22 @@
```
usage: tv [-c COIN] [-vs {ETH,USD,BTC,USDT}] [-t TOP]
[-s {exchange,tradeAmount,trades}] [--descend] [-h]
[--export {csv,json,xlsx}]
```
Display daily volume for given crypto pair [Source: https://graphql.bitquery.io/]
```
optional arguments:
-c COIN, --coin COIN ERC20 token symbol or address. (default: None)
-vs {ETH,USD,BTC,USDT}, --vs {ETH,USD,BTC,USDT}
Currency of displayed trade amount. (default: USD)
-t TOP, --top TOP top N number records (default: 10)
-s {exchange,tradeAmount,trades}, --sort {exchange,tradeAmount,trades}
Sort by given column. (default: trades)
--descend Flag to sort in descending order (lowest first)
(default: False)
-h, --help show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -0,0 +1,26 @@
```
usage: lt [-k {dex,time}] [-vs {ETH,USD,BTC,USDT}] [-t TOP] [-d DAYS]
[-s {trades,tradeAmount,exchange}] [--descend] [-h]
[--export {csv,json,xlsx}]
```
Display Trades on Decentralized Exchanges aggregated by DEX or Month [Source: https://graphql.bitquery.io/]
```
optional arguments:
-k {dex,time}, --kind {dex,time}
Aggregate trades by dex or time Default: dex (default:
dex)
-vs {ETH,USD,BTC,USDT}, --vs {ETH,USD,BTC,USDT}
Currency of displayed trade amount. (default: USD)
-t TOP, --top TOP top N number records (default: 10)
-d DAYS, --days DAYS Number of days to display data for. (default: 90)
-s {trades,tradeAmount,exchange}, --sort {trades,tradeAmount,exchange}
Sort by given column. Default: tradeAmount. For
monthly trades date. (default: tradeAmount)
--descend Flag to sort in descending order (lowest first)
(default: False)
-h, --help show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -0,0 +1,28 @@
```
usage: ttcp [-t TOP]
[-e {1inch,afrodex,airswap,amplbitcratic,balancer,bestswap,bitox,cellswap,cofix,coinchangex,curve,ddex,dubiex,decentrex,deversifi,dodo,ethercexchange,etherblockchain,etherdelta,ethernext,ethfinex,fegex,fffswap,fordex,gudecks,gudeks,hiswap,idex,ledgerdex,mat
cha,miniswap,mooniswap,oasis,openrelay,s.finance,sakeswap,seeddex,singularx,starbitex,sushiswap,swapx,switchdex,tacoswap,tokenjar,tokenstore,tokentrove,tokenlon,tradexone,uniswap,zeusswap,dydx,dex.blue}]
[-d DAYS] [-s {base,quoted,trades,tradeAmount}] [--descend] [-h]
[--export {csv,json,xlsx}]
```
Display most traded crypto pairs on given decentralized exchange in chosen
time period [Source: https://graphql.bitquery.io/]
```
optional arguments:
-t TOP, --top TOP top N number records (default: 10)
-e {1inch,afrodex,airswap,amplbitcratic,balancer,bestswap,bitox,cellswap,cofix,coinchangex,curve,ddex,dubiex,decentrex,deversifi,dodo,ethercexchange,etherblockchain,etherdelta,ethernext,ethfinex,fegex,fffswap,fordex,gudecks,gudeks,hiswap,idex,ledgerdex,matcha,miniswa
p,mooniswap,oasis,openrelay,s.finance,sakeswap,seeddex,singularx,starbitex,sushiswap,swapx,switchdex,tacoswap,tokenjar,tokenstore,tokentrove,tokenlon,tradexone,uniswap,zeusswap,dydx,dex.blue}, --exchange {1inch,afrodex,airswap,amplbitcratic,balancer,bestswap,bitox,cell
swap,cofix,coinchangex,curve,ddex,dubiex,decentrex,deversifi,dodo,ethercexchange,etherblockchain,etherdelta,ethernext,ethfinex,fegex,fffswap,fordex,gudecks,gudeks,hiswap,idex,ledgerdex,matcha,miniswap,mooniswap,oasis,openrelay,s.finance,sakeswap,seeddex,singularx,starb
itex,sushiswap,swapx,switchdex,tacoswap,tokenjar,tokenstore,tokentrove,tokenlon,tradexone,uniswap,zeusswap,dydx,dex.blue}
Decentralized exchange name. (default: Uniswap)
-d DAYS, --days DAYS Number of days to display data for. (default: 30)
-s {base,quoted,trades,tradeAmount}, --sort {base,quoted,trades,tradeAmount}
Sort by given column. (default: tradeAmount)
--descend Flag to sort in descending order (lowest first)
(default: False)
-h, --help show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -0,0 +1,23 @@
```
usage: volt [-c COIN] [-vs {ETH,USD,BTC,USDT}] [-t TOP]
[-s {exchange,coin,tradeAmount,trades}] [--descend] [-h]
[--export {csv,json,xlsx}]
```
Display token volume on different Decentralized Exchanges [Source: https://graphql.bitquery.io/]
```
optional arguments:
-c COIN, --coin COIN ERC20 token symbol or address. (default: ETH)
-vs {ETH,USD,BTC,USDT}, --vs {ETH,USD,BTC,USDT}
Currency of displayed trade amount. (default: USD)
-t TOP, --top TOP top N number records (default: 10)
-s {exchange,coin,tradeAmount,trades}, --sort {exchange,coin,tradeAmount,trades}
Sort by given column. (default: trades)
--descend Flag to sort in descending order (lowest first)
(default: False)
-h, --help show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -0,0 +1,30 @@
```
usage: ueat [-t TOP]
[-s {date,uniqueSenders,transactions,averageGasPrice,mediumGasPrice,maximumGasPrice}]
[-i {day,month,week}] [--descend] [-h] [--export {csv,json,xlsx}]
```
Display number of unique ethereum addresses which made a transaction in given
time interval [Source: https://graphql.bitquery.io/]
```
optional arguments:
-t TOP, --top TOP top N number records. (Maximum available time period
is 90 days.Depending on chosen time period, top N
records will be recalculated. E.g.For interval: month,
and top: 10, period of calculation equals to 300, but
because of max days limit: 90, it will only return
last 3 months (3 records). (default: 10)
-s {date,uniqueSenders,transactions,averageGasPrice,mediumGasPrice,maximumGasPrice}, --sort {date,uniqueSenders,transactions,averageGasPrice,mediumGasPrice,maximumGasPrice}
Sort by given column. (default: date)
-i {day,month,week}, --interval {day,month,week}
Time interval in which ethereum address made
transaction. month, week or day. Maximum time period
is 90 days (3 months, 14 weeks) (default: day)
--descend Flag to sort in descending order (lowest first)
(default: False)
-h, --help show this help message (default: False)
--export {csv,json,xlsx}
Export raw data into csv, json, xlsx (default: )
```

View File

@@ -766,6 +766,38 @@ main:
sub:
- name: gwei
ref: "/cryptocurrency/onchain/gwei"
- name: address
ref: "/cryptocurrency/onchain/address"
- name: balance
ref: "/cryptocurrency/onchain/balance"
- name: hist
ref: "/cryptocurrency/onchain/hist"
- name: holders
ref: "/cryptocurrency/onchain/holders"
- name: info
ref: "/cryptocurrency/onchain/info"
- name: ttcp
ref: "/cryptocurrency/onchain/ttcp"
- name: prices
ref: "/cryptocurrency/onchain/prices"
- name: ueat
ref: "/cryptocurrency/onchain/ueat"
- name: baas
ref: "/cryptocurrency/onchain/baas"
- name: th
ref: "/cryptocurrency/onchain/th"
- name: top
ref: "/cryptocurrency/onchain/top"
- name: lt
ref: "/cryptocurrency/onchain/lt"
- name: tx
ref: "/cryptocurrency/onchain/tx"
- name: dvcp
ref: "/cryptocurrency/onchain/dvcp"
- name: tv
ref: "/cryptocurrency/onchain/tv"
- name: whales
ref: "/cryptocurrency/onchain/whales"
- name: nft
ref: "/cryptocurrency/nft"
sub: