Terra luna (#1197)

* 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 dataframe helper denomination method, add terramoney_fcd model

* add account growth function, goverment proposals function

* add staking ratio and returns for terra:

* Refactor terra model, add terramoney_fcd_view with 2 methods

* Add terramoney_fdc_model views

* add plots for terra fcd views

* add terra fcd to defi controller

* add hugo docs, refactor defi controller

* change export parameters, refactor chart tickers, fix --descend flag in validators command, add multiline formatted string for terra staking report, change tabulate to rich, add terra adress validator
This commit is contained in:
jp
2022-01-17 19:47:59 +01:00
committed by GitHub
parent 880579a732
commit c37a116a25
12 changed files with 1030 additions and 7 deletions

View File

@@ -2,7 +2,7 @@
__docformat__ = "numpy"
import re
from typing import Union, Any
from typing import Union, Any, Optional
import textwrap
import pandas as pd
from gamestonk_terminal.helper_funcs import long_number_format
@@ -137,3 +137,46 @@ def prettify_column_names(columns: list) -> list:
list with reformatted columns
"""
return [" ".join(re.findall(".[^A-Z]*", val)).capitalize() for val in columns]
def denominate_number(
number: Any, divider: int = 1000000, round_digits: Optional[int] = 4
) -> float:
"""Denominate numbers base on provided divider and round number by provided digit
Parameters
----------
number: Any
value to round
divider: int
divide by value
round_digits:
round number to n digits
Returns
-------
float:
denominated number
"""
if round_digits:
return round(float(number) / divider, round_digits)
return round(float(number) / divider)
def replace_unicode(x: Any) -> Any:
"""Replace unicode characters to ?
Parameters
----------
x: Any
value to replace unicode chars
Returns
-------
Any
replaced value
"""
if isinstance(x, str):
return x.encode("ascii", "replace").decode()
return x

View File

@@ -1,6 +1,8 @@
"""Defi Controller Module"""
__docformat__ = "numpy"
# pylint: disable=C0302
import argparse
from typing import List
@@ -11,6 +13,8 @@ from gamestonk_terminal.cryptocurrency.defi import (
coindix_model,
terraengineer_model,
terraengineer_view,
terramoney_fcd_view,
terramoney_fcd_model,
)
from gamestonk_terminal.parent_classes import BaseController
from gamestonk_terminal import feature_flags as gtff
@@ -18,6 +22,7 @@ from gamestonk_terminal.menu import session
from gamestonk_terminal.helper_funcs import (
parse_known_args_and_warn,
check_positive,
check_terra_address_format,
EXPORT_ONLY_RAW_DATA_ALLOWED,
EXPORT_BOTH_RAW_DATA_AND_FIGURES,
)
@@ -54,6 +59,12 @@ class DefiController(BaseController):
"vaults",
"ayr",
"aterra",
"sinfo",
"validators",
"govp",
"gacc",
"sratio",
"sreturn",
]
PATH = "/crypto/defi/"
@@ -75,6 +86,14 @@ class DefiController(BaseController):
choices["vaults"]["-k"] = {c: {} for c in coindix_model.VAULT_KINDS}
choices["vaults"]["-c"] = {c: {} for c in coindix_model.CHAINS}
choices["vaults"]["-p"] = {c: {} for c in coindix_model.PROTOCOLS}
choices["govp"]["-s"] = {c: {} for c in terramoney_fcd_model.GOV_COLUMNS}
choices["govp"]["--status"] = {
c: {} for c in terramoney_fcd_model.GOV_STATUSES
}
choices["validators"]["-s"] = {
c: {} for c in terramoney_fcd_model.VALIDATORS_COLUMNS
}
self.completer = NestedCompleter.from_nested_dict(choices)
def print_help(self):
@@ -95,12 +114,19 @@ class DefiController(BaseController):
swaps Recent swaps done on Uniswap
[src][Defi Llama][/src]
ldapps Lists dApps
gdapps Display top DeFi dApps grouped by chain
stvl Display historical values of the total sum of TVLs from all dApps
dtvl Display historical total value locked (TVL) by dApp
gdapps Displays top DeFi dApps grouped by chain
stvl Displays historical values of the total sum of TVLs from all dApps
dtvl Displays historical total value locked (TVL) by dApp
[src][Terra Engineer][/src]
aterra Displays 30-day history of specified asset in terra address
ayr Displays 30-day history of anchor yield reserve[/cmds]
aterra Displays 30-day history of specified asset in terra address [src][Terra Engineer][/src]
ayr Displays 30-day history of anchor yield reserve [src][Terra Engineer][/src]
[src][Terra FCD][/src]
sinfo Displays staking info for provided terra account address
validators Displays information about terra blockchain validators
govp Displays terra blockchain governance proposals list
gacc Displays terra blockchain account growth history
sratio Displays terra blockchain staking ratio history
sreturn Displays terra blockchain staking returns history[/cmds]
"""
console.print(text=help_text, menu="Cryptocurrency - Decentralized Finance")
@@ -125,7 +151,7 @@ class DefiController(BaseController):
parser.add_argument(
"--address",
dest="address",
type=str,
type=check_terra_address_format,
help="Terra address. Valid terra addresses start with 'terra'",
required=True,
)
@@ -167,6 +193,265 @@ class DefiController(BaseController):
if ns_parser:
terraengineer_view.display_anchor_yield_reserve(export=ns_parser.export)
def call_sinfo(self, other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="sinfo",
description="""
Displays staking info of a certain terra address.
[Source: https://fcd.terra.dev/swagger]
""",
)
parser.add_argument(
"-a",
"--address",
dest="address",
type=check_terra_address_format,
help="Terra address. Valid terra addresses start with 'terra'",
required="-h" not in other_args,
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
type=check_positive,
help="Number of delegations",
default=10,
)
if other_args and not other_args[0][0] == "-":
other_args.insert(0, "-a")
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
terramoney_fcd_view.display_account_staking_info(
export=ns_parser.export, address=ns_parser.address, top=ns_parser.limit
)
def call_validators(self, other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="validators",
description="""
Displays information about terra validators.
[Source: https://fcd.terra.dev/swagger]
""",
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
type=check_positive,
help="Number of validators to show",
default=10,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column. Default: votingPower",
default="votingPower",
choices=[
"validatorName",
"tokensAmount",
"votingPower",
"commissionRate",
"status",
"uptime",
],
)
parser.add_argument(
"--descend",
action="store_true",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
terramoney_fcd_view.display_validators(
export=ns_parser.export,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
top=ns_parser.limit,
)
def call_govp(self, other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="govp",
description="""
Displays terra blockchain governance proposals list.
[Source: https://fcd.terra.dev/swagger]
""",
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
type=check_positive,
help="Number of proposals to show",
default=10,
)
parser.add_argument(
"-s",
"--sort",
dest="sortby",
type=str,
help="Sort by given column. Default: id",
default="id",
choices=terramoney_fcd_model.GOV_COLUMNS,
)
parser.add_argument(
"--status",
dest="status",
type=str,
help="Status of proposal. Default: all",
default="all",
choices=terramoney_fcd_model.GOV_STATUSES,
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_ONLY_RAW_DATA_ALLOWED
)
if ns_parser:
terramoney_fcd_view.display_gov_proposals(
status=ns_parser.status,
export=ns_parser.export,
sortby=ns_parser.sortby,
descend=ns_parser.descend,
top=ns_parser.limit,
)
def call_gacc(self, other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="gacc",
description="""
Displays terra blockchain account growth history.
[Source: https://fcd.terra.dev/swagger]
""",
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
type=check_positive,
help="Number of days to show",
default=90,
)
parser.add_argument(
"--cumulative",
action="store_false",
help="Show cumulative or discrete values. For active accounts only discrete value are available",
dest="cumulative",
default=True,
)
parser.add_argument(
"-k",
"--kind",
dest="kind",
type=str,
help="Total account count or active account count. Default: total",
default="total",
choices=["active", "total"],
)
parser.add_argument(
"--descend",
action="store_false",
help="Flag to sort in descending order (lowest first)",
dest="descend",
default=False,
)
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
terramoney_fcd_view.display_account_growth(
kind=ns_parser.kind,
export=ns_parser.export,
cumulative=ns_parser.cumulative,
top=ns_parser.limit,
)
def call_sratio(self, other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="sratio",
description="""
Displays terra blockchain staking ratio history.
[Source: https://fcd.terra.dev/swagger]
""",
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
type=check_positive,
help="Number of days to show",
default=90,
)
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
terramoney_fcd_view.display_staking_ratio_history(
export=ns_parser.export, top=ns_parser.limit
)
def call_sreturn(self, other_args: List[str]):
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="sreturn",
description="""
Displays terra blockchain staking returns history.
[Source: https://fcd.terra.dev/swagger]
""",
)
parser.add_argument(
"-l",
"--limit",
dest="limit",
type=check_positive,
help="Number of days to show",
default=90,
)
ns_parser = parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
terramoney_fcd_view.display_staking_returns_history(
export=ns_parser.export, top=ns_parser.limit
)
def call_dpi(self, other_args: List[str]):
"""Process dpi command"""
parser = argparse.ArgumentParser(

View File

@@ -0,0 +1,273 @@
"""Terra Money FCD model"""
__docformat__ = "numpy"
import textwrap
from typing import Any, Tuple
from datetime import datetime
import requests
import pandas as pd
from gamestonk_terminal.cryptocurrency.dataframe_helpers import (
denominate_number,
prettify_column_names,
replace_unicode,
)
GOV_COLUMNS = [
"submitTime",
"id",
"depositEndTime",
"status",
"type",
"title",
"Yes",
"No",
]
GOV_STATUSES = ["voting", "deposit", "passed", "rejected", "all"]
VALIDATORS_COLUMNS = [
"validatorName",
"tokensAmount",
"votingPower",
"commissionRate",
"status",
"uptime",
]
def _make_request(endpoint: str) -> dict:
"""Helper method handles terra fcd api requests. [Source: https://fcd.terra.dev/v1]
Parameters
----------
endpoint: str
endpoint url
Returns
-------
dict:
dictionary with response data
"""
url = f"https://fcd.terra.dev/v1/{endpoint}"
response = requests.get(
url, headers={"Accept": "application/json", "User-Agent": "GST"}
)
if not 200 <= response.status_code < 300:
raise Exception(f"fcd terra api exception: {response.text}")
try:
return response.json()
except Exception as e:
raise ValueError(f"Invalid Response: {response.text}") from e
def _adjust_delegation_info(delegation: dict) -> dict:
"""Helper method which removes redundant fields from delegation info dictionary,
and denominate value fields. [Source: https://fcd.terra.dev/v1]
Parameters
----------
delegation:
dictionary object with delegation data e.g.
Returns
-------
dict
adjusted dictionary with delegation data
"""
delegation_info = {}
for key, value in delegation.items():
if key in ["amountDelegated", "totalReward"]:
delegation_info[key] = denominate_number(value)
elif key in ["validatorAddress", "rewards"]:
continue
else:
delegation_info[key] = value
return delegation_info
def get_staking_account_info(address: str = "") -> Tuple[pd.DataFrame, str]:
"""Get staking info for provided terra account [Source: https://fcd.terra.dev/swagger]
Parameters
----------
address: str
terra blockchain address e.g. terra1jvwelvs7rdk6j3mqdztq5tya99w8lxk6l9hcqg
Returns
-------
Tuple[pd.DataFrame, str]:
luna delegations and summary report for given address
"""
response = _make_request(f"staking/{address}")
results: dict[str, Any] = {"myDelegations": []}
for field in ["availableLuna", "delegationTotal"]:
results[field] = denominate_number(response.get(field, 0))
my_delegations = response.get("myDelegations")
if my_delegations:
for delegation in my_delegations:
validator = _adjust_delegation_info(delegation)
results["myDelegations"].append(validator)
df = pd.DataFrame(results["myDelegations"])
try:
df["validatorName"] = df["validatorName"].apply(lambda x: replace_unicode(x))
df.columns = prettify_column_names(list(df.columns))
except KeyError:
df = pd.DataFrame()
results["totalRewards"] = denominate_number(
response.get("rewards", {}).get("total", 0)
)
report = f"""Overview:
Address: {address}
Available Luna: {results['availableLuna']}
Delegated Luna: {results['delegationTotal']}
Total Rewards: {results['totalRewards']}\n"""
report += "\nDelegations: " if not df.empty else "\nNo delegations found\n"
return df, report
def get_validators() -> pd.DataFrame:
"""Get information about terra validators [Source: https://fcd.terra.dev/swagger]
Returns
-------
pd.DataFrame
terra validators details
"""
response = _make_request("staking")["validators"]
results = []
for validator in response:
results.append(
{
"accountAddress": validator["accountAddress"],
"validatorName": validator["description"].get("moniker"),
"tokensAmount": denominate_number(validator["tokens"]),
"votingPower": round(
(float(validator["votingPower"].get("weight")) * 100), 2
),
"commissionRate": round(
(float(validator["commissionInfo"].get("rate", 0)) * 100), 2
),
"status": validator["status"],
"uptime": round((float(validator.get("upTime", 0)) * 100), 2),
}
)
return pd.DataFrame(results).sort_values(by="votingPower")
def get_proposals(status: str = "") -> pd.DataFrame:
"""Get terra blockchain governance proposals list [Source: https://fcd.terra.dev/swagger]
Parameters
----------
status: str
status of proposal, one from list: ['Voting','Deposit','Passed','Rejected']
Returns
-------
pd.DataFrame
Terra blockchain governance proposals list
"""
statuses = ["Voting", "Deposit", "Passed", "Rejected"]
response = _make_request("gov/proposals")["proposals"]
results = []
votes_options = ["Yes", "Abstain", "No", "NoWithVeto"]
for proposal in response:
deposit = proposal.pop("deposit")
proposal["depositEndTime"] = deposit.get("depositEndTime")
vote = proposal.pop("vote")
proposal.pop("proposer")
for opt in votes_options:
proposal[opt] = vote["count"].get(opt)
results.append(proposal)
columns = [
"id",
"submitTime",
"depositEndTime",
"status",
"type",
"title",
"Yes",
"No",
"Abstain",
"NoWithVeto",
]
df = pd.DataFrame(results)[columns]
df[["id", "Yes", "No", "Abstain", "NoWithVeto"]] = df[
["id", "Yes", "No", "Abstain", "NoWithVeto"]
].astype(int, errors="ignore")
df["title"] = df["title"].apply(
lambda x: "\n".join(textwrap.wrap(x, width=40)) if isinstance(x, str) else x
)
for col in ["submitTime", "depositEndTime"]:
df[col] = df[col].apply(lambda x: pd.to_datetime(x).strftime("%Y-%m-%d %H:%M"))
if status.title() in statuses:
df = df[df["status"] == status.title()]
return df
def get_account_growth(cumulative: bool = True) -> pd.DataFrame:
"""Get terra blockchain account growth history [Source: https://fcd.terra.dev/swagger]
Parameters
----------
cumulative: bool
distinguish between periodical and cumulative account growth data
Returns
-------
pd.DataFrame
historical data of accounts growth
"""
response = _make_request("dashboard/account_growth")
kind = "cumulative" if cumulative else "periodic"
df = pd.DataFrame(response[kind])
df["date"] = df["datetime"].apply(lambda x: datetime.fromtimestamp(x / 1000).date())
df = df[["date", "totalAccountCount", "activeAccountCount"]]
df.columns = ["date", "Total accounts", "Active accounts"]
return df
def get_staking_ratio_history():
"""Get terra blockchain staking ratio history [Source: https://fcd.terra.dev/swagger]
Returns
-------
pd.DataFrame
historical staking ratio
"""
response = _make_request("dashboard/staking_ratio")
df = pd.DataFrame(response)
df["date"] = df["datetime"].apply(lambda x: datetime.fromtimestamp(x / 1000).date())
df["stakingRatio"] = df["stakingRatio"].apply(lambda x: round(float(x) * 100, 2))
return df[["date", "stakingRatio"]]
def get_staking_returns_history():
"""Get terra blockchain staking returns history [Source: https://fcd.terra.dev/v1]
Returns
-------
pd.DataFrame
historical staking returns
"""
response = _make_request("dashboard/staking_return")
df = pd.DataFrame(response)
df["date"] = df["datetime"].apply(lambda x: datetime.fromtimestamp(x / 1000).date())
df["annualizedReturn"] = df["annualizedReturn"].apply(
lambda x: round(float(x) * 100, 2)
)
return df[["date", "annualizedReturn"]]

View File

@@ -0,0 +1,299 @@
"""Terra Money FCD view"""
__docformat__ = "numpy"
import os
import matplotlib.pyplot as plt
from matplotlib import ticker, dates as mdates
from gamestonk_terminal.cryptocurrency.defi import terramoney_fcd_model
from gamestonk_terminal.helper_funcs import (
export_data,
long_number_format,
plot_autoscale,
rich_table_from_df,
)
from gamestonk_terminal.cryptocurrency.dataframe_helpers import (
prettify_column_names,
very_long_number_formatter,
)
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.config_plot import PLOT_DPI
from gamestonk_terminal.rich_config import console
def display_account_staking_info(
address: str = "", top: int = 10, export: str = ""
) -> None:
"""Display staking info for provided terra account address [Source: https://fcd.terra.dev/swagger]
Parameters
----------
address: str
terra blockchain address e.g. terra1jvwelvs7rdk6j3mqdztq5tya99w8lxk6l9hcqg
top: int
Number of records to display
export : str
Export dataframe data to csv,json,xlsx file
"""
df, report = terramoney_fcd_model.get_staking_account_info(address)
console.print(report)
if not df.empty:
if gtff.USE_TABULATE_DF:
console.print(
rich_table_from_df(
df.head(top),
headers=list(df.columns),
floatfmt=".2f",
show_index=False,
),
"\n",
)
else:
console.print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"sinfo",
df,
)
def display_validators(
top: int = 10, sortby: str = "votingPower", descend: bool = False, export: str = ""
) -> None:
"""Display information about terra validators [Source: https://fcd.terra.dev/swagger]
Parameters
----------
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
"""
df = terramoney_fcd_model.get_validators()
df_data = df.copy()
df = df.sort_values(by=sortby, ascending=descend)
df["tokensAmount"] = df["tokensAmount"].apply(
lambda x: very_long_number_formatter(x)
)
df.columns = [
x if x not in ["Voting power", "Commission rate", "Uptime"] else f"{x} %"
for x in prettify_column_names(df.columns)
]
if gtff.USE_TABULATE_DF:
console.print(
rich_table_from_df(
df.head(top),
headers=list(df.columns),
floatfmt=".2f",
show_index=False,
),
"\n",
)
else:
console.print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"validators",
df_data,
)
def display_gov_proposals(
top: int = 10,
status: str = "all",
sortby: str = "id",
descend: bool = False,
export: str = "",
) -> None:
"""Display terra blockchain governance proposals list [Source: https://fcd.terra.dev/swagger]
Parameters
----------
top: int
Number of records to display
status: str
status of proposal, one from list: ['Voting','Deposit','Passed','Rejected']
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
"""
df = terramoney_fcd_model.get_proposals(status)
df_data = df.copy()
df = df.sort_values(by=sortby, ascending=descend).head(top)
df.columns = prettify_column_names(df.columns)
if gtff.USE_TABULATE_DF:
console.print(
rich_table_from_df(
df,
headers=list(df.columns),
floatfmt=".2f",
show_index=False,
),
"\n",
)
else:
console.print(df.to_string, "\n")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"govp",
df_data,
)
def display_account_growth(
kind: str = "total", cumulative: bool = False, top: int = 90, export: str = ""
) -> None:
"""Display terra blockchain account growth history [Source: https://fcd.terra.dev/swagger]
Parameters
----------
top: int
Number of records to display
kind: str
display total account count or active account count. One from list [active, total]
cumulative: bool
Flag to show cumulative or discrete values. For active accounts only discrete value are available.
export : str
Export dataframe data to csv,json,xlsx file
"""
df = terramoney_fcd_model.get_account_growth(cumulative)
if kind not in ["active", "total"]:
kind = "total"
options = {"total": "Total accounts", "active": "Active accounts"}
opt = options[kind]
label = "Cumulative" if cumulative and opt == "total" else "Daily"
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
df = df.sort_values("date", ascending=False).head(top)
df = df.set_index("date")
start, end = df.index[-1], df.index[0]
if cumulative:
ax.plot(df[opt], label=df[opt])
else:
ax.bar(x=df.index, height=df[opt], label=df[opt])
ax.set_ylabel(f"{opt}")
ax.set_xlabel("Date")
dateFmt = mdates.DateFormatter("%m/%d/%Y")
ax.xaxis.set_major_formatter(dateFmt)
ax.get_yaxis().set_major_formatter(
ticker.FuncFormatter(lambda x, _: long_number_format(x))
)
fig.tight_layout(pad=8)
ax.set_title(f"{label} number of {opt.lower()} in period from {start} to {end}")
ax.grid(alpha=0.5)
ax.tick_params(axis="x", labelrotation=45)
if gtff.USE_ION:
plt.ion()
plt.show()
print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"gacc",
df,
)
def display_staking_ratio_history(top: int = 90, export: str = "") -> None:
"""Display terra blockchain staking ratio history [Source: https://fcd.terra.dev/v1]
Parameters
----------
top: int
Number of records to display
export : str
Export dataframe data to csv,json,xlsx file
"""
df = terramoney_fcd_model.get_staking_ratio_history()
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
df = df.sort_values("date", ascending=False).head(top)
df = df.set_index("date")
start, end = df.index[-1], df.index[0]
ax.plot(df, label=df["stakingRatio"])
ax.set_ylabel("Staking ratio [%]")
ax.set_xlabel("Date")
dateFmt = mdates.DateFormatter("%m/%d/%Y")
ax.xaxis.set_major_formatter(dateFmt)
fig.tight_layout(pad=8)
ax.set_title(f"Staking ratio in period from {start} to {end}")
ax.grid(alpha=0.5)
ax.tick_params(axis="x", labelrotation=45)
if gtff.USE_ION:
plt.ion()
plt.show()
print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"sratio",
df,
)
def display_staking_returns_history(top: int = 90, export: str = "") -> None:
"""Display terra blockchain staking returns history [Source: https://fcd.terra.dev/swagger]
Parameters
----------
top: int
Number of records to display
export : str
Export dataframe data to csv,json,xlsx file
"""
df = terramoney_fcd_model.get_staking_returns_history()
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
df = df.sort_values("date", ascending=False).head(top)
df = df.set_index("date")
start, end = df.index[-1], df.index[0]
ax.plot(df, label=df["annualizedReturn"])
ax.set_ylabel("Staking returns [%]")
ax.set_xlabel("Date")
dateFmt = mdates.DateFormatter("%m/%d/%Y")
ax.xaxis.set_major_formatter(dateFmt)
fig.tight_layout(pad=8)
ax.set_title(f"Staking returns in period from {start} to {end}")
ax.grid(alpha=0.5)
ax.tick_params(axis="x", labelrotation=45)
if gtff.USE_ION:
plt.ion()
plt.show()
print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"sreturn",
df,
)

View File

@@ -161,6 +161,27 @@ def check_non_negative(value) -> int:
return new_value
def check_terra_address_format(address: str) -> str:
"""Validate if terra account address has proper format: ^terra1[a-z0-9]{38}$
Parameters
----------
address: str
terra blockchain account address
Returns
-------
str
Terra blockchain address or raise argparse exception
"""
pattern = re.compile(r"^terra1[a-z0-9]{38}$")
if not pattern.match(address):
raise argparse.ArgumentTypeError(
f"Terra address: {address} has invalid format. Valid format: ^terra1[a-z0-9]{{38}}$"
)
return address
def check_non_negative_float(value) -> float:
"""Argparse type to check non negative int"""
new_value = float(value)

View File

@@ -0,0 +1,17 @@
```
usage: gacc [-l LIMIT] [--cumulative] [-k {active,total}] [--descend] [-h] [--export {csv,json,xlsx}]
```
Displays terra blockchain account growth history. [Source: https://fcd.terra.dev/swagger]
```
optional arguments:
-l LIMIT, --limit LIMIT
Number of days to show (default: 90)
--cumulative Show cumulative or discrete values. For active accounts only discrete value are available (default: True)
-k {active,total}, --kind {active,total}
Total account count or active account count. Default: total (default: total)
--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,17 @@
```
usage: govp [-l LIMIT] [-s {submitTime,id,depositEndTime,status,type,title,Yes,No}] [--status {voting,deposit,passed,rejected,all}] [--descend] [-h] [--export {csv,json,xlsx}]
```
Displays terra blockchain governance proposals list. [Source: https://fcd.terra.dev/swagger]
```
optional arguments:
-l LIMIT, --limit LIMIT
Number of proposals to show (default: 10)
-s {submitTime,id,depositEndTime,status,type,title,Yes,No}, --sort {submitTime,id,depositEndTime,status,type,title,Yes,No}
Sort by given column. Default: id (default: id)
--status {voting,deposit,passed,rejected,all}
Status of proposal. Default: all (default: all)
--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,15 @@
```
usage: sinfo [-a ADDRESS] [-l LIMIT] [-h] [--export {csv,json,xlsx}]
```
Displays staking info of a certain terra address. [Source: https://fcd.terra.dev/swagger]
```
optional arguments:
-a ADDRESS, --address ADDRESS
Terra address. Valid terra addresses start with 'terra' (default: None)
-l LIMIT, --limit LIMIT
Number of delegations (default: 10)
-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,12 @@
```
usage: sratio [-l LIMIT] [-h] [--export {csv,json,xlsx}]
```
Displays terra blockchain staking ratio history. [Source: https://fcd.terra.dev/swagger]
```
optional arguments:
-l LIMIT, --limit LIMIT
Number of days to show (default: 90)
-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,13 @@
```
usage: sreturn [-l LIMIT] [-h] [--export {csv,json,xlsx}]
```
Displays terra blockchain staking returns history. [Source: https://fcd.terra.dev/swagger]
```
optional arguments:
-l LIMIT, --limit LIMIT
Number of days to show (default: 90)
-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,16 @@
```
usage: validators [-l LIMIT] [-s {validatorName,tokensAmount,votingPower,commissionRate,status,uptime}] [--descend] [-h] [--export {csv,json,xlsx}]
```
Displays information about terra validators. [Source: https://fcd.terra.dev/swagger]
```
optional arguments:
-l LIMIT, --limit LIMIT
Number of validators to show (default: 10)
-s {validatorName,tokensAmount,votingPower,commissionRate,status,uptime}, --sort {validatorName,tokensAmount,votingPower,commissionRate,status,uptime}
Sort by given column. Default: votingPower (default: votingPower)
--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

@@ -903,6 +903,18 @@ main:
ref: "/cryptocurrency/defi/pools"
- name: swaps
ref: "/cryptocurrency/defi/swaps"
- name: sinfo
ref: "/cryptocurrency/defi/sinfo"
- name: govp
ref: "/cryptocurrency/defi/govp"
- name: gacc
ref: "/cryptocurrency/defi/gacc"
- name: validators
ref: "/cryptocurrency/defi/validators"
- name: sratio
ref: "/cryptocurrency/defi/sratio"
- name: sreturn
ref: "/cryptocurrency/defi/sreturn"
- name: economy
ref: "/economy"
sub: