website: snapshot

This commit is contained in:
nym21
2026-01-25 20:11:32 +01:00
parent 543cde525e
commit 35bf1afcff
38 changed files with 2221 additions and 3018 deletions
+273 -273
View File
@@ -1532,6 +1532,42 @@ impl PeriodLumpSumStackPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct ClassAveragePricePattern<T> {
pub _2015: MetricPattern4<T>,
pub _2016: MetricPattern4<T>,
pub _2017: MetricPattern4<T>,
pub _2018: MetricPattern4<T>,
pub _2019: MetricPattern4<T>,
pub _2020: MetricPattern4<T>,
pub _2021: MetricPattern4<T>,
pub _2022: MetricPattern4<T>,
pub _2023: MetricPattern4<T>,
pub _2024: MetricPattern4<T>,
pub _2025: MetricPattern4<T>,
pub _2026: MetricPattern4<T>,
}
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_returns")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_returns")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_returns")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_returns")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_returns")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_returns")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_returns")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_returns")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_returns")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_returns")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_returns")),
_2026: MetricPattern4::new(client.clone(), _m(&acc, "2026_returns")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct PeriodAveragePricePattern<T> {
pub _10y: MetricPattern4<T>,
@@ -1568,42 +1604,6 @@ impl<T: DeserializeOwned> PeriodAveragePricePattern<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct ClassAveragePricePattern<T> {
pub _2015: MetricPattern4<T>,
pub _2016: MetricPattern4<T>,
pub _2017: MetricPattern4<T>,
pub _2018: MetricPattern4<T>,
pub _2019: MetricPattern4<T>,
pub _2020: MetricPattern4<T>,
pub _2021: MetricPattern4<T>,
pub _2022: MetricPattern4<T>,
pub _2023: MetricPattern4<T>,
pub _2024: MetricPattern4<T>,
pub _2025: MetricPattern4<T>,
pub _2026: MetricPattern4<T>,
}
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_average_price")),
_2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_average_price")),
_2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_average_price")),
_2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_average_price")),
_2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_average_price")),
_2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_average_price")),
_2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_average_price")),
_2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_average_price")),
_2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_average_price")),
_2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_average_price")),
_2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_average_price")),
_2026: MetricPattern4::new(client.clone(), _m(&acc, "2026_average_price")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct BitcoinPattern {
pub average: MetricPattern2<Bitcoin>,
@@ -1672,38 +1672,6 @@ impl<T: DeserializeOwned> DollarsPattern<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern2 {
pub neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
pub unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
}
impl RelativePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap")),
neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl")),
net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap")),
net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl")),
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")),
unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")),
unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl")),
unrealized_profit_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_market_cap")),
unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern {
pub neg_unrealized_loss_rel_to_market_cap: MetricPattern1<StoredF32>,
@@ -1736,6 +1704,38 @@ impl RelativePattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct RelativePattern2 {
pub neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
pub supply_in_profit_rel_to_own_supply: MetricPattern1<StoredF64>,
pub unrealized_loss_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_market_cap: MetricPattern1<StoredF32>,
pub unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1<StoredF32>,
}
impl RelativePattern2 {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap")),
neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl")),
net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap")),
net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl")),
supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")),
supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")),
unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")),
unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl")),
unrealized_profit_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_market_cap")),
unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CountPattern2<T> {
pub average: MetricPattern1<T>,
@@ -1798,36 +1798,6 @@ impl AddrCountPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct FeeRatePattern<T> {
pub average: MetricPattern1<T>,
pub max: MetricPattern1<T>,
pub median: MetricPattern11<T>,
pub min: MetricPattern1<T>,
pub pct10: MetricPattern11<T>,
pub pct25: MetricPattern11<T>,
pub pct75: MetricPattern11<T>,
pub pct90: MetricPattern11<T>,
pub txindex: MetricPattern27<T>,
}
impl<T: DeserializeOwned> FeeRatePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
average: MetricPattern1::new(client.clone(), _m(&acc, "average")),
max: MetricPattern1::new(client.clone(), _m(&acc, "max")),
median: MetricPattern11::new(client.clone(), _m(&acc, "median")),
min: MetricPattern1::new(client.clone(), _m(&acc, "min")),
pct10: MetricPattern11::new(client.clone(), _m(&acc, "pct10")),
pct25: MetricPattern11::new(client.clone(), _m(&acc, "pct25")),
pct75: MetricPattern11::new(client.clone(), _m(&acc, "pct75")),
pct90: MetricPattern11::new(client.clone(), _m(&acc, "pct90")),
txindex: MetricPattern27::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct FullnessPattern<T> {
pub average: MetricPattern2<T>,
@@ -1858,6 +1828,36 @@ impl<T: DeserializeOwned> FullnessPattern<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct FeeRatePattern<T> {
pub average: MetricPattern1<T>,
pub max: MetricPattern1<T>,
pub median: MetricPattern11<T>,
pub min: MetricPattern1<T>,
pub pct10: MetricPattern11<T>,
pub pct25: MetricPattern11<T>,
pub pct75: MetricPattern11<T>,
pub pct90: MetricPattern11<T>,
pub txindex: MetricPattern27<T>,
}
impl<T: DeserializeOwned> FeeRatePattern<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
average: MetricPattern1::new(client.clone(), _m(&acc, "average")),
max: MetricPattern1::new(client.clone(), _m(&acc, "max")),
median: MetricPattern11::new(client.clone(), _m(&acc, "median")),
min: MetricPattern1::new(client.clone(), _m(&acc, "min")),
pct10: MetricPattern11::new(client.clone(), _m(&acc, "pct10")),
pct25: MetricPattern11::new(client.clone(), _m(&acc, "pct25")),
pct75: MetricPattern11::new(client.clone(), _m(&acc, "pct75")),
pct90: MetricPattern11::new(client.clone(), _m(&acc, "pct90")),
txindex: MetricPattern27::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _0satsPattern {
pub activity: ActivityPattern2,
@@ -1914,58 +1914,6 @@ impl<T: DeserializeOwned> PhaseDailyCentsPattern<T> {
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yTo12yPattern {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern2,
pub outputs: OutputsPattern,
pub realized: RealizedPattern2,
pub relative: RelativePattern2,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _10yTo12yPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern2::new(client.clone(), acc.clone()),
relative: RelativePattern2::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct UnrealizedPattern {
pub neg_unrealized_loss: MetricPattern1<Dollars>,
pub net_unrealized_pnl: MetricPattern1<Dollars>,
pub supply_in_loss: ActiveSupplyPattern,
pub supply_in_profit: ActiveSupplyPattern,
pub total_unrealized_pnl: MetricPattern1<Dollars>,
pub unrealized_loss: MetricPattern1<Dollars>,
pub unrealized_profit: MetricPattern1<Dollars>,
}
impl UnrealizedPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")),
net_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
supply_in_loss: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_loss")),
supply_in_profit: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_profit")),
total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "total_unrealized_pnl")),
unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss")),
unrealized_profit: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _0satsPattern2 {
pub activity: ActivityPattern2,
@@ -1992,6 +1940,32 @@ impl _0satsPattern2 {
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yTo12yPattern {
pub activity: ActivityPattern2,
pub cost_basis: CostBasisPattern2,
pub outputs: OutputsPattern,
pub realized: RealizedPattern2,
pub relative: RelativePattern2,
pub supply: SupplyPattern2,
pub unrealized: UnrealizedPattern,
}
impl _10yTo12yPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
activity: ActivityPattern2::new(client.clone(), acc.clone()),
cost_basis: CostBasisPattern2::new(client.clone(), acc.clone()),
outputs: OutputsPattern::new(client.clone(), _m(&acc, "utxo_count")),
realized: RealizedPattern2::new(client.clone(), acc.clone()),
relative: RelativePattern2::new(client.clone(), acc.clone()),
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct PeriodCagrPattern {
pub _10y: MetricPattern4<StoredF32>,
@@ -2018,6 +1992,32 @@ impl PeriodCagrPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct UnrealizedPattern {
pub neg_unrealized_loss: MetricPattern1<Dollars>,
pub net_unrealized_pnl: MetricPattern1<Dollars>,
pub supply_in_loss: ActiveSupplyPattern,
pub supply_in_profit: ActiveSupplyPattern,
pub total_unrealized_pnl: MetricPattern1<Dollars>,
pub unrealized_loss: MetricPattern1<Dollars>,
pub unrealized_profit: MetricPattern1<Dollars>,
}
impl UnrealizedPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
neg_unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")),
net_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
supply_in_loss: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_loss")),
supply_in_profit: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_profit")),
total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "total_unrealized_pnl")),
unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss")),
unrealized_profit: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _10yPattern {
pub activity: ActivityPattern2,
@@ -2113,55 +2113,19 @@ impl<T: DeserializeOwned> SplitPattern2<T> {
}
/// Pattern struct for repeated tree structure.
pub struct UnclaimedRewardsPattern {
pub bitcoin: BitcoinPattern2<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
pub struct _2015Pattern {
pub bitcoin: MetricPattern4<Bitcoin>,
pub dollars: MetricPattern4<Dollars>,
pub sats: MetricPattern4<Sats>,
}
impl UnclaimedRewardsPattern {
impl _2015Pattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern2::new(client.clone(), _m(&acc, "btc")),
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
sats: BlockCountPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CoinbasePattern {
pub bitcoin: BitcoinPattern,
pub dollars: DollarsPattern<Dollars>,
pub sats: DollarsPattern<Sats>,
}
impl CoinbasePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")),
dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")),
sats: DollarsPattern::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct SegwitAdoptionPattern {
pub base: MetricPattern11<StoredF32>,
pub cumulative: MetricPattern2<StoredF32>,
pub sum: MetricPattern2<StoredF32>,
}
impl SegwitAdoptionPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
base: MetricPattern11::new(client.clone(), acc.clone()),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
bitcoin: MetricPattern4::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern4::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern4::new(client.clone(), acc.clone()),
}
}
}
@@ -2185,37 +2149,19 @@ impl CostBasisPattern2 {
}
/// Pattern struct for repeated tree structure.
pub struct ActiveSupplyPattern {
pub bitcoin: MetricPattern1<Bitcoin>,
pub dollars: MetricPattern1<Dollars>,
pub sats: MetricPattern1<Sats>,
pub struct CoinbasePattern {
pub bitcoin: BitcoinPattern,
pub dollars: DollarsPattern<Dollars>,
pub sats: DollarsPattern<Sats>,
}
impl ActiveSupplyPattern {
impl CoinbasePattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _2015Pattern {
pub bitcoin: MetricPattern4<Bitcoin>,
pub dollars: MetricPattern4<Dollars>,
pub sats: MetricPattern4<Sats>,
}
impl _2015Pattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: MetricPattern4::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern4::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern4::new(client.clone(), acc.clone()),
bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")),
dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")),
sats: DollarsPattern::new(client.clone(), acc.clone()),
}
}
}
@@ -2239,33 +2185,55 @@ impl CoinbasePattern2 {
}
/// Pattern struct for repeated tree structure.
pub struct _1dReturns1mSdPattern {
pub sd: MetricPattern4<StoredF32>,
pub sma: MetricPattern4<StoredF32>,
pub struct SegwitAdoptionPattern {
pub base: MetricPattern11<StoredF32>,
pub cumulative: MetricPattern2<StoredF32>,
pub sum: MetricPattern2<StoredF32>,
}
impl _1dReturns1mSdPattern {
impl SegwitAdoptionPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
sd: MetricPattern4::new(client.clone(), _m(&acc, "sd")),
sma: MetricPattern4::new(client.clone(), _m(&acc, "sma")),
base: MetricPattern11::new(client.clone(), acc.clone()),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern2::new(client.clone(), _m(&acc, "sum")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct CostBasisPattern {
pub max: MetricPattern1<Dollars>,
pub min: MetricPattern1<Dollars>,
pub struct ActiveSupplyPattern {
pub bitcoin: MetricPattern1<Bitcoin>,
pub dollars: MetricPattern1<Dollars>,
pub sats: MetricPattern1<Sats>,
}
impl CostBasisPattern {
impl ActiveSupplyPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
max: MetricPattern1::new(client.clone(), _m(&acc, "max_cost_basis")),
min: MetricPattern1::new(client.clone(), _m(&acc, "min_cost_basis")),
bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")),
dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")),
sats: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct UnclaimedRewardsPattern {
pub bitcoin: BitcoinPattern2<Bitcoin>,
pub dollars: BlockCountPattern<Dollars>,
pub sats: BlockCountPattern<Sats>,
}
impl UnclaimedRewardsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
bitcoin: BitcoinPattern2::new(client.clone(), _m(&acc, "btc")),
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
sats: BlockCountPattern::new(client.clone(), acc.clone()),
}
}
}
@@ -2303,17 +2271,33 @@ impl RelativePattern4 {
}
/// Pattern struct for repeated tree structure.
pub struct BitcoinPattern2<T> {
pub cumulative: MetricPattern2<T>,
pub sum: MetricPattern1<T>,
pub struct CostBasisPattern {
pub max: MetricPattern1<Dollars>,
pub min: MetricPattern1<Dollars>,
}
impl<T: DeserializeOwned> BitcoinPattern2<T> {
impl CostBasisPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern1::new(client.clone(), acc.clone()),
max: MetricPattern1::new(client.clone(), _m(&acc, "max_cost_basis")),
min: MetricPattern1::new(client.clone(), _m(&acc, "min_cost_basis")),
}
}
}
/// Pattern struct for repeated tree structure.
pub struct _1dReturns1mSdPattern {
pub sd: MetricPattern4<StoredF32>,
pub sma: MetricPattern4<StoredF32>,
}
impl _1dReturns1mSdPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
sd: MetricPattern4::new(client.clone(), _m(&acc, "sd")),
sma: MetricPattern4::new(client.clone(), _m(&acc, "sma")),
}
}
}
@@ -2351,15 +2335,17 @@ impl<T: DeserializeOwned> BlockCountPattern<T> {
}
/// Pattern struct for repeated tree structure.
pub struct OutputsPattern {
pub utxo_count: MetricPattern1<StoredU64>,
pub struct BitcoinPattern2<T> {
pub cumulative: MetricPattern2<T>,
pub sum: MetricPattern1<T>,
}
impl OutputsPattern {
impl<T: DeserializeOwned> BitcoinPattern2<T> {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
cumulative: MetricPattern2::new(client.clone(), _m(&acc, "cumulative")),
sum: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
@@ -2378,6 +2364,20 @@ impl RealizedPriceExtraPattern {
}
}
/// Pattern struct for repeated tree structure.
pub struct OutputsPattern {
pub utxo_count: MetricPattern1<StoredU64>,
}
impl OutputsPattern {
/// Create a new pattern node with accumulated metric name.
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
Self {
utxo_count: MetricPattern1::new(client.clone(), acc.clone()),
}
}
}
// Metrics tree
/// Metrics tree node.
@@ -4204,8 +4204,8 @@ impl MetricsTree_Market_Ath {
/// Metrics tree node.
pub struct MetricsTree_Market_Dca {
pub class_average_price: ClassAveragePricePattern<Dollars>,
pub class_returns: MetricsTree_Market_Dca_ClassReturns,
pub class_average_price: MetricsTree_Market_Dca_ClassAveragePrice,
pub class_returns: ClassAveragePricePattern<StoredF32>,
pub class_stack: MetricsTree_Market_Dca_ClassStack,
pub period_average_price: PeriodAveragePricePattern<Dollars>,
pub period_cagr: PeriodCagrPattern,
@@ -4217,8 +4217,8 @@ pub struct MetricsTree_Market_Dca {
impl MetricsTree_Market_Dca {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
class_average_price: ClassAveragePricePattern::new(client.clone(), "dca_class".to_string()),
class_returns: MetricsTree_Market_Dca_ClassReturns::new(client.clone(), format!("{base_path}_class_returns")),
class_average_price: MetricsTree_Market_Dca_ClassAveragePrice::new(client.clone(), format!("{base_path}_class_average_price")),
class_returns: ClassAveragePricePattern::new(client.clone(), "dca_class".to_string()),
class_stack: MetricsTree_Market_Dca_ClassStack::new(client.clone(), format!("{base_path}_class_stack")),
period_average_price: PeriodAveragePricePattern::new(client.clone(), "dca_average_price".to_string()),
period_cagr: PeriodCagrPattern::new(client.clone(), "dca_cagr".to_string()),
@@ -4230,36 +4230,36 @@ impl MetricsTree_Market_Dca {
}
/// Metrics tree node.
pub struct MetricsTree_Market_Dca_ClassReturns {
pub _2015: MetricPattern4<StoredF32>,
pub _2016: MetricPattern4<StoredF32>,
pub _2017: MetricPattern4<StoredF32>,
pub _2018: MetricPattern4<StoredF32>,
pub _2019: MetricPattern4<StoredF32>,
pub _2020: MetricPattern4<StoredF32>,
pub _2021: MetricPattern4<StoredF32>,
pub _2022: MetricPattern4<StoredF32>,
pub _2023: MetricPattern4<StoredF32>,
pub _2024: MetricPattern4<StoredF32>,
pub _2025: MetricPattern4<StoredF32>,
pub _2026: MetricPattern4<StoredF32>,
pub struct MetricsTree_Market_Dca_ClassAveragePrice {
pub _2015: MetricPattern4<Dollars>,
pub _2016: MetricPattern4<Dollars>,
pub _2017: MetricPattern4<Dollars>,
pub _2018: MetricPattern4<Dollars>,
pub _2019: MetricPattern4<Dollars>,
pub _2020: MetricPattern4<Dollars>,
pub _2021: MetricPattern4<Dollars>,
pub _2022: MetricPattern4<Dollars>,
pub _2023: MetricPattern4<Dollars>,
pub _2024: MetricPattern4<Dollars>,
pub _2025: MetricPattern4<Dollars>,
pub _2026: MetricPattern4<Dollars>,
}
impl MetricsTree_Market_Dca_ClassReturns {
impl MetricsTree_Market_Dca_ClassAveragePrice {
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
Self {
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_returns".to_string()),
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_returns".to_string()),
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_returns".to_string()),
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_returns".to_string()),
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_returns".to_string()),
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_returns".to_string()),
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_returns".to_string()),
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_returns".to_string()),
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_returns".to_string()),
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_returns".to_string()),
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_returns".to_string()),
_2026: MetricPattern4::new(client.clone(), "dca_class_2026_returns".to_string()),
_2015: MetricPattern4::new(client.clone(), "dca_class_2015_average_price".to_string()),
_2016: MetricPattern4::new(client.clone(), "dca_class_2016_average_price".to_string()),
_2017: MetricPattern4::new(client.clone(), "dca_class_2017_average_price".to_string()),
_2018: MetricPattern4::new(client.clone(), "dca_class_2018_average_price".to_string()),
_2019: MetricPattern4::new(client.clone(), "dca_class_2019_average_price".to_string()),
_2020: MetricPattern4::new(client.clone(), "dca_class_2020_average_price".to_string()),
_2021: MetricPattern4::new(client.clone(), "dca_class_2021_average_price".to_string()),
_2022: MetricPattern4::new(client.clone(), "dca_class_2022_average_price".to_string()),
_2023: MetricPattern4::new(client.clone(), "dca_class_2023_average_price".to_string()),
_2024: MetricPattern4::new(client.clone(), "dca_class_2024_average_price".to_string()),
_2025: MetricPattern4::new(client.clone(), "dca_class_2025_average_price".to_string()),
_2026: MetricPattern4::new(client.clone(), "dca_class_2026_average_price".to_string()),
}
}
}
@@ -5449,7 +5449,7 @@ pub struct BrkClient {
impl BrkClient {
/// Client version.
pub const VERSION: &'static str = "v0.1.0-alpha.6";
pub const VERSION: &'static str = "v0.1.0-beta.0";
/// Create a new client with the given base URL.
pub fn new(base_url: impl Into<String>) -> Self {
+21 -21
View File
@@ -89,27 +89,27 @@ pub const AGE_RANGE_FILTERS: ByAgeRange<Filter> = ByAgeRange {
/// Age range names
pub const AGE_RANGE_NAMES: ByAgeRange<CohortName> = ByAgeRange {
up_to_1h: CohortName::new("up_to_1h_old", "<1h", "Up to 1 Hour Old"),
_1h_to_1d: CohortName::new("at_least_1h_up_to_1d_old", "1h-1d", "1 Hour to 1 Day Old"),
_1d_to_1w: CohortName::new("at_least_1d_up_to_1w_old", "1d-1w", "1 Day to 1 Week Old"),
_1w_to_1m: CohortName::new("at_least_1w_up_to_1m_old", "1w-1m", "1 Week to 1 Month Old"),
_1m_to_2m: CohortName::new("at_least_1m_up_to_2m_old", "1m-2m", "1 to 2 Months Old"),
_2m_to_3m: CohortName::new("at_least_2m_up_to_3m_old", "2m-3m", "2 to 3 Months Old"),
_3m_to_4m: CohortName::new("at_least_3m_up_to_4m_old", "3m-4m", "3 to 4 Months Old"),
_4m_to_5m: CohortName::new("at_least_4m_up_to_5m_old", "4m-5m", "4 to 5 Months Old"),
_5m_to_6m: CohortName::new("at_least_5m_up_to_6m_old", "5m-6m", "5 to 6 Months Old"),
_6m_to_1y: CohortName::new("at_least_6m_up_to_1y_old", "6m-1y", "6 Months to 1 Year Old"),
_1y_to_2y: CohortName::new("at_least_1y_up_to_2y_old", "1y-2y", "1 to 2 Years Old"),
_2y_to_3y: CohortName::new("at_least_2y_up_to_3y_old", "2y-3y", "2 to 3 Years Old"),
_3y_to_4y: CohortName::new("at_least_3y_up_to_4y_old", "3y-4y", "3 to 4 Years Old"),
_4y_to_5y: CohortName::new("at_least_4y_up_to_5y_old", "4y-5y", "4 to 5 Years Old"),
_5y_to_6y: CohortName::new("at_least_5y_up_to_6y_old", "5y-6y", "5 to 6 Years Old"),
_6y_to_7y: CohortName::new("at_least_6y_up_to_7y_old", "6y-7y", "6 to 7 Years Old"),
_7y_to_8y: CohortName::new("at_least_7y_up_to_8y_old", "7y-8y", "7 to 8 Years Old"),
_8y_to_10y: CohortName::new("at_least_8y_up_to_10y_old", "8y-10y", "8 to 10 Years Old"),
_10y_to_12y: CohortName::new("at_least_10y_up_to_12y_old", "10y-12y", "10 to 12 Years Old"),
_12y_to_15y: CohortName::new("at_least_12y_up_to_15y_old", "12y-15y", "12 to 15 Years Old"),
from_15y: CohortName::new("at_least_15y_old", "15y+", "15+ Years Old"),
up_to_1h: CohortName::new("under_1h_old", "<1h", "Under 1 Hour Old"),
_1h_to_1d: CohortName::new("1h_to_1d_old", "1h-1d", "1 Hour to 1 Day Old"),
_1d_to_1w: CohortName::new("1d_to_1w_old", "1d-1w", "1 Day to 1 Week Old"),
_1w_to_1m: CohortName::new("1w_to_1m_old", "1w-1m", "1 Week to 1 Month Old"),
_1m_to_2m: CohortName::new("1m_to_2m_old", "1m-2m", "1 to 2 Months Old"),
_2m_to_3m: CohortName::new("2m_to_3m_old", "2m-3m", "2 to 3 Months Old"),
_3m_to_4m: CohortName::new("3m_to_4m_old", "3m-4m", "3 to 4 Months Old"),
_4m_to_5m: CohortName::new("4m_to_5m_old", "4m-5m", "4 to 5 Months Old"),
_5m_to_6m: CohortName::new("5m_to_6m_old", "5m-6m", "5 to 6 Months Old"),
_6m_to_1y: CohortName::new("6m_to_1y_old", "6m-1y", "6 Months to 1 Year Old"),
_1y_to_2y: CohortName::new("1y_to_2y_old", "1y-2y", "1 to 2 Years Old"),
_2y_to_3y: CohortName::new("2y_to_3y_old", "2y-3y", "2 to 3 Years Old"),
_3y_to_4y: CohortName::new("3y_to_4y_old", "3y-4y", "3 to 4 Years Old"),
_4y_to_5y: CohortName::new("4y_to_5y_old", "4y-5y", "4 to 5 Years Old"),
_5y_to_6y: CohortName::new("5y_to_6y_old", "5y-6y", "5 to 6 Years Old"),
_6y_to_7y: CohortName::new("6y_to_7y_old", "6y-7y", "6 to 7 Years Old"),
_7y_to_8y: CohortName::new("7y_to_8y_old", "7y-8y", "7 to 8 Years Old"),
_8y_to_10y: CohortName::new("8y_to_10y_old", "8y-10y", "8 to 10 Years Old"),
_10y_to_12y: CohortName::new("10y_to_12y_old", "10y-12y", "10 to 12 Years Old"),
_12y_to_15y: CohortName::new("12y_to_15y_old", "12y-15y", "12 to 15 Years Old"),
from_15y: CohortName::new("over_15y_old", "15y+", "15+ Years Old"),
};
impl ByAgeRange<CohortName> {
+13 -13
View File
@@ -80,50 +80,50 @@ pub const AMOUNT_RANGE_BOUNDS: ByAmountRange<Range<Sats>> = ByAmountRange {
/// Amount range names
pub const AMOUNT_RANGE_NAMES: ByAmountRange<CohortName> = ByAmountRange {
_0sats: CohortName::new("with_0sats", "0 sats", "0 Sats"),
_1sat_to_10sats: CohortName::new("above_1sat_under_10sats", "1-10 sats", "1 to 10 Sats"),
_1sat_to_10sats: CohortName::new("above_1sat_under_10sats", "1-10 sats", "1-10 Sats"),
_10sats_to_100sats: CohortName::new(
"above_10sats_under_100sats",
"10-100 sats",
"10 to 100 Sats",
"10-100 Sats",
),
_100sats_to_1k_sats: CohortName::new(
"above_100sats_under_1k_sats",
"100-1k sats",
"100 to 1K Sats",
"100-1K Sats",
),
_1k_sats_to_10k_sats: CohortName::new(
"above_1k_sats_under_10k_sats",
"1k-10k sats",
"1K to 10K Sats",
"1K-10K Sats",
),
_10k_sats_to_100k_sats: CohortName::new(
"above_10k_sats_under_100k_sats",
"10k-100k sats",
"10K to 100K Sats",
"10K-100K Sats",
),
_100k_sats_to_1m_sats: CohortName::new(
"above_100k_sats_under_1m_sats",
"100k-1M sats",
"100K to 1M Sats",
"100K-1M Sats",
),
_1m_sats_to_10m_sats: CohortName::new(
"above_1m_sats_under_10m_sats",
"1M-10M sats",
"1M to 10M Sats",
"1M-10M Sats",
),
_10m_sats_to_1btc: CohortName::new("above_10m_sats_under_1btc", "0.1-1 BTC", "0.1 to 1 BTC"),
_1btc_to_10btc: CohortName::new("above_1btc_under_10btc", "1-10 BTC", "1 to 10 BTC"),
_10btc_to_100btc: CohortName::new("above_10btc_under_100btc", "10-100 BTC", "10 to 100 BTC"),
_100btc_to_1k_btc: CohortName::new("above_100btc_under_1k_btc", "100-1k BTC", "100 to 1K BTC"),
_10m_sats_to_1btc: CohortName::new("above_10m_sats_under_1btc", "0.1-1 BTC", "0.1-1 BTC"),
_1btc_to_10btc: CohortName::new("above_1btc_under_10btc", "1-10 BTC", "1-10 BTC"),
_10btc_to_100btc: CohortName::new("above_10btc_under_100btc", "10-100 BTC", "10-100 BTC"),
_100btc_to_1k_btc: CohortName::new("above_100btc_under_1k_btc", "100-1k BTC", "100-1K BTC"),
_1k_btc_to_10k_btc: CohortName::new(
"above_1k_btc_under_10k_btc",
"1k-10k BTC",
"1K to 10K BTC",
"1K-10K BTC",
),
_10k_btc_to_100k_btc: CohortName::new(
"above_10k_btc_under_100k_btc",
"10k-100k BTC",
"10K to 100K BTC",
"10K-100K BTC",
),
_100k_btc_or_more: CohortName::new("above_100k_btc", "100k+ BTC", "100K+ BTC"),
};
+5 -5
View File
@@ -25,11 +25,11 @@ pub const EPOCH_FILTERS: ByEpoch<Filter> = ByEpoch {
/// Epoch names
pub const EPOCH_NAMES: ByEpoch<CohortName> = ByEpoch {
_0: CohortName::new("epoch_0", "Epoch 0", "Epoch 0"),
_1: CohortName::new("epoch_1", "Epoch 1", "Epoch 1"),
_2: CohortName::new("epoch_2", "Epoch 2", "Epoch 2"),
_3: CohortName::new("epoch_3", "Epoch 3", "Epoch 3"),
_4: CohortName::new("epoch_4", "Epoch 4", "Epoch 4"),
_0: CohortName::new("epoch_0", "0", "Epoch 0"),
_1: CohortName::new("epoch_1", "1", "Epoch 1"),
_2: CohortName::new("epoch_2", "2", "Epoch 2"),
_3: CohortName::new("epoch_3", "3", "Epoch 3"),
_4: CohortName::new("epoch_4", "4", "Epoch 4"),
};
#[derive(Default, Clone, Traversable, Serialize)]
+13 -13
View File
@@ -24,19 +24,19 @@ pub const GE_AMOUNT_THRESHOLDS: ByGreatEqualAmount<Sats> = ByGreatEqualAmount {
/// Greater-or-equal amount names
pub const GE_AMOUNT_NAMES: ByGreatEqualAmount<CohortName> = ByGreatEqualAmount {
_1sat: CohortName::new("above_1sat", "1+ sats", "Above 1 Sat"),
_10sats: CohortName::new("above_10sats", "10+ sats", "Above 10 Sats"),
_100sats: CohortName::new("above_100sats", "100+ sats", "Above 100 Sats"),
_1k_sats: CohortName::new("above_1k_sats", "1k+ sats", "Above 1K Sats"),
_10k_sats: CohortName::new("above_10k_sats", "10k+ sats", "Above 10K Sats"),
_100k_sats: CohortName::new("above_100k_sats", "100k+ sats", "Above 100K Sats"),
_1m_sats: CohortName::new("above_1m_sats", "1M+ sats", "Above 1M Sats"),
_10m_sats: CohortName::new("above_10m_sats", "0.1+ BTC", "Above 0.1 BTC"),
_1btc: CohortName::new("above_1btc", "1+ BTC", "Above 1 BTC"),
_10btc: CohortName::new("above_10btc", "10+ BTC", "Above 10 BTC"),
_100btc: CohortName::new("above_100btc", "100+ BTC", "Above 100 BTC"),
_1k_btc: CohortName::new("above_1k_btc", "1k+ BTC", "Above 1K BTC"),
_10k_btc: CohortName::new("above_10k_btc", "10k+ BTC", "Above 10K BTC"),
_1sat: CohortName::new("over_1sat", "1+ sats", "Over 1 Sat"),
_10sats: CohortName::new("over_10sats", "10+ sats", "Over 10 Sats"),
_100sats: CohortName::new("over_100sats", "100+ sats", "Over 100 Sats"),
_1k_sats: CohortName::new("over_1k_sats", "1k+ sats", "Over 1K Sats"),
_10k_sats: CohortName::new("over_10k_sats", "10k+ sats", "Over 10K Sats"),
_100k_sats: CohortName::new("over_100k_sats", "100k+ sats", "Over 100K Sats"),
_1m_sats: CohortName::new("over_1m_sats", "1M+ sats", "Over 1M Sats"),
_10m_sats: CohortName::new("over_10m_sats", "0.1+ BTC", "Over 0.1 BTC"),
_1btc: CohortName::new("over_1btc", "1+ BTC", "Over 1 BTC"),
_10btc: CohortName::new("over_10btc", "10+ BTC", "Over 10 BTC"),
_100btc: CohortName::new("over_100btc", "100+ BTC", "Over 100 BTC"),
_1k_btc: CohortName::new("over_1k_btc", "1k+ BTC", "Over 1K BTC"),
_10k_btc: CohortName::new("over_10k_btc", "10k+ BTC", "Over 10K BTC"),
};
/// Greater-or-equal amount filters
+18 -18
View File
@@ -54,24 +54,24 @@ pub const MAX_AGE_FILTERS: ByMaxAge<Filter> = ByMaxAge {
/// Max age names
pub const MAX_AGE_NAMES: ByMaxAge<CohortName> = ByMaxAge {
_1w: CohortName::new("up_to_1w_old", "<1w", "Up to 1 Week Old"),
_1m: CohortName::new("up_to_1m_old", "<1m", "Up to 1 Month Old"),
_2m: CohortName::new("up_to_2m_old", "<2m", "Up to 2 Months Old"),
_3m: CohortName::new("up_to_3m_old", "<3m", "Up to 3 Months Old"),
_4m: CohortName::new("up_to_4m_old", "<4m", "Up to 4 Months Old"),
_5m: CohortName::new("up_to_5m_old", "<5m", "Up to 5 Months Old"),
_6m: CohortName::new("up_to_6m_old", "<6m", "Up to 6 Months Old"),
_1y: CohortName::new("up_to_1y_old", "<1y", "Up to 1 Year Old"),
_2y: CohortName::new("up_to_2y_old", "<2y", "Up to 2 Years Old"),
_3y: CohortName::new("up_to_3y_old", "<3y", "Up to 3 Years Old"),
_4y: CohortName::new("up_to_4y_old", "<4y", "Up to 4 Years Old"),
_5y: CohortName::new("up_to_5y_old", "<5y", "Up to 5 Years Old"),
_6y: CohortName::new("up_to_6y_old", "<6y", "Up to 6 Years Old"),
_7y: CohortName::new("up_to_7y_old", "<7y", "Up to 7 Years Old"),
_8y: CohortName::new("up_to_8y_old", "<8y", "Up to 8 Years Old"),
_10y: CohortName::new("up_to_10y_old", "<10y", "Up to 10 Years Old"),
_12y: CohortName::new("up_to_12y_old", "<12y", "Up to 12 Years Old"),
_15y: CohortName::new("up_to_15y_old", "<15y", "Up to 15 Years Old"),
_1w: CohortName::new("under_1w_old", "<1w", "Under 1 Week Old"),
_1m: CohortName::new("under_1m_old", "<1m", "Under 1 Month Old"),
_2m: CohortName::new("under_2m_old", "<2m", "Under 2 Months Old"),
_3m: CohortName::new("under_3m_old", "<3m", "Under 3 Months Old"),
_4m: CohortName::new("under_4m_old", "<4m", "Under 4 Months Old"),
_5m: CohortName::new("under_5m_old", "<5m", "Under 5 Months Old"),
_6m: CohortName::new("under_6m_old", "<6m", "Under 6 Months Old"),
_1y: CohortName::new("under_1y_old", "<1y", "Under 1 Year Old"),
_2y: CohortName::new("under_2y_old", "<2y", "Under 2 Years Old"),
_3y: CohortName::new("under_3y_old", "<3y", "Under 3 Years Old"),
_4y: CohortName::new("under_4y_old", "<4y", "Under 4 Years Old"),
_5y: CohortName::new("under_5y_old", "<5y", "Under 5 Years Old"),
_6y: CohortName::new("under_6y_old", "<6y", "Under 6 Years Old"),
_7y: CohortName::new("under_7y_old", "<7y", "Under 7 Years Old"),
_8y: CohortName::new("under_8y_old", "<8y", "Under 8 Years Old"),
_10y: CohortName::new("under_10y_old", "<10y", "Under 10 Years Old"),
_12y: CohortName::new("under_12y_old", "<12y", "Under 12 Years Old"),
_15y: CohortName::new("under_15y_old", "<15y", "Under 15 Years Old"),
};
#[derive(Default, Clone, Traversable, Serialize)]
+18 -18
View File
@@ -54,24 +54,24 @@ pub const MIN_AGE_FILTERS: ByMinAge<Filter> = ByMinAge {
/// Min age names
pub const MIN_AGE_NAMES: ByMinAge<CohortName> = ByMinAge {
_1d: CohortName::new("at_least_1d_old", "1d+", "At Least 1 Day Old"),
_1w: CohortName::new("at_least_1w_old", "1w+", "At Least 1 Week Old"),
_1m: CohortName::new("at_least_1m_old", "1m+", "At Least 1 Month Old"),
_2m: CohortName::new("at_least_2m_old", "2m+", "At Least 2 Months Old"),
_3m: CohortName::new("at_least_3m_old", "3m+", "At Least 3 Months Old"),
_4m: CohortName::new("at_least_4m_old", "4m+", "At Least 4 Months Old"),
_5m: CohortName::new("at_least_5m_old", "5m+", "At Least 5 Months Old"),
_6m: CohortName::new("at_least_6m_old", "6m+", "At Least 6 Months Old"),
_1y: CohortName::new("at_least_1y_old", "1y+", "At Least 1 Year Old"),
_2y: CohortName::new("at_least_2y_old", "2y+", "At Least 2 Years Old"),
_3y: CohortName::new("at_least_3y_old", "3y+", "At Least 3 Years Old"),
_4y: CohortName::new("at_least_4y_old", "4y+", "At Least 4 Years Old"),
_5y: CohortName::new("at_least_5y_old", "5y+", "At Least 5 Years Old"),
_6y: CohortName::new("at_least_6y_old", "6y+", "At Least 6 Years Old"),
_7y: CohortName::new("at_least_7y_old", "7y+", "At Least 7 Years Old"),
_8y: CohortName::new("at_least_8y_old", "8y+", "At Least 8 Years Old"),
_10y: CohortName::new("at_least_10y_old", "10y+", "At Least 10 Years Old"),
_12y: CohortName::new("at_least_12y_old", "12y+", "At Least 12 Years Old"),
_1d: CohortName::new("over_1d_old", "1d+", "Over 1 Day Old"),
_1w: CohortName::new("over_1w_old", "1w+", "Over 1 Week Old"),
_1m: CohortName::new("over_1m_old", "1m+", "Over 1 Month Old"),
_2m: CohortName::new("over_2m_old", "2m+", "Over 2 Months Old"),
_3m: CohortName::new("over_3m_old", "3m+", "Over 3 Months Old"),
_4m: CohortName::new("over_4m_old", "4m+", "Over 4 Months Old"),
_5m: CohortName::new("over_5m_old", "5m+", "Over 5 Months Old"),
_6m: CohortName::new("over_6m_old", "6m+", "Over 6 Months Old"),
_1y: CohortName::new("over_1y_old", "1y+", "Over 1 Year Old"),
_2y: CohortName::new("over_2y_old", "2y+", "Over 2 Years Old"),
_3y: CohortName::new("over_3y_old", "3y+", "Over 3 Years Old"),
_4y: CohortName::new("over_4y_old", "4y+", "Over 4 Years Old"),
_5y: CohortName::new("over_5y_old", "5y+", "Over 5 Years Old"),
_6y: CohortName::new("over_6y_old", "6y+", "Over 6 Years Old"),
_7y: CohortName::new("over_7y_old", "7y+", "Over 7 Years Old"),
_8y: CohortName::new("over_8y_old", "8y+", "Over 8 Years Old"),
_10y: CohortName::new("over_10y_old", "10y+", "Over 10 Years Old"),
_12y: CohortName::new("over_12y_old", "12y+", "Over 12 Years Old"),
};
#[derive(Default, Clone, Traversable, Serialize)]
-7
View File
@@ -1,7 +0,0 @@
# Ignore everything in playground except essential files
*
!.gitignore
!Cargo.toml
!src/
!src/lib.rs
!README.md
-57
View File
@@ -1,57 +0,0 @@
[package]
name = "brk_playground"
description = "Experimental playground for brk development"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
publish = false
[package.metadata.release]
release = false
[dependencies]
brk_computer = { workspace = true }
brk_error = { workspace = true }
brk_fetcher = { workspace = true }
brk_indexer = { workspace = true }
brk_logger = { workspace = true }
brk_types = { workspace = true }
jiff = { workspace = true }
memmap2 = "0.9"
plotters = "0.3"
tracing = { workspace = true }
vecdb = { workspace = true }
[[example]]
name = "heatmap"
path = "examples/heatmap.rs"
[[example]]
name = "oracle"
path = "examples/oracle.rs"
[[example]]
name = "plot_oracle"
path = "examples/plot_oracle.rs"
[[example]]
name = "tune_smooth"
path = "examples/tune_smooth.rs"
[[example]]
name = "debug_oracle"
path = "examples/debug_oracle.rs"
[[example]]
name = "filters"
path = "examples/filters.rs"
[[example]]
name = "stencil"
path = "examples/stencil.rs"
[[example]]
name = "epoch5_test"
path = "examples/epoch5_test.rs"
-28
View File
@@ -1,28 +0,0 @@
//! Playground library for Bitcoin on-chain analysis
//!
//! This crate provides tools for:
//! - Phase histogram analysis of UTXO patterns
//! - Filter-based output selection for price signal extraction
//! - On-chain OHLC price oracle derivation
pub mod anchors;
pub mod conditions;
pub mod constants;
pub mod filters;
pub mod histogram;
pub mod oracle;
pub mod render;
pub mod signal;
pub use anchors::{Ohlc, get_anchor_ohlc, get_anchor_range};
pub use conditions::{MappedOutputConditions, out_bits, tx_bits};
pub use constants::{NUM_BINS, OutputFilter, ROUND_USD_AMOUNTS, START_HEIGHT};
pub use filters::FILTERS;
pub use histogram::load_or_compute_output_conditions;
pub use oracle::{
HeightPriceResult, OracleConfig, OracleResult, derive_daily_ohlc,
derive_daily_ohlc_with_confidence, derive_height_price, derive_height_price_with_confidence,
derive_ohlc_from_height_prices, derive_ohlc_from_height_prices_with_confidence,
derive_price_fast, derive_price_fast_with_confidence, derive_price_from_histogram,
};
pub use signal::{compute_expected_bins_per_day, usd_to_bin};
+1
View File
@@ -0,0 +1 @@
website/*
+332 -332
View File
@@ -1931,6 +1931,47 @@ function createPeriodLumpSumStackPattern(client, acc) {
};
}
/**
* @template T
* @typedef {Object} ClassAveragePricePattern
* @property {MetricPattern4<T>} _2015
* @property {MetricPattern4<T>} _2016
* @property {MetricPattern4<T>} _2017
* @property {MetricPattern4<T>} _2018
* @property {MetricPattern4<T>} _2019
* @property {MetricPattern4<T>} _2020
* @property {MetricPattern4<T>} _2021
* @property {MetricPattern4<T>} _2022
* @property {MetricPattern4<T>} _2023
* @property {MetricPattern4<T>} _2024
* @property {MetricPattern4<T>} _2025
* @property {MetricPattern4<T>} _2026
*/
/**
* Create a ClassAveragePricePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ClassAveragePricePattern<T>}
*/
function createClassAveragePricePattern(client, acc) {
return {
_2015: createMetricPattern4(client, _m(acc, '2015_returns')),
_2016: createMetricPattern4(client, _m(acc, '2016_returns')),
_2017: createMetricPattern4(client, _m(acc, '2017_returns')),
_2018: createMetricPattern4(client, _m(acc, '2018_returns')),
_2019: createMetricPattern4(client, _m(acc, '2019_returns')),
_2020: createMetricPattern4(client, _m(acc, '2020_returns')),
_2021: createMetricPattern4(client, _m(acc, '2021_returns')),
_2022: createMetricPattern4(client, _m(acc, '2022_returns')),
_2023: createMetricPattern4(client, _m(acc, '2023_returns')),
_2024: createMetricPattern4(client, _m(acc, '2024_returns')),
_2025: createMetricPattern4(client, _m(acc, '2025_returns')),
_2026: createMetricPattern4(client, _m(acc, '2026_returns')),
};
}
/**
* @template T
* @typedef {Object} PeriodAveragePricePattern
@@ -1972,47 +2013,6 @@ function createPeriodAveragePricePattern(client, acc) {
};
}
/**
* @template T
* @typedef {Object} ClassAveragePricePattern
* @property {MetricPattern4<T>} _2015
* @property {MetricPattern4<T>} _2016
* @property {MetricPattern4<T>} _2017
* @property {MetricPattern4<T>} _2018
* @property {MetricPattern4<T>} _2019
* @property {MetricPattern4<T>} _2020
* @property {MetricPattern4<T>} _2021
* @property {MetricPattern4<T>} _2022
* @property {MetricPattern4<T>} _2023
* @property {MetricPattern4<T>} _2024
* @property {MetricPattern4<T>} _2025
* @property {MetricPattern4<T>} _2026
*/
/**
* Create a ClassAveragePricePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ClassAveragePricePattern<T>}
*/
function createClassAveragePricePattern(client, acc) {
return {
_2015: createMetricPattern4(client, _m(acc, '2015_average_price')),
_2016: createMetricPattern4(client, _m(acc, '2016_average_price')),
_2017: createMetricPattern4(client, _m(acc, '2017_average_price')),
_2018: createMetricPattern4(client, _m(acc, '2018_average_price')),
_2019: createMetricPattern4(client, _m(acc, '2019_average_price')),
_2020: createMetricPattern4(client, _m(acc, '2020_average_price')),
_2021: createMetricPattern4(client, _m(acc, '2021_average_price')),
_2022: createMetricPattern4(client, _m(acc, '2022_average_price')),
_2023: createMetricPattern4(client, _m(acc, '2023_average_price')),
_2024: createMetricPattern4(client, _m(acc, '2024_average_price')),
_2025: createMetricPattern4(client, _m(acc, '2025_average_price')),
_2026: createMetricPattern4(client, _m(acc, '2026_average_price')),
};
}
/**
* @typedef {Object} BitcoinPattern
* @property {MetricPattern2<Bitcoin>} average
@@ -2089,41 +2089,6 @@ function createDollarsPattern(client, acc) {
};
}
/**
* @typedef {Object} RelativePattern2
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnTotalUnrealizedPnl
*/
/**
* Create a RelativePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern2}
*/
function createRelativePattern2(client, acc) {
return {
negUnrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap')),
negUnrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl')),
netUnrealizedPnlRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap')),
netUnrealizedPnlRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl')),
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply')),
unrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')),
unrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl')),
unrealizedProfitRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap')),
unrealizedProfitRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl')),
};
}
/**
* @typedef {Object} RelativePattern
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToMarketCap
@@ -2159,6 +2124,41 @@ function createRelativePattern(client, acc) {
};
}
/**
* @typedef {Object} RelativePattern2
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} negUnrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} netUnrealizedPnlRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
* @property {MetricPattern1<StoredF64>} supplyInProfitRelToOwnSupply
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedLossRelToOwnTotalUnrealizedPnl
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnMarketCap
* @property {MetricPattern1<StoredF32>} unrealizedProfitRelToOwnTotalUnrealizedPnl
*/
/**
* Create a RelativePattern2 pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {RelativePattern2}
*/
function createRelativePattern2(client, acc) {
return {
negUnrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap')),
negUnrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl')),
netUnrealizedPnlRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap')),
netUnrealizedPnlRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl')),
supplyInLossRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply')),
supplyInProfitRelToOwnSupply: createMetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply')),
unrealizedLossRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap')),
unrealizedLossRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl')),
unrealizedProfitRelToOwnMarketCap: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap')),
unrealizedProfitRelToOwnTotalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl')),
};
}
/**
* @template T
* @typedef {Object} CountPattern2
@@ -2229,41 +2229,6 @@ function createAddrCountPattern(client, acc) {
};
}
/**
* @template T
* @typedef {Object} FeeRatePattern
* @property {MetricPattern1<T>} average
* @property {MetricPattern1<T>} max
* @property {MetricPattern11<T>} median
* @property {MetricPattern1<T>} min
* @property {MetricPattern11<T>} pct10
* @property {MetricPattern11<T>} pct25
* @property {MetricPattern11<T>} pct75
* @property {MetricPattern11<T>} pct90
* @property {MetricPattern27<T>} txindex
*/
/**
* Create a FeeRatePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {FeeRatePattern<T>}
*/
function createFeeRatePattern(client, acc) {
return {
average: createMetricPattern1(client, _m(acc, 'average')),
max: createMetricPattern1(client, _m(acc, 'max')),
median: createMetricPattern11(client, _m(acc, 'median')),
min: createMetricPattern1(client, _m(acc, 'min')),
pct10: createMetricPattern11(client, _m(acc, 'pct10')),
pct25: createMetricPattern11(client, _m(acc, 'pct25')),
pct75: createMetricPattern11(client, _m(acc, 'pct75')),
pct90: createMetricPattern11(client, _m(acc, 'pct90')),
txindex: createMetricPattern27(client, acc),
};
}
/**
* @template T
* @typedef {Object} FullnessPattern
@@ -2299,6 +2264,41 @@ function createFullnessPattern(client, acc) {
};
}
/**
* @template T
* @typedef {Object} FeeRatePattern
* @property {MetricPattern1<T>} average
* @property {MetricPattern1<T>} max
* @property {MetricPattern11<T>} median
* @property {MetricPattern1<T>} min
* @property {MetricPattern11<T>} pct10
* @property {MetricPattern11<T>} pct25
* @property {MetricPattern11<T>} pct75
* @property {MetricPattern11<T>} pct90
* @property {MetricPattern27<T>} txindex
*/
/**
* Create a FeeRatePattern pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {FeeRatePattern<T>}
*/
function createFeeRatePattern(client, acc) {
return {
average: createMetricPattern1(client, _m(acc, 'average')),
max: createMetricPattern1(client, _m(acc, 'max')),
median: createMetricPattern11(client, _m(acc, 'median')),
min: createMetricPattern1(client, _m(acc, 'min')),
pct10: createMetricPattern11(client, _m(acc, 'pct10')),
pct25: createMetricPattern11(client, _m(acc, 'pct25')),
pct75: createMetricPattern11(client, _m(acc, 'pct75')),
pct90: createMetricPattern11(client, _m(acc, 'pct90')),
txindex: createMetricPattern27(client, acc),
};
}
/**
* @typedef {Object} _0satsPattern
* @property {ActivityPattern2} activity
@@ -2363,64 +2363,6 @@ function createPhaseDailyCentsPattern(client, acc) {
};
}
/**
* @typedef {Object} _10yTo12yPattern
* @property {ActivityPattern2} activity
* @property {CostBasisPattern2} costBasis
* @property {OutputsPattern} outputs
* @property {RealizedPattern2} realized
* @property {RelativePattern2} relative
* @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized
*/
/**
* Create a _10yTo12yPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_10yTo12yPattern}
*/
function create_10yTo12yPattern(client, acc) {
return {
activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern2(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern2(client, acc),
relative: createRelativePattern2(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc),
};
}
/**
* @typedef {Object} UnrealizedPattern
* @property {MetricPattern1<Dollars>} negUnrealizedLoss
* @property {MetricPattern1<Dollars>} netUnrealizedPnl
* @property {ActiveSupplyPattern} supplyInLoss
* @property {ActiveSupplyPattern} supplyInProfit
* @property {MetricPattern1<Dollars>} totalUnrealizedPnl
* @property {MetricPattern1<Dollars>} unrealizedLoss
* @property {MetricPattern1<Dollars>} unrealizedProfit
*/
/**
* Create a UnrealizedPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {UnrealizedPattern}
*/
function createUnrealizedPattern(client, acc) {
return {
negUnrealizedLoss: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss')),
netUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl')),
supplyInLoss: createActiveSupplyPattern(client, _m(acc, 'supply_in_loss')),
supplyInProfit: createActiveSupplyPattern(client, _m(acc, 'supply_in_profit')),
totalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'total_unrealized_pnl')),
unrealizedLoss: createMetricPattern1(client, _m(acc, 'unrealized_loss')),
unrealizedProfit: createMetricPattern1(client, _m(acc, 'unrealized_profit')),
};
}
/**
* @typedef {Object} _0satsPattern2
* @property {ActivityPattern2} activity
@@ -2450,6 +2392,35 @@ function create_0satsPattern2(client, acc) {
};
}
/**
* @typedef {Object} _10yTo12yPattern
* @property {ActivityPattern2} activity
* @property {CostBasisPattern2} costBasis
* @property {OutputsPattern} outputs
* @property {RealizedPattern2} realized
* @property {RelativePattern2} relative
* @property {SupplyPattern2} supply
* @property {UnrealizedPattern} unrealized
*/
/**
* Create a _10yTo12yPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_10yTo12yPattern}
*/
function create_10yTo12yPattern(client, acc) {
return {
activity: createActivityPattern2(client, acc),
costBasis: createCostBasisPattern2(client, acc),
outputs: createOutputsPattern(client, _m(acc, 'utxo_count')),
realized: createRealizedPattern2(client, acc),
relative: createRelativePattern2(client, acc),
supply: createSupplyPattern2(client, _m(acc, 'supply')),
unrealized: createUnrealizedPattern(client, acc),
};
}
/**
* @typedef {Object} PeriodCagrPattern
* @property {MetricPattern4<StoredF32>} _10y
@@ -2479,6 +2450,35 @@ function createPeriodCagrPattern(client, acc) {
};
}
/**
* @typedef {Object} UnrealizedPattern
* @property {MetricPattern1<Dollars>} negUnrealizedLoss
* @property {MetricPattern1<Dollars>} netUnrealizedPnl
* @property {ActiveSupplyPattern} supplyInLoss
* @property {ActiveSupplyPattern} supplyInProfit
* @property {MetricPattern1<Dollars>} totalUnrealizedPnl
* @property {MetricPattern1<Dollars>} unrealizedLoss
* @property {MetricPattern1<Dollars>} unrealizedProfit
*/
/**
* Create a UnrealizedPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {UnrealizedPattern}
*/
function createUnrealizedPattern(client, acc) {
return {
negUnrealizedLoss: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss')),
netUnrealizedPnl: createMetricPattern1(client, _m(acc, 'net_unrealized_pnl')),
supplyInLoss: createActiveSupplyPattern(client, _m(acc, 'supply_in_loss')),
supplyInProfit: createActiveSupplyPattern(client, _m(acc, 'supply_in_profit')),
totalUnrealizedPnl: createMetricPattern1(client, _m(acc, 'total_unrealized_pnl')),
unrealizedLoss: createMetricPattern1(client, _m(acc, 'unrealized_loss')),
unrealizedProfit: createMetricPattern1(client, _m(acc, 'unrealized_profit')),
};
}
/**
* @typedef {Object} _10yPattern
* @property {ActivityPattern2} activity
@@ -2588,65 +2588,23 @@ function createSplitPattern2(client, acc) {
}
/**
* @typedef {Object} UnclaimedRewardsPattern
* @property {BitcoinPattern2<Bitcoin>} bitcoin
* @property {BlockCountPattern<Dollars>} dollars
* @property {BlockCountPattern<Sats>} sats
* @typedef {Object} _2015Pattern
* @property {MetricPattern4<Bitcoin>} bitcoin
* @property {MetricPattern4<Dollars>} dollars
* @property {MetricPattern4<Sats>} sats
*/
/**
* Create a UnclaimedRewardsPattern pattern node
* Create a _2015Pattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {UnclaimedRewardsPattern}
* @returns {_2015Pattern}
*/
function createUnclaimedRewardsPattern(client, acc) {
function create_2015Pattern(client, acc) {
return {
bitcoin: createBitcoinPattern2(client, _m(acc, 'btc')),
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
sats: createBlockCountPattern(client, acc),
};
}
/**
* @typedef {Object} CoinbasePattern
* @property {BitcoinPattern} bitcoin
* @property {DollarsPattern<Dollars>} dollars
* @property {DollarsPattern<Sats>} sats
*/
/**
* Create a CoinbasePattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CoinbasePattern}
*/
function createCoinbasePattern(client, acc) {
return {
bitcoin: createBitcoinPattern(client, _m(acc, 'btc')),
dollars: createDollarsPattern(client, _m(acc, 'usd')),
sats: createDollarsPattern(client, acc),
};
}
/**
* @typedef {Object} SegwitAdoptionPattern
* @property {MetricPattern11<StoredF32>} base
* @property {MetricPattern2<StoredF32>} cumulative
* @property {MetricPattern2<StoredF32>} sum
*/
/**
* Create a SegwitAdoptionPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {SegwitAdoptionPattern}
*/
function createSegwitAdoptionPattern(client, acc) {
return {
base: createMetricPattern11(client, acc),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern2(client, _m(acc, 'sum')),
bitcoin: createMetricPattern4(client, _m(acc, 'btc')),
dollars: createMetricPattern4(client, _m(acc, 'usd')),
sats: createMetricPattern4(client, acc),
};
}
@@ -2672,44 +2630,23 @@ function createCostBasisPattern2(client, acc) {
}
/**
* @typedef {Object} ActiveSupplyPattern
* @property {MetricPattern1<Bitcoin>} bitcoin
* @property {MetricPattern1<Dollars>} dollars
* @property {MetricPattern1<Sats>} sats
* @typedef {Object} CoinbasePattern
* @property {BitcoinPattern} bitcoin
* @property {DollarsPattern<Dollars>} dollars
* @property {DollarsPattern<Sats>} sats
*/
/**
* Create a ActiveSupplyPattern pattern node
* Create a CoinbasePattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {ActiveSupplyPattern}
* @returns {CoinbasePattern}
*/
function createActiveSupplyPattern(client, acc) {
function createCoinbasePattern(client, acc) {
return {
bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
dollars: createMetricPattern1(client, _m(acc, 'usd')),
sats: createMetricPattern1(client, acc),
};
}
/**
* @typedef {Object} _2015Pattern
* @property {MetricPattern4<Bitcoin>} bitcoin
* @property {MetricPattern4<Dollars>} dollars
* @property {MetricPattern4<Sats>} sats
*/
/**
* Create a _2015Pattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_2015Pattern}
*/
function create_2015Pattern(client, acc) {
return {
bitcoin: createMetricPattern4(client, _m(acc, 'btc')),
dollars: createMetricPattern4(client, _m(acc, 'usd')),
sats: createMetricPattern4(client, acc),
bitcoin: createBitcoinPattern(client, _m(acc, 'btc')),
dollars: createDollarsPattern(client, _m(acc, 'usd')),
sats: createDollarsPattern(client, acc),
};
}
@@ -2735,40 +2672,65 @@ function createCoinbasePattern2(client, acc) {
}
/**
* @typedef {Object} _1dReturns1mSdPattern
* @property {MetricPattern4<StoredF32>} sd
* @property {MetricPattern4<StoredF32>} sma
* @typedef {Object} SegwitAdoptionPattern
* @property {MetricPattern11<StoredF32>} base
* @property {MetricPattern2<StoredF32>} cumulative
* @property {MetricPattern2<StoredF32>} sum
*/
/**
* Create a _1dReturns1mSdPattern pattern node
* Create a SegwitAdoptionPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_1dReturns1mSdPattern}
* @returns {SegwitAdoptionPattern}
*/
function create_1dReturns1mSdPattern(client, acc) {
function createSegwitAdoptionPattern(client, acc) {
return {
sd: createMetricPattern4(client, _m(acc, 'sd')),
sma: createMetricPattern4(client, _m(acc, 'sma')),
base: createMetricPattern11(client, acc),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern2(client, _m(acc, 'sum')),
};
}
/**
* @typedef {Object} CostBasisPattern
* @property {MetricPattern1<Dollars>} max
* @property {MetricPattern1<Dollars>} min
* @typedef {Object} ActiveSupplyPattern
* @property {MetricPattern1<Bitcoin>} bitcoin
* @property {MetricPattern1<Dollars>} dollars
* @property {MetricPattern1<Sats>} sats
*/
/**
* Create a CostBasisPattern pattern node
* Create a ActiveSupplyPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {CostBasisPattern}
* @returns {ActiveSupplyPattern}
*/
function createCostBasisPattern(client, acc) {
function createActiveSupplyPattern(client, acc) {
return {
max: createMetricPattern1(client, _m(acc, 'max_cost_basis')),
min: createMetricPattern1(client, _m(acc, 'min_cost_basis')),
bitcoin: createMetricPattern1(client, _m(acc, 'btc')),
dollars: createMetricPattern1(client, _m(acc, 'usd')),
sats: createMetricPattern1(client, acc),
};
}
/**
* @typedef {Object} UnclaimedRewardsPattern
* @property {BitcoinPattern2<Bitcoin>} bitcoin
* @property {BlockCountPattern<Dollars>} dollars
* @property {BlockCountPattern<Sats>} sats
*/
/**
* Create a UnclaimedRewardsPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {UnclaimedRewardsPattern}
*/
function createUnclaimedRewardsPattern(client, acc) {
return {
bitcoin: createBitcoinPattern2(client, _m(acc, 'btc')),
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
sats: createBlockCountPattern(client, acc),
};
}
@@ -2811,23 +2773,40 @@ function createRelativePattern4(client, acc) {
}
/**
* @template T
* @typedef {Object} BitcoinPattern2
* @property {MetricPattern2<T>} cumulative
* @property {MetricPattern1<T>} sum
* @typedef {Object} CostBasisPattern
* @property {MetricPattern1<Dollars>} max
* @property {MetricPattern1<Dollars>} min
*/
/**
* Create a BitcoinPattern2 pattern node
* @template T
* Create a CostBasisPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {BitcoinPattern2<T>}
* @returns {CostBasisPattern}
*/
function createBitcoinPattern2(client, acc) {
function createCostBasisPattern(client, acc) {
return {
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern1(client, acc),
max: createMetricPattern1(client, _m(acc, 'max_cost_basis')),
min: createMetricPattern1(client, _m(acc, 'min_cost_basis')),
};
}
/**
* @typedef {Object} _1dReturns1mSdPattern
* @property {MetricPattern4<StoredF32>} sd
* @property {MetricPattern4<StoredF32>} sma
*/
/**
* Create a _1dReturns1mSdPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {_1dReturns1mSdPattern}
*/
function create_1dReturns1mSdPattern(client, acc) {
return {
sd: createMetricPattern4(client, _m(acc, 'sd')),
sma: createMetricPattern4(client, _m(acc, 'sma')),
};
}
@@ -2874,19 +2853,23 @@ function createBlockCountPattern(client, acc) {
}
/**
* @typedef {Object} OutputsPattern
* @property {MetricPattern1<StoredU64>} utxoCount
* @template T
* @typedef {Object} BitcoinPattern2
* @property {MetricPattern2<T>} cumulative
* @property {MetricPattern1<T>} sum
*/
/**
* Create a OutputsPattern pattern node
* Create a BitcoinPattern2 pattern node
* @template T
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {OutputsPattern}
* @returns {BitcoinPattern2<T>}
*/
function createOutputsPattern(client, acc) {
function createBitcoinPattern2(client, acc) {
return {
utxoCount: createMetricPattern1(client, acc),
cumulative: createMetricPattern2(client, _m(acc, 'cumulative')),
sum: createMetricPattern1(client, acc),
};
}
@@ -2907,6 +2890,23 @@ function createRealizedPriceExtraPattern(client, acc) {
};
}
/**
* @typedef {Object} OutputsPattern
* @property {MetricPattern1<StoredU64>} utxoCount
*/
/**
* Create a OutputsPattern pattern node
* @param {BrkClientBase} client
* @param {string} acc - Accumulated metric name
* @returns {OutputsPattern}
*/
function createOutputsPattern(client, acc) {
return {
utxoCount: createMetricPattern1(client, acc),
};
}
// Catalog tree typedefs
/**
@@ -3711,8 +3711,8 @@ function createRealizedPriceExtraPattern(client, acc) {
/**
* @typedef {Object} MetricsTree_Market_Dca
* @property {ClassAveragePricePattern<Dollars>} classAveragePrice
* @property {MetricsTree_Market_Dca_ClassReturns} classReturns
* @property {MetricsTree_Market_Dca_ClassAveragePrice} classAveragePrice
* @property {ClassAveragePricePattern<StoredF32>} classReturns
* @property {MetricsTree_Market_Dca_ClassStack} classStack
* @property {PeriodAveragePricePattern<Dollars>} periodAveragePrice
* @property {PeriodCagrPattern} periodCagr
@@ -3722,19 +3722,19 @@ function createRealizedPriceExtraPattern(client, acc) {
*/
/**
* @typedef {Object} MetricsTree_Market_Dca_ClassReturns
* @property {MetricPattern4<StoredF32>} _2015
* @property {MetricPattern4<StoredF32>} _2016
* @property {MetricPattern4<StoredF32>} _2017
* @property {MetricPattern4<StoredF32>} _2018
* @property {MetricPattern4<StoredF32>} _2019
* @property {MetricPattern4<StoredF32>} _2020
* @property {MetricPattern4<StoredF32>} _2021
* @property {MetricPattern4<StoredF32>} _2022
* @property {MetricPattern4<StoredF32>} _2023
* @property {MetricPattern4<StoredF32>} _2024
* @property {MetricPattern4<StoredF32>} _2025
* @property {MetricPattern4<StoredF32>} _2026
* @typedef {Object} MetricsTree_Market_Dca_ClassAveragePrice
* @property {MetricPattern4<Dollars>} _2015
* @property {MetricPattern4<Dollars>} _2016
* @property {MetricPattern4<Dollars>} _2017
* @property {MetricPattern4<Dollars>} _2018
* @property {MetricPattern4<Dollars>} _2019
* @property {MetricPattern4<Dollars>} _2020
* @property {MetricPattern4<Dollars>} _2021
* @property {MetricPattern4<Dollars>} _2022
* @property {MetricPattern4<Dollars>} _2023
* @property {MetricPattern4<Dollars>} _2024
* @property {MetricPattern4<Dollars>} _2025
* @property {MetricPattern4<Dollars>} _2026
*/
/**
@@ -4281,7 +4281,7 @@ function createRealizedPriceExtraPattern(client, acc) {
* @extends BrkClientBase
*/
class BrkClient extends BrkClientBase {
VERSION = "v0.1.0-alpha.6";
VERSION = "v0.1.0-beta.0";
INDEXES = /** @type {const} */ ([
"dateindex",
@@ -4491,27 +4491,27 @@ class BrkClient extends BrkClientBase {
EPOCH_NAMES = /** @type {const} */ ({
"_0": {
"id": "epoch_0",
"short": "Epoch 0",
"short": "0",
"long": "Epoch 0"
},
"_1": {
"id": "epoch_1",
"short": "Epoch 1",
"short": "1",
"long": "Epoch 1"
},
"_2": {
"id": "epoch_2",
"short": "Epoch 2",
"short": "2",
"long": "Epoch 2"
},
"_3": {
"id": "epoch_3",
"short": "Epoch 3",
"short": "3",
"long": "Epoch 3"
},
"_4": {
"id": "epoch_4",
"short": "Epoch 4",
"short": "4",
"long": "Epoch 4"
}
});
@@ -4970,67 +4970,67 @@ class BrkClient extends BrkClientBase {
"_1satTo10sats": {
"id": "above_1sat_under_10sats",
"short": "1-10 sats",
"long": "1 to 10 Sats"
"long": "1-10 Sats"
},
"_10satsTo100sats": {
"id": "above_10sats_under_100sats",
"short": "10-100 sats",
"long": "10 to 100 Sats"
"long": "10-100 Sats"
},
"_100satsTo1kSats": {
"id": "above_100sats_under_1k_sats",
"short": "100-1k sats",
"long": "100 to 1K Sats"
"long": "100-1K Sats"
},
"_1kSatsTo10kSats": {
"id": "above_1k_sats_under_10k_sats",
"short": "1k-10k sats",
"long": "1K to 10K Sats"
"long": "1K-10K Sats"
},
"_10kSatsTo100kSats": {
"id": "above_10k_sats_under_100k_sats",
"short": "10k-100k sats",
"long": "10K to 100K Sats"
"long": "10K-100K Sats"
},
"_100kSatsTo1mSats": {
"id": "above_100k_sats_under_1m_sats",
"short": "100k-1M sats",
"long": "100K to 1M Sats"
"long": "100K-1M Sats"
},
"_1mSatsTo10mSats": {
"id": "above_1m_sats_under_10m_sats",
"short": "1M-10M sats",
"long": "1M to 10M Sats"
"long": "1M-10M Sats"
},
"_10mSatsTo1btc": {
"id": "above_10m_sats_under_1btc",
"short": "0.1-1 BTC",
"long": "0.1 to 1 BTC"
"long": "0.1-1 BTC"
},
"_1btcTo10btc": {
"id": "above_1btc_under_10btc",
"short": "1-10 BTC",
"long": "1 to 10 BTC"
"long": "1-10 BTC"
},
"_10btcTo100btc": {
"id": "above_10btc_under_100btc",
"short": "10-100 BTC",
"long": "10 to 100 BTC"
"long": "10-100 BTC"
},
"_100btcTo1kBtc": {
"id": "above_100btc_under_1k_btc",
"short": "100-1k BTC",
"long": "100 to 1K BTC"
"long": "100-1K BTC"
},
"_1kBtcTo10kBtc": {
"id": "above_1k_btc_under_10k_btc",
"short": "1k-10k BTC",
"long": "1K to 10K BTC"
"long": "1K-10K BTC"
},
"_10kBtcTo100kBtc": {
"id": "above_10k_btc_under_100k_btc",
"short": "10k-100k BTC",
"long": "10K to 100K BTC"
"long": "10K-100K BTC"
},
"_100kBtcOrMore": {
"id": "above_100k_btc",
@@ -5754,21 +5754,21 @@ class BrkClient extends BrkClientBase {
yearsSincePriceAth: createMetricPattern4(this, 'years_since_price_ath'),
},
dca: {
classAveragePrice: createClassAveragePricePattern(this, 'dca_class'),
classReturns: {
_2015: createMetricPattern4(this, 'dca_class_2015_returns'),
_2016: createMetricPattern4(this, 'dca_class_2016_returns'),
_2017: createMetricPattern4(this, 'dca_class_2017_returns'),
_2018: createMetricPattern4(this, 'dca_class_2018_returns'),
_2019: createMetricPattern4(this, 'dca_class_2019_returns'),
_2020: createMetricPattern4(this, 'dca_class_2020_returns'),
_2021: createMetricPattern4(this, 'dca_class_2021_returns'),
_2022: createMetricPattern4(this, 'dca_class_2022_returns'),
_2023: createMetricPattern4(this, 'dca_class_2023_returns'),
_2024: createMetricPattern4(this, 'dca_class_2024_returns'),
_2025: createMetricPattern4(this, 'dca_class_2025_returns'),
_2026: createMetricPattern4(this, 'dca_class_2026_returns'),
classAveragePrice: {
_2015: createMetricPattern4(this, 'dca_class_2015_average_price'),
_2016: createMetricPattern4(this, 'dca_class_2016_average_price'),
_2017: createMetricPattern4(this, 'dca_class_2017_average_price'),
_2018: createMetricPattern4(this, 'dca_class_2018_average_price'),
_2019: createMetricPattern4(this, 'dca_class_2019_average_price'),
_2020: createMetricPattern4(this, 'dca_class_2020_average_price'),
_2021: createMetricPattern4(this, 'dca_class_2021_average_price'),
_2022: createMetricPattern4(this, 'dca_class_2022_average_price'),
_2023: createMetricPattern4(this, 'dca_class_2023_average_price'),
_2024: createMetricPattern4(this, 'dca_class_2024_average_price'),
_2025: createMetricPattern4(this, 'dca_class_2025_average_price'),
_2026: createMetricPattern4(this, 'dca_class_2026_average_price'),
},
classReturns: createClassAveragePricePattern(this, 'dca_class'),
classStack: {
_2015: create_2015Pattern(this, 'dca_class_2015_stack'),
_2016: create_2015Pattern(this, 'dca_class_2016_stack'),
+155 -155
View File
@@ -2054,6 +2054,24 @@ class PeriodLumpSumStackPattern:
self._6y: _2015Pattern = _2015Pattern(client, _p('6y', acc))
self._8y: _2015Pattern = _2015Pattern(client, _p('8y', acc))
class ClassAveragePricePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_returns'))
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_returns'))
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_returns'))
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_returns'))
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_returns'))
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_returns'))
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_returns'))
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_returns'))
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_returns'))
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_returns'))
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_returns'))
self._2026: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2026_returns'))
class PeriodAveragePricePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2072,24 +2090,6 @@ class PeriodAveragePricePattern(Generic[T]):
self._6y: MetricPattern4[T] = MetricPattern4(client, _p('6y', acc))
self._8y: MetricPattern4[T] = MetricPattern4(client, _p('8y', acc))
class ClassAveragePricePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_average_price'))
self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_average_price'))
self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_average_price'))
self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_average_price'))
self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_average_price'))
self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_average_price'))
self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_average_price'))
self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_average_price'))
self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_average_price'))
self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_average_price'))
self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_average_price'))
self._2026: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2026_average_price'))
class BitcoinPattern:
"""Pattern struct for repeated tree structure."""
@@ -2124,22 +2124,6 @@ class DollarsPattern(Generic[T]):
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
self.sum: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'sum'))
class RelativePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap'))
self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap'))
self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl'))
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
self.unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap'))
self.unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.unrealized_profit_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
self.unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl'))
class RelativePattern:
"""Pattern struct for repeated tree structure."""
@@ -2156,6 +2140,22 @@ class RelativePattern:
self.unrealized_loss_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_market_cap'))
self.unrealized_profit_rel_to_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_market_cap'))
class RelativePattern2:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_market_cap'))
self.neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_market_cap'))
self.net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl_rel_to_own_total_unrealized_pnl'))
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'supply_in_profit_rel_to_own_supply'))
self.unrealized_loss_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_market_cap'))
self.unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_loss_rel_to_own_total_unrealized_pnl'))
self.unrealized_profit_rel_to_own_market_cap: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_market_cap'))
self.unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'unrealized_profit_rel_to_own_total_unrealized_pnl'))
class CountPattern2(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2187,21 +2187,6 @@ class AddrCountPattern:
self.p2wpkh: MetricPattern1[StoredU64] = MetricPattern1(client, _p('p2wpkh', acc))
self.p2wsh: MetricPattern1[StoredU64] = MetricPattern1(client, _p('p2wsh', acc))
class FeeRatePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.average: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'average'))
self.max: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'max'))
self.median: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'median'))
self.min: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'min'))
self.pct10: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct10'))
self.pct25: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct25'))
self.pct75: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct75'))
self.pct90: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct90'))
self.txindex: MetricPattern27[T] = MetricPattern27(client, acc)
class FullnessPattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2217,6 +2202,21 @@ class FullnessPattern(Generic[T]):
self.pct75: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct75'))
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
class FeeRatePattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.average: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'average'))
self.max: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'max'))
self.median: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'median'))
self.min: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'min'))
self.pct10: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct10'))
self.pct25: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct25'))
self.pct75: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct75'))
self.pct90: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct90'))
self.txindex: MetricPattern27[T] = MetricPattern27(client, acc)
class _0satsPattern:
"""Pattern struct for repeated tree structure."""
@@ -2245,32 +2245,6 @@ class PhaseDailyCentsPattern(Generic[T]):
self.pct75: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct75'))
self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90'))
class _10yTo12yPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern2 = CostBasisPattern2(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern2 = RealizedPattern2(client, acc)
self.relative: RelativePattern2 = RelativePattern2(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class UnrealizedPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss'))
self.net_unrealized_pnl: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl'))
self.supply_in_loss: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'supply_in_loss'))
self.supply_in_profit: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'supply_in_profit'))
self.total_unrealized_pnl: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'total_unrealized_pnl'))
self.unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_loss'))
self.unrealized_profit: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_profit'))
class _0satsPattern2:
"""Pattern struct for repeated tree structure."""
@@ -2284,6 +2258,19 @@ class _0satsPattern2:
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class _10yTo12yPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.activity: ActivityPattern2 = ActivityPattern2(client, acc)
self.cost_basis: CostBasisPattern2 = CostBasisPattern2(client, acc)
self.outputs: OutputsPattern = OutputsPattern(client, _m(acc, 'utxo_count'))
self.realized: RealizedPattern2 = RealizedPattern2(client, acc)
self.relative: RelativePattern2 = RelativePattern2(client, acc)
self.supply: SupplyPattern2 = SupplyPattern2(client, _m(acc, 'supply'))
self.unrealized: UnrealizedPattern = UnrealizedPattern(client, acc)
class PeriodCagrPattern:
"""Pattern struct for repeated tree structure."""
@@ -2297,6 +2284,19 @@ class PeriodCagrPattern:
self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc))
self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc))
class UnrealizedPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.neg_unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss'))
self.net_unrealized_pnl: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'net_unrealized_pnl'))
self.supply_in_loss: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'supply_in_loss'))
self.supply_in_profit: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'supply_in_profit'))
self.total_unrealized_pnl: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'total_unrealized_pnl'))
self.unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_loss'))
self.unrealized_profit: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_profit'))
class _10yPattern:
"""Pattern struct for repeated tree structure."""
@@ -2344,32 +2344,14 @@ class SplitPattern2(Generic[T]):
self.low: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'low'))
self.open: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'open'))
class UnclaimedRewardsPattern:
class _2015Pattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: BitcoinPattern2[Bitcoin] = BitcoinPattern2(client, _m(acc, 'btc'))
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class CoinbasePattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: BitcoinPattern = BitcoinPattern(client, _m(acc, 'btc'))
self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd'))
self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc)
class SegwitAdoptionPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.base: MetricPattern11[StoredF32] = MetricPattern11(client, acc)
self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum'))
self.bitcoin: MetricPattern4[Bitcoin] = MetricPattern4(client, _m(acc, 'btc'))
self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd'))
self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc)
class CostBasisPattern2:
"""Pattern struct for repeated tree structure."""
@@ -2380,23 +2362,14 @@ class CostBasisPattern2:
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
self.percentiles: PercentilesPattern = PercentilesPattern(client, _m(acc, 'cost_basis'))
class ActiveSupplyPattern:
class CoinbasePattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
class _2015Pattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: MetricPattern4[Bitcoin] = MetricPattern4(client, _m(acc, 'btc'))
self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd'))
self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc)
self.bitcoin: BitcoinPattern = BitcoinPattern(client, _m(acc, 'btc'))
self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd'))
self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc)
class CoinbasePattern2:
"""Pattern struct for repeated tree structure."""
@@ -2407,21 +2380,32 @@ class CoinbasePattern2:
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class _1dReturns1mSdPattern:
class SegwitAdoptionPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd'))
self.sma: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sma'))
self.base: MetricPattern11[StoredF32] = MetricPattern11(client, acc)
self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum'))
class CostBasisPattern:
class ActiveSupplyPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis'))
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc'))
self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd'))
self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc)
class UnclaimedRewardsPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.bitcoin: BitcoinPattern2[Bitcoin] = BitcoinPattern2(client, _m(acc, 'btc'))
self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd'))
self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc)
class SupplyPattern2:
"""Pattern struct for repeated tree structure."""
@@ -2439,13 +2423,21 @@ class RelativePattern4:
self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'loss_rel_to_own_supply'))
self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'profit_rel_to_own_supply'))
class BitcoinPattern2(Generic[T]):
class CostBasisPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.cumulative: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern1[T] = MetricPattern1(client, acc)
self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis'))
self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis'))
class _1dReturns1mSdPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd'))
self.sma: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sma'))
class SatsPattern(Generic[T]):
"""Pattern struct for repeated tree structure."""
@@ -2463,12 +2455,13 @@ class BlockCountPattern(Generic[T]):
self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative'))
self.sum: MetricPattern1[T] = MetricPattern1(client, acc)
class OutputsPattern:
class BitcoinPattern2(Generic[T]):
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc)
self.cumulative: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'cumulative'))
self.sum: MetricPattern1[T] = MetricPattern1(client, acc)
class RealizedPriceExtraPattern:
"""Pattern struct for repeated tree structure."""
@@ -2477,6 +2470,13 @@ class RealizedPriceExtraPattern:
"""Create pattern node with accumulated metric name."""
self.ratio: MetricPattern4[StoredF32] = MetricPattern4(client, acc)
class OutputsPattern:
"""Pattern struct for repeated tree structure."""
def __init__(self, client: BrkClientBase, acc: str):
"""Create pattern node with accumulated metric name."""
self.utxo_count: MetricPattern1[StoredU64] = MetricPattern1(client, acc)
# Metrics tree classes
class MetricsTree_Addresses:
@@ -3320,22 +3320,22 @@ class MetricsTree_Market_Ath:
self.price_drawdown: MetricPattern3[StoredF32] = MetricPattern3(client, 'price_drawdown')
self.years_since_price_ath: MetricPattern4[StoredF32] = MetricPattern4(client, 'years_since_price_ath')
class MetricsTree_Market_Dca_ClassReturns:
class MetricsTree_Market_Dca_ClassAveragePrice:
"""Metrics tree node."""
def __init__(self, client: BrkClientBase, base_path: str = ''):
self._2015: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2015_returns')
self._2016: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2016_returns')
self._2017: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2017_returns')
self._2018: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2018_returns')
self._2019: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2019_returns')
self._2020: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2020_returns')
self._2021: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2021_returns')
self._2022: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2022_returns')
self._2023: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2023_returns')
self._2024: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2024_returns')
self._2025: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2025_returns')
self._2026: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2026_returns')
self._2015: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2015_average_price')
self._2016: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2016_average_price')
self._2017: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2017_average_price')
self._2018: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2018_average_price')
self._2019: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2019_average_price')
self._2020: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2020_average_price')
self._2021: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2021_average_price')
self._2022: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2022_average_price')
self._2023: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2023_average_price')
self._2024: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2024_average_price')
self._2025: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2025_average_price')
self._2026: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2026_average_price')
class MetricsTree_Market_Dca_ClassStack:
"""Metrics tree node."""
@@ -3358,8 +3358,8 @@ class MetricsTree_Market_Dca:
"""Metrics tree node."""
def __init__(self, client: BrkClientBase, base_path: str = ''):
self.class_average_price: ClassAveragePricePattern[Dollars] = ClassAveragePricePattern(client, 'dca_class')
self.class_returns: MetricsTree_Market_Dca_ClassReturns = MetricsTree_Market_Dca_ClassReturns(client)
self.class_average_price: MetricsTree_Market_Dca_ClassAveragePrice = MetricsTree_Market_Dca_ClassAveragePrice(client)
self.class_returns: ClassAveragePricePattern[StoredF32] = ClassAveragePricePattern(client, 'dca_class')
self.class_stack: MetricsTree_Market_Dca_ClassStack = MetricsTree_Market_Dca_ClassStack(client)
self.period_average_price: PeriodAveragePricePattern[Dollars] = PeriodAveragePricePattern(client, 'dca_average_price')
self.period_cagr: PeriodCagrPattern = PeriodCagrPattern(client, 'dca_cagr')
@@ -3958,7 +3958,7 @@ class MetricsTree:
class BrkClient(BrkClientBase):
"""Main BRK client with metrics tree and API methods."""
VERSION = "v0.1.0-alpha.6"
VERSION = "v0.1.0-beta.0"
INDEXES = [
"dateindex",
@@ -4168,27 +4168,27 @@ class BrkClient(BrkClientBase):
EPOCH_NAMES = {
"_0": {
"id": "epoch_0",
"short": "Epoch 0",
"short": "0",
"long": "Epoch 0"
},
"_1": {
"id": "epoch_1",
"short": "Epoch 1",
"short": "1",
"long": "Epoch 1"
},
"_2": {
"id": "epoch_2",
"short": "Epoch 2",
"short": "2",
"long": "Epoch 2"
},
"_3": {
"id": "epoch_3",
"short": "Epoch 3",
"short": "3",
"long": "Epoch 3"
},
"_4": {
"id": "epoch_4",
"short": "Epoch 4",
"short": "4",
"long": "Epoch 4"
}
}
@@ -4647,67 +4647,67 @@ class BrkClient(BrkClientBase):
"_1sat_to_10sats": {
"id": "above_1sat_under_10sats",
"short": "1-10 sats",
"long": "1 to 10 Sats"
"long": "1-10 Sats"
},
"_10sats_to_100sats": {
"id": "above_10sats_under_100sats",
"short": "10-100 sats",
"long": "10 to 100 Sats"
"long": "10-100 Sats"
},
"_100sats_to_1k_sats": {
"id": "above_100sats_under_1k_sats",
"short": "100-1k sats",
"long": "100 to 1K Sats"
"long": "100-1K Sats"
},
"_1k_sats_to_10k_sats": {
"id": "above_1k_sats_under_10k_sats",
"short": "1k-10k sats",
"long": "1K to 10K Sats"
"long": "1K-10K Sats"
},
"_10k_sats_to_100k_sats": {
"id": "above_10k_sats_under_100k_sats",
"short": "10k-100k sats",
"long": "10K to 100K Sats"
"long": "10K-100K Sats"
},
"_100k_sats_to_1m_sats": {
"id": "above_100k_sats_under_1m_sats",
"short": "100k-1M sats",
"long": "100K to 1M Sats"
"long": "100K-1M Sats"
},
"_1m_sats_to_10m_sats": {
"id": "above_1m_sats_under_10m_sats",
"short": "1M-10M sats",
"long": "1M to 10M Sats"
"long": "1M-10M Sats"
},
"_10m_sats_to_1btc": {
"id": "above_10m_sats_under_1btc",
"short": "0.1-1 BTC",
"long": "0.1 to 1 BTC"
"long": "0.1-1 BTC"
},
"_1btc_to_10btc": {
"id": "above_1btc_under_10btc",
"short": "1-10 BTC",
"long": "1 to 10 BTC"
"long": "1-10 BTC"
},
"_10btc_to_100btc": {
"id": "above_10btc_under_100btc",
"short": "10-100 BTC",
"long": "10 to 100 BTC"
"long": "10-100 BTC"
},
"_100btc_to_1k_btc": {
"id": "above_100btc_under_1k_btc",
"short": "100-1k BTC",
"long": "100 to 1K BTC"
"long": "100-1K BTC"
},
"_1k_btc_to_10k_btc": {
"id": "above_1k_btc_under_10k_btc",
"short": "1k-10k BTC",
"long": "1K to 10K BTC"
"long": "1K-10K BTC"
},
"_10k_btc_to_100k_btc": {
"id": "above_10k_btc_under_100k_btc",
"short": "10k-100k BTC",
"long": "10K to 100K BTC"
"long": "10K-100K BTC"
},
"_100k_btc_or_more": {
"id": "above_100k_btc",
+2 -2
View File
@@ -55,7 +55,7 @@ echo ""
echo "--- Rust ---"
cd "$ROOT_DIR"
cargo test --workspace --exclude brk_playground
cargo test --workspace
echo ""
echo "--- JavaScript ---"
@@ -125,7 +125,7 @@ cd "$ROOT_DIR"
# Verify all crates package correctly
# Note: --no-verify skips rebuild check due to version collision with crates.io
# The cargo build --workspace --release step above already verified compilation
cargo package --workspace --allow-dirty --exclude brk_playground --no-verify
cargo package --workspace --allow-dirty --no-verify
# Version bump, commit, and tag (but don't publish yet)
cargo release "$RELEASE_ARG" --execute --no-publish --no-confirm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+162 -7
View File
@@ -189,6 +189,13 @@ export function createChainSection(ctx) {
unit: Unit.count,
options: { lineStyle: 4 },
}),
line({
metric: blocks.count._24hBlockCount,
name: "24h sum",
color: colors.pink,
unit: Unit.count,
defaultActive: false,
}),
line({
metric: blocks.count._1wBlockCount,
name: "1w sum",
@@ -199,7 +206,7 @@ export function createChainSection(ctx) {
line({
metric: blocks.count._1mBlockCount,
name: "1m sum",
color: colors.pink,
color: colors.orange,
unit: Unit.count,
defaultActive: false,
}),
@@ -225,10 +232,36 @@ export function createChainSection(ctx) {
title: "Block Size",
bottom: [
...fromSizePattern(blocks.size, Unit.bytes),
line({
metric: blocks.totalSize,
name: "total",
color: colors.purple,
unit: Unit.bytes,
defaultActive: false,
}),
...fromFullnessPattern(blocks.vbytes, Unit.vb),
...fromFullnessPattern(blocks.weight, Unit.wu),
line({
metric: blocks.weight.sum,
name: "sum",
color: colors.stat.sum,
unit: Unit.wu,
defaultActive: false,
}),
line({
metric: blocks.weight.cumulative,
name: "cumulative",
color: colors.stat.cumulative,
unit: Unit.wu,
defaultActive: false,
}),
],
},
{
name: "Fullness",
title: "Block Fullness",
bottom: fromFullnessPattern(blocks.fullness, Unit.percentage),
},
],
},
@@ -380,11 +413,6 @@ export function createChainSection(ctx) {
title: "Output Count",
bottom: [...fromSizePattern(outputs.count.totalCount, Unit.count)],
},
{
name: "OP_RETURN",
title: "OP_RETURN Outputs",
bottom: fromFullnessPattern(scripts.count.opreturn, Unit.count),
},
{
name: "Speed",
title: "Outputs Per Second",
@@ -416,6 +444,60 @@ export function createChainSection(ctx) {
],
},
// Scripts
{
name: "Scripts",
tree: [
{
name: "Count",
tree: [
{ name: "P2PKH", title: "P2PKH Output Count", bottom: fromDollarsPattern(scripts.count.p2pkh, Unit.count) },
{ name: "P2SH", title: "P2SH Output Count", bottom: fromDollarsPattern(scripts.count.p2sh, Unit.count) },
{ name: "P2WPKH", title: "P2WPKH Output Count", bottom: fromDollarsPattern(scripts.count.p2wpkh, Unit.count) },
{ name: "P2WSH", title: "P2WSH Output Count", bottom: fromDollarsPattern(scripts.count.p2wsh, Unit.count) },
{ name: "P2TR", title: "P2TR Output Count", bottom: fromDollarsPattern(scripts.count.p2tr, Unit.count) },
{ name: "P2PK33", title: "P2PK33 Output Count", bottom: fromDollarsPattern(scripts.count.p2pk33, Unit.count) },
{ name: "P2PK65", title: "P2PK65 Output Count", bottom: fromDollarsPattern(scripts.count.p2pk65, Unit.count) },
{ name: "P2MS", title: "P2MS Output Count", bottom: fromDollarsPattern(scripts.count.p2ms, Unit.count) },
{ name: "P2A", title: "P2A Output Count", bottom: fromDollarsPattern(scripts.count.p2a, Unit.count) },
{ name: "OP_RETURN", title: "OP_RETURN Output Count", bottom: fromDollarsPattern(scripts.count.opreturn, Unit.count) },
{ name: "SegWit", title: "SegWit Output Count", bottom: fromDollarsPattern(scripts.count.segwit, Unit.count) },
{ name: "Empty", title: "Empty Output Count", bottom: fromDollarsPattern(scripts.count.emptyoutput, Unit.count) },
{ name: "Unknown", title: "Unknown Output Count", bottom: fromDollarsPattern(scripts.count.unknownoutput, Unit.count) },
],
},
{
name: "Adoption",
tree: [
{
name: "SegWit",
title: "SegWit Adoption",
bottom: [
line({ metric: scripts.count.segwitAdoption.base, name: "base", unit: Unit.percentage }),
line({ metric: scripts.count.segwitAdoption.sum, name: "sum", color: colors.stat.sum, unit: Unit.percentage }),
line({ metric: scripts.count.segwitAdoption.cumulative, name: "cumulative", color: colors.stat.cumulative, unit: Unit.percentage, defaultActive: false }),
],
},
{
name: "Taproot",
title: "Taproot Adoption",
bottom: [
line({ metric: scripts.count.taprootAdoption.base, name: "base", unit: Unit.percentage }),
line({ metric: scripts.count.taprootAdoption.sum, name: "sum", color: colors.stat.sum, unit: Unit.percentage }),
line({ metric: scripts.count.taprootAdoption.cumulative, name: "cumulative", color: colors.stat.cumulative, unit: Unit.percentage, defaultActive: false }),
],
},
],
},
{
name: "Value",
tree: [
{ name: "OP_RETURN", title: "OP_RETURN Value", bottom: fromCoinbasePattern(scripts.value.opreturn) },
],
},
],
},
// Supply
{
name: "Supply",
@@ -456,7 +538,10 @@ export function createChainSection(ctx) {
{
name: "Coinbase",
title: "Coinbase Rewards",
bottom: fromCoinbasePattern(blocks.rewards.coinbase),
bottom: [
...fromCoinbasePattern(blocks.rewards.coinbase),
...satsBtcUsd(blocks.rewards._24hCoinbaseSum, "24h sum", colors.pink, { defaultActive: false }),
],
},
{
name: "Subsidy",
@@ -470,6 +555,13 @@ export function createChainSection(ctx) {
unit: Unit.percentage,
defaultActive: false,
}),
line({
metric: blocks.rewards.subsidyUsd1ySma,
name: "1y SMA",
color: colors.lime,
unit: Unit.usd,
defaultActive: false,
}),
],
},
{
@@ -557,6 +649,63 @@ export function createChainSection(ctx) {
}),
],
},
{
name: "Empty by Type",
title: "Empty Address Count by Type",
bottom: [
line({
metric: distribution.emptyAddrCount.p2pkh,
name: "P2PKH",
color: colors.orange,
unit: Unit.count,
}),
line({
metric: distribution.emptyAddrCount.p2sh,
name: "P2SH",
color: colors.yellow,
unit: Unit.count,
}),
line({
metric: distribution.emptyAddrCount.p2wpkh,
name: "P2WPKH",
color: colors.green,
unit: Unit.count,
}),
line({
metric: distribution.emptyAddrCount.p2wsh,
name: "P2WSH",
color: colors.teal,
unit: Unit.count,
}),
line({
metric: distribution.emptyAddrCount.p2tr,
name: "P2TR",
color: colors.purple,
unit: Unit.count,
}),
line({
metric: distribution.emptyAddrCount.p2pk65,
name: "P2PK65",
color: colors.pink,
unit: Unit.count,
defaultActive: false,
}),
line({
metric: distribution.emptyAddrCount.p2pk33,
name: "P2PK33",
color: colors.red,
unit: Unit.count,
defaultActive: false,
}),
line({
metric: distribution.emptyAddrCount.p2a,
name: "P2A",
color: colors.blue,
unit: Unit.count,
defaultActive: false,
}),
],
},
{
name: "By Type",
title: "Address Count by Type",
@@ -678,6 +827,12 @@ export function createChainSection(ctx) {
name: "Difficulty",
unit: Unit.difficulty,
}),
line({
metric: blocks.difficulty.epoch,
name: "Epoch",
color: colors.teal,
unit: Unit.epoch,
}),
line({
metric: blocks.difficulty.blocksBeforeNextAdjustment,
name: "before next",
+11 -2
View File
@@ -4,6 +4,7 @@ import {
satsBtcUsd,
createRatioChart,
createZScoresFolder,
formatCohortTitle,
} from "./shared.js";
/**
@@ -27,7 +28,7 @@ function createCointimePriceWithRatioOptions(
title,
top: [line({ metric: price, name: legend, color, unit: Unit.usd })],
},
createRatioChart(ctx, { title, price, ratio, color }),
createRatioChart(ctx, { title: formatCohortTitle(title), price, ratio, color }),
createZScoresFolder(ctx, { title, legend, price, ratio, color }),
];
}
@@ -40,7 +41,15 @@ function createCointimePriceWithRatioOptions(
export function createCointimeSection(ctx) {
const { colors, brk } = ctx;
const { cointime, distribution, supply } = brk.metrics;
const { pricing, cap, activity, supply: cointimeSupply, adjusted, reserveRisk, value } = cointime;
const {
pricing,
cap,
activity,
supply: cointimeSupply,
adjusted,
reserveRisk,
value,
} = cointime;
const { all } = distribution.utxoCohorts;
// Cointime prices data
-12
View File
@@ -1,7 +1,4 @@
import {
fromBlockCount,
fromBitcoin,
fromBlockSize,
fromSizePattern,
fromFullnessPattern,
fromDollarsPattern,
@@ -32,15 +29,6 @@ export function createContext({ brk }) {
colors,
brk,
/** @type {OmitFirstArg<typeof fromBlockCount>} */
fromBlockCount: (pattern, title, color) =>
fromBlockCount(colors, pattern, title, color),
/** @type {OmitFirstArg<typeof fromBitcoin>} */
fromBitcoin: (pattern, title, color) =>
fromBitcoin(colors, pattern, title, color),
/** @type {OmitFirstArg<typeof fromBlockSize>} */
fromBlockSize: (pattern, title, color) =>
fromBlockSize(colors, pattern, title, color),
/** @type {OmitFirstArg<typeof fromSizePattern>} */
fromSizePattern: (pattern, unit, title) =>
fromSizePattern(colors, pattern, unit, title),
+57 -62
View File
@@ -7,11 +7,10 @@
import { Unit } from "../../utils/units.js";
import { priceLine } from "../constants.js";
import { line, baseline } from "../series.js";
import { formatCohortTitle } from "../shared.js";
import {
createSingleSupplySeries,
createGroupedSupplyTotalSeries,
createGroupedSupplyInProfitSeries,
createGroupedSupplyInLossSeries,
createGroupedSupplySection,
createUtxoCountSeries,
createAddressCountSeries,
createRealizedPriceSeries,
@@ -25,6 +24,8 @@ import {
createGroupedSentSatsSeries,
createGroupedSentBitcoinSeries,
createGroupedSentDollarsSeries,
groupedSupplyRelativeGenerators,
createSingleSupplyRelativeOptions,
} from "./shared.js";
/**
@@ -39,7 +40,7 @@ export function createAddressCohortFolder(ctx, args) {
const useGroupName = "list" in args;
const isSingle = !("list" in args);
const title = args.title ? `${useGroupName ? "by" : "of"} ${args.title}` : "";
const title = formatCohortTitle(args.title);
return {
name: args.name || "all",
@@ -48,44 +49,26 @@ export function createAddressCohortFolder(ctx, args) {
isSingle
? {
name: "supply",
title: `Supply ${title}`,
title: title("Supply"),
bottom: createSingleSupplySeries(
ctx,
/** @type {AddressCohortObject} */ (args),
createSingleSupplyRelativeOptions(ctx, /** @type {AddressCohortObject} */ (args)),
),
}
: {
name: "supply",
tree: [
{
name: "total",
title: `Supply ${title}`,
bottom: createGroupedSupplyTotalSeries(list),
},
{
name: "in profit",
title: `Supply In Profit ${title}`,
bottom: createGroupedSupplyInProfitSeries(list),
},
{
name: "in loss",
title: `Supply In Loss ${title}`,
bottom: createGroupedSupplyInLossSeries(list),
},
],
},
: createGroupedSupplySection(list, title, groupedSupplyRelativeGenerators),
// UTXO count
{
name: "utxo count",
title: `UTXO Count ${title}`,
title: title("UTXO Count"),
bottom: createUtxoCountSeries(list, useGroupName),
},
// Address count (ADDRESS COHORTS ONLY - fully type safe!)
{
name: "address count",
title: `Address Count ${title}`,
title: title("Address Count"),
bottom: createAddressCountSeries(ctx, list, useGroupName),
},
@@ -97,12 +80,12 @@ export function createAddressCohortFolder(ctx, args) {
? [
{
name: "Price",
title: `Realized Price ${title}`,
title: title("Realized Price"),
top: createRealizedPriceSeries(list),
},
{
name: "Ratio",
title: `Realized Price Ratio ${title}`,
title: title("Realized Price Ratio"),
bottom: createRealizedPriceRatioSeries(ctx, list),
},
]
@@ -112,9 +95,21 @@ export function createAddressCohortFolder(ctx, args) {
)),
{
name: "capitalization",
title: `Realized Cap ${title}`,
title: title("Realized Cap"),
bottom: createRealizedCapWithExtras(ctx, list, args, useGroupName),
},
{
name: "value",
title: title("Realized Value"),
bottom: list.map(({ color, name, tree }) =>
line({
metric: tree.realized.realizedValue,
name: useGroupName ? name : "Realized Value",
color,
unit: Unit.usd,
}),
),
},
...(!useGroupName
? createRealizedPnlSection(
ctx,
@@ -140,7 +135,7 @@ export function createAddressCohortFolder(ctx, args) {
/**
* Create realized price options for single cohort
* @param {AddressCohortObject} args
* @param {string} title
* @param {(metric: string) => string} title
* @returns {PartialOptionsTree}
*/
function createRealizedPriceOptions(args, title) {
@@ -149,7 +144,7 @@ function createRealizedPriceOptions(args, title) {
return [
{
name: "price",
title: `Realized Price ${title}`,
title: title("Realized Price"),
top: [
line({
metric: tree.realized.realizedPrice,
@@ -199,7 +194,7 @@ function createRealizedCapWithExtras(ctx, list, args, useGroupName) {
* Create realized PnL section for single cohort
* @param {PartialContext} ctx
* @param {AddressCohortObject} args
* @param {string} title
* @param {(metric: string) => string} title
* @returns {PartialOptionsTree}
*/
function createRealizedPnlSection(ctx, args, title) {
@@ -209,7 +204,7 @@ function createRealizedPnlSection(ctx, args, title) {
return [
{
name: "pnl",
title: `Realized P&L ${title}`,
title: title("Realized P&L"),
bottom: [
line({
metric: realized.realizedProfit.sum,
@@ -287,7 +282,7 @@ function createRealizedPnlSection(ctx, args, title) {
},
{
name: "Net pnl",
title: `Net Realized P&L ${title}`,
title: title("Net Realized P&L"),
bottom: [
baseline({
metric: realized.netRealizedPnl.sum,
@@ -345,7 +340,7 @@ function createRealizedPnlSection(ctx, args, title) {
},
{
name: "sopr",
title: `SOPR ${title}`,
title: title("SOPR"),
bottom: [
baseline({
metric: realized.sopr,
@@ -378,7 +373,7 @@ function createRealizedPnlSection(ctx, args, title) {
},
{
name: "Sell Side Risk",
title: `Sell Side Risk Ratio ${title}`,
title: title("Sell Side Risk Ratio"),
bottom: [
line({
metric: realized.sellSideRiskRatio,
@@ -404,7 +399,7 @@ function createRealizedPnlSection(ctx, args, title) {
},
{
name: "value",
title: `Value Created & Destroyed ${title}`,
title: title("Value Created & Destroyed"),
bottom: [
line({
metric: realized.valueCreated,
@@ -428,7 +423,7 @@ function createRealizedPnlSection(ctx, args, title) {
* @param {PartialContext} ctx
* @param {readonly AddressCohortObject[]} list
* @param {boolean} useGroupName
* @param {string} title
* @param {(metric: string) => string} title
* @returns {PartialOptionsTree}
*/
function createUnrealizedSection(ctx, list, useGroupName, title) {
@@ -440,7 +435,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
tree: [
{
name: "profit",
title: `Unrealized Profit ${title}`,
title: title("Unrealized Profit"),
bottom: list.flatMap(({ color, name, tree }) => [
line({
metric: tree.unrealized.unrealizedProfit,
@@ -452,7 +447,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "loss",
title: `Unrealized Loss ${title}`,
title: title("Unrealized Loss"),
bottom: list.flatMap(({ color, name, tree }) => [
line({
metric: tree.unrealized.unrealizedLoss,
@@ -464,7 +459,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "total pnl",
title: `Total Unrealized P&L ${title}`,
title: title("Total Unrealized P&L"),
bottom: list.flatMap(({ color, name, tree }) => [
baseline({
metric: tree.unrealized.totalUnrealizedPnl,
@@ -476,7 +471,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "negative loss",
title: `Negative Unrealized Loss ${title}`,
title: title("Negative Unrealized Loss"),
bottom: list.flatMap(({ color, name, tree }) => [
line({
metric: tree.unrealized.negUnrealizedLoss,
@@ -491,7 +486,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
tree: [
{
name: "nupl",
title: `NUPL (Rel to Market Cap) ${title}`,
title: title("NUPL (Rel to Market Cap)"),
bottom: list.flatMap(({ color, name, tree }) => [
baseline({
metric: tree.relative.nupl,
@@ -504,7 +499,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "profit",
title: `Unrealized Profit (% of Market Cap) ${title}`,
title: title("Unrealized Profit (% of Market Cap)"),
bottom: list.flatMap(({ color, name, tree }) => [
line({
metric: tree.relative.unrealizedProfitRelToMarketCap,
@@ -516,7 +511,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "loss",
title: `Unrealized Loss (% of Market Cap) ${title}`,
title: title("Unrealized Loss (% of Market Cap)"),
bottom: list.flatMap(({ color, name, tree }) => [
line({
metric: tree.relative.unrealizedLossRelToMarketCap,
@@ -528,7 +523,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "net pnl",
title: `Net Unrealized P&L (% of Market Cap) ${title}`,
title: title("Net Unrealized P&L (% of Market Cap)"),
bottom: list.flatMap(({ color, name, tree }) => [
baseline({
metric: tree.relative.netUnrealizedPnlRelToMarketCap,
@@ -540,7 +535,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "negative loss",
title: `Negative Unrealized Loss (% of Market Cap) ${title}`,
title: title("Negative Unrealized Loss (% of Market Cap)"),
bottom: list.flatMap(({ color, name, tree }) => [
line({
metric: tree.relative.negUnrealizedLossRelToMarketCap,
@@ -554,7 +549,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
},
{
name: "nupl",
title: `Net Unrealized P&L ${title}`,
title: title("Net Unrealized P&L"),
bottom: list.flatMap(({ color, name, tree }) => [
baseline({
metric: tree.unrealized.netUnrealizedPnl,
@@ -577,7 +572,7 @@ function createUnrealizedSection(ctx, list, useGroupName, title) {
* Create cost basis section (no percentiles for address cohorts)
* @param {readonly AddressCohortObject[]} list
* @param {boolean} useGroupName
* @param {string} title
* @param {(metric: string) => string} title
* @returns {PartialOptionsTree}
*/
function createCostBasisSection(list, useGroupName, title) {
@@ -587,7 +582,7 @@ function createCostBasisSection(list, useGroupName, title) {
tree: [
{
name: "min",
title: `Min Cost Basis ${title}`,
title: title("Min Cost Basis"),
top: list.map(({ color, name, tree }) =>
line({
metric: tree.costBasis.min,
@@ -599,7 +594,7 @@ function createCostBasisSection(list, useGroupName, title) {
},
{
name: "max",
title: `Max Cost Basis ${title}`,
title: title("Max Cost Basis"),
top: list.map(({ color, name, tree }) =>
line({
metric: tree.costBasis.max,
@@ -617,7 +612,7 @@ function createCostBasisSection(list, useGroupName, title) {
/**
* Create activity section
* @param {AddressCohortObject | AddressCohortGroupObject} args
* @param {string} title
* @param {(metric: string) => string} title
* @returns {PartialOptionsTree}
*/
function createActivitySection(args, title) {
@@ -633,12 +628,12 @@ function createActivitySection(args, title) {
tree: [
{
name: "Coins Destroyed",
title: `Coins Destroyed ${title}`,
title: title("Coins Destroyed"),
bottom: createSingleCoinsDestroyedSeries(cohort),
},
{
name: "Sent",
title: `Sent ${title}`,
title: title("Sent"),
bottom: createSingleSentSeries(cohort),
},
],
@@ -653,22 +648,22 @@ function createActivitySection(args, title) {
tree: [
{
name: "coinblocks destroyed",
title: `Coinblocks Destroyed ${title}`,
title: title("Coinblocks Destroyed"),
bottom: createGroupedCoinblocksDestroyedSeries(list),
},
{
name: "coindays destroyed",
title: `Coindays Destroyed ${title}`,
title: title("Coindays Destroyed"),
bottom: createGroupedCoindaysDestroyedSeries(list),
},
{
name: "satblocks destroyed",
title: `Satblocks Destroyed ${title}`,
title: title("Satblocks Destroyed"),
bottom: createGroupedSatblocksDestroyedSeries(list),
},
{
name: "satdays destroyed",
title: `Satdays Destroyed ${title}`,
title: title("Satdays Destroyed"),
bottom: createGroupedSatdaysDestroyedSeries(list),
},
{
@@ -676,17 +671,17 @@ function createActivitySection(args, title) {
tree: [
{
name: "sats",
title: `Sent (Sats) ${title}`,
title: title("Sent (Sats)"),
bottom: createGroupedSentSatsSeries(list),
},
{
name: "bitcoin",
title: `Sent (BTC) ${title}`,
title: title("Sent (BTC)"),
bottom: createGroupedSentBitcoinSeries(list),
},
{
name: "dollars",
title: `Sent ($) ${title}`,
title: title("Sent ($)"),
bottom: createGroupedSentDollarsSeries(list),
},
],
+33 -37
View File
@@ -24,10 +24,20 @@ const entries = (obj) =>
);
/** @type {readonly AddressableType[]} */
const ADDRESSABLE_TYPES = ["p2pk65", "p2pk33", "p2pkh", "p2sh", "p2wpkh", "p2wsh", "p2tr", "p2a"];
const ADDRESSABLE_TYPES = [
"p2pk65",
"p2pk33",
"p2pkh",
"p2sh",
"p2wpkh",
"p2wsh",
"p2tr",
"p2a",
];
/** @type {(key: SpendableType) => key is AddressableType} */
const isAddressable = (key) => ADDRESSABLE_TYPES.includes(/** @type {any} */ (key));
const isAddressable = (key) =>
ADDRESSABLE_TYPES.includes(/** @type {any} */ (key));
/**
* Build all cohort data from brk tree
@@ -51,8 +61,7 @@ export function buildCohortData(colors, brk) {
YEAR_NAMES,
} = brk;
// Base cohort representing "all" - CohortAll (adjustedSopr + percentiles but no RelToMarketCap)
/** @type {CohortAll} */
// Base cohort representing "all"
const cohortAll = {
name: "",
title: "",
@@ -61,9 +70,8 @@ export function buildCohortData(colors, brk) {
addrCount: addrCount.all,
};
// Term cohorts - split because short is CohortFull, long is CohortWithPercentiles
// Term cohorts
const shortNames = TERM_NAMES.short;
/** @type {CohortFull} */
const termShort = {
name: shortNames.short,
title: shortNames.long,
@@ -79,43 +87,40 @@ export function buildCohortData(colors, brk) {
tree: utxoCohorts.term.long,
};
// Max age cohorts (up to X time) - CohortWithAdjusted (adjustedSopr only)
/** @type {readonly CohortWithAdjusted[]} */
// Max age cohorts (up to X time)
const upToDate = entries(utxoCohorts.maxAge).map(([key, tree]) => {
const names = MAX_AGE_NAMES[key];
return {
name: names.short,
title: names.long,
title: `UTXOs ${names.long}`,
color: colors[maxAgeColors[key]],
tree,
};
});
// Min age cohorts (from X time) - CohortBasicWithMarketCap (has RelToMarketCap)
/** @type {readonly CohortBasicWithMarketCap[]} */
// Min age cohorts (from X time)
const fromDate = entries(utxoCohorts.minAge).map(([key, tree]) => {
const names = MIN_AGE_NAMES[key];
return {
name: names.short,
title: names.long,
title: `UTXOs ${names.long}`,
color: colors[minAgeColors[key]],
tree,
};
});
// Age range cohorts - CohortAgeRange (no nupl)
// Age range cohorts
const dateRange = entries(utxoCohorts.ageRange).map(([key, tree]) => {
const names = AGE_RANGE_NAMES[key];
return {
name: names.short,
title: names.long,
title: `UTXOs ${names.long}`,
color: colors[ageRangeColors[key]],
tree,
};
});
// Epoch cohorts - CohortBasicWithoutMarketCap (no RelToMarketCap)
/** @type {readonly CohortBasicWithoutMarketCap[]} */
// Epoch cohorts
const epoch = entries(utxoCohorts.epoch).map(([key, tree]) => {
const names = EPOCH_NAMES[key];
return {
@@ -126,66 +131,61 @@ export function buildCohortData(colors, brk) {
};
});
// UTXOs above amount - CohortBasicWithMarketCap (has RelToMarketCap)
/** @type {readonly CohortBasicWithMarketCap[]} */
// UTXOs above amount
const utxosAboveAmount = entries(utxoCohorts.geAmount).map(([key, tree]) => {
const names = GE_AMOUNT_NAMES[key];
return {
name: names.short,
title: names.long,
title: `UTXOs ${names.long}`,
color: colors[geAmountColors[key]],
tree,
};
});
// Addresses above amount
/** @type {readonly AddressCohortObject[]} */
const addressesAboveAmount = entries(addressCohorts.geAmount).map(
([key, tree]) => {
const names = GE_AMOUNT_NAMES[key];
return {
name: names.short,
title: names.long,
title: `Addresses ${names.long}`,
color: colors[geAmountColors[key]],
tree,
};
},
);
// UTXOs under amount - CohortBasicWithMarketCap (has RelToMarketCap)
/** @type {readonly CohortBasicWithMarketCap[]} */
// UTXOs under amount
const utxosUnderAmount = entries(utxoCohorts.ltAmount).map(([key, tree]) => {
const names = LT_AMOUNT_NAMES[key];
return {
name: names.short,
title: names.long,
title: `UTXOs ${names.long}`,
color: colors[ltAmountColors[key]],
tree,
};
});
// Addresses under amount
/** @type {readonly AddressCohortObject[]} */
const addressesUnderAmount = entries(addressCohorts.ltAmount).map(
([key, tree]) => {
const names = LT_AMOUNT_NAMES[key];
return {
name: names.short,
title: names.long,
title: `Addresses ${names.long}`,
color: colors[ltAmountColors[key]],
tree,
};
},
);
// UTXOs amount ranges - CohortBasicWithoutMarketCap (no RelToMarketCap)
/** @type {readonly CohortBasicWithoutMarketCap[]} */
// UTXOs amount ranges
const utxosAmountRanges = entries(utxoCohorts.amountRange).map(
([key, tree]) => {
const names = AMOUNT_RANGE_NAMES[key];
return {
name: names.short,
title: names.long,
title: `UTXOs ${names.long}`,
color: colors[amountRangeColors[key]],
tree,
};
@@ -193,13 +193,12 @@ export function buildCohortData(colors, brk) {
);
// Addresses amount ranges
/** @type {readonly AddressCohortObject[]} */
const addressesAmountRanges = entries(addressCohorts.amountRange).map(
([key, tree]) => {
const names = AMOUNT_RANGE_NAMES[key];
return {
name: names.short,
title: names.long,
title: `Addresses ${names.long}`,
color: colors[amountRangeColors[key]],
tree,
};
@@ -207,33 +206,30 @@ export function buildCohortData(colors, brk) {
);
// Spendable type cohorts - split by addressability
/** @type {readonly CohortAddress[]} */
const typeAddressable = ADDRESSABLE_TYPES.map((key) => {
const names = SPENDABLE_TYPE_NAMES[key];
return {
name: names.short,
title: names.long,
title: names.short,
color: colors[spendableTypeColors[key]],
tree: utxoCohorts.type[key],
addrCount: addrCount[key],
};
});
/** @type {readonly CohortBasicWithoutMarketCap[]} */
const typeOther = entries(utxoCohorts.type)
.filter(([key]) => !isAddressable(key))
.map(([key, tree]) => {
const names = SPENDABLE_TYPE_NAMES[key];
return {
name: names.short,
title: names.long,
title: names.short,
color: colors[spendableTypeColors[key]],
tree,
};
});
// Year cohorts - CohortBasicWithoutMarketCap (no RelToMarketCap)
/** @type {readonly CohortBasicWithoutMarketCap[]} */
// Year cohorts
const year = entries(utxoCohorts.year).map(([key, tree]) => {
const names = YEAR_NAMES[key];
return {
@@ -10,8 +10,7 @@ export {
createCohortFolderAll,
createCohortFolderFull,
createCohortFolderWithAdjusted,
createCohortFolderWithPercentiles,
createCohortFolderLongTerm,
createCohortFolderWithNupl,
createCohortFolderAgeRange,
createCohortFolderBasicWithMarketCap,
createCohortFolderBasicWithoutMarketCap,
+179 -69
View File
@@ -9,46 +9,25 @@ import { satsBtcUsd } from "../shared.js";
* Create supply section for a single cohort
* @param {PartialContext} ctx
* @param {CohortObject} cohort
* @param {Object} [options]
* @param {AnyFetchedSeriesBlueprint[]} [options.supplyRelative] - Supply relative to circulating supply metrics
* @param {AnyFetchedSeriesBlueprint[]} [options.pnlRelative] - Supply in profit/loss relative to circulating supply metrics
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createSingleSupplySeries(ctx, cohort) {
export function createSingleSupplySeries(ctx, cohort, { supplyRelative = [], pnlRelative = [] } = {}) {
const { colors } = ctx;
const { tree } = cohort;
return [
...satsBtcUsd(tree.supply.total, "Supply", colors.default),
...("supplyRelToCirculatingSupply" in tree.relative
? [
line({
metric: tree.relative.supplyRelToCirculatingSupply,
name: "Supply",
color: colors.default,
unit: Unit.pctSupply,
}),
]
: []),
...supplyRelative,
...satsBtcUsd(tree.unrealized.supplyInProfit, "In Profit", colors.green),
...satsBtcUsd(tree.unrealized.supplyInLoss, "In Loss", colors.red),
...satsBtcUsd(tree.supply.halved, "half", colors.gray).map((s) => ({
...s,
options: { lineStyle: 4 },
})),
...("supplyInProfitRelToCirculatingSupply" in tree.relative
? [
line({
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
name: "In Profit",
color: colors.green,
unit: Unit.pctSupply,
}),
line({
metric: tree.relative.supplyInLossRelToCirculatingSupply,
name: "In Loss",
color: colors.red,
unit: Unit.pctSupply,
}),
]
: []),
...pnlRelative,
line({
metric: tree.relative.supplyInProfitRelToOwnSupply,
name: "In Profit",
@@ -74,67 +53,198 @@ export function createSingleSupplySeries(ctx, cohort) {
/**
* Create supply total series for grouped cohorts
* @param {readonly CohortObject[]} list
* @template {readonly CohortObject[]} T
* @param {T} list
* @param {Object} [options]
* @param {(cohort: T[number]) => AnyFetchedSeriesBlueprint[]} [options.relativeMetrics] - Generator for relative supply metrics
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createGroupedSupplyTotalSeries(list) {
return list.flatMap(({ color, name, tree }) => [
...satsBtcUsd(tree.supply.total, name, color),
...("supplyRelToCirculatingSupply" in tree.relative
? [
line({
metric: tree.relative.supplyRelToCirculatingSupply,
name,
color,
unit: Unit.pctSupply,
}),
]
: []),
export function createGroupedSupplyTotalSeries(list, { relativeMetrics } = {}) {
return list.flatMap((cohort) => [
...satsBtcUsd(cohort.tree.supply.total, cohort.name, cohort.color),
...(relativeMetrics ? relativeMetrics(cohort) : []),
]);
}
/**
* Create supply in profit series for grouped cohorts
* @param {readonly CohortObject[]} list
* @template {readonly CohortObject[]} T
* @param {T} list
* @param {Object} [options]
* @param {(cohort: T[number]) => AnyFetchedSeriesBlueprint[]} [options.relativeMetrics] - Generator for relative supply metrics
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createGroupedSupplyInProfitSeries(list) {
return list.flatMap(({ color, name, tree }) => [
...satsBtcUsd(tree.unrealized.supplyInProfit, name, color),
...("supplyInProfitRelToCirculatingSupply" in tree.relative
? [
line({
metric: tree.relative.supplyInProfitRelToCirculatingSupply,
name,
color,
unit: Unit.pctSupply,
}),
]
: []),
export function createGroupedSupplyInProfitSeries(list, { relativeMetrics } = {}) {
return list.flatMap((cohort) => [
...satsBtcUsd(cohort.tree.unrealized.supplyInProfit, cohort.name, cohort.color),
...(relativeMetrics ? relativeMetrics(cohort) : []),
]);
}
/**
* Create supply in loss series for grouped cohorts
* @param {readonly CohortObject[]} list
* @template {readonly CohortObject[]} T
* @param {T} list
* @param {Object} [options]
* @param {(cohort: T[number]) => AnyFetchedSeriesBlueprint[]} [options.relativeMetrics] - Generator for relative supply metrics
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createGroupedSupplyInLossSeries(list) {
return list.flatMap(({ color, name, tree }) => [
...satsBtcUsd(tree.unrealized.supplyInLoss, name, color),
...("supplyInLossRelToCirculatingSupply" in tree.relative
? [
line({
metric: tree.relative.supplyInLossRelToCirculatingSupply,
name,
color,
unit: Unit.pctSupply,
}),
]
: []),
export function createGroupedSupplyInLossSeries(list, { relativeMetrics } = {}) {
return list.flatMap((cohort) => [
...satsBtcUsd(cohort.tree.unrealized.supplyInLoss, cohort.name, cohort.color),
...(relativeMetrics ? relativeMetrics(cohort) : []),
]);
}
/**
* Create supply section for grouped cohorts
* @template {readonly CohortObject[]} T
* @param {T} list
* @param {(metric: string) => string} title
* @param {Object} [options]
* @param {(cohort: T[number]) => AnyFetchedSeriesBlueprint[]} [options.supplyRelativeMetrics] - Generator for supply relative metrics
* @param {(cohort: T[number]) => AnyFetchedSeriesBlueprint[]} [options.profitRelativeMetrics] - Generator for supply in profit relative metrics
* @param {(cohort: T[number]) => AnyFetchedSeriesBlueprint[]} [options.lossRelativeMetrics] - Generator for supply in loss relative metrics
* @returns {PartialOptionsGroup}
*/
export function createGroupedSupplySection(list, title, { supplyRelativeMetrics, profitRelativeMetrics, lossRelativeMetrics } = {}) {
return {
name: "supply",
tree: [
{
name: "total",
title: title("Supply"),
bottom: createGroupedSupplyTotalSeries(list, { relativeMetrics: supplyRelativeMetrics }),
},
{
name: "in profit",
title: title("Supply In Profit"),
bottom: createGroupedSupplyInProfitSeries(list, { relativeMetrics: profitRelativeMetrics }),
},
{
name: "in loss",
title: title("Supply In Loss"),
bottom: createGroupedSupplyInLossSeries(list, { relativeMetrics: lossRelativeMetrics }),
},
],
};
}
// ============================================================================
// Circulating Supply Relative Metrics Generators
// ============================================================================
/**
* Create supply relative to circulating supply series for single cohort
* @param {PartialContext} ctx
* @param {CohortWithCirculatingSupplyRelative} cohort
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createSupplyRelativeToCirculatingSeries(ctx, cohort) {
return [
line({
metric: cohort.tree.relative.supplyRelToCirculatingSupply,
name: "Supply",
color: ctx.colors.default,
unit: Unit.pctSupply,
}),
];
}
/**
* Create supply in profit/loss relative to circulating supply series for single cohort
* @param {PartialContext} ctx
* @param {CohortWithCirculatingSupplyRelative} cohort
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createSupplyPnlRelativeToCirculatingSeries(ctx, cohort) {
return [
line({
metric: cohort.tree.relative.supplyInProfitRelToCirculatingSupply,
name: "In Profit",
color: ctx.colors.green,
unit: Unit.pctSupply,
}),
line({
metric: cohort.tree.relative.supplyInLossRelToCirculatingSupply,
name: "In Loss",
color: ctx.colors.red,
unit: Unit.pctSupply,
}),
];
}
/**
* Create supply relative to circulating supply metrics generator for grouped cohorts
* @param {CohortWithCirculatingSupplyRelative} cohort
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createGroupedSupplyRelativeMetrics(cohort) {
return [
line({
metric: cohort.tree.relative.supplyRelToCirculatingSupply,
name: cohort.name,
color: cohort.color,
unit: Unit.pctSupply,
}),
];
}
/**
* Create supply in profit relative to circulating supply metrics generator for grouped cohorts
* @param {CohortWithCirculatingSupplyRelative} cohort
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createGroupedSupplyInProfitRelativeMetrics(cohort) {
return [
line({
metric: cohort.tree.relative.supplyInProfitRelToCirculatingSupply,
name: cohort.name,
color: cohort.color,
unit: Unit.pctSupply,
}),
];
}
/**
* Create supply in loss relative to circulating supply metrics generator for grouped cohorts
* @param {CohortWithCirculatingSupplyRelative} cohort
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function createGroupedSupplyInLossRelativeMetrics(cohort) {
return [
line({
metric: cohort.tree.relative.supplyInLossRelToCirculatingSupply,
name: cohort.name,
color: cohort.color,
unit: Unit.pctSupply,
}),
];
}
/**
* Grouped supply relative generators object for cohorts with circulating supply relative
* @type {{ supplyRelativeMetrics: typeof createGroupedSupplyRelativeMetrics, profitRelativeMetrics: typeof createGroupedSupplyInProfitRelativeMetrics, lossRelativeMetrics: typeof createGroupedSupplyInLossRelativeMetrics }}
*/
export const groupedSupplyRelativeGenerators = {
supplyRelativeMetrics: createGroupedSupplyRelativeMetrics,
profitRelativeMetrics: createGroupedSupplyInProfitRelativeMetrics,
lossRelativeMetrics: createGroupedSupplyInLossRelativeMetrics,
};
/**
* Create single cohort supply relative options for cohorts with circulating supply relative
* @param {PartialContext} ctx
* @param {CohortWithCirculatingSupplyRelative} cohort
* @returns {{ supplyRelative: AnyFetchedSeriesBlueprint[], pnlRelative: AnyFetchedSeriesBlueprint[] }}
*/
export function createSingleSupplyRelativeOptions(ctx, cohort) {
return {
supplyRelative: createSupplyRelativeToCirculatingSeries(ctx, cohort),
pnlRelative: createSupplyPnlRelativeToCirculatingSeries(ctx, cohort),
};
}
/**
* Create UTXO count series
* @param {readonly CohortObject[]} list
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2,7 +2,7 @@
import { Unit } from "../../utils/units.js";
import { line } from "../series.js";
import { createRatioChart, createZScoresFolder } from "../shared.js";
import { createRatioChart, createZScoresFolder, formatCohortTitle } from "../shared.js";
import { periodIdToName } from "./utils.js";
/**
@@ -89,7 +89,7 @@ export function createPriceWithRatioOptions(
title,
top: [line({ metric: priceMetric, name: legend, color, unit: Unit.usd })],
},
createRatioChart(ctx, { title, price: priceMetric, ratio, color }),
createRatioChart(ctx, { title: formatCohortTitle(title), price: priceMetric, ratio, color }),
createZScoresFolder(ctx, {
title,
legend,
+92 -71
View File
@@ -47,83 +47,104 @@ export function createInvestingSection(ctx, { dca, lookback, returns }) {
const { colors } = ctx;
const dcaClasses = buildDcaClasses(colors, dca);
/**
* @param {string} id
* @param {ShortPeriodKey} key
*/
const createPeriodTree = (id, key) => {
const name = periodIdToName(id, true);
return {
name,
tree: [
{
name: "Cost basis",
title: `${name} Cost Basis`,
top: [
line({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green, unit: Unit.usd }),
line({ metric: lookback[key], name: "Lump sum", color: colors.orange, unit: Unit.usd }),
],
},
{
name: "Returns",
title: `${name} Returns`,
bottom: [
baseline({ metric: dca.periodReturns[key], name: "DCA", unit: Unit.percentage }),
baseline({ metric: returns.priceReturns[key], name: "Lump sum", color: [colors.cyan, colors.orange], unit: Unit.percentage }),
priceLine({ ctx, unit: Unit.percentage }),
],
},
{
name: "Stack",
title: `${name} Stack`,
bottom: [
...satsBtcUsd(dca.periodStack[key], "DCA", colors.green),
...satsBtcUsd(dca.periodLumpSumStack[key], "Lump sum", colors.orange),
],
},
],
};
};
/**
* @param {string} id
* @param {LongPeriodKey} key
*/
const createPeriodTreeWithCagr = (id, key) => {
const name = periodIdToName(id, true);
return {
name,
tree: [
{
name: "Cost basis",
title: `${name} Cost Basis`,
top: [
line({ metric: dca.periodAveragePrice[key], name: "DCA", color: colors.green, unit: Unit.usd }),
line({ metric: lookback[key], name: "Lump sum", color: colors.orange, unit: Unit.usd }),
],
},
{
name: "Returns",
title: `${name} Returns`,
bottom: [
baseline({ metric: dca.periodReturns[key], name: "DCA", unit: Unit.percentage }),
baseline({ metric: returns.priceReturns[key], name: "Lump sum", color: [colors.cyan, colors.orange], unit: Unit.percentage }),
line({ metric: dca.periodCagr[key], name: "DCA CAGR", color: colors.purple, unit: Unit.percentage, defaultActive: false }),
line({ metric: returns.cagr[key], name: "Lump sum CAGR", color: colors.indigo, unit: Unit.percentage, defaultActive: false }),
priceLine({ ctx, unit: Unit.percentage }),
],
},
{
name: "Stack",
title: `${name} Stack`,
bottom: [
...satsBtcUsd(dca.periodStack[key], "DCA", colors.green),
...satsBtcUsd(dca.periodLumpSumStack[key], "Lump sum", colors.orange),
],
},
],
};
};
return {
name: "Investing",
tree: [
// DCA vs Lump sum
{
name: "DCA vs Lump sum",
tree: /** @type {const} */ ([
["1w", "_1w"],
["1m", "_1m"],
["3m", "_3m"],
["6m", "_6m"],
["1y", "_1y"],
["2y", "_2y"],
["3y", "_3y"],
["4y", "_4y"],
["5y", "_5y"],
["6y", "_6y"],
["8y", "_8y"],
["10y", "_10y"],
]).map(([id, key]) => {
const name = periodIdToName(id, true);
const priceAgo = lookback[key];
const priceReturns = returns.priceReturns[key];
const dcaCostBasis = dca.periodAveragePrice[key];
const dcaReturns = dca.periodReturns[key];
const dcaStack = dca.periodStack[key];
const lumpSumStack = dca.periodLumpSumStack[key];
return {
name,
tree: [
{
name: "Cost basis",
title: `${name} Cost Basis`,
top: [
line({
metric: dcaCostBasis,
name: "DCA",
color: colors.green,
unit: Unit.usd,
}),
line({
metric: priceAgo,
name: "Lump sum",
color: colors.orange,
unit: Unit.usd,
}),
],
},
{
name: "Returns",
title: `${name} Returns`,
bottom: [
baseline({
metric: dcaReturns,
name: "DCA",
unit: Unit.percentage,
}),
baseline({
metric: priceReturns,
name: "Lump sum",
color: [colors.cyan, colors.orange],
unit: Unit.percentage,
}),
priceLine({ ctx, unit: Unit.percentage }),
],
},
{
name: "Stack",
title: `${name} Stack`,
bottom: [
...satsBtcUsd(dcaStack, "DCA", colors.green),
...satsBtcUsd(lumpSumStack, "Lump sum", colors.orange),
],
},
],
};
}),
tree: [
createPeriodTree("1w", "_1w"),
createPeriodTree("1m", "_1m"),
createPeriodTree("3m", "_3m"),
createPeriodTree("6m", "_6m"),
createPeriodTree("1y", "_1y"),
createPeriodTreeWithCagr("2y", "_2y"),
createPeriodTreeWithCagr("3y", "_3y"),
createPeriodTreeWithCagr("4y", "_4y"),
createPeriodTreeWithCagr("5y", "_5y"),
createPeriodTreeWithCagr("6y", "_6y"),
createPeriodTreeWithCagr("8y", "_8y"),
createPeriodTreeWithCagr("10y", "_10y"),
],
},
// DCA classes
+5 -6
View File
@@ -6,8 +6,7 @@ import {
createCohortFolderAll,
createCohortFolderFull,
createCohortFolderWithAdjusted,
createCohortFolderWithPercentiles,
createCohortFolderLongTerm,
createCohortFolderWithNupl,
createCohortFolderAgeRange,
createCohortFolderBasicWithMarketCap,
createCohortFolderBasicWithoutMarketCap,
@@ -99,19 +98,19 @@ export function createPartialOptions({ brk }) {
// All UTXOs - CohortAll (adjustedSopr + percentiles but no RelToMarketCap)
createCohortFolderAll(ctx, cohortAll),
// Terms (STH/LTH) - Short is Full, Long is LongTerm
// Terms (STH/LTH) - Short is Full, Long has nupl
{
name: "Terms",
tree: [
// Compare folder uses WithPercentiles (common capabilities)
createCohortFolderWithPercentiles(ctx, {
// Compare folder - both have nupl + percentiles
createCohortFolderWithNupl(ctx, {
name: "Compare",
title: "Term",
list: [termShort, termLong],
}),
// Individual cohorts with their specific capabilities
createCohortFolderFull(ctx, termShort),
createCohortFolderLongTerm(ctx, termLong),
createCohortFolderWithNupl(ctx, termLong),
],
},
+63 -463
View File
@@ -2,6 +2,34 @@
import { Unit } from "../utils/units.js";
// ============================================================================
// Shared percentile helper
// ============================================================================
/**
* Create percentile series (max/min/median/pct75/pct25/pct90/pct10) from any stats pattern
* Works with FullnessPattern, FeeRatePattern, AnyStatsPattern, DollarsPattern, etc.
* @param {Colors} colors
* @param {FullnessPattern<any> | FeeRatePattern<any> | AnyStatsPattern | DollarsPattern<any>} pattern
* @param {Unit} unit
* @param {string} title
* @param {{ type?: "Dots" }} [options]
* @returns {AnyFetchedSeriesBlueprint[]}
*/
function percentileSeries(colors, pattern, unit, title, { type } = {}) {
const { stat } = colors;
const base = { unit, defaultActive: false };
return [
{ type, metric: pattern.max, title: `${title} max`.trim(), color: stat.max, ...base },
{ type, metric: pattern.min, title: `${title} min`.trim(), color: stat.min, ...base },
{ type, metric: pattern.median, title: `${title} median`.trim(), color: stat.median, ...base },
{ type, metric: pattern.pct75, title: `${title} pct75`.trim(), color: stat.pct75, ...base },
{ type, metric: pattern.pct25, title: `${title} pct25`.trim(), color: stat.pct25, ...base },
{ type, metric: pattern.pct90, title: `${title} pct90`.trim(), color: stat.pct90, ...base },
{ type, metric: pattern.pct10, title: `${title} pct10`.trim(), color: stat.pct10, ...base },
];
}
/**
* Create a Line series
* @param {Object} args
@@ -180,158 +208,6 @@ export function histogram({
};
}
/**
* Create series from a BlockCountPattern ({ base, sum, cumulative })
* @param {Colors} colors
* @param {BlockCountPattern<any>} pattern
* @param {string} title
* @param {Color} [color]
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function fromBlockCount(colors, pattern, title, color) {
return [
{ metric: pattern.sum, title, color: color ?? colors.default },
{
metric: pattern.cumulative,
title: `${title} cumulative`,
color: colors.stat.cumulative,
defaultActive: false,
},
];
}
/**
* Create series from a FullnessPattern ({ base, sum, cumulative, average, min, max, percentiles })
* @param {Colors} colors
* @param {FullnessPattern<any>} pattern
* @param {string} title
* @param {Color} [color]
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function fromBitcoin(colors, pattern, title, color) {
const { stat } = colors;
return [
{ metric: pattern.base, title, color: color ?? colors.default },
{
metric: pattern.average,
title: `${title} avg`,
color: stat.avg,
defaultActive: false,
},
{
metric: pattern.max,
title: `${title} max`,
color: stat.max,
defaultActive: false,
},
{
metric: pattern.min,
title: `${title} min`,
color: stat.min,
defaultActive: false,
},
{
metric: pattern.median,
title: `${title} median`,
color: stat.median,
defaultActive: false,
},
{
metric: pattern.pct75,
title: `${title} pct75`,
color: stat.pct75,
defaultActive: false,
},
{
metric: pattern.pct25,
title: `${title} pct25`,
color: stat.pct25,
defaultActive: false,
},
{
metric: pattern.pct90,
title: `${title} pct90`,
color: stat.pct90,
defaultActive: false,
},
{
metric: pattern.pct10,
title: `${title} pct10`,
color: stat.pct10,
defaultActive: false,
},
];
}
/**
* Create series from a SizePattern ({ sum, cumulative, average, min, max, percentiles })
* @param {Colors} colors
* @param {AnyStatsPattern} pattern
* @param {string} title
* @param {Color} [color]
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function fromBlockSize(colors, pattern, title, color) {
const { stat } = colors;
return [
{ metric: pattern.sum, title, color: color ?? colors.default },
{
metric: pattern.average,
title: `${title} avg`,
color: stat.avg,
defaultActive: false,
},
{
metric: pattern.cumulative,
title: `${title} cumulative`,
color: stat.cumulative,
defaultActive: false,
},
{
metric: pattern.max,
title: `${title} max`,
color: stat.max,
defaultActive: false,
},
{
metric: pattern.min,
title: `${title} min`,
color: stat.min,
defaultActive: false,
},
{
metric: pattern.median,
title: `${title} median`,
color: stat.median,
defaultActive: false,
},
{
metric: pattern.pct75,
title: `${title} pct75`,
color: stat.pct75,
defaultActive: false,
},
{
metric: pattern.pct25,
title: `${title} pct25`,
color: stat.pct25,
defaultActive: false,
},
{
metric: pattern.pct90,
title: `${title} pct90`,
color: stat.pct90,
defaultActive: false,
},
{
metric: pattern.pct10,
title: `${title} pct10`,
color: stat.pct10,
defaultActive: false,
},
];
}
/**
* Create series from a SizePattern ({ average, sum, cumulative, min, max, percentiles })
* @param {Colors} colors
@@ -344,69 +220,9 @@ export function fromSizePattern(colors, pattern, unit, title = "") {
const { stat } = colors;
return [
{ metric: pattern.average, title: `${title} avg`.trim(), unit },
{
metric: pattern.sum,
title: `${title} sum`.trim(),
color: stat.sum,
unit,
defaultActive: false,
},
{
metric: pattern.cumulative,
title: `${title} cumulative`.trim(),
color: stat.cumulative,
unit,
defaultActive: false,
},
{
metric: pattern.max,
title: `${title} max`.trim(),
color: stat.max,
unit,
defaultActive: false,
},
{
metric: pattern.min,
title: `${title} min`.trim(),
color: stat.min,
unit,
defaultActive: false,
},
{
metric: pattern.median,
title: `${title} median`.trim(),
color: stat.median,
unit,
defaultActive: false,
},
{
metric: pattern.pct75,
title: `${title} pct75`.trim(),
color: stat.pct75,
unit,
defaultActive: false,
},
{
metric: pattern.pct25,
title: `${title} pct25`.trim(),
color: stat.pct25,
unit,
defaultActive: false,
},
{
metric: pattern.pct90,
title: `${title} pct90`.trim(),
color: stat.pct90,
unit,
defaultActive: false,
},
{
metric: pattern.pct10,
title: `${title} pct10`.trim(),
color: stat.pct10,
unit,
defaultActive: false,
},
{ metric: pattern.sum, title: `${title} sum`.trim(), color: stat.sum, unit, defaultActive: false },
{ metric: pattern.cumulative, title: `${title} cumulative`.trim(), color: stat.cumulative, unit, defaultActive: false },
...percentileSeries(colors, pattern, unit, title),
];
}
@@ -422,61 +238,8 @@ export function fromFullnessPattern(colors, pattern, unit, title = "") {
const { stat } = colors;
return [
{ metric: pattern.base, title: title || "base", unit },
{
metric: pattern.average,
title: `${title} avg`.trim(),
color: stat.avg,
unit,
},
{
metric: pattern.max,
title: `${title} max`.trim(),
color: stat.max,
unit,
defaultActive: false,
},
{
metric: pattern.min,
title: `${title} min`.trim(),
color: stat.min,
unit,
defaultActive: false,
},
{
metric: pattern.median,
title: `${title} median`.trim(),
color: stat.median,
unit,
defaultActive: false,
},
{
metric: pattern.pct75,
title: `${title} pct75`.trim(),
color: stat.pct75,
unit,
defaultActive: false,
},
{
metric: pattern.pct25,
title: `${title} pct25`.trim(),
color: stat.pct25,
unit,
defaultActive: false,
},
{
metric: pattern.pct90,
title: `${title} pct90`.trim(),
color: stat.pct90,
unit,
defaultActive: false,
},
{
metric: pattern.pct10,
title: `${title} pct10`.trim(),
color: stat.pct10,
unit,
defaultActive: false,
},
{ metric: pattern.average, title: `${title} avg`.trim(), color: stat.avg, unit },
...percentileSeries(colors, pattern, unit, title),
];
}
@@ -492,75 +255,10 @@ export function fromDollarsPattern(colors, pattern, unit, title = "") {
const { stat } = colors;
return [
{ metric: pattern.base, title: title || "base", unit },
{
metric: pattern.sum,
title: `${title} sum`.trim(),
color: stat.sum,
unit,
},
{
metric: pattern.cumulative,
title: `${title} cumulative`.trim(),
color: stat.cumulative,
unit,
defaultActive: false,
},
{
metric: pattern.average,
title: `${title} avg`.trim(),
color: stat.avg,
unit,
defaultActive: false,
},
{
metric: pattern.max,
title: `${title} max`.trim(),
color: stat.max,
unit,
defaultActive: false,
},
{
metric: pattern.min,
title: `${title} min`.trim(),
color: stat.min,
unit,
defaultActive: false,
},
{
metric: pattern.median,
title: `${title} median`.trim(),
color: stat.median,
unit,
defaultActive: false,
},
{
metric: pattern.pct75,
title: `${title} pct75`.trim(),
color: stat.pct75,
unit,
defaultActive: false,
},
{
metric: pattern.pct25,
title: `${title} pct25`.trim(),
color: stat.pct25,
unit,
defaultActive: false,
},
{
metric: pattern.pct90,
title: `${title} pct90`.trim(),
color: stat.pct90,
unit,
defaultActive: false,
},
{
metric: pattern.pct10,
title: `${title} pct10`.trim(),
color: stat.pct10,
unit,
defaultActive: false,
},
{ metric: pattern.sum, title: `${title} sum`.trim(), color: stat.sum, unit },
{ metric: pattern.cumulative, title: `${title} cumulative`.trim(), color: stat.cumulative, unit, defaultActive: false },
{ metric: pattern.average, title: `${title} avg`.trim(), color: stat.avg, unit, defaultActive: false },
...percentileSeries(colors, pattern, unit, title),
];
}
@@ -573,85 +271,41 @@ export function fromDollarsPattern(colors, pattern, unit, title = "") {
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function fromFeeRatePattern(colors, pattern, unit, title = "") {
const { stat } = colors;
return [
{
type: "Dots",
metric: pattern.average,
title: `${title} avg`.trim(),
unit,
},
{
type: "Dots",
metric: pattern.max,
title: `${title} max`.trim(),
color: stat.max,
unit,
defaultActive: false,
},
{
type: "Dots",
metric: pattern.min,
title: `${title} min`.trim(),
color: stat.min,
unit,
defaultActive: false,
},
{
type: "Dots",
metric: pattern.median,
title: `${title} median`.trim(),
color: stat.median,
unit,
defaultActive: false,
},
{
type: "Dots",
metric: pattern.pct75,
title: `${title} pct75`.trim(),
color: stat.pct75,
unit,
defaultActive: false,
},
{
type: "Dots",
metric: pattern.pct25,
title: `${title} pct25`.trim(),
color: stat.pct25,
unit,
defaultActive: false,
},
{
type: "Dots",
metric: pattern.pct90,
title: `${title} pct90`.trim(),
color: stat.pct90,
unit,
defaultActive: false,
},
{
type: "Dots",
metric: pattern.pct10,
title: `${title} pct10`.trim(),
color: stat.pct10,
unit,
defaultActive: false,
},
{ type: "Dots", metric: pattern.average, title: `${title} avg`.trim(), unit },
...percentileSeries(colors, pattern, unit, title, { type: "Dots" }),
];
}
/**
* Create series from a CoinbasePattern ({ sats, bitcoin, dollars } each as FullnessPattern)
* Create series from a pattern with sum and cumulative (fullness stats + sum + cumulative)
* @param {Colors} colors
* @param {FullnessPatternWithSumCumulative} pattern
* @param {Unit} unit
* @param {string} [title]
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function fromFullnessPatternWithSumCumulative(colors, pattern, unit, title = "") {
const { stat } = colors;
return [
...fromFullnessPattern(colors, pattern, unit, title),
{ metric: pattern.sum, title: `${title} sum`.trim(), color: stat.sum, unit },
{ metric: pattern.cumulative, title: `${title} cumulative`.trim(), color: stat.cumulative, unit, defaultActive: false },
];
}
/**
* Create series from a CoinbasePattern ({ sats, bitcoin, dollars } each with stats + sum + cumulative)
* @param {Colors} colors
* @param {CoinbasePattern} pattern
* @param {string} [title]
* @returns {AnyFetchedSeriesBlueprint[]}
*/
export function fromCoinbasePattern(colors, pattern, title) {
export function fromCoinbasePattern(colors, pattern, title = "") {
return [
...fromFullnessPattern(colors, pattern.bitcoin, Unit.btc, title),
...fromFullnessPattern(colors, pattern.sats, Unit.sats, title),
...fromFullnessPattern(colors, pattern.dollars, Unit.usd, title),
...fromFullnessPatternWithSumCumulative(colors, pattern.bitcoin, Unit.btc, title),
...fromFullnessPatternWithSumCumulative(colors, pattern.sats, Unit.sats, title),
...fromFullnessPatternWithSumCumulative(colors, pattern.dollars, Unit.usd, title),
];
}
@@ -797,62 +451,8 @@ export function fromIntervalPattern(colors, pattern, unit, title = "", color) {
const { stat } = colors;
return [
{ metric: pattern.base, title: title ?? "base", color, unit },
{
metric: pattern.average,
title: `${title} avg`.trim(),
color: stat.avg,
unit,
defaultActive: false,
},
{
metric: pattern.max,
title: `${title} max`.trim(),
color: stat.max,
unit,
defaultActive: false,
},
{
metric: pattern.min,
title: `${title} min`.trim(),
color: stat.min,
unit,
defaultActive: false,
},
{
metric: pattern.median,
title: `${title} median`.trim(),
color: stat.median,
unit,
defaultActive: false,
},
{
metric: pattern.pct75,
title: `${title} pct75`.trim(),
color: stat.pct75,
unit,
defaultActive: false,
},
{
metric: pattern.pct25,
title: `${title} pct25`.trim(),
color: stat.pct25,
unit,
defaultActive: false,
},
{
metric: pattern.pct90,
title: `${title} pct90`.trim(),
color: stat.pct90,
unit,
defaultActive: false,
},
{
metric: pattern.pct10,
title: `${title} pct10`.trim(),
color: stat.pct10,
unit,
defaultActive: false,
},
{ metric: pattern.average, title: `${title} avg`.trim(), color: stat.avg, unit, defaultActive: false },
...percentileSeries(colors, pattern, unit, title),
];
}
+10 -2
View File
@@ -4,6 +4,14 @@ import { Unit } from "../utils/units.js";
import { line, baseline } from "./series.js";
import { priceLine, priceLines } from "./constants.js";
/**
* Create a title formatter for chart titles
* @param {string} [cohortTitle]
* @returns {(metric: string) => string}
*/
export const formatCohortTitle = (cohortTitle) =>
(metric) => cohortTitle ? `${metric}: ${cohortTitle}` : metric;
/**
* Create sats/btc/usd line series from a pattern with .sats/.bitcoin/.dollars
* @param {{ sats: AnyMetricPattern, bitcoin: AnyMetricPattern, dollars: AnyMetricPattern }} pattern
@@ -144,7 +152,7 @@ export function ratioSmas(colors, ratio) {
* Create ratio chart from ActivePriceRatioPattern
* @param {PartialContext} ctx
* @param {Object} args
* @param {string} args.title
* @param {(metric: string) => string} args.title
* @param {AnyMetricPattern} args.price - The price metric to show in top pane
* @param {ActivePriceRatioPattern} args.ratio - The ratio pattern
* @param {Color} args.color
@@ -156,7 +164,7 @@ export function createRatioChart(ctx, { title, price, ratio, color, name }) {
return {
name: name ?? "ratio",
title: name ? (title ? `${name} - ${title}` : name) : `${title} Ratio`,
title: title(name ?? "Ratio"),
top: [
line({ metric: price, name: "price", color, unit: Unit.usd }),
...percentileUsdMap(colors, ratio).map(({ name, prop, color }) =>
+5
View File
@@ -289,6 +289,11 @@
* @property {readonly AddressCohortObject[]} list
*
* @typedef {UtxoCohortGroupObject | AddressCohortGroupObject} CohortGroupObject
*
* @typedef {Object} CohortGroupAddress
* @property {string} name
* @property {string} title
* @property {readonly CohortAddress[]} list
*/
// Re-export for type consumers
+18 -1
View File
@@ -1,8 +1,19 @@
import { localhost } from "../utils/env.js";
import { serdeChartableIndex } from "../utils/serde.js";
/** @type {Map<AnyMetricPattern, string[]> | null} */
export const unused = localhost ? new Map() : null;
/**
* Check if a metric pattern has at least one chartable index
* @param {AnyMetricPattern} node
* @returns {boolean}
*/
function hasChartableIndex(node) {
const indexes = node.indexes();
return indexes.some((idx) => serdeChartableIndex.serialize(idx) !== null);
}
/**
* @param {TreeNode | null | undefined} node
* @param {Map<AnyMetricPattern, string[]>} map
@@ -10,7 +21,9 @@ export const unused = localhost ? new Map() : null;
*/
function walk(node, map, path) {
if (node && "by" in node) {
map.set(/** @type {AnyMetricPattern} */ (node), path);
const metricNode = /** @type {AnyMetricPattern} */ (node);
if (!hasChartableIndex(metricNode)) return;
map.set(metricNode, path);
} else if (node && typeof node === "object") {
for (const [key, value] of Object.entries(node)) {
const kn = key.toLowerCase();
@@ -19,12 +32,16 @@ function walk(node, map, path) {
kn === "time" ||
kn === "height" ||
kn === "constants" ||
kn === "blockhash" ||
kn === "oracle" ||
kn === "split" ||
kn === "ohlc" ||
kn === "outpoint" ||
kn === "positions" ||
kn === "outputtype" ||
kn === "heighttopool" ||
kn === "txid" ||
kn.endsWith("state") ||
kn.endsWith("index") ||
kn.endsWith("indexes") ||
kn.endsWith("bytes") ||
+27 -1
View File
@@ -14,7 +14,7 @@
*
* @import { WebSockets } from "./utils/ws.js"
*
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType, AnyFetchedSeriesBlueprint, TableOption, ExplorerOption, UrlOption, PartialOptionsGroup, OptionsGroup, PartialOptionsTree, UtxoCohortObject, AddressCohortObject, CohortObject, CohortGroupObject, FetchedLineSeriesBlueprint, FetchedBaselineSeriesBlueprint, FetchedHistogramSeriesBlueprint, PartialContext, PatternAll, PatternFull, PatternWithAdjusted, PatternWithPercentiles, PatternBasic, PatternBasicWithMarketCap, PatternBasicWithoutMarketCap, CohortAll, CohortFull, CohortWithAdjusted, CohortWithPercentiles, CohortBasic, CohortBasicWithMarketCap, CohortBasicWithoutMarketCap, CohortAddress, CohortLongTerm, CohortAgeRange, CohortGroupFull, CohortGroupWithAdjusted, CohortGroupWithPercentiles, CohortGroupLongTerm, CohortGroupAgeRange, CohortGroupBasic, CohortGroupBasicWithMarketCap, CohortGroupBasicWithoutMarketCap, UtxoCohortGroupObject, AddressCohortGroupObject, FetchedDotsSeriesBlueprint, FetchedCandlestickSeriesBlueprint } from "./options/partial.js"
* @import { Option, PartialChartOption, ChartOption, AnyPartialOption, ProcessedOptionAddons, OptionsTree, SimulationOption, AnySeriesBlueprint, SeriesType, AnyFetchedSeriesBlueprint, TableOption, ExplorerOption, UrlOption, PartialOptionsGroup, OptionsGroup, PartialOptionsTree, UtxoCohortObject, AddressCohortObject, CohortObject, CohortGroupObject, FetchedLineSeriesBlueprint, FetchedBaselineSeriesBlueprint, FetchedHistogramSeriesBlueprint, PartialContext, PatternAll, PatternFull, PatternWithAdjusted, PatternWithPercentiles, PatternBasic, PatternBasicWithMarketCap, PatternBasicWithoutMarketCap, CohortAll, CohortFull, CohortWithAdjusted, CohortWithPercentiles, CohortBasic, CohortBasicWithMarketCap, CohortBasicWithoutMarketCap, CohortAddress, CohortLongTerm, CohortAgeRange, CohortGroupFull, CohortGroupWithAdjusted, CohortGroupWithPercentiles, CohortGroupLongTerm, CohortGroupAgeRange, CohortGroupBasic, CohortGroupBasicWithMarketCap, CohortGroupBasicWithoutMarketCap, CohortGroupAddress, UtxoCohortGroupObject, AddressCohortGroupObject, FetchedDotsSeriesBlueprint, FetchedCandlestickSeriesBlueprint } from "./options/partial.js"
*
*
* @import { UnitObject as Unit } from "./utils/units.js"
@@ -111,6 +111,12 @@
* @typedef {Brk.MetricsTree_Market} Market
* @typedef {Brk.MetricsTree_Market_MovingAverage} MarketMovingAverage
* @typedef {Brk.MetricsTree_Market_Dca} MarketDca
* @typedef {Brk.PeriodCagrPattern} PeriodCagrPattern
* @typedef {Brk.BitcoinPattern | Brk.DollarsPattern<any>} FullnessPatternWithSumCumulative
*
* DCA period keys
* @typedef {"_1w" | "_1m" | "_3m" | "_6m" | "_1y"} ShortPeriodKey
* @typedef {keyof PeriodCagrPattern} LongPeriodKey
*
* Pattern unions by cohort type
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} UtxoCohortPattern
@@ -123,6 +129,9 @@
* @typedef {OwnRelativePattern | FullRelativePattern | AllRelativePattern} RelativeWithOwnPnl
* @typedef {GlobalRelativePattern | FullRelativePattern} RelativeWithNupl
*
* Realized pattern capability types (RealizedPattern2 and RealizedPattern3 have extra metrics)
* @typedef {Brk.RealizedPattern2 | Brk.RealizedPattern3} RealizedWithExtras
*
* Capability-based pattern groupings (patterns that have specific properties)
* @typedef {AllUtxoPattern | AgeRangePattern | UtxoAmountPattern} PatternWithRealizedPrice
* @typedef {AllUtxoPattern} PatternWithFullRealized
@@ -139,6 +148,23 @@
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithActivity }} CohortWithActivity
* @typedef {{ name: string, title: string, color: Color, tree: PatternWithCostBasisPercentiles }} CohortWithCostBasisPercentiles
*
* Cohorts with nupl + percentiles (CohortFull and CohortLongTerm both have nupl and percentiles)
* @typedef {CohortFull | CohortLongTerm} CohortWithNuplPercentiles
* @typedef {{ name: string, title: string, list: readonly CohortWithNuplPercentiles[] }} CohortGroupWithNuplPercentiles
*
* Cohorts with RealizedWithExtras (realizedCapRelToOwnMarketCap + realizedProfitToLossRatio)
* @typedef {CohortAll | CohortFull | CohortWithPercentiles} CohortWithRealizedExtras
*
* Cohorts with circulating supply relative metrics (supplyRelToCirculatingSupply etc.)
* These have GlobalRelativePattern or FullRelativePattern (same as RelativeWithMarketCap/RelativeWithNupl)
* @typedef {CohortFull | CohortLongTerm | CohortWithAdjusted | CohortBasicWithMarketCap} UtxoCohortWithCirculatingSupplyRelative
*
* Address cohorts with circulating supply relative metrics (all address amount cohorts have these)
* @typedef {AddressCohortObject} AddressCohortWithCirculatingSupplyRelative
*
* All cohorts with circulating supply relative metrics
* @typedef {UtxoCohortWithCirculatingSupplyRelative | AddressCohortWithCirculatingSupplyRelative} CohortWithCirculatingSupplyRelative
*
* Generic tree node type for walking
* @typedef {AnyMetricPattern | Record<string, unknown>} TreeNode
*
+4 -19
View File
@@ -1,29 +1,14 @@
@font-face {
font-family: "Geist Mono";
src: url("/assets/fonts/GeistMono[wght]-v1_5.woff2") format("woff2");
font-style: normal;
font-weight: 100 900;
font-display: block;
}
@font-face {
font-family: "Geist Mono";
src: url("/assets/fonts/GeistMono-Italic[wght]-v1_5.woff2") format("woff2");
font-style: italic;
font-weight: 100 900;
font-display: block;
}
@font-face {
font-family: Lilex;
src: url("/assets/fonts/Lilex[wght].woff2") format("woff2");
src: url("/assets/fonts/Lilex[wght]-v2_620.woff2") format("woff2");
font-style: normal;
font-weight: 100 900;
font-weight: 100 700;
font-display: block;
}
@font-face {
font-family: Lilex;
src: url("/assets/fonts/Lilex-Italic[wght].woff2") format("woff2");
src: url("/assets/fonts/Lilex-Italic[wght]-v2_620.woff2") format("woff2");
font-style: italic;
font-weight: 100 900;
font-weight: 100 700;
font-display: block;
}
+1 -2
View File
@@ -15,9 +15,8 @@ html,
-webkit-text-size-adjust: 100%;
tab-size: 4;
font-family:
"Geist Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
"Lilex", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
"Liberation Mono", "Courier New", monospace;
font-feature-settings: "ss03";
-webkit-tap-highlight-color: transparent;
}