mirror of
https://github.com/webclinic017/drift.git
synced 2026-07-27 18:57:55 +00:00
chore(Linter): reformatted code with black (#211)
* chore(Linter): reformatted code with black * Create black.yaml
This commit is contained in:
committed by
GitHub
parent
f3fee4a4e1
commit
8dd2d88740
+78
-48
@@ -8,95 +8,125 @@ import numpy as np
|
||||
from data_loader.types import ForwardReturnSeries, ySeries
|
||||
from training.types import Stats, WeightsSeries
|
||||
|
||||
def backtest(returns: pd.Series, signal: pd.Series, transaction_cost = 0.002) -> pd.Series:
|
||||
delta_pos = signal.diff(1).abs().fillna(0.)
|
||||
|
||||
def backtest(
|
||||
returns: pd.Series, signal: pd.Series, transaction_cost=0.002
|
||||
) -> pd.Series:
|
||||
delta_pos = signal.diff(1).abs().fillna(0.0)
|
||||
costs = transaction_cost * delta_pos
|
||||
return (signal * returns) - costs
|
||||
|
||||
|
||||
def __preprocess(forward_returns: ForwardReturnSeries, y_pred: pd.Series, y_true: pd.Series, no_of_classes: Literal['two', 'three-balanced', 'three-imbalanced'], discretize: bool) -> pd.DataFrame:
|
||||
y_pred.name = 'y_pred'
|
||||
forward_returns.name = 'forward_returns'
|
||||
df = pd.concat([y_pred, forward_returns],axis=1).dropna()
|
||||
def __preprocess(
|
||||
forward_returns: ForwardReturnSeries,
|
||||
y_pred: pd.Series,
|
||||
y_true: pd.Series,
|
||||
no_of_classes: Literal["two", "three-balanced", "three-imbalanced"],
|
||||
discretize: bool,
|
||||
) -> pd.DataFrame:
|
||||
y_pred.name = "y_pred"
|
||||
forward_returns.name = "forward_returns"
|
||||
df = pd.concat([y_pred, forward_returns], axis=1).dropna()
|
||||
|
||||
discretize_func = get_discretize_function(no_of_classes)
|
||||
# make sure that we evaluate binary/three-way predictions even if the model is a regression
|
||||
df['sign_pred'] = df.y_pred.apply(discretize_func) if discretize else df.y_pred
|
||||
df['sign_true'] = y_true
|
||||
df["sign_pred"] = df.y_pred.apply(discretize_func) if discretize else df.y_pred
|
||||
df["sign_true"] = y_true
|
||||
|
||||
df['result'] = backtest(df.forward_returns, df.sign_pred)
|
||||
df["result"] = backtest(df.forward_returns, df.sign_pred)
|
||||
|
||||
return df
|
||||
|
||||
|
||||
def evaluate_predictions(
|
||||
forward_returns: ForwardReturnSeries,
|
||||
y_pred: WeightsSeries,
|
||||
y_true: ySeries,
|
||||
no_of_classes: Literal['two', 'three-balanced', 'three-imbalanced'],
|
||||
discretize: bool = False,
|
||||
) -> Stats:
|
||||
forward_returns: ForwardReturnSeries,
|
||||
y_pred: WeightsSeries,
|
||||
y_true: ySeries,
|
||||
no_of_classes: Literal["two", "three-balanced", "three-imbalanced"],
|
||||
discretize: bool = False,
|
||||
) -> Stats:
|
||||
# ignore the predictions until we see a non-zero returns (and definitely skip the first sliding_window_size)
|
||||
evaluate_from = max(get_first_valid_return_index(forward_returns), get_first_valid_return_index(y_pred))
|
||||
|
||||
evaluate_from = max(
|
||||
get_first_valid_return_index(forward_returns),
|
||||
get_first_valid_return_index(y_pred),
|
||||
)
|
||||
|
||||
forward_returns = pd.Series(forward_returns[evaluate_from:])
|
||||
y_pred = pd.Series(y_pred[evaluate_from:])
|
||||
|
||||
df = __preprocess(forward_returns, y_pred, y_true, no_of_classes, discretize)
|
||||
|
||||
|
||||
scorecard = dict()
|
||||
|
||||
|
||||
def count_non_zero(series: pd.Series) -> int:
|
||||
return len(series[series != 0])
|
||||
no_of_samples = count_non_zero(df.y_pred)
|
||||
scorecard['no_of_samples'] = no_of_samples
|
||||
sharpe = sharpe_ratio(df.result + 1e-20)
|
||||
scorecard['sharpe'] = sharpe
|
||||
benchmark_sharpe = sharpe_ratio(df.forward_returns)
|
||||
scorecard['benchmark_sharpe'] = benchmark_sharpe
|
||||
scorecard['prob_sharpe'] = probabilistic_sharpe_ratio(sharpe, benchmark_sharpe, no_of_samples)
|
||||
scorecard['sortino'] = sortino(df.result)
|
||||
scorecard['skew'] = skew(df.result)
|
||||
|
||||
labels = [1, -1] if no_of_classes == 'two' else [1, -1, 0]
|
||||
avg_type = 'weighted' if no_of_classes == 'two' else 'macro'
|
||||
no_of_samples = count_non_zero(df.y_pred)
|
||||
scorecard["no_of_samples"] = no_of_samples
|
||||
sharpe = sharpe_ratio(df.result + 1e-20)
|
||||
scorecard["sharpe"] = sharpe
|
||||
benchmark_sharpe = sharpe_ratio(df.forward_returns)
|
||||
scorecard["benchmark_sharpe"] = benchmark_sharpe
|
||||
scorecard["prob_sharpe"] = probabilistic_sharpe_ratio(
|
||||
sharpe, benchmark_sharpe, no_of_samples
|
||||
)
|
||||
scorecard["sortino"] = sortino(df.result)
|
||||
scorecard["skew"] = skew(df.result)
|
||||
|
||||
labels = [1, -1] if no_of_classes == "two" else [1, -1, 0]
|
||||
avg_type = "weighted" if no_of_classes == "two" else "macro"
|
||||
|
||||
if discretize == True:
|
||||
scorecard['accuracy'] = accuracy_score(df.sign_true, df.sign_pred) * 100
|
||||
scorecard['recall'] = recall_score(df.sign_true, df.sign_pred, labels = labels, average=avg_type)
|
||||
scorecard['precision'] = precision_score(df.sign_true, df.sign_pred, labels = labels, average=avg_type)
|
||||
scorecard['f1_score'] = f1_score(df.sign_true, df.sign_pred, labels = labels, average=avg_type)
|
||||
scorecard['edge'] = df.result.mean()
|
||||
scorecard['noise'] = df.y_pred.diff().abs().mean()
|
||||
scorecard['edge_to_noise'] = scorecard['edge'] / (scorecard['noise'] + 0.00001)
|
||||
|
||||
scorecard["accuracy"] = accuracy_score(df.sign_true, df.sign_pred) * 100
|
||||
scorecard["recall"] = recall_score(
|
||||
df.sign_true, df.sign_pred, labels=labels, average=avg_type
|
||||
)
|
||||
scorecard["precision"] = precision_score(
|
||||
df.sign_true, df.sign_pred, labels=labels, average=avg_type
|
||||
)
|
||||
scorecard["f1_score"] = f1_score(
|
||||
df.sign_true, df.sign_pred, labels=labels, average=avg_type
|
||||
)
|
||||
scorecard["edge"] = df.result.mean()
|
||||
scorecard["noise"] = df.y_pred.diff().abs().mean()
|
||||
scorecard["edge_to_noise"] = scorecard["edge"] / (scorecard["noise"] + 0.00001)
|
||||
|
||||
if discretize == True:
|
||||
for index, row in df.sign_true.value_counts().iteritems():
|
||||
scorecard['sign_true_ratio_' + str(index)] = row / len(df.sign_true)
|
||||
|
||||
scorecard["sign_true_ratio_" + str(index)] = row / len(df.sign_true)
|
||||
|
||||
for index, row in df.sign_pred.value_counts().iteritems():
|
||||
scorecard['sign_pred_ratio_' + str(index)] = row / len(df.sign_pred)
|
||||
scorecard["sign_pred_ratio_" + str(index)] = row / len(df.sign_pred)
|
||||
|
||||
scorecard = {k: round(float(v), 3) for k, v in scorecard.items()}
|
||||
return scorecard
|
||||
return scorecard
|
||||
|
||||
|
||||
def __discretize_binary(x):
|
||||
return 1 if x > 0 else -1
|
||||
|
||||
|
||||
def __discretize_threeway(x):
|
||||
return 0 if x == 0 else 1 if x > 0 else -1
|
||||
|
||||
|
||||
def __discretize_binary(x): return 1 if x > 0 else -1
|
||||
def __discretize_threeway(x): return 0 if x == 0 else 1 if x > 0 else -1
|
||||
def discretize_threeway_threshold(threshold: float) -> Callable:
|
||||
def discretize(current_value):
|
||||
lower_threshold = -threshold
|
||||
upper_threshold = threshold
|
||||
if np.isnan(current_value):
|
||||
return np.nan
|
||||
return np.nan
|
||||
elif current_value <= lower_threshold:
|
||||
return -1
|
||||
elif current_value > lower_threshold and current_value < upper_threshold:
|
||||
return 0
|
||||
else:
|
||||
return 1
|
||||
|
||||
return discretize
|
||||
|
||||
def get_discretize_function(no_of_classes: Literal['two', 'three-balanced', 'three-imbalanced']) -> Callable:
|
||||
return __discretize_binary if no_of_classes == 'two' else __discretize_threeway
|
||||
|
||||
|
||||
def get_discretize_function(
|
||||
no_of_classes: Literal["two", "three-balanced", "three-imbalanced"]
|
||||
) -> Callable:
|
||||
return __discretize_binary if no_of_classes == "two" else __discretize_threeway
|
||||
|
||||
@@ -4,49 +4,50 @@ from .client import GlassnodeClient
|
||||
|
||||
class Blockchain:
|
||||
"""
|
||||
Blockchain class.
|
||||
Blockchain class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Blockchain object.
|
||||
utxos_total():
|
||||
Returns the total number of UTXOs in the network.
|
||||
utxos_created():
|
||||
Returns the number of created unspent transaction outputs.
|
||||
utxos_spent():
|
||||
Returns the number of spent transaction outputs.
|
||||
utxo_value_created_total():
|
||||
Returns the total amount of coins in newly created UTXOs.
|
||||
utxo_value_spent_total():
|
||||
Returns the total amount of coins in spent transaction outputs.
|
||||
utxo_value_created_mean():
|
||||
Returns the mean amount of coins in newly created UTXOs.
|
||||
utxo_value_spent_mean():
|
||||
Returns the mean amount of coins in spent transaction outputs.
|
||||
utxo_value_created_median():
|
||||
Returns the median amount of coins in newly created UTXOs.
|
||||
utxo_value_spent_median():
|
||||
Returns the median amount of coins in spent transaction outputs.
|
||||
utxos_in_profit():
|
||||
Returns the number of unspent transaction outputs in profit.
|
||||
utxos_in_loss():
|
||||
Returns the number of unspent transaction outputs in loss.
|
||||
percent_utxos_in_profit():
|
||||
Returns the percentage of unspent transaction outputs in profit.
|
||||
block_heights():
|
||||
Returns the block height.
|
||||
blocks_mined():
|
||||
Returns the number of blocks mined.
|
||||
block_interval_mean():
|
||||
Returns the mean time (in seconds) between mined blocks.
|
||||
block_interval_median():
|
||||
Returns the median time (in seconds) between mined blocks.
|
||||
block_size_mean():
|
||||
Returns the mean size of all blocks created within the time period (in bytes).
|
||||
block_size_total():
|
||||
Returns the total size of all blocks created within the time period (in bytes).
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Blockchain object.
|
||||
utxos_total():
|
||||
Returns the total number of UTXOs in the network.
|
||||
utxos_created():
|
||||
Returns the number of created unspent transaction outputs.
|
||||
utxos_spent():
|
||||
Returns the number of spent transaction outputs.
|
||||
utxo_value_created_total():
|
||||
Returns the total amount of coins in newly created UTXOs.
|
||||
utxo_value_spent_total():
|
||||
Returns the total amount of coins in spent transaction outputs.
|
||||
utxo_value_created_mean():
|
||||
Returns the mean amount of coins in newly created UTXOs.
|
||||
utxo_value_spent_mean():
|
||||
Returns the mean amount of coins in spent transaction outputs.
|
||||
utxo_value_created_median():
|
||||
Returns the median amount of coins in newly created UTXOs.
|
||||
utxo_value_spent_median():
|
||||
Returns the median amount of coins in spent transaction outputs.
|
||||
utxos_in_profit():
|
||||
Returns the number of unspent transaction outputs in profit.
|
||||
utxos_in_loss():
|
||||
Returns the number of unspent transaction outputs in loss.
|
||||
percent_utxos_in_profit():
|
||||
Returns the percentage of unspent transaction outputs in profit.
|
||||
block_heights():
|
||||
Returns the block height.
|
||||
blocks_mined():
|
||||
Returns the number of blocks mined.
|
||||
block_interval_mean():
|
||||
Returns the mean time (in seconds) between mined blocks.
|
||||
block_interval_median():
|
||||
Returns the median time (in seconds) between mined blocks.
|
||||
block_size_mean():
|
||||
Returns the mean size of all blocks created within the time period (in bytes).
|
||||
block_size_total():
|
||||
Returns the total size of all blocks created within the time period (in bytes).
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client: GlassnodeClient):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -57,7 +58,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_count'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -70,7 +71,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_created_count'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_created_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -83,7 +84,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_spent_count'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_spent_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -96,7 +97,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_created_value_sum'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_created_value_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -109,7 +110,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_spent_value_sum'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_spent_value_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -122,7 +123,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_created_value_mean'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_created_value_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -135,7 +136,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_spent_value_mean'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_spent_value_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -148,7 +149,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_created_value_median'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_created_value_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -161,7 +162,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_spent_value_median'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_spent_value_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -174,7 +175,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_profit_count'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_profit_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -187,7 +188,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_loss_count'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_loss_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -200,7 +201,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/utxo_profit_relative'
|
||||
endpoint = "/v1/metrics/blockchain/utxo_profit_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -213,7 +214,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/block_height'
|
||||
endpoint = "/v1/metrics/blockchain/block_height"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -226,7 +227,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/block_count'
|
||||
endpoint = "/v1/metrics/blockchain/block_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -239,7 +240,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/block_interval_mean'
|
||||
endpoint = "/v1/metrics/blockchain/block_interval_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -252,7 +253,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/block_interval_median'
|
||||
endpoint = "/v1/metrics/blockchain/block_interval_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -265,7 +266,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/block_size_mean'
|
||||
endpoint = "/v1/metrics/blockchain/block_size_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -278,7 +279,7 @@ class Blockchain:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/blockchain/block_size_sum'
|
||||
endpoint = "/v1/metrics/blockchain/block_size_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
+19
-19
@@ -6,13 +6,13 @@ from .endpoints import Endpoints
|
||||
|
||||
class GlassnodeClient:
|
||||
def __init__(
|
||||
self,
|
||||
api_key=None,
|
||||
asset='BTC',
|
||||
resolution='24h',
|
||||
currency='native',
|
||||
since=None,
|
||||
until=None
|
||||
self,
|
||||
api_key=None,
|
||||
asset="BTC",
|
||||
resolution="24h",
|
||||
currency="native",
|
||||
since=None,
|
||||
until=None,
|
||||
):
|
||||
"""
|
||||
Glassnode API client.
|
||||
@@ -25,11 +25,11 @@ class GlassnodeClient:
|
||||
"""
|
||||
if api_key:
|
||||
self._api_key = api_key
|
||||
elif 'GLASSNODE_API_KEY' in os.environ:
|
||||
self._api_key = os.environ.get('GLASSNODE_API_KEY')
|
||||
elif "GLASSNODE_API_KEY" in os.environ:
|
||||
self._api_key = os.environ.get("GLASSNODE_API_KEY")
|
||||
else:
|
||||
# API key is required for every endpoint!
|
||||
print(f'\033[91m ERROR: Glassnode API key required!\033[0m')
|
||||
print(f"\033[91m ERROR: Glassnode API key required!\033[0m")
|
||||
sys.exit()
|
||||
|
||||
self.endpoints = Endpoints()
|
||||
@@ -53,27 +53,27 @@ class GlassnodeClient:
|
||||
|
||||
def __prepare_request_params(self, params):
|
||||
p = dict()
|
||||
p['api_key'] = self._api_key
|
||||
p['a'] = self._asset
|
||||
p['i'] = self._resolution
|
||||
p["api_key"] = self._api_key
|
||||
p["a"] = self._asset
|
||||
p["i"] = self._resolution
|
||||
|
||||
if self._since is not None:
|
||||
try:
|
||||
p['s'] = unix_timestamp(self._since)
|
||||
p["s"] = unix_timestamp(self._since)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
if self._until is not None:
|
||||
try:
|
||||
p['u'] = unix_timestamp(self._until)
|
||||
p["u"] = unix_timestamp(self._until)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
# Set domain specific query parameters if available
|
||||
if params:
|
||||
if 'e' in p:
|
||||
p['e'] = params['e']
|
||||
if 'm' in p:
|
||||
p['miner'] = params['m']
|
||||
if "e" in p:
|
||||
p["e"] = params["e"]
|
||||
if "m" in p:
|
||||
p["miner"] = params["m"]
|
||||
|
||||
return p
|
||||
|
||||
@@ -4,45 +4,46 @@ from .client import GlassnodeClient
|
||||
|
||||
class Derivatives:
|
||||
"""
|
||||
Derivatives class.
|
||||
Derivatives class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Derivatives object.
|
||||
futures_perpetual_funding_rate([exchange]):
|
||||
Returns the average funding rate (in %) set by exchanges for perpetual futures contracts.
|
||||
futures_perpetual_funding_rate_all():
|
||||
Returns the average funding rate (in %) set by exchanges for perpetual futures contracts.
|
||||
futures_volume([exchange]):
|
||||
Returns the total volume traded in futures contracts in the last 24 hours.
|
||||
futures_volume_latest_24h():
|
||||
Returns the total volume traded in futures contracts per exchange over the last 24 hours.
|
||||
futures_volume_stacked():
|
||||
Returns the total volume traded in futures contracts in the last 24 hours.
|
||||
futures_volume_perpetual([exchange]):
|
||||
Returns The total volume traded in perpetual futures contracts in the last 24 hours.
|
||||
futures_volume_perpetual_stacked():
|
||||
Returns the total volume traded in perpetual futures contracts in the last 24 hours.
|
||||
futures_open_interest([exchange]):
|
||||
Returns the total amount of funds allocated in open futures contracts.
|
||||
futures_open_interest_current():
|
||||
Returns the current amount of allocated funds in futures contracts per exchange.
|
||||
futures_open_interest_perpetual([exchange]):
|
||||
Returns the total amount of funds allocated in open perpetual futures contracts.
|
||||
futures_open_interest_perpetual_stacked():
|
||||
Returns the total amount of funds allocated in open perpetual futures contracts.
|
||||
futures_open_interest_stacked():
|
||||
Returns the total amount of funds allocated in open futures contracts.
|
||||
futures_long_liquidations([exchange]):
|
||||
Returns the sum liquidated volume from long positions in futures contracts.
|
||||
futures_long_liquidations_mean([exchange]):
|
||||
Returns the mean liquidated volume from long positions in futures contracts.
|
||||
futures_short_liquidations([exchange]):
|
||||
Returns the sum liquidated volume from short positions in futures contracts.
|
||||
futures_short_liquidations_mean([exchange]):
|
||||
Returns the mean liquidated volume from short positions in futures contracts.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Derivatives object.
|
||||
futures_perpetual_funding_rate([exchange]):
|
||||
Returns the average funding rate (in %) set by exchanges for perpetual futures contracts.
|
||||
futures_perpetual_funding_rate_all():
|
||||
Returns the average funding rate (in %) set by exchanges for perpetual futures contracts.
|
||||
futures_volume([exchange]):
|
||||
Returns the total volume traded in futures contracts in the last 24 hours.
|
||||
futures_volume_latest_24h():
|
||||
Returns the total volume traded in futures contracts per exchange over the last 24 hours.
|
||||
futures_volume_stacked():
|
||||
Returns the total volume traded in futures contracts in the last 24 hours.
|
||||
futures_volume_perpetual([exchange]):
|
||||
Returns The total volume traded in perpetual futures contracts in the last 24 hours.
|
||||
futures_volume_perpetual_stacked():
|
||||
Returns the total volume traded in perpetual futures contracts in the last 24 hours.
|
||||
futures_open_interest([exchange]):
|
||||
Returns the total amount of funds allocated in open futures contracts.
|
||||
futures_open_interest_current():
|
||||
Returns the current amount of allocated funds in futures contracts per exchange.
|
||||
futures_open_interest_perpetual([exchange]):
|
||||
Returns the total amount of funds allocated in open perpetual futures contracts.
|
||||
futures_open_interest_perpetual_stacked():
|
||||
Returns the total amount of funds allocated in open perpetual futures contracts.
|
||||
futures_open_interest_stacked():
|
||||
Returns the total amount of funds allocated in open futures contracts.
|
||||
futures_long_liquidations([exchange]):
|
||||
Returns the sum liquidated volume from long positions in futures contracts.
|
||||
futures_long_liquidations_mean([exchange]):
|
||||
Returns the mean liquidated volume from long positions in futures contracts.
|
||||
futures_short_liquidations([exchange]):
|
||||
Returns the sum liquidated volume from short positions in futures contracts.
|
||||
futures_short_liquidations_mean([exchange]):
|
||||
Returns the mean liquidated volume from short positions in futures contracts.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client: GlassnodeClient):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -51,11 +52,11 @@ class Derivatives:
|
||||
The average funding rate (in %) set by exchanges for perpetual futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesFundingRatePerpetual>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_funding_rate_perpetual'
|
||||
endpoint = "/v1/metrics/derivatives/futures_funding_rate_perpetual"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
@dataframe_with_inner_object
|
||||
def futures_perpetual_funding_rate_all(self) -> pd.DataFrame:
|
||||
@@ -63,7 +64,7 @@ class Derivatives:
|
||||
The average funding rate (in %) set by exchanges for perpetual futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesFundingRatePerpetualAll>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_funding_rate_perpetual_all'
|
||||
endpoint = "/v1/metrics/derivatives/futures_funding_rate_perpetual_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -74,11 +75,11 @@ class Derivatives:
|
||||
The total volume traded in futures contracts in the last 24 hours.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesVolumeDailySum>`_
|
||||
"""
|
||||
url = '/v1/metrics/derivatives/futures_volume_daily_sum'
|
||||
url = "/v1/metrics/derivatives/futures_volume_daily_sum"
|
||||
if not is_supported_by_endpoint(self._gc, url):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(url, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(url, {"e": exchange}))
|
||||
|
||||
# TODO: Unpack inner object from response
|
||||
def futures_volume_latest_24h(self) -> pd.DataFrame:
|
||||
@@ -87,7 +88,7 @@ class Derivatives:
|
||||
Values are updated every 10 min.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesVolumeDailyLatest>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_volume_daily_latest'
|
||||
endpoint = "/v1/metrics/derivatives/futures_volume_daily_latest"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -99,7 +100,7 @@ class Derivatives:
|
||||
The total volume traded in futures contracts in the last 24 hours.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesVolumeDailySumAll>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_volume_daily_sum_all'
|
||||
endpoint = "/v1/metrics/derivatives/futures_volume_daily_sum_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -110,11 +111,11 @@ class Derivatives:
|
||||
The total volume traded in perpetual (non-expiring) futures contracts in the last 24 hours.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesVolumeDailyPerpetualSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_volume_daily_perpetual_sum'
|
||||
endpoint = "/v1/metrics/derivatives/futures_volume_daily_perpetual_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
@dataframe_with_inner_object
|
||||
def futures_volume_perpetual_stacked(self) -> pd.DataFrame:
|
||||
@@ -122,7 +123,7 @@ class Derivatives:
|
||||
The total volume traded in perpetual (non-expiring) futures contracts in the last 24 hours.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesVolumeDailyPerpetualSumAll>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_volume_daily_perpetual_sum_all'
|
||||
endpoint = "/v1/metrics/derivatives/futures_volume_daily_perpetual_sum_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -133,11 +134,11 @@ class Derivatives:
|
||||
The total amount of funds allocated in open futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesOpenInterestSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_open_interest_sum'
|
||||
endpoint = "/v1/metrics/derivatives/futures_open_interest_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
# TODO: Unpack inner object from response
|
||||
def futures_open_interest_current(self) -> pd.DataFrame:
|
||||
@@ -145,7 +146,7 @@ class Derivatives:
|
||||
The current amount of allocated funds in futures contracts per exchange.Values are updated every 10 min.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesOpenInterestLatest>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_open_interest_latest'
|
||||
endpoint = "/v1/metrics/derivatives/futures_open_interest_latest"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -156,11 +157,11 @@ class Derivatives:
|
||||
The total amount of funds allocated in open perpetual (non-expiring) futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesOpenInterestPerpetualSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_open_interest_perpetual_sum'
|
||||
endpoint = "/v1/metrics/derivatives/futures_open_interest_perpetual_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
@dataframe_with_inner_object
|
||||
def futures_open_interest_perpetual_stacked(self) -> pd.DataFrame:
|
||||
@@ -168,7 +169,7 @@ class Derivatives:
|
||||
The total amount of funds allocated in open perpetual (non-expiring) futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesOpenInterestPerpetualSumAll>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_open_interest_perpetual_sum_all'
|
||||
endpoint = "/v1/metrics/derivatives/futures_open_interest_perpetual_sum_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -180,7 +181,7 @@ class Derivatives:
|
||||
The total amount of funds allocated in open futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesOpenInterestSumAll>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_open_interest_sum_all'
|
||||
endpoint = "/v1/metrics/derivatives/futures_open_interest_sum_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -191,49 +192,49 @@ class Derivatives:
|
||||
The sum liquidated volume from long positions in futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesLiquidatedVolumeLongSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_liquidated_volume_long_sum'
|
||||
endpoint = "/v1/metrics/derivatives/futures_liquidated_volume_long_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
def futures_long_liquidations_mean(self, exchange: str = None) -> pd.DataFrame:
|
||||
"""
|
||||
The mean liquidated volume from long positions in futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesLiquidatedVolumeLongMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_liquidated_volume_long_mean'
|
||||
endpoint = "/v1/metrics/derivatives/futures_liquidated_volume_long_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
def futures_short_liquidations(self, exchange: str = None) -> pd.DataFrame:
|
||||
"""
|
||||
The sum liquidated volume from short positions in futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesLiquidatedVolumeShortSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_liquidated_volume_short_sum'
|
||||
endpoint = "/v1/metrics/derivatives/futures_liquidated_volume_short_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
def futures_short_liquidations_mean(self, exchange: str = None) -> pd.DataFrame:
|
||||
"""
|
||||
The mean liquidated volume from short positions in futures contracts.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=derivatives.FuturesLiquidatedVolumeShortMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/derivatives/futures_liquidated_volume_short_mean'
|
||||
endpoint = "/v1/metrics/derivatives/futures_liquidated_volume_short_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
def futures_estimated_leverage_ratio(self, exchange: str = None) -> pd.DataFrame:
|
||||
|
||||
endpoint = '/v1/metrics/derivatives/futures_estimated_leverage_ratio'
|
||||
endpoint = "/v1/metrics/derivatives/futures_estimated_leverage_ratio"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
@@ -3,33 +3,34 @@ from .utils import *
|
||||
|
||||
class Distribution:
|
||||
"""
|
||||
Distribution class.
|
||||
Distribution class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Distribution object.
|
||||
exchange_balance_total(exchange):
|
||||
Returns the total amount of coins held on exchange addresses.
|
||||
exchange_balance_percent(exchange):
|
||||
Returns the percent supply held on exchange addresses.
|
||||
exchange_balance_stacked():
|
||||
Returns the total amount of coins held on exchange addresses.
|
||||
miner_balance():
|
||||
Returns the total supply held in miner addresses.
|
||||
miner_balance_stacked():
|
||||
Returns the total supply held in miner addresses.
|
||||
balance_miners_change():
|
||||
Returns 30d change of the supply held in miner addresses.
|
||||
supply_top_one_pct_addresses():
|
||||
Returns the percentage of supply held by the top 1% addresses.
|
||||
gini_coefficient():
|
||||
Returns gini coefficient data.
|
||||
herfindahl_index():
|
||||
Returns herfindahl index data.
|
||||
supply_in_smart_contracts():
|
||||
Returns percent of total supply that is held in smart contracts.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Distribution object.
|
||||
exchange_balance_total(exchange):
|
||||
Returns the total amount of coins held on exchange addresses.
|
||||
exchange_balance_percent(exchange):
|
||||
Returns the percent supply held on exchange addresses.
|
||||
exchange_balance_stacked():
|
||||
Returns the total amount of coins held on exchange addresses.
|
||||
miner_balance():
|
||||
Returns the total supply held in miner addresses.
|
||||
miner_balance_stacked():
|
||||
Returns the total supply held in miner addresses.
|
||||
balance_miners_change():
|
||||
Returns 30d change of the supply held in miner addresses.
|
||||
supply_top_one_pct_addresses():
|
||||
Returns the percentage of supply held by the top 1% addresses.
|
||||
gini_coefficient():
|
||||
Returns gini coefficient data.
|
||||
herfindahl_index():
|
||||
Returns herfindahl index data.
|
||||
supply_in_smart_contracts():
|
||||
Returns percent of total supply that is held in smart contracts.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -41,11 +42,11 @@ class Distribution:
|
||||
:return: A DataFrame with exchange balance data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_exchanges'
|
||||
endpoint = "/v1/metrics/distribution/balance_exchanges"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
def exchange_balance_percent(self, exchange=None) -> pd.DataFrame:
|
||||
"""
|
||||
@@ -55,11 +56,11 @@ class Distribution:
|
||||
:return: A DataFrame with exchange balance data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_exchanges_relative'
|
||||
endpoint = "/v1/metrics/distribution/balance_exchanges_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'e': exchange}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"e": exchange}))
|
||||
|
||||
def exchange_balance_stacked(self) -> pd.DataFrame:
|
||||
"""
|
||||
@@ -69,7 +70,7 @@ class Distribution:
|
||||
:return: A DataFrame with stacked exchange balance data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_exchanges_all'
|
||||
endpoint = "/v1/metrics/distribution/balance_exchanges_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -83,7 +84,7 @@ class Distribution:
|
||||
:return: A DataFrame miner balance data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_miners_sum'
|
||||
endpoint = "/v1/metrics/distribution/balance_miners_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -97,7 +98,7 @@ class Distribution:
|
||||
:return: A DataFrame with stacked miner balance data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_miners_all'
|
||||
endpoint = "/v1/metrics/distribution/balance_miners_all"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -105,13 +106,13 @@ class Distribution:
|
||||
|
||||
def balance_miners_change(self) -> pd.DataFrame:
|
||||
"""
|
||||
The 30d change of the supply held in miner addresses.
|
||||
The 30d change of the supply held in miner addresses.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=distribution.BalanceMinersChange>`_
|
||||
|
||||
:return: A DataFrame with 30d change of the supply held in miner addresses.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_miners_change'
|
||||
endpoint = "/v1/metrics/distribution/balance_miners_change"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -125,7 +126,7 @@ class Distribution:
|
||||
:return: A DataFrame with top 1% supply data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/balance_1pct_holders'
|
||||
endpoint = "/v1/metrics/distribution/balance_1pct_holders"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -139,7 +140,7 @@ class Distribution:
|
||||
:return: A DataFrame Gini Coefficient data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/gini'
|
||||
endpoint = "/v1/metrics/distribution/gini"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -153,7 +154,7 @@ class Distribution:
|
||||
:return: A DataFrame Herfindahl index data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/herfindahl'
|
||||
endpoint = "/v1/metrics/distribution/herfindahl"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -167,7 +168,7 @@ class Distribution:
|
||||
:return: A DataFrame smart contracts supply data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/distribution/supply_contracts'
|
||||
endpoint = "/v1/metrics/distribution/supply_contracts"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ from .utils import fetch
|
||||
|
||||
def create_endpoints_dict(endpoints):
|
||||
return {
|
||||
endpoint['path']: {
|
||||
'assets': {asset['symbol']: asset['tags'] for asset in endpoint['assets']},
|
||||
'currencies': endpoint['currencies'],
|
||||
'resolutions': endpoint['resolutions'],
|
||||
'formats': endpoint['formats']
|
||||
endpoint["path"]: {
|
||||
"assets": {asset["symbol"]: asset["tags"] for asset in endpoint["assets"]},
|
||||
"currencies": endpoint["currencies"],
|
||||
"resolutions": endpoint["resolutions"],
|
||||
"formats": endpoint["formats"],
|
||||
}
|
||||
for endpoint in endpoints
|
||||
}
|
||||
@@ -37,7 +37,9 @@ class Endpoints(metaclass=MetaEndpoints):
|
||||
|
||||
@endpoints.setter
|
||||
def endpoints(self, api_key):
|
||||
self._endpoints = create_endpoints_dict(fetch('/v2/metrics/endpoints', {'api_key': api_key}))
|
||||
self._endpoints = create_endpoints_dict(
|
||||
fetch("/v2/metrics/endpoints", {"api_key": api_key})
|
||||
)
|
||||
|
||||
def query(self, path):
|
||||
return self._endpoints[path]
|
||||
|
||||
+61
-60
@@ -4,49 +4,50 @@ from .client import GlassnodeClient
|
||||
|
||||
class Entities:
|
||||
"""
|
||||
Entities class.
|
||||
Entities class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Entities object.
|
||||
sending_entities():
|
||||
Returns the number of unique entities that were active as a sender.
|
||||
receiving_entities():
|
||||
Returns the number of unique entities that were active as a receiver.
|
||||
active_entities():
|
||||
Returns the number of unique entities that were active either as a sender or receiver.
|
||||
new_entities():
|
||||
Returns The number of unique entities that appeared for the first time in a transaction.
|
||||
entities_net_growth():
|
||||
Returns the net growth of unique entities in the network.
|
||||
number_of_whales():
|
||||
Returns the number of unique entities holding at least 1k coins.
|
||||
supply_balance_less_0001():
|
||||
Returns the total circulating supply held by entities with a balance lower than 0.001 coins.
|
||||
supply_balance_0001_001():
|
||||
Returns the total circulating supply held by entities with a balance between 0.001 and 0.01 coins.
|
||||
supply_balance_001_01():
|
||||
Returns the total circulating supply held by entities with a balance between 0.01 and 0.1 coins.
|
||||
supply_balance_01_1():
|
||||
Returns the total circulating supply held by entities with a balance between 0.1 and 1 coins.
|
||||
supply_balance_1_10():
|
||||
Returns the total circulating supply held by entities with a balance between 1 and 10 coins.
|
||||
supply_balance_10_100():
|
||||
Returns the total circulating supply held by entities with a balance between 10 and 100 coins.
|
||||
supply_balance_100_1k():
|
||||
Returns the total circulating supply held by entities with a balance between 100 and 1,000 coins.
|
||||
supply_balance_1k_10k():
|
||||
Returns the total circulating supply held by entities with a balance between 1,000 and 10,000 coins.
|
||||
supply_balance_10k_100k():
|
||||
Returns the total circulating supply held by entities with a balance between 10,000 and 100,000 coins.
|
||||
supply_balance_more_100k():
|
||||
Returns the total circulating supply held by entities with a balance of at least 100,000 coins.
|
||||
entities_supply_distribution():
|
||||
Returns relative distribution of the circulating supply held by entities with specific balance bands.
|
||||
percent_entities_in_profit():
|
||||
Returns the percentage of entities in the network that are currently in profit.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Entities object.
|
||||
sending_entities():
|
||||
Returns the number of unique entities that were active as a sender.
|
||||
receiving_entities():
|
||||
Returns the number of unique entities that were active as a receiver.
|
||||
active_entities():
|
||||
Returns the number of unique entities that were active either as a sender or receiver.
|
||||
new_entities():
|
||||
Returns The number of unique entities that appeared for the first time in a transaction.
|
||||
entities_net_growth():
|
||||
Returns the net growth of unique entities in the network.
|
||||
number_of_whales():
|
||||
Returns the number of unique entities holding at least 1k coins.
|
||||
supply_balance_less_0001():
|
||||
Returns the total circulating supply held by entities with a balance lower than 0.001 coins.
|
||||
supply_balance_0001_001():
|
||||
Returns the total circulating supply held by entities with a balance between 0.001 and 0.01 coins.
|
||||
supply_balance_001_01():
|
||||
Returns the total circulating supply held by entities with a balance between 0.01 and 0.1 coins.
|
||||
supply_balance_01_1():
|
||||
Returns the total circulating supply held by entities with a balance between 0.1 and 1 coins.
|
||||
supply_balance_1_10():
|
||||
Returns the total circulating supply held by entities with a balance between 1 and 10 coins.
|
||||
supply_balance_10_100():
|
||||
Returns the total circulating supply held by entities with a balance between 10 and 100 coins.
|
||||
supply_balance_100_1k():
|
||||
Returns the total circulating supply held by entities with a balance between 100 and 1,000 coins.
|
||||
supply_balance_1k_10k():
|
||||
Returns the total circulating supply held by entities with a balance between 1,000 and 10,000 coins.
|
||||
supply_balance_10k_100k():
|
||||
Returns the total circulating supply held by entities with a balance between 10,000 and 100,000 coins.
|
||||
supply_balance_more_100k():
|
||||
Returns the total circulating supply held by entities with a balance of at least 100,000 coins.
|
||||
entities_supply_distribution():
|
||||
Returns relative distribution of the circulating supply held by entities with specific balance bands.
|
||||
percent_entities_in_profit():
|
||||
Returns the percentage of entities in the network that are currently in profit.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client: GlassnodeClient):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -55,7 +56,7 @@ class Entities:
|
||||
The number of unique entities that were active as a sender.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SendingCount>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/sending_count'
|
||||
endpoint = "/v1/metrics/entities/sending_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -66,7 +67,7 @@ class Entities:
|
||||
The number of unique entities that were active as a receiver.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.ReceivingCount>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/receiving_count'
|
||||
endpoint = "/v1/metrics/entities/receiving_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -77,7 +78,7 @@ class Entities:
|
||||
The number of unique entities that were active either as a sender or receiver.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.ActiveCount>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/active_count'
|
||||
endpoint = "/v1/metrics/entities/active_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -89,7 +90,7 @@ class Entities:
|
||||
in a transaction of the native coin in the network.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.NewCount>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/new_count'
|
||||
endpoint = "/v1/metrics/entities/new_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -100,7 +101,7 @@ class Entities:
|
||||
The net growth of unique entities in the network.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.NetGrowthCount>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/net_growth_count'
|
||||
endpoint = "/v1/metrics/entities/net_growth_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -111,7 +112,7 @@ class Entities:
|
||||
The number of unique entities holding at least 1k coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.Min1KCount>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/min_1k_count'
|
||||
endpoint = "/v1/metrics/entities/min_1k_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -122,7 +123,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance lower than 0.001 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalanceLess0001>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_less_0001'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_less_0001"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -133,7 +134,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 0.001 and 0.01 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance0001001>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_0001_001'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_0001_001"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -144,7 +145,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 0.01 and 0.1 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance00101>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_001_01'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_001_01"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -155,7 +156,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 0.1 and 1 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance011>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_01_1'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_01_1"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -166,7 +167,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 1 and 10 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance110>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_1_10'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_1_10"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -177,7 +178,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 10 and 100 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance10100>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_10_100'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_10_100"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -188,7 +189,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 100 and 1,000 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance1001K>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_100_1k'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_100_1k"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -199,7 +200,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 1,000 and 10,000 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance1K10K>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_1k_10k'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_1k_10k"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -210,7 +211,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance between 10,000 and 100,000 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalance10K100K>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_10k_100k'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_10k_100k"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -221,7 +222,7 @@ class Entities:
|
||||
The total circulating supply held by entities with a balance of at least 100,000 coins.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyBalanceMore100K>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_balance_more_100k'
|
||||
endpoint = "/v1/metrics/entities/supply_balance_more_100k"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -233,7 +234,7 @@ class Entities:
|
||||
Relative distribution of the circulating supply held by entities with specific balance bands.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.SupplyDistributionRelative>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/supply_distribution_relative'
|
||||
endpoint = "/v1/metrics/entities/supply_distribution_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -244,8 +245,8 @@ class Entities:
|
||||
The percentage of entities in the network that are currently in profit.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=entities.ProfitRelative>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/entities/profit_relative'
|
||||
endpoint = "/v1/metrics/entities/profit_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint))
|
||||
return response_to_dataframe(self._gc.get(endpoint))
|
||||
|
||||
+27
-26
@@ -3,27 +3,28 @@ from .utils import *
|
||||
|
||||
class ETH2:
|
||||
"""
|
||||
ETH 2.0 class.
|
||||
ETH 2.0 class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs an ETH2 object.
|
||||
new_deposits():
|
||||
Returns the number transactions depositing 32 ETH to the ETH2 deposit contract.
|
||||
new_value_staked():
|
||||
Returns the amount of ETH transferred to the ETH2 deposit contract.
|
||||
new_validators():
|
||||
Returns the number of new validators depositing 32 ETH to the ETH2 deposit contract.
|
||||
total_number_of_deposits():
|
||||
Returns the total number of transactions to the ETH2 deposit contract.
|
||||
total_value_staked():
|
||||
Returns the amount of ETH deposited to the ETH2 deposit contract.
|
||||
total_number_of_validators():
|
||||
Returns the total number of unique validators.
|
||||
phase_zero_staking_goal():
|
||||
Returns the percentage of the Phase 0 staking goal.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs an ETH2 object.
|
||||
new_deposits():
|
||||
Returns the number transactions depositing 32 ETH to the ETH2 deposit contract.
|
||||
new_value_staked():
|
||||
Returns the amount of ETH transferred to the ETH2 deposit contract.
|
||||
new_validators():
|
||||
Returns the number of new validators depositing 32 ETH to the ETH2 deposit contract.
|
||||
total_number_of_deposits():
|
||||
Returns the total number of transactions to the ETH2 deposit contract.
|
||||
total_value_staked():
|
||||
Returns the amount of ETH deposited to the ETH2 deposit contract.
|
||||
total_number_of_validators():
|
||||
Returns the total number of unique validators.
|
||||
phase_zero_staking_goal():
|
||||
Returns the percentage of the Phase 0 staking goal.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -35,7 +36,7 @@ class ETH2:
|
||||
:return: A DataFrame with ETH2 deposit data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_deposits_count'
|
||||
endpoint = "/v1/metrics/eth2/staking_deposits_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -49,7 +50,7 @@ class ETH2:
|
||||
:return: A DataFrame with staked value data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_volume_sum'
|
||||
endpoint = "/v1/metrics/eth2/staking_volume_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -63,7 +64,7 @@ class ETH2:
|
||||
:return: A DataFrame with new validators data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_validators_count'
|
||||
endpoint = "/v1/metrics/eth2/staking_validators_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -77,7 +78,7 @@ class ETH2:
|
||||
:return: A DataFrame with ETH2 deposit data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_total_deposits_count'
|
||||
endpoint = "/v1/metrics/eth2/staking_total_deposits_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -92,7 +93,7 @@ class ETH2:
|
||||
:return: A DataFrame with ETH2 deposit data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_total_volume_sum'
|
||||
endpoint = "/v1/metrics/eth2/staking_total_volume_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -106,7 +107,7 @@ class ETH2:
|
||||
:return: A DataFrame with ETH2 deposit data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_total_validators_count'
|
||||
endpoint = "/v1/metrics/eth2/staking_total_validators_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -120,7 +121,7 @@ class ETH2:
|
||||
:return: A DataFrame with staking goal data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/eth2/staking_phase_0_goal_percent'
|
||||
endpoint = "/v1/metrics/eth2/staking_phase_0_goal_percent"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
+48
-47
@@ -4,41 +4,42 @@ from .client import GlassnodeClient
|
||||
|
||||
class Fees:
|
||||
"""
|
||||
Fees class.
|
||||
Fees class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Mining object.
|
||||
fee_ratio_multiple():
|
||||
Returns the Fee Ratio Multiple (FRM).
|
||||
fees_total():
|
||||
Returns the total amount of fees paid to miners.
|
||||
fees_mean():
|
||||
Returns the mean fee per transaction.
|
||||
fees_median():
|
||||
Returns the median fee per transaction.
|
||||
gas_used_total():
|
||||
Returns the total amount of gas used in all transactions.
|
||||
gas_used_mean():
|
||||
Returns the mean amount of gas used per transaction.
|
||||
gas_used_median():
|
||||
Returns the median amount of gas used per transaction.
|
||||
gas_price_mean():
|
||||
Returns the mean gas price paid per transaction.
|
||||
gas_price_median():
|
||||
Returns the median gas price paid per transaction.
|
||||
transaction_gas_limit_mean():
|
||||
Returns the mean gas limit per transaction.
|
||||
transaction_gas_limit_median():
|
||||
Returns the median gas limit per transaction.
|
||||
exchange_fees_total():
|
||||
Returns the total amount of fees paid in transactions related to on-chain exchange activity.
|
||||
exchange_fees_mean():
|
||||
Returns the mean amount of fees paid in transactions related to on-chain exchange activity.
|
||||
exchange_fees_dominance():
|
||||
Returns the exchange fee dominance.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Mining object.
|
||||
fee_ratio_multiple():
|
||||
Returns the Fee Ratio Multiple (FRM).
|
||||
fees_total():
|
||||
Returns the total amount of fees paid to miners.
|
||||
fees_mean():
|
||||
Returns the mean fee per transaction.
|
||||
fees_median():
|
||||
Returns the median fee per transaction.
|
||||
gas_used_total():
|
||||
Returns the total amount of gas used in all transactions.
|
||||
gas_used_mean():
|
||||
Returns the mean amount of gas used per transaction.
|
||||
gas_used_median():
|
||||
Returns the median amount of gas used per transaction.
|
||||
gas_price_mean():
|
||||
Returns the mean gas price paid per transaction.
|
||||
gas_price_median():
|
||||
Returns the median gas price paid per transaction.
|
||||
transaction_gas_limit_mean():
|
||||
Returns the mean gas limit per transaction.
|
||||
transaction_gas_limit_median():
|
||||
Returns the median gas limit per transaction.
|
||||
exchange_fees_total():
|
||||
Returns the total amount of fees paid in transactions related to on-chain exchange activity.
|
||||
exchange_fees_mean():
|
||||
Returns the mean amount of fees paid in transactions related to on-chain exchange activity.
|
||||
exchange_fees_dominance():
|
||||
Returns the exchange fee dominance.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client: GlassnodeClient):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -48,7 +49,7 @@ class Fees:
|
||||
and gives an assessment how secure a chain is once block rewards disappear.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.FeeRatioMultiple>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/fee_ratio_multiple'
|
||||
endpoint = "/v1/metrics/fees/fee_ratio_multiple"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -59,7 +60,7 @@ class Fees:
|
||||
The total amount of fees paid to miners. Issued (minted) coins are not included.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.VolumeSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/volume_sum'
|
||||
endpoint = "/v1/metrics/fees/volume_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -70,7 +71,7 @@ class Fees:
|
||||
The mean fee per transaction. Issued (minted) coins are not included.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.VolumeMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/volume_mean'
|
||||
endpoint = "/v1/metrics/fees/volume_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -81,7 +82,7 @@ class Fees:
|
||||
The median fee per transaction. Issued (minted) coins are not included.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.VolumeMedian>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/volume_median'
|
||||
endpoint = "/v1/metrics/fees/volume_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -92,7 +93,7 @@ class Fees:
|
||||
The total amount of gas used in all transactions.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasUsedSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_used_sum'
|
||||
endpoint = "/v1/metrics/fees/gas_used_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -103,7 +104,7 @@ class Fees:
|
||||
The mean amount of gas used per transaction.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasUsedMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_used_mean'
|
||||
endpoint = "/v1/metrics/fees/gas_used_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -114,7 +115,7 @@ class Fees:
|
||||
The median amount of gas used per transaction.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasUsedMedian>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_used_median'
|
||||
endpoint = "/v1/metrics/fees/gas_used_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -125,7 +126,7 @@ class Fees:
|
||||
The mean gas price paid per transaction.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasPriceMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_price_mean'
|
||||
endpoint = "/v1/metrics/fees/gas_price_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -136,7 +137,7 @@ class Fees:
|
||||
The median gas price paid per transaction.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasPriceMedian>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_price_median'
|
||||
endpoint = "/v1/metrics/fees/gas_price_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -147,7 +148,7 @@ class Fees:
|
||||
The mean gas limit per transaction.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasLimitTxMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_limit_tx_mean'
|
||||
endpoint = "/v1/metrics/fees/gas_limit_tx_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -158,7 +159,7 @@ class Fees:
|
||||
The median gas limit per transaction.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=ETH&m=fees.GasLimitTxMedian>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/gas_limit_tx_median'
|
||||
endpoint = "/v1/metrics/fees/gas_limit_tx_median"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -170,7 +171,7 @@ class Fees:
|
||||
The total amount of fees paid in transactions related to on-chain exchange activity.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.ExchangesSum>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/exchanges_sum'
|
||||
endpoint = "/v1/metrics/fees/exchanges_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -182,7 +183,7 @@ class Fees:
|
||||
The mean amount of fees paid in transactions related to on-chain exchange activity.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.ExchangesMean>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/exchanges_mean'
|
||||
endpoint = "/v1/metrics/fees/exchanges_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -195,7 +196,7 @@ class Fees:
|
||||
paid in transactions related to on-chain exchange activity.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=fees.ExchangesRelative>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/fees/exchanges_relative'
|
||||
endpoint = "/v1/metrics/fees/exchanges_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class Indicators:
|
||||
The Realized HODL Ratio is a market indicator that uses a ratio of the Realized Cap HODL Waves.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.RhodlRatio>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/rhodl_ratio'
|
||||
endpoint = "/v1/metrics/indicators/rhodl_ratio"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -23,7 +23,7 @@ class Indicators:
|
||||
the market age (in days). Historically, CVDD has been an accurate indicator for global Bitcoin market bottoms.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Cvdd>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/cvdd'
|
||||
endpoint = "/v1/metrics/indicators/cvdd"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -37,7 +37,7 @@ class Indicators:
|
||||
the worst of the miner capitulation is over when the 30d MA of the hash rate crosses above the 60d MA.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.HashRibbon>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/hash_ribbon'
|
||||
endpoint = "/v1/metrics/indicators/hash_ribbon"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -50,7 +50,7 @@ class Indicators:
|
||||
of the Bitcoin mining difficulty to create the ribbon.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.DifficultyRibbon>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/difficulty_ribbon'
|
||||
endpoint = "/v1/metrics/indicators/difficulty_ribbon"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -62,7 +62,7 @@ class Indicators:
|
||||
standard deviation to quantify compression of the Difficulty Ribbon.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.DifficultyRibbonCompression>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/difficulty_ribbon_compression'
|
||||
endpoint = "/v1/metrics/indicators/difficulty_ribbon_compression"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -74,7 +74,7 @@ class Indicators:
|
||||
the market cap by the transferred on-chain volume measured in USD.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Nvt>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/nvt'
|
||||
endpoint = "/v1/metrics/indicators/nvt"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -85,7 +85,7 @@ class Indicators:
|
||||
The NVT Signal (NVTS) is a modified version of the original NVT Ratio.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Nvts>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/nvts'
|
||||
endpoint = "/v1/metrics/indicators/nvts"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -97,7 +97,7 @@ class Indicators:
|
||||
by dividing the on-chain transaction volume (in USD) by the market cap, i.e. the inverse of the NVT ratio.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Velocity>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/velocity'
|
||||
endpoint = "/v1/metrics/indicators/velocity"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -108,7 +108,7 @@ class Indicators:
|
||||
Adjusted Coin Days Destroyed simply divides CDD by the circulating supply.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.CddSupplyAdjusted>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/cdd_supply_adjusted'
|
||||
endpoint = "/v1/metrics/indicators/cdd_supply_adjusted"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -119,7 +119,7 @@ class Indicators:
|
||||
Binary Coin Days Destroyed is computed by thresholding Adjusted CDD by its average over time.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.CddSupplyAdjustedBinary>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/cdd_supply_adjusted_binary'
|
||||
endpoint = "/v1/metrics/indicators/cdd_supply_adjusted_binary"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -131,7 +131,7 @@ class Indicators:
|
||||
and is defined as the ratio of coin days destroyed and total transfer volume.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.AverageDormancySupplyAdjusted>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/average_dormancy_supply_adjusted'
|
||||
endpoint = "/v1/metrics/indicators/average_dormancy_supply_adjusted"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -144,7 +144,7 @@ class Indicators:
|
||||
0 and the current ATH in 100 equally-spaced partitions.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.SpentOutputPriceDistributionAth>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/spent_output_price_distribution_ath'
|
||||
endpoint = "/v1/metrics/indicators/spent_output_price_distribution_ath"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -157,7 +157,7 @@ class Indicators:
|
||||
and creating 50 equally-spaced bucket each above and below the current price in steps of +/- 2%.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.SpentOutputPriceDistributionPercent>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/spent_output_price_distribution_percent'
|
||||
endpoint = "/v1/metrics/indicators/spent_output_price_distribution_percent"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -169,7 +169,7 @@ class Indicators:
|
||||
by the 365-day moving average of daily issuance value.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.PuellMultiple>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/puell_multiple'
|
||||
endpoint = "/v1/metrics/indicators/puell_multiple"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -180,7 +180,7 @@ class Indicators:
|
||||
Adjusted SOPR is SOPR ignoring all outputs with a lifespan of less than 1 hour.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.SoprAdjusted>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/sopr_adjusted'
|
||||
endpoint = "/v1/metrics/indicators/sopr_adjusted"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -192,7 +192,7 @@ class Indicators:
|
||||
When confidence is low and price is high then risk/reward is unattractive at that time (Reserve Risk is high).
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.ReserveRisk>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/reserve_risk'
|
||||
endpoint = "/v1/metrics/indicators/reserve_risk"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -204,7 +204,7 @@ class Indicators:
|
||||
younger than 155 days and serves as an indicator to assess the behaviour of short term investors.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.SoprLess155>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/sopr_less_155'
|
||||
endpoint = "/v1/metrics/indicators/sopr_less_155"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -216,7 +216,7 @@ class Indicators:
|
||||
of at least 155 days and serves as an indicator to assess the behaviour of long term investors.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.SoprMore155>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/sopr_more_155'
|
||||
endpoint = "/v1/metrics/indicators/sopr_more_155"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -227,7 +227,7 @@ class Indicators:
|
||||
HODLer Net Position Change shows the monthly position change of long term investors.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.HodlerNetPositionChange>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/hodler_net_position_change'
|
||||
endpoint = "/v1/metrics/indicators/hodler_net_position_change"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -238,7 +238,7 @@ class Indicators:
|
||||
Lost or HODLed Bitcoins indicates moves of large and old stashes.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.HodledLostCoins>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/hodled_lost_coins'
|
||||
endpoint = "/v1/metrics/indicators/hodled_lost_coins"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -250,7 +250,7 @@ class Indicators:
|
||||
divided by the value at creation (USD) of a spent output. Or simply: price sold / price paid.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Sopr>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/sopr'
|
||||
endpoint = "/v1/metrics/indicators/sopr"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -262,7 +262,7 @@ class Indicators:
|
||||
in a transaction and multiplying it by the number of days it has been since those coins were last spent.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Cdd>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/cdd'
|
||||
endpoint = "/v1/metrics/indicators/cdd"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -274,7 +274,7 @@ class Indicators:
|
||||
Outputs with a lifespan of less than 1h are discarded.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Asol>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/asol'
|
||||
endpoint = "/v1/metrics/indicators/asol"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -286,7 +286,7 @@ class Indicators:
|
||||
Outputs with a lifespan of less than 1h are discarded.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Msol>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/msol'
|
||||
endpoint = "/v1/metrics/indicators/msol"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -298,7 +298,7 @@ class Indicators:
|
||||
and is defined as the ratio of coin days destroyed and total transfer volume.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.AverageDormancy>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/average_dormancy'
|
||||
endpoint = "/v1/metrics/indicators/average_dormancy"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -310,7 +310,7 @@ class Indicators:
|
||||
Liveliness increases as long term holder liquidate positions and decreases while they accumulate to HODL.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Liveliness>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/liveliness'
|
||||
endpoint = "/v1/metrics/indicators/liveliness"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -322,7 +322,7 @@ class Indicators:
|
||||
whose price at realisation time was lower than the current price normalised by the market cap.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.UnrealizedProfit>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/unrealized_profit'
|
||||
endpoint = "/v1/metrics/indicators/unrealized_profit"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -334,7 +334,7 @@ class Indicators:
|
||||
whose price at realisation time was higher than the current price normalised by the market cap.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.UnrealizedLoss>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/unrealized_loss'
|
||||
endpoint = "/v1/metrics/indicators/unrealized_loss"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -345,7 +345,7 @@ class Indicators:
|
||||
Net Unrealized Profit/Loss (NUPL) is the difference between Relative Unrealized Profit/Loss.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.NetUnrealizedProfitLoss>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/net_unrealized_profit_loss'
|
||||
endpoint = "/v1/metrics/indicators/net_unrealized_profit_loss"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -357,7 +357,7 @@ class Indicators:
|
||||
younger than 155 days and serves as an indicator to assess the behaviour of short term investors.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.NuplLess155>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/nupl_less_155'
|
||||
endpoint = "/v1/metrics/indicators/nupl_less_155"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -369,7 +369,7 @@ class Indicators:
|
||||
with a lifespan of at least 155 days and serves as an indicator to assess the behaviour of long term investors.
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.NuplMore155>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/nupl_more_155'
|
||||
endpoint = "/v1/metrics/indicators/nupl_more_155"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -378,28 +378,26 @@ class Indicators:
|
||||
@dataframe_with_inner_object
|
||||
def ssr(self) -> pd.DataFrame:
|
||||
"""
|
||||
The Stablecoin Supply Ratio (SSR) is the ratio between Bitcoin supply and the supply of stablecoins denoted
|
||||
in BTC, or: Bitcoin Marketcap / Stablecoin Marketcap. We use the following stablecoins for the supply: USDT,
|
||||
TUSD, USDC, PAX, GUSD, DAI, SAI, and BUSD. When the SSR is low, the current stablecoin supply has more "buying power"
|
||||
to purchase BTC. It serves as a proxy for the supply/demand mechanics between BTC and USD. For more information see
|
||||
this article (https://medium.com/@glassnode/stablecoins-buying-power-over-bitcoin-3475c0d8779d).
|
||||
The Stablecoin Supply Ratio (SSR) is the ratio between Bitcoin supply and the supply of stablecoins denoted
|
||||
in BTC, or: Bitcoin Marketcap / Stablecoin Marketcap. We use the following stablecoins for the supply: USDT,
|
||||
TUSD, USDC, PAX, GUSD, DAI, SAI, and BUSD. When the SSR is low, the current stablecoin supply has more "buying power"
|
||||
to purchase BTC. It serves as a proxy for the supply/demand mechanics between BTC and USD. For more information see
|
||||
this article (https://medium.com/@glassnode/stablecoins-buying-power-over-bitcoin-3475c0d8779d).
|
||||
|
||||
`View in Studio <https://studio.glassnode.com/metrics?a=BTC&m=indicators.Ssr>`_
|
||||
"""
|
||||
endpoint = '/v1/metrics/indicators/ssr'
|
||||
endpoint = "/v1/metrics/indicators/ssr"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint))
|
||||
|
||||
|
||||
def bvin(self):
|
||||
'''
|
||||
"""
|
||||
The Bitcoin Volatility Index (BVIN) is an implied volatility index that also represents the fair value of a bitcoin variance swap. The index is calculated by CryptoCompare using options data from Deribit and has been developed in collaboration with Carol Alexander and Arben Imeraj at the University of Sussex Business School. The index is suitable for use as a settlement price for bitcoin volatility futures. For more information on the methodology please see Alexander and Imeraj (2020).
|
||||
'''
|
||||
endpoint = '/v1/metrics/indicators/bvin'
|
||||
"""
|
||||
endpoint = "/v1/metrics/indicators/bvin"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint))
|
||||
|
||||
|
||||
+36
-35
@@ -3,33 +3,34 @@ from .utils import *
|
||||
|
||||
class Market:
|
||||
"""
|
||||
Market class.
|
||||
Market class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Market object.
|
||||
price():
|
||||
Returns the asset's price in USD.
|
||||
price_ohlc():
|
||||
Returns OHLC candlestick data.
|
||||
price_drawdown_from_ath():
|
||||
Returns the percent drawdown from previous all-time high.
|
||||
marketcap():
|
||||
Returns the market capitalization of the asset.
|
||||
mvrv_ratio():
|
||||
Returns MVRV ratio.
|
||||
realized_cap():
|
||||
Returns realized cap data.
|
||||
mvrv_z_score():
|
||||
Returns MVRV Z-Score.
|
||||
sth_mvrv():
|
||||
Returns Short Term Holder MVRV data.
|
||||
lth_mvrv():
|
||||
Returns Long Term Holder MVRV data.
|
||||
realized_price():
|
||||
Returns realized price data.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Market object.
|
||||
price():
|
||||
Returns the asset's price in USD.
|
||||
price_ohlc():
|
||||
Returns OHLC candlestick data.
|
||||
price_drawdown_from_ath():
|
||||
Returns the percent drawdown from previous all-time high.
|
||||
marketcap():
|
||||
Returns the market capitalization of the asset.
|
||||
mvrv_ratio():
|
||||
Returns MVRV ratio.
|
||||
realized_cap():
|
||||
Returns realized cap data.
|
||||
mvrv_z_score():
|
||||
Returns MVRV Z-Score.
|
||||
sth_mvrv():
|
||||
Returns Short Term Holder MVRV data.
|
||||
lth_mvrv():
|
||||
Returns Long Term Holder MVRV data.
|
||||
realized_price():
|
||||
Returns realized price data.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -41,7 +42,7 @@ class Market:
|
||||
:return: A DataFrame containing the asset's price data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/price_usd'
|
||||
endpoint = "/v1/metrics/market/price_usd"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -56,7 +57,7 @@ class Market:
|
||||
:return: A DataFrame containing OHLC candlestick data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/price_usd_ohlc'
|
||||
endpoint = "/v1/metrics/market/price_usd_ohlc"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -70,7 +71,7 @@ class Market:
|
||||
:return: A DataFrame containing the percent drawdown data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/price_drawdown_relative'
|
||||
endpoint = "/v1/metrics/market/price_drawdown_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -84,7 +85,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/marketcap_usd'
|
||||
endpoint = "/v1/metrics/market/marketcap_usd"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -98,7 +99,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/mvrv'
|
||||
endpoint = "/v1/metrics/market/mvrv"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -112,7 +113,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/marketcap_realized_usd'
|
||||
endpoint = "/v1/metrics/market/marketcap_realized_usd"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -125,7 +126,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/mvrv_z_score'
|
||||
endpoint = "/v1/metrics/market/mvrv_z_score"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -139,7 +140,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/mvrv_less_155'
|
||||
endpoint = "/v1/metrics/market/mvrv_less_155"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -153,7 +154,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/mvrv_more_155'
|
||||
endpoint = "/v1/metrics/market/mvrv_more_155"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -166,7 +167,7 @@ class Market:
|
||||
|
||||
:return: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/market/price_realized_usd'
|
||||
endpoint = "/v1/metrics/market/price_realized_usd"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
+40
-39
@@ -3,33 +3,34 @@ from .utils import *
|
||||
|
||||
class Mining:
|
||||
"""
|
||||
Mining class.
|
||||
Mining class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Mining object.
|
||||
difficulty():
|
||||
Returns difficulty to mine a block.
|
||||
hash_rate():
|
||||
Returns hash rate.
|
||||
miner_revenue_total():
|
||||
Returns the total miner revenue.
|
||||
miner_revenue_fees():
|
||||
Returns the percentage of miner revenue derived from fees.
|
||||
miner_revenue_block_rewards():
|
||||
Returns the total amount of newly minted coins.
|
||||
miner_outflow_multiple():
|
||||
Returns the miner outflow multiple.
|
||||
thermocap():
|
||||
Returns Thermocap data.
|
||||
market_cap_to_thermocap_ratio():
|
||||
Returns the Marketcap to Thermocap Ratio.
|
||||
miner_unspent_supply():
|
||||
Returns unspent miner supply.
|
||||
miner_names():
|
||||
Returns miner names for a mining endpoint.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Mining object.
|
||||
difficulty():
|
||||
Returns difficulty to mine a block.
|
||||
hash_rate():
|
||||
Returns hash rate.
|
||||
miner_revenue_total():
|
||||
Returns the total miner revenue.
|
||||
miner_revenue_fees():
|
||||
Returns the percentage of miner revenue derived from fees.
|
||||
miner_revenue_block_rewards():
|
||||
Returns the total amount of newly minted coins.
|
||||
miner_outflow_multiple():
|
||||
Returns the miner outflow multiple.
|
||||
thermocap():
|
||||
Returns Thermocap data.
|
||||
market_cap_to_thermocap_ratio():
|
||||
Returns the Marketcap to Thermocap Ratio.
|
||||
miner_unspent_supply():
|
||||
Returns unspent miner supply.
|
||||
miner_names():
|
||||
Returns miner names for a mining endpoint.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -41,7 +42,7 @@ class Mining:
|
||||
:return: A DataFrame with the latest difficulty data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/difficulty_latest'
|
||||
endpoint = "/v1/metrics/mining/difficulty_latest"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -55,7 +56,7 @@ class Mining:
|
||||
:return: A DataFrame with hash rate data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/hash_rate_mean'
|
||||
endpoint = "/v1/metrics/mining/hash_rate_mean"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -69,11 +70,11 @@ class Mining:
|
||||
:return: A DataFrame with total revenue data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/revenue_sum'
|
||||
endpoint = "/v1/metrics/mining/revenue_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'m': miner}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"m": miner}))
|
||||
|
||||
def miner_revenue_fees(self) -> pd.DataFrame:
|
||||
"""
|
||||
@@ -83,7 +84,7 @@ class Mining:
|
||||
:return: A DataFrame with revenue fees data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/revenue_from_fees'
|
||||
endpoint = "/v1/metrics/mining/revenue_from_fees"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -97,11 +98,11 @@ class Mining:
|
||||
:return: A DataFrame with revenue block rewards data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/volume_mined_sum'
|
||||
endpoint = "/v1/metrics/mining/volume_mined_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'m': miner}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"m": miner}))
|
||||
|
||||
def miner_outflow_multiple(self, miner=None) -> pd.DataFrame:
|
||||
"""
|
||||
@@ -112,11 +113,11 @@ class Mining:
|
||||
:return: A DataFrame MOM data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/miners_outflow_multiple'
|
||||
endpoint = "/v1/metrics/mining/miners_outflow_multiple"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint, {'m': miner}))
|
||||
return response_to_dataframe(self._gc.get(endpoint, {"m": miner}))
|
||||
|
||||
def thermocap(self) -> pd.DataFrame:
|
||||
"""
|
||||
@@ -127,7 +128,7 @@ class Mining:
|
||||
:return: A DataFrame with thermocap data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/thermocap'
|
||||
endpoint = "/v1/metrics/mining/thermocap"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -142,7 +143,7 @@ class Mining:
|
||||
:return: A DataFrame with M/T ratio data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/marketcap_thermocap_ratio'
|
||||
endpoint = "/v1/metrics/mining/marketcap_thermocap_ratio"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -156,13 +157,13 @@ class Mining:
|
||||
:return: A DataFrame with unspent miner supply data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/mining/miners_unspent_supply'
|
||||
endpoint = "/v1/metrics/mining/miners_unspent_supply"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
return response_to_dataframe(self._gc.get(endpoint))
|
||||
|
||||
def miner_names(self, endpoint='revenue_sum') -> list:
|
||||
def miner_names(self, endpoint="revenue_sum") -> list:
|
||||
"""
|
||||
Returns a list of miner names for a mining endpoint.
|
||||
|
||||
@@ -170,5 +171,5 @@ class Mining:
|
||||
:return: A List with miner names.
|
||||
:rtype: List
|
||||
"""
|
||||
miners = self._gc.get(f'/v1/metrics/mining/{endpoint}/miners')
|
||||
miners = self._gc.get(f"/v1/metrics/mining/{endpoint}/miners")
|
||||
return miners[self._gc.asset]
|
||||
|
||||
@@ -3,20 +3,21 @@ from .utils import *
|
||||
|
||||
class Protocols:
|
||||
"""
|
||||
Protocols class.
|
||||
Protocols class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Protocols object.
|
||||
uniswap_transactions():
|
||||
Returns the total number of transactions
|
||||
that contains an interaction within Uniswap contracts.
|
||||
uniswap_liquidity():
|
||||
Returns the current liquidity on Uniswap.
|
||||
uniswap_volume():
|
||||
Returns the total volume traded on Uniswap.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Protocols object.
|
||||
uniswap_transactions():
|
||||
Returns the total number of transactions
|
||||
that contains an interaction within Uniswap contracts.
|
||||
uniswap_liquidity():
|
||||
Returns the current liquidity on Uniswap.
|
||||
uniswap_volume():
|
||||
Returns the total volume traded on Uniswap.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client):
|
||||
self._gc = glassnode_client
|
||||
self._endpoints = self._gc.endpoints
|
||||
@@ -30,7 +31,7 @@ class Protocols:
|
||||
:return: A DataFrame containing Uniswap transactions data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/protocols/uniswap_transaction_count'
|
||||
endpoint = "/v1/metrics/protocols/uniswap_transaction_count"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -44,7 +45,7 @@ class Protocols:
|
||||
:return: A DataFrame containing Uniswap liquidity data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/protocols/uniswap_liquidity_latest'
|
||||
endpoint = "/v1/metrics/protocols/uniswap_liquidity_latest"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -58,7 +59,7 @@ class Protocols:
|
||||
:return: A DataFrame containing Uniswap volume data.
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/protocols/uniswap_volume_sum'
|
||||
endpoint = "/v1/metrics/protocols/uniswap_volume_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
+114
-113
@@ -4,85 +4,86 @@ from .client import GlassnodeClient
|
||||
|
||||
class Supply:
|
||||
"""
|
||||
Supply class.
|
||||
Supply class.
|
||||
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Supply object.
|
||||
liquid_illiquid_supply():
|
||||
Returns the total supply held by illiquid, liquid, and highly liquid entities.
|
||||
liquid_supply_change():
|
||||
Returns the monthly (30d) net change of supply held by liquid and highly liquid entities.
|
||||
illiquid_supply_change():
|
||||
Returns the monthly (30d) net change of supply held by illiquid entities.
|
||||
circulating_supply():
|
||||
Returns the total amount of all coins ever created/issued.
|
||||
issuance():
|
||||
Returns the total amount of new coins added to the current supply.
|
||||
inflation_rate():
|
||||
Returns the yearly inflation rate.
|
||||
supply_last_active_less_24h():
|
||||
Returns the amount of circulating supply last moved in the last 24 hours.
|
||||
supply_last_active_1d_1w():
|
||||
Returns the amount of circulating supply last moved between 1 day and 1 week ago.
|
||||
supply_last_active_1w_1m():
|
||||
Returns the amount of circulating supply last moved between 1 week and 1 month ago.
|
||||
supply_last_active_1m_3m():
|
||||
Returns the amount of circulating supply last moved between 1 month and 3 months ago.
|
||||
supply_last_active_3m_6m():
|
||||
Returns the amount of circulating supply last moved between 3 months and 6 months ago.
|
||||
supply_last_active_6m_12m():
|
||||
Returns the amount of circulating supply last moved between 6 months and 12 months ago.
|
||||
supply_last_active_1y_2y():
|
||||
Returns the amount of circulating supply last moved between 1 year and 6 years ago.
|
||||
supply_last_active_2y_3y():
|
||||
Returns the amount of circulating supply last moved between 2 years and 3 years ago.
|
||||
supply_last_active_3y_5y():
|
||||
Returns the amount of circulating supply last moved between 3 years and 5 years ago.
|
||||
supply_last_active_5y_7y():
|
||||
Returns the amount of circulating supply last moved between 5 years and 7 years ago.
|
||||
supply_last_active_7y_10y():
|
||||
Returns the amount of circulating supply last moved between 7 years and 10 years ago.
|
||||
supply_last_active_more_10y():
|
||||
Returns the amount of circulating supply last moved more than 10 years ago.
|
||||
hodl_waves():
|
||||
Returns a bundle of all active supply age bands, aka HODL waves.
|
||||
supply_last_active_more_1y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 1 year.
|
||||
supply_last_active_more_2y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 2 years.
|
||||
supply_last_active_more_3y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 3 years.
|
||||
supply_last_active_more_5y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 5 years.
|
||||
realized_cap_hodl_waves():
|
||||
Returns HODL waves weighted by Realized Price.
|
||||
adjusted_supply():
|
||||
Returns the circulating supply adjusted by accounting for lost coins.
|
||||
supply_in_profit():
|
||||
Returns the circulating supply in profit.
|
||||
supply_in_loss():
|
||||
Returns the circulating supply in loss.
|
||||
supply_in_profit_relative():
|
||||
Returns the percentage of circulating supply in profit.
|
||||
short_term_holder_supply():
|
||||
Returns the total amount of circulating supply held by short-term holders.
|
||||
long_term_holder_supply():
|
||||
Returns the total amount of circulating supply held by long-term holders.
|
||||
short_term_holder_supply_in_loss():
|
||||
Returns the total amount of circulating supply that is currently at loss and held by short-term holders.
|
||||
long_term_holder_supply_in_loss():
|
||||
Returns the total amount of circulating supply that is currently at loss and held by long-term holders.
|
||||
short_term_holder_supply_in_profit():
|
||||
Returns the total amount of circulating supply that is currently in profit and held by short-term holders.
|
||||
long_term_holder_supply_in_profit():
|
||||
Returns the total amount of circulating supply that is currently in profit and held by long-term holders.
|
||||
relative_long_short_term_holder_supply():
|
||||
Returns the relative amount of circulating supply of held by long- and short-term holders in profit/loss.
|
||||
long_term_holder_position_change():
|
||||
Returns the monthly net position change of long-term holders.
|
||||
Methods
|
||||
-------
|
||||
__init__(glassnode_client):
|
||||
Constructs a Supply object.
|
||||
liquid_illiquid_supply():
|
||||
Returns the total supply held by illiquid, liquid, and highly liquid entities.
|
||||
liquid_supply_change():
|
||||
Returns the monthly (30d) net change of supply held by liquid and highly liquid entities.
|
||||
illiquid_supply_change():
|
||||
Returns the monthly (30d) net change of supply held by illiquid entities.
|
||||
circulating_supply():
|
||||
Returns the total amount of all coins ever created/issued.
|
||||
issuance():
|
||||
Returns the total amount of new coins added to the current supply.
|
||||
inflation_rate():
|
||||
Returns the yearly inflation rate.
|
||||
supply_last_active_less_24h():
|
||||
Returns the amount of circulating supply last moved in the last 24 hours.
|
||||
supply_last_active_1d_1w():
|
||||
Returns the amount of circulating supply last moved between 1 day and 1 week ago.
|
||||
supply_last_active_1w_1m():
|
||||
Returns the amount of circulating supply last moved between 1 week and 1 month ago.
|
||||
supply_last_active_1m_3m():
|
||||
Returns the amount of circulating supply last moved between 1 month and 3 months ago.
|
||||
supply_last_active_3m_6m():
|
||||
Returns the amount of circulating supply last moved between 3 months and 6 months ago.
|
||||
supply_last_active_6m_12m():
|
||||
Returns the amount of circulating supply last moved between 6 months and 12 months ago.
|
||||
supply_last_active_1y_2y():
|
||||
Returns the amount of circulating supply last moved between 1 year and 6 years ago.
|
||||
supply_last_active_2y_3y():
|
||||
Returns the amount of circulating supply last moved between 2 years and 3 years ago.
|
||||
supply_last_active_3y_5y():
|
||||
Returns the amount of circulating supply last moved between 3 years and 5 years ago.
|
||||
supply_last_active_5y_7y():
|
||||
Returns the amount of circulating supply last moved between 5 years and 7 years ago.
|
||||
supply_last_active_7y_10y():
|
||||
Returns the amount of circulating supply last moved between 7 years and 10 years ago.
|
||||
supply_last_active_more_10y():
|
||||
Returns the amount of circulating supply last moved more than 10 years ago.
|
||||
hodl_waves():
|
||||
Returns a bundle of all active supply age bands, aka HODL waves.
|
||||
supply_last_active_more_1y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 1 year.
|
||||
supply_last_active_more_2y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 2 years.
|
||||
supply_last_active_more_3y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 3 years.
|
||||
supply_last_active_more_5y_ago():
|
||||
Returns the percent of circulating supply that has not moved in at least 5 years.
|
||||
realized_cap_hodl_waves():
|
||||
Returns HODL waves weighted by Realized Price.
|
||||
adjusted_supply():
|
||||
Returns the circulating supply adjusted by accounting for lost coins.
|
||||
supply_in_profit():
|
||||
Returns the circulating supply in profit.
|
||||
supply_in_loss():
|
||||
Returns the circulating supply in loss.
|
||||
supply_in_profit_relative():
|
||||
Returns the percentage of circulating supply in profit.
|
||||
short_term_holder_supply():
|
||||
Returns the total amount of circulating supply held by short-term holders.
|
||||
long_term_holder_supply():
|
||||
Returns the total amount of circulating supply held by long-term holders.
|
||||
short_term_holder_supply_in_loss():
|
||||
Returns the total amount of circulating supply that is currently at loss and held by short-term holders.
|
||||
long_term_holder_supply_in_loss():
|
||||
Returns the total amount of circulating supply that is currently at loss and held by long-term holders.
|
||||
short_term_holder_supply_in_profit():
|
||||
Returns the total amount of circulating supply that is currently in profit and held by short-term holders.
|
||||
long_term_holder_supply_in_profit():
|
||||
Returns the total amount of circulating supply that is currently in profit and held by long-term holders.
|
||||
relative_long_short_term_holder_supply():
|
||||
Returns the relative amount of circulating supply of held by long- and short-term holders in profit/loss.
|
||||
long_term_holder_position_change():
|
||||
Returns the monthly net position change of long-term holders.
|
||||
"""
|
||||
|
||||
def __init__(self, glassnode_client: GlassnodeClient):
|
||||
self._gc = glassnode_client
|
||||
|
||||
@@ -93,7 +94,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/liquid_illiquid_sum'
|
||||
endpoint = "/v1/metrics/supply/liquid_illiquid_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -106,7 +107,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/liquid_change'
|
||||
endpoint = "/v1/metrics/supply/liquid_change"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -119,7 +120,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/illiquid_change'
|
||||
endpoint = "/v1/metrics/supply/illiquid_change"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -132,7 +133,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/current'
|
||||
endpoint = "/v1/metrics/supply/current"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -146,7 +147,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/issued'
|
||||
endpoint = "/v1/metrics/supply/issued"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -160,7 +161,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/inflation_rate'
|
||||
endpoint = "/v1/metrics/supply/inflation_rate"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -173,7 +174,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_24h'
|
||||
endpoint = "/v1/metrics/supply/active_24h"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -186,7 +187,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_1d_1w'
|
||||
endpoint = "/v1/metrics/supply/active_1d_1w"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -199,7 +200,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_1w_1m'
|
||||
endpoint = "/v1/metrics/supply/active_1w_1m"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -212,7 +213,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_1m_3m'
|
||||
endpoint = "/v1/metrics/supply/active_1m_3m"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -225,7 +226,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_3m_6m'
|
||||
endpoint = "/v1/metrics/supply/active_3m_6m"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -238,7 +239,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_6m_12m'
|
||||
endpoint = "/v1/metrics/supply/active_6m_12m"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -251,7 +252,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_1y_2y'
|
||||
endpoint = "/v1/metrics/supply/active_1y_2y"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -264,7 +265,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_2y_3y'
|
||||
endpoint = "/v1/metrics/supply/active_2y_3y"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -277,7 +278,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_3y_5y'
|
||||
endpoint = "/v1/metrics/supply/active_3y_5y"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -290,7 +291,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_5y_7y'
|
||||
endpoint = "/v1/metrics/supply/active_5y_7y"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -303,7 +304,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_7y_10y'
|
||||
endpoint = "/v1/metrics/supply/active_7y_10y"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -316,7 +317,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_more_10y'
|
||||
endpoint = "/v1/metrics/supply/active_more_10y"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -329,7 +330,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/hodl_waves'
|
||||
endpoint = "/v1/metrics/supply/hodl_waves"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -342,7 +343,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_more_1y_percent'
|
||||
endpoint = "/v1/metrics/supply/active_more_1y_percent"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -355,7 +356,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_more_2y_percent'
|
||||
endpoint = "/v1/metrics/supply/active_more_2y_percent"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -368,7 +369,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_more_3y_percent'
|
||||
endpoint = "/v1/metrics/supply/active_more_3y_percent"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -381,7 +382,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/active_more_5y_percent'
|
||||
endpoint = "/v1/metrics/supply/active_more_5y_percent"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -394,7 +395,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/rcap_hodl_waves'
|
||||
endpoint = "/v1/metrics/supply/rcap_hodl_waves"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -407,7 +408,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/current_adjusted'
|
||||
endpoint = "/v1/metrics/supply/current_adjusted"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -421,7 +422,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/profit_sum'
|
||||
endpoint = "/v1/metrics/supply/profit_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -435,7 +436,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/loss_sum'
|
||||
endpoint = "/v1/metrics/supply/loss_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -448,7 +449,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/profit_relative'
|
||||
endpoint = "/v1/metrics/supply/profit_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -461,7 +462,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/sth_sum'
|
||||
endpoint = "/v1/metrics/supply/sth_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -474,7 +475,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/lth_sum'
|
||||
endpoint = "/v1/metrics/supply/lth_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -487,7 +488,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/sth_loss_sum'
|
||||
endpoint = "/v1/metrics/supply/sth_loss_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -500,7 +501,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/lth_loss_sum'
|
||||
endpoint = "/v1/metrics/supply/lth_loss_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -513,7 +514,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/sth_profit_sum'
|
||||
endpoint = "/v1/metrics/supply/sth_profit_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -526,7 +527,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/lth_profit_sum'
|
||||
endpoint = "/v1/metrics/supply/lth_profit_sum"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -539,7 +540,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/lth_sth_profit_loss_relative'
|
||||
endpoint = "/v1/metrics/supply/lth_sth_profit_loss_relative"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
@@ -553,7 +554,7 @@ class Supply:
|
||||
|
||||
:rtype: DataFrame
|
||||
"""
|
||||
endpoint = '/v1/metrics/supply/lth_net_change'
|
||||
endpoint = "/v1/metrics/supply/lth_net_change"
|
||||
if not is_supported_by_endpoint(self._gc, endpoint):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ def unix_timestamp(date_str):
|
||||
|
||||
def is_supported_by_endpoint(glassnode_client, url):
|
||||
path = glassnode_client.endpoints.query(url)
|
||||
if glassnode_client.asset not in path['assets']:
|
||||
print(f'{url} metric is not available for {glassnode_client.asset}')
|
||||
if glassnode_client.asset not in path["assets"]:
|
||||
print(f"{url} metric is not available for {glassnode_client.asset}")
|
||||
return False
|
||||
if glassnode_client.resolution not in path['resolutions']:
|
||||
print(f'{url} metric is not available for {glassnode_client.resolution}')
|
||||
if glassnode_client.resolution not in path["resolutions"]:
|
||||
print(f"{url} metric is not available for {glassnode_client.resolution}")
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -36,8 +36,8 @@ def response_to_dataframe(response):
|
||||
"""
|
||||
try:
|
||||
df = pd.DataFrame(response)
|
||||
df.set_index('t', inplace=True)
|
||||
df.index = pd.to_datetime(df.index, unit='s')
|
||||
df.set_index("t", inplace=True)
|
||||
df.index = pd.to_datetime(df.index, unit="s")
|
||||
df.index.name = None
|
||||
df.sort_index(ascending=False, inplace=True)
|
||||
return df
|
||||
@@ -48,7 +48,8 @@ def response_to_dataframe(response):
|
||||
def dataframe_with_inner_object(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
df = func(*args, **kwargs)
|
||||
return pd.concat([df.drop(['o'], axis=1), df['o'].apply(pd.Series)], axis=1)
|
||||
return pd.concat([df.drop(["o"], axis=1), df["o"].apply(pd.Series)], axis=1)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
@@ -60,7 +61,7 @@ def fetch(endpoint, params=None):
|
||||
:param endpoint: Endpoint url corresponding to some metric (ex. '/v1/metrics/market/price_usd')
|
||||
:return: DataFrame of {'t' : datetime, 'v' : 'metric-value'} pairs
|
||||
"""
|
||||
r = requests.get(f'https://api.glassnode.com{endpoint}', params=params, stream=True)
|
||||
r = requests.get(f"https://api.glassnode.com{endpoint}", params=params, stream=True)
|
||||
try:
|
||||
r.raise_for_status()
|
||||
except requests.exceptions.HTTPError as e:
|
||||
|
||||
+3
-1
@@ -1,10 +1,12 @@
|
||||
from hashlib import sha256
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def hash_df(df: pd.DataFrame) -> str:
|
||||
s = str(df.columns) + str(df.index) + str(df.values)
|
||||
return sha256(s.encode()).hexdigest()
|
||||
|
||||
|
||||
def hash_series(df: pd.Series) -> str:
|
||||
s = str(df.name) + str(df.index) + str(df.values)
|
||||
return sha256(s.encode()).hexdigest()
|
||||
return sha256(s.encode()).hexdigest()
|
||||
|
||||
+33
-11
@@ -5,11 +5,19 @@ import string
|
||||
import random
|
||||
from itertools import dropwhile
|
||||
|
||||
|
||||
def get_files_from_dir(path: str) -> list[str]:
|
||||
return [f for f in os.listdir(path) if os.path.isfile(os.path.join(path,f)) and not f.startswith('.')]
|
||||
return [
|
||||
f
|
||||
for f in os.listdir(path)
|
||||
if os.path.isfile(os.path.join(path, f)) and not f.startswith(".")
|
||||
]
|
||||
|
||||
|
||||
def get_first_valid_return_index(series: pd.Series) -> int:
|
||||
double_nested_results = np.where(np.logical_and(series != 0, np.logical_not(pd.isna(series))))
|
||||
double_nested_results = np.where(
|
||||
np.logical_and(series != 0, np.logical_not(pd.isna(series)))
|
||||
)
|
||||
if len(double_nested_results) == 0:
|
||||
return 0
|
||||
nested_result = double_nested_results[0]
|
||||
@@ -17,42 +25,56 @@ def get_first_valid_return_index(series: pd.Series) -> int:
|
||||
return 0
|
||||
return nested_result[0]
|
||||
|
||||
|
||||
def get_last_non_na_index(series: pd.Series, index: int) -> int:
|
||||
return next(dropwhile(lambda x: pd.isna(x[1]), enumerate(reversed(series[:index+1]))))[0]
|
||||
return next(
|
||||
dropwhile(lambda x: pd.isna(x[1]), enumerate(reversed(series[: index + 1])))
|
||||
)[0]
|
||||
|
||||
|
||||
def flatten(list_of_lists: list) -> list:
|
||||
return [item for sublist in list_of_lists for item in sublist]
|
||||
|
||||
|
||||
def weighted_average(df: pd.DataFrame, weights_source: str) -> pd.Series:
|
||||
if df.shape[1] == 0:
|
||||
return df
|
||||
mean_df = df.iloc[:,0]
|
||||
mean_df = df.iloc[:, 0]
|
||||
weights = df.loc[weights_source]
|
||||
|
||||
for i, row in df.iterrows():
|
||||
if i == weights_source: continue
|
||||
if i == weights_source:
|
||||
continue
|
||||
mean_df.loc[i] = (row * weights).sum() / df.loc[weights_source].sum()
|
||||
|
||||
return mean_df
|
||||
|
||||
|
||||
def drop_columns_if_exist(df: pd.DataFrame, columns: list) -> pd.DataFrame:
|
||||
for column in columns:
|
||||
if column in df.columns:
|
||||
df = df.drop(column, axis=1)
|
||||
return df
|
||||
|
||||
|
||||
def random_string(n: int) -> str:
|
||||
return ''.join(random.choices(string.ascii_uppercase + string.digits, k=n))
|
||||
return "".join(random.choices(string.ascii_uppercase + string.digits, k=n))
|
||||
|
||||
|
||||
def equal_except_nan(row: pd.Series):
|
||||
if np.isnan(row.iloc[0]) or np.isnan(row.iloc[1]):
|
||||
return np.nan
|
||||
if row.iloc[0] == row.iloc[1]:
|
||||
return 1.
|
||||
return 1.0
|
||||
else:
|
||||
return 0.
|
||||
return 0.0
|
||||
|
||||
def drop_until_first_valid_index(df: pd.DataFrame, series: pd.Series) -> tuple[pd.DataFrame, pd.Series]:
|
||||
first_valid_index = max(get_first_valid_return_index(df.iloc[:,0]), get_first_valid_return_index(series))
|
||||
return df.iloc[first_valid_index:], series.iloc[first_valid_index:]
|
||||
|
||||
def drop_until_first_valid_index(
|
||||
df: pd.DataFrame, series: pd.Series
|
||||
) -> tuple[pd.DataFrame, pd.Series]:
|
||||
first_valid_index = max(
|
||||
get_first_valid_return_index(df.iloc[:, 0]),
|
||||
get_first_valid_return_index(series),
|
||||
)
|
||||
return df.iloc[first_valid_index:], series.iloc[first_valid_index:]
|
||||
|
||||
+129
-61
@@ -3,6 +3,7 @@ import pandas as pd
|
||||
import scipy.stats as ss
|
||||
import numpy as np
|
||||
|
||||
|
||||
def timing_of_flattening_and_flips(target_positions: pd.Series) -> pd.DatetimeIndex:
|
||||
"""
|
||||
Advances in Financial Machine Learning, Snippet 14.1, page 197
|
||||
@@ -15,8 +16,12 @@ def timing_of_flattening_and_flips(target_positions: pd.Series) -> pd.DatetimeIn
|
||||
:return: (pd.DatetimeIndex) Timestamps of trades flattening, flipping and last bet
|
||||
"""
|
||||
|
||||
empty_positions = target_positions[(target_positions == 0)].index # Empty positions index
|
||||
previous_positions = target_positions.shift(1) # Timestamps pointing at previous positions
|
||||
empty_positions = target_positions[
|
||||
(target_positions == 0)
|
||||
].index # Empty positions index
|
||||
previous_positions = target_positions.shift(
|
||||
1
|
||||
) # Timestamps pointing at previous positions
|
||||
|
||||
# Index of positions where previous one wasn't empty
|
||||
previous_positions = previous_positions[(previous_positions != 0)].index
|
||||
@@ -30,8 +35,12 @@ def timing_of_flattening_and_flips(target_positions: pd.Series) -> pd.DatetimeIn
|
||||
# FLIPS - if current position has another direction compared to the next
|
||||
flips = multiplied_posions[(multiplied_posions < 0)].index
|
||||
flips_and_flattenings = flattening.union(flips).sort_values()
|
||||
if target_positions.index[-1] not in flips_and_flattenings: # Appending with last bet
|
||||
flips_and_flattenings = flips_and_flattenings.append(target_positions.index[-1:])
|
||||
if (
|
||||
target_positions.index[-1] not in flips_and_flattenings
|
||||
): # Appending with last bet
|
||||
flips_and_flattenings = flips_and_flattenings.append(
|
||||
target_positions.index[-1:]
|
||||
)
|
||||
|
||||
return flips_and_flattenings
|
||||
|
||||
@@ -50,19 +59,23 @@ def average_holding_period(target_positions: pd.Series) -> float:
|
||||
:return: (float) Estimated average holding period, NaN if zero or unpredicted
|
||||
"""
|
||||
|
||||
holding_period = pd.DataFrame(columns=['holding_time', 'weight'])
|
||||
holding_period = pd.DataFrame(columns=["holding_time", "weight"])
|
||||
entry_time = 0
|
||||
position_difference = target_positions.diff()
|
||||
|
||||
# Time elapsed from the starting time for each position
|
||||
time_difference = (target_positions.index - target_positions.index[0]) / np.timedelta64(1, 'D')
|
||||
time_difference = (
|
||||
target_positions.index - target_positions.index[0]
|
||||
) / np.timedelta64(1, "D")
|
||||
for i in range(1, target_positions.size):
|
||||
|
||||
# Increased or unchanged position
|
||||
if float(position_difference.iloc[i] * target_positions.iloc[i - 1]) >= 0:
|
||||
if float(target_positions.iloc[i]) != 0: # And not an empty position
|
||||
entry_time = (entry_time * target_positions.iloc[i - 1] +
|
||||
time_difference[i] * position_difference.iloc[i]) / target_positions.iloc[i]
|
||||
entry_time = (
|
||||
entry_time * target_positions.iloc[i - 1]
|
||||
+ time_difference[i] * position_difference.iloc[i]
|
||||
) / target_positions.iloc[i]
|
||||
|
||||
# Decreased
|
||||
if float(position_difference.iloc[i] * target_positions.iloc[i - 1]) < 0:
|
||||
@@ -71,19 +84,25 @@ def average_holding_period(target_positions: pd.Series) -> float:
|
||||
# Flip of a position
|
||||
if float(target_positions.iloc[i] * target_positions.iloc[i - 1]) < 0:
|
||||
weight = abs(target_positions.iloc[i - 1])
|
||||
holding_period.loc[target_positions.index[i], ['holding_time', 'weight']] = (hold_time, weight)
|
||||
holding_period.loc[
|
||||
target_positions.index[i], ["holding_time", "weight"]
|
||||
] = (hold_time, weight)
|
||||
entry_time = time_difference[i] # Reset entry time
|
||||
|
||||
# Only a part of position is closed
|
||||
else:
|
||||
weight = abs(position_difference.iloc[i])
|
||||
holding_period.loc[target_positions.index[i], ['holding_time', 'weight']] = (hold_time, weight)
|
||||
holding_period.loc[
|
||||
target_positions.index[i], ["holding_time", "weight"]
|
||||
] = (hold_time, weight)
|
||||
|
||||
if float(holding_period['weight'].sum()) > 0: # If there were closed trades at all
|
||||
avg_holding_period = float((holding_period['holding_time'] * \
|
||||
holding_period['weight']).sum() / holding_period['weight'].sum())
|
||||
if float(holding_period["weight"].sum()) > 0: # If there were closed trades at all
|
||||
avg_holding_period = float(
|
||||
(holding_period["holding_time"] * holding_period["weight"]).sum()
|
||||
/ holding_period["weight"].sum()
|
||||
)
|
||||
else:
|
||||
avg_holding_period = float('nan')
|
||||
avg_holding_period = float("nan")
|
||||
|
||||
return avg_holding_period
|
||||
|
||||
@@ -99,15 +118,15 @@ def bets_concentration(returns: pd.Series) -> float:
|
||||
"""
|
||||
|
||||
if returns.size <= 2:
|
||||
return float('nan') # If less than 3 bets
|
||||
return float("nan") # If less than 3 bets
|
||||
weights = returns / returns.sum() # Weights of each bet
|
||||
hhi = (weights ** 2).sum() # Herfindahl-Hirschman Index for weights
|
||||
hhi = (weights**2).sum() # Herfindahl-Hirschman Index for weights
|
||||
hhi = float((hhi - returns.size ** (-1)) / (1 - returns.size ** (-1)))
|
||||
|
||||
return hhi
|
||||
|
||||
|
||||
def all_bets_concentration(returns: pd.Series, frequency: str = 'M') -> tuple:
|
||||
def all_bets_concentration(returns: pd.Series, frequency: str = "M") -> tuple:
|
||||
"""
|
||||
Advances in Financial Machine Learning, Snippet 14.3, page 201
|
||||
Given a pd.Series of returns, derives concentration of positive returns, negative returns
|
||||
@@ -131,7 +150,9 @@ def all_bets_concentration(returns: pd.Series, frequency: str = 'M') -> tuple:
|
||||
negative_concentration = bets_concentration(returns[returns < 0])
|
||||
|
||||
# Concentration of bets/time period (month by default)
|
||||
time_concentration = bets_concentration(returns.groupby(pd.Grouper(freq=frequency)).count())
|
||||
time_concentration = bets_concentration(
|
||||
returns.groupby(pd.Grouper(freq=frequency)).count()
|
||||
)
|
||||
|
||||
return (positive_concentration, negative_concentration, time_concentration)
|
||||
|
||||
@@ -157,35 +178,42 @@ def drawdown_and_time_under_water(returns: pd.Series, dollars: bool = False) ->
|
||||
:return: (tuple of pd.Series) Series of drawdowns and time under water
|
||||
"""
|
||||
|
||||
frame = returns.to_frame('pnl')
|
||||
frame['hwm'] = returns.expanding().max() # Adding high watermarks as column
|
||||
frame = returns.to_frame("pnl")
|
||||
frame["hwm"] = returns.expanding().max() # Adding high watermarks as column
|
||||
|
||||
# Grouped as min returns by high watermarks
|
||||
high_watermarks = frame.groupby('hwm').min().reset_index()
|
||||
high_watermarks.columns = ['hwm', 'min']
|
||||
high_watermarks = frame.groupby("hwm").min().reset_index()
|
||||
high_watermarks.columns = ["hwm", "min"]
|
||||
|
||||
# Time high watermark occurred
|
||||
high_watermarks.index = frame['hwm'].drop_duplicates(keep='first').index
|
||||
high_watermarks.index = frame["hwm"].drop_duplicates(keep="first").index
|
||||
|
||||
# Picking ones that had a drawdown after high watermark
|
||||
high_watermarks = high_watermarks[high_watermarks['hwm'] > high_watermarks['min']]
|
||||
high_watermarks = high_watermarks[high_watermarks["hwm"] > high_watermarks["min"]]
|
||||
if dollars:
|
||||
drawdown = high_watermarks['hwm'] - high_watermarks['min']
|
||||
drawdown = high_watermarks["hwm"] - high_watermarks["min"]
|
||||
else:
|
||||
drawdown = 1 - high_watermarks['min'] / high_watermarks['hwm']
|
||||
drawdown = 1 - high_watermarks["min"] / high_watermarks["hwm"]
|
||||
|
||||
time_under_water = ((high_watermarks.index[1:] - high_watermarks.index[:-1]) / np.timedelta64(1, 'Y')).values
|
||||
time_under_water = (
|
||||
(high_watermarks.index[1:] - high_watermarks.index[:-1])
|
||||
/ np.timedelta64(1, "Y")
|
||||
).values
|
||||
|
||||
# Adding also period from last High watermark to last return observed.
|
||||
time_under_water = np.append(time_under_water,
|
||||
(returns.index[-1] - high_watermarks.index[-1]) / np.timedelta64(1, 'Y'))
|
||||
time_under_water = np.append(
|
||||
time_under_water,
|
||||
(returns.index[-1] - high_watermarks.index[-1]) / np.timedelta64(1, "Y"),
|
||||
)
|
||||
|
||||
time_under_water = pd.Series(time_under_water, index=high_watermarks.index)
|
||||
|
||||
return drawdown, time_under_water
|
||||
|
||||
|
||||
def sharpe_ratio(returns: pd.Series, entries_per_year: int = 252, risk_free_rate: float = 0) -> float:
|
||||
def sharpe_ratio(
|
||||
returns: pd.Series, entries_per_year: int = 252, risk_free_rate: float = 0
|
||||
) -> float:
|
||||
"""
|
||||
Calculates annualized Sharpe ratio for pd.Series of normal or log returns.
|
||||
Risk_free_rate should be given for the same period the returns are given.
|
||||
@@ -197,12 +225,18 @@ def sharpe_ratio(returns: pd.Series, entries_per_year: int = 252, risk_free_rate
|
||||
:return: (float) Annualized Sharpe ratio
|
||||
"""
|
||||
|
||||
sharpe_r = (returns.mean() - risk_free_rate) / returns.std() * (entries_per_year) ** (1 / 2)
|
||||
sharpe_r = (
|
||||
(returns.mean() - risk_free_rate)
|
||||
/ returns.std()
|
||||
* (entries_per_year) ** (1 / 2)
|
||||
)
|
||||
|
||||
return sharpe_r
|
||||
|
||||
|
||||
def information_ratio(returns: pd.Series, benchmark: float = 0, entries_per_year: int = 252) -> float:
|
||||
def information_ratio(
|
||||
returns: pd.Series, benchmark: float = 0, entries_per_year: int = 252
|
||||
) -> float:
|
||||
"""
|
||||
Calculates annualized information ratio for pd.Series of normal or log returns.
|
||||
Benchmark should be provided as a return for the same time period as that between
|
||||
@@ -223,8 +257,13 @@ def information_ratio(returns: pd.Series, benchmark: float = 0, entries_per_year
|
||||
return information_r
|
||||
|
||||
|
||||
def probabilistic_sharpe_ratio(observed_sr: float, benchmark_sr: float, number_of_returns: int,
|
||||
skewness_of_returns: float = 0, kurtosis_of_returns: float = 3) -> float:
|
||||
def probabilistic_sharpe_ratio(
|
||||
observed_sr: float,
|
||||
benchmark_sr: float,
|
||||
number_of_returns: int,
|
||||
skewness_of_returns: float = 0,
|
||||
kurtosis_of_returns: float = 3,
|
||||
) -> float:
|
||||
"""
|
||||
Calculates the probabilistic Sharpe ratio (PSR) that provides an adjusted estimate of SR,
|
||||
by removing the inflationary effect caused by short series with skewed and/or
|
||||
@@ -241,30 +280,47 @@ def probabilistic_sharpe_ratio(observed_sr: float, benchmark_sr: float, number_o
|
||||
:return: (float) Probabilistic Sharpe ratio
|
||||
"""
|
||||
|
||||
test_value = ((observed_sr - benchmark_sr) * np.sqrt(number_of_returns - 1)) / \
|
||||
((1 - skewness_of_returns * observed_sr + (kurtosis_of_returns - 1) / \
|
||||
4 * observed_sr ** 2)**(1 / 2))
|
||||
test_value = ((observed_sr - benchmark_sr) * np.sqrt(number_of_returns - 1)) / (
|
||||
(
|
||||
1
|
||||
- skewness_of_returns * observed_sr
|
||||
+ (kurtosis_of_returns - 1) / 4 * observed_sr**2
|
||||
)
|
||||
** (1 / 2)
|
||||
)
|
||||
|
||||
if np.isnan(test_value):
|
||||
warnings.warn('Test value is nan. Please check the input values.', UserWarning)
|
||||
warnings.warn("Test value is nan. Please check the input values.", UserWarning)
|
||||
return test_value
|
||||
|
||||
if isinstance(test_value, complex):
|
||||
warnings.warn('Output is a complex number. You may want to check the input skewness (too high), '
|
||||
'kurtosis (too low), or observed_sr values.', UserWarning)
|
||||
warnings.warn(
|
||||
"Output is a complex number. You may want to check the input skewness (too high), "
|
||||
"kurtosis (too low), or observed_sr values.",
|
||||
UserWarning,
|
||||
)
|
||||
|
||||
if np.isinf(test_value):
|
||||
warnings.warn('Test value is infinite. You may want to check the input skewness, '
|
||||
'kurtosis, or observed_sr values.', UserWarning)
|
||||
warnings.warn(
|
||||
"Test value is infinite. You may want to check the input skewness, "
|
||||
"kurtosis, or observed_sr values.",
|
||||
UserWarning,
|
||||
)
|
||||
|
||||
probab_sr = ss.norm.cdf(test_value)
|
||||
|
||||
return probab_sr
|
||||
|
||||
|
||||
def deflated_sharpe_ratio(observed_sr: float, sr_estimates: list, number_of_returns: int,
|
||||
skewness_of_returns: float = 0, kurtosis_of_returns: float = 3,
|
||||
estimates_param: bool = False, benchmark_out: bool = False) -> float:
|
||||
def deflated_sharpe_ratio(
|
||||
observed_sr: float,
|
||||
sr_estimates: list,
|
||||
number_of_returns: int,
|
||||
skewness_of_returns: float = 0,
|
||||
kurtosis_of_returns: float = 3,
|
||||
estimates_param: bool = False,
|
||||
benchmark_out: bool = False,
|
||||
) -> float:
|
||||
"""
|
||||
Calculates the deflated Sharpe ratio (DSR) - a PSR where the rejection threshold is
|
||||
adjusted to reflect the multiplicity of trials. DSR is estimated as PSR[SR∗], where
|
||||
@@ -290,18 +346,25 @@ def deflated_sharpe_ratio(observed_sr: float, sr_estimates: list, number_of_retu
|
||||
|
||||
# Calculating benchmark_SR from the parameters of estimates
|
||||
if estimates_param:
|
||||
benchmark_sr = sr_estimates[0] * \
|
||||
((1 - np.euler_gamma) * ss.norm.ppf(1 - 1 / sr_estimates[1]) +
|
||||
np.euler_gamma * ss.norm.ppf(1 - 1 / sr_estimates[1] * np.e ** (-1)))
|
||||
benchmark_sr = sr_estimates[0] * (
|
||||
(1 - np.euler_gamma) * ss.norm.ppf(1 - 1 / sr_estimates[1])
|
||||
+ np.euler_gamma * ss.norm.ppf(1 - 1 / sr_estimates[1] * np.e ** (-1))
|
||||
)
|
||||
|
||||
# Calculating benchmark_SR from a list of estimates
|
||||
else:
|
||||
benchmark_sr = np.array(sr_estimates).std() * \
|
||||
((1 - np.euler_gamma) * ss.norm.ppf(1 - 1 / len(sr_estimates)) +
|
||||
np.euler_gamma * ss.norm.ppf(1 - 1 / len(sr_estimates) * np.e ** (-1)))
|
||||
benchmark_sr = np.array(sr_estimates).std() * (
|
||||
(1 - np.euler_gamma) * ss.norm.ppf(1 - 1 / len(sr_estimates))
|
||||
+ np.euler_gamma * ss.norm.ppf(1 - 1 / len(sr_estimates) * np.e ** (-1))
|
||||
)
|
||||
|
||||
deflated_sr = probabilistic_sharpe_ratio(observed_sr, benchmark_sr, number_of_returns,
|
||||
skewness_of_returns, kurtosis_of_returns)
|
||||
deflated_sr = probabilistic_sharpe_ratio(
|
||||
observed_sr,
|
||||
benchmark_sr,
|
||||
number_of_returns,
|
||||
skewness_of_returns,
|
||||
kurtosis_of_returns,
|
||||
)
|
||||
|
||||
if benchmark_out:
|
||||
return benchmark_sr
|
||||
@@ -309,10 +372,13 @@ def deflated_sharpe_ratio(observed_sr: float, sr_estimates: list, number_of_retu
|
||||
return deflated_sr
|
||||
|
||||
|
||||
def minimum_track_record_length(observed_sr: float, benchmark_sr: float,
|
||||
skewness_of_returns: float = 0,
|
||||
kurtosis_of_returns: float = 3,
|
||||
alpha: float = 0.05) -> float:
|
||||
def minimum_track_record_length(
|
||||
observed_sr: float,
|
||||
benchmark_sr: float,
|
||||
skewness_of_returns: float = 0,
|
||||
kurtosis_of_returns: float = 3,
|
||||
alpha: float = 0.05,
|
||||
) -> float:
|
||||
"""
|
||||
Calculates the minimum track record length (MinTRL) - "How long should a track
|
||||
record be in order to have statistical confidence that its Sharpe ratio is above
|
||||
@@ -329,8 +395,10 @@ def minimum_track_record_length(observed_sr: float, benchmark_sr: float,
|
||||
:return: (float) Minimum number of track records
|
||||
"""
|
||||
|
||||
track_rec_length = 1 + (1 - skewness_of_returns * observed_sr +
|
||||
(kurtosis_of_returns - 1) / 4 * observed_sr ** 2) * \
|
||||
(ss.norm.ppf(1 - alpha) / (observed_sr - benchmark_sr)) ** (2)
|
||||
track_rec_length = 1 + (
|
||||
1
|
||||
- skewness_of_returns * observed_sr
|
||||
+ (kurtosis_of_returns - 1) / 4 * observed_sr**2
|
||||
) * (ss.norm.ppf(1 - alpha) / (observed_sr - benchmark_sr)) ** (2)
|
||||
|
||||
return track_rec_length
|
||||
return track_rec_length
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
from tqdm import tqdm
|
||||
import ray
|
||||
|
||||
def parallel_compute_with_bar(computations) -> list:
|
||||
|
||||
def parallel_compute_with_bar(computations) -> list:
|
||||
def to_iterator(obj_ids):
|
||||
while obj_ids:
|
||||
done, obj_ids = ray.wait(obj_ids)
|
||||
@@ -12,4 +12,4 @@ def parallel_compute_with_bar(computations) -> list:
|
||||
for x in tqdm(to_iterator(computations), total=len(computations)):
|
||||
ret.append(x)
|
||||
|
||||
return ret
|
||||
return ret
|
||||
|
||||
+6
-5
@@ -1,9 +1,10 @@
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def resample_ohlc(df, period):
|
||||
output = pd.DataFrame()
|
||||
output['open'] = df.open.resample(period).first()
|
||||
output['high'] = df.high.resample(period).max()
|
||||
output['low'] = df.low.resample(period).min()
|
||||
output['close'] = df.close.resample(period).last()
|
||||
return output
|
||||
output["open"] = df.open.resample(period).first()
|
||||
output["high"] = df.high.resample(period).max()
|
||||
output["low"] = df.low.resample(period).min()
|
||||
output["close"] = df.close.resample(period).last()
|
||||
return output
|
||||
|
||||
+7
-6
@@ -1,17 +1,18 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
|
||||
def from_df_to_sktime_data(x: pd.DataFrame) -> pd.DataFrame:
|
||||
instance_list = []
|
||||
instance_list.append([])
|
||||
|
||||
|
||||
x_data = pd.DataFrame(dtype=np.float32)
|
||||
|
||||
|
||||
for i in range(len(x.index)):
|
||||
instance_list[0].append(pd.Series(x.iloc[i]))
|
||||
|
||||
|
||||
# only dim_0 for univariate time series
|
||||
for dim in range(len(instance_list)):
|
||||
x_data['dim_' + str(dim)] = instance_list[dim]
|
||||
|
||||
return x_data
|
||||
x_data["dim_" + str(dim)] = instance_list[dim]
|
||||
|
||||
return x_data
|
||||
|
||||
@@ -1,29 +1,43 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
|
||||
def STOK(close, low, high, n):
|
||||
STOK = ((close - low.rolling(n).min()) / (high.rolling(n).max() - low.rolling(n).min())) * 100
|
||||
STOK = (
|
||||
(close - low.rolling(n).min()) / (high.rolling(n).max() - low.rolling(n).min())
|
||||
) * 100
|
||||
return STOK
|
||||
|
||||
|
||||
def STOD(close, low, high, n):
|
||||
STOK = ((close - low.rolling(n).min()) / (high.rolling(n).max() - low.rolling(n).min())) * 100
|
||||
STOK = (
|
||||
(close - low.rolling(n).min()) / (high.rolling(n).max() - low.rolling(n).min())
|
||||
) * 100
|
||||
STOD = STOK.rolling(3).mean()
|
||||
return STOD
|
||||
|
||||
|
||||
def RSI(series, period):
|
||||
delta = series.diff().dropna()
|
||||
u=delta*0
|
||||
u = delta * 0
|
||||
d = u.copy()
|
||||
u[delta > 0] = delta[delta > 0]
|
||||
d[delta < 0] = -delta[delta < 0]
|
||||
u[u.index[period-1]] = np.mean( u[:period] ) #first value is sum of avg gains u = u.drop(u.index[:(period-1)])
|
||||
d[d.index[period-1]] = np.mean( d[:period] ) #first value is sum of avg losses d = d.drop(d.index[:(period-1)])
|
||||
rs = u.ewm(com=period-1, adjust=False).mean() / \
|
||||
d.ewm(com=period-1, adjust=False).mean()
|
||||
return 100-100/(1+rs)
|
||||
u[u.index[period - 1]] = np.mean(
|
||||
u[:period]
|
||||
) # first value is sum of avg gains u = u.drop(u.index[:(period-1)])
|
||||
d[d.index[period - 1]] = np.mean(
|
||||
d[:period]
|
||||
) # first value is sum of avg losses d = d.drop(d.index[:(period-1)])
|
||||
rs = (
|
||||
u.ewm(com=period - 1, adjust=False).mean()
|
||||
/ d.ewm(com=period - 1, adjust=False).mean()
|
||||
)
|
||||
return 100 - 100 / (1 + rs)
|
||||
|
||||
|
||||
def ROC(df, n):
|
||||
M = df.diff(n - 1)
|
||||
N = df.shift(n - 1)
|
||||
ROC = pd.Series(((M / N) * 100), name = 'ROC_' + str(n))
|
||||
return ROC
|
||||
ROC = pd.Series(((M / N) * 100), name="ROC_" + str(n))
|
||||
return ROC
|
||||
|
||||
Reference in New Issue
Block a user