mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-08 14:11:56 -07:00
bindgen: snapshot
This commit is contained in:
@@ -8,7 +8,10 @@ use std::collections::BTreeMap;
|
||||
|
||||
use brk_types::TreeNode;
|
||||
|
||||
use super::{find_common_prefix, find_common_suffix, get_node_fields, normalize_prefix};
|
||||
use super::{
|
||||
find_common_prefix, find_common_suffix, get_node_fields, get_shortest_leaf_name,
|
||||
normalize_prefix,
|
||||
};
|
||||
use crate::{PatternBaseResult, PatternField, PatternMode, StructuralPattern, build_child_path};
|
||||
|
||||
/// Result of analyzing a single pattern instance.
|
||||
@@ -91,7 +94,47 @@ fn collect_instance_analyses(
|
||||
}
|
||||
|
||||
// Analyze this instance
|
||||
let analysis = analyze_instance(&child_bases);
|
||||
let mut analysis = analyze_instance(&child_bases);
|
||||
|
||||
// When some field_parts are empty (children returned the same base),
|
||||
// replace empty parts with discriminators derived from shortest leaf names.
|
||||
let has_empty = analysis.field_parts.values().any(|v| v.is_empty());
|
||||
let has_nonempty = analysis.field_parts.values().any(|v| !v.is_empty());
|
||||
if has_empty && has_nonempty {
|
||||
// Mixed case: some fields have parts, some don't.
|
||||
// Use shortest leaf to derive discriminators for empty fields.
|
||||
let prefix = format!("{}_", analysis.base);
|
||||
for (field_name, child_node) in children {
|
||||
if let Some(part) = analysis.field_parts.get(field_name)
|
||||
&& part.is_empty()
|
||||
&& let Some(leaf) = get_shortest_leaf_name(child_node)
|
||||
&& let Some(suffix) = leaf.strip_prefix(&prefix)
|
||||
&& !suffix.is_empty()
|
||||
// Only use if the suffix starts with the field key,
|
||||
// avoiding internal sub-field names like "0sd" from a Price child
|
||||
&& suffix.starts_with(field_name.trim_start_matches('_'))
|
||||
{
|
||||
analysis
|
||||
.field_parts
|
||||
.insert(field_name.clone(), suffix.to_string());
|
||||
}
|
||||
}
|
||||
} else if has_empty && analysis.field_parts.len() > 1 {
|
||||
// All-empty case: all children returned the same base.
|
||||
// Re-analyze using shortest leaf names which may differentiate.
|
||||
let mut leaf_bases: BTreeMap<String, String> = BTreeMap::new();
|
||||
for (field_name, child_node) in children {
|
||||
if let Some(leaf) = get_shortest_leaf_name(child_node) {
|
||||
leaf_bases.insert(field_name.clone(), leaf);
|
||||
}
|
||||
}
|
||||
if leaf_bases.len() == child_bases.len() {
|
||||
let leaf_analysis = analyze_instance(&leaf_bases);
|
||||
if !leaf_analysis.field_parts.values().all(|v| v.is_empty()) {
|
||||
analysis.field_parts = leaf_analysis.field_parts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store the base result for this node
|
||||
// Note: has_outlier is false because we use recursive base computation
|
||||
@@ -121,6 +164,126 @@ fn collect_instance_analyses(
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to detect a template pattern when instances have different field_parts.
|
||||
///
|
||||
/// Supports two cases:
|
||||
/// 1. **Embedded discriminator**: a substring varies per instance within field_parts.
|
||||
/// E.g., `ratio_pct99_bps` vs `ratio_pct1_bps` → template `ratio_{disc}_bps`
|
||||
/// 2. **Suffix discriminator**: a common suffix is appended to all field_parts.
|
||||
/// E.g., `ratio_sd` vs `ratio_sd_4y` → template `ratio_sd{disc}`
|
||||
fn try_detect_template(
|
||||
majority: &[&InstanceAnalysis],
|
||||
fields: &[PatternField],
|
||||
) -> Option<PatternMode> {
|
||||
if majority.len() < 2 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Strategy 1: Find an embedded discriminator (shortest non-empty field_part
|
||||
// that differs between instances and appears as substring in other parts)
|
||||
if let Some(mode) = try_embedded_disc(majority, fields) {
|
||||
return Some(mode);
|
||||
}
|
||||
|
||||
// Strategy 2: Find a common suffix difference across ALL field_parts
|
||||
try_suffix_disc(majority, fields)
|
||||
}
|
||||
|
||||
/// Strategy 1: embedded discriminator (e.g., pct99 inside ratio_pct99_bps)
|
||||
fn try_embedded_disc(
|
||||
majority: &[&InstanceAnalysis],
|
||||
fields: &[PatternField],
|
||||
) -> Option<PatternMode> {
|
||||
let first = &majority[0];
|
||||
let second = &majority[1];
|
||||
|
||||
// Find the discriminator: shortest non-empty field_part that differs
|
||||
let disc_field = fields
|
||||
.iter()
|
||||
.filter_map(|f| first.field_parts.get(&f.name).map(|v| (&f.name, v)))
|
||||
.filter(|(_, v)| !v.is_empty())
|
||||
.min_by_key(|(_, v)| v.len())?;
|
||||
|
||||
let disc_first = disc_field.1;
|
||||
let disc_second = second.field_parts.get(disc_field.0)?;
|
||||
|
||||
if disc_first == disc_second || disc_first.is_empty() || disc_second.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Build templates by replacing the discriminator with {disc}
|
||||
let mut templates = BTreeMap::new();
|
||||
for field in fields {
|
||||
let part = first.field_parts.get(&field.name)?;
|
||||
let template = part.replacen(disc_first, "{disc}", 1);
|
||||
templates.insert(field.name.clone(), template);
|
||||
}
|
||||
|
||||
// Verify ALL instances match
|
||||
for analysis in majority {
|
||||
let inst_disc = analysis.field_parts.get(disc_field.0)?;
|
||||
for field in fields {
|
||||
let part = analysis.field_parts.get(&field.name)?;
|
||||
let expected = templates.get(&field.name)?.replace("{disc}", inst_disc);
|
||||
if part != &expected {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(PatternMode::Templated { templates })
|
||||
}
|
||||
|
||||
/// Strategy 2: suffix discriminator (e.g., all field_parts differ by `_4y` suffix)
|
||||
fn try_suffix_disc(
|
||||
majority: &[&InstanceAnalysis],
|
||||
fields: &[PatternField],
|
||||
) -> Option<PatternMode> {
|
||||
let first = &majority[0];
|
||||
|
||||
// For each other instance, check if ALL field_parts differ from the first
|
||||
// by the same suffix. Use the first field to detect the suffix.
|
||||
let ref_field = &fields[0].name;
|
||||
let ref_first = first.field_parts.get(ref_field)?;
|
||||
|
||||
// Build templates from the first instance
|
||||
// Non-empty parts get {disc} appended; empty parts (identity) stay empty
|
||||
let mut templates = BTreeMap::new();
|
||||
for field in fields {
|
||||
let part = first.field_parts.get(&field.name)?;
|
||||
if part.is_empty() {
|
||||
templates.insert(field.name.clone(), String::new());
|
||||
} else {
|
||||
templates.insert(field.name.clone(), format!("{part}{{disc}}"));
|
||||
}
|
||||
}
|
||||
|
||||
// Verify ALL other instances: non-empty parts differ by the same suffix
|
||||
for analysis in &majority[1..] {
|
||||
let ref_other = analysis.field_parts.get(ref_field)?;
|
||||
let suffix = ref_other.strip_prefix(ref_first)?;
|
||||
|
||||
for field in fields {
|
||||
let first_part = first.field_parts.get(&field.name)?;
|
||||
let other_part = analysis.field_parts.get(&field.name)?;
|
||||
|
||||
if first_part.is_empty() {
|
||||
// Identity field — must stay empty in all instances
|
||||
if !other_part.is_empty() {
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
let expected = format!("{first_part}{suffix}");
|
||||
if other_part != &expected {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(PatternMode::Templated { templates })
|
||||
}
|
||||
|
||||
/// Analyze a single pattern instance from its child bases.
|
||||
fn analyze_instance(child_bases: &BTreeMap<String, String>) -> InstanceAnalysis {
|
||||
let bases: Vec<&str> = child_bases.values().map(|s| s.as_str()).collect();
|
||||
@@ -144,6 +307,19 @@ fn analyze_instance(child_bases: &BTreeMap<String, String>) -> InstanceAnalysis
|
||||
field_parts.insert(field_name.clone(), relative);
|
||||
}
|
||||
|
||||
// If all field_parts are empty (all children returned the same base),
|
||||
// use the field keys as suffix discriminators. This handles patterns like
|
||||
// period windows (all/_4y/_2y/_1y) where children differ by a suffix
|
||||
// that corresponds to the tree key.
|
||||
if field_parts.len() > 1 && field_parts.values().all(|v| v.is_empty()) {
|
||||
// Can't differentiate — this pattern is non-parameterizable
|
||||
return InstanceAnalysis {
|
||||
base,
|
||||
field_parts,
|
||||
is_suffix_mode: true,
|
||||
};
|
||||
}
|
||||
|
||||
return InstanceAnalysis {
|
||||
base,
|
||||
field_parts,
|
||||
@@ -188,64 +364,56 @@ fn analyze_instance(child_bases: &BTreeMap<String, String>) -> InstanceAnalysis
|
||||
}
|
||||
|
||||
/// Determine the consistent mode for a pattern from all its instances.
|
||||
/// Uses majority voting: if most instances agree on mode and field_parts,
|
||||
/// use those. Minority instances will be inlined at usage sites.
|
||||
/// Picks the majority mode (suffix vs prefix), then requires all instances
|
||||
/// in that mode to agree on field_parts. Minority-mode instances get inlined.
|
||||
fn determine_pattern_mode(
|
||||
analyses: &[InstanceAnalysis],
|
||||
fields: &[PatternField],
|
||||
) -> Option<PatternMode> {
|
||||
if analyses.is_empty() {
|
||||
return None;
|
||||
}
|
||||
analyses.first()?;
|
||||
|
||||
// Group instances by (mode, field_parts) signature
|
||||
let suffix_instances: Vec<_> = analyses.iter().filter(|a| a.is_suffix_mode).collect();
|
||||
let prefix_instances: Vec<_> = analyses.iter().filter(|a| !a.is_suffix_mode).collect();
|
||||
// Pick the majority mode
|
||||
let suffix_count = analyses.iter().filter(|a| a.is_suffix_mode).count();
|
||||
let is_suffix = suffix_count * 2 >= analyses.len();
|
||||
|
||||
// Pick the majority mode group
|
||||
let (majority_instances, is_suffix) = if suffix_instances.len() >= prefix_instances.len() {
|
||||
(suffix_instances, true)
|
||||
} else {
|
||||
(prefix_instances, false)
|
||||
};
|
||||
|
||||
if majority_instances.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Find the most common field_parts within the majority group
|
||||
// Convert to sorted Vec for comparison since BTreeMap isn't hashable
|
||||
let mut parts_counts: BTreeMap<Vec<(String, String)>, usize> = BTreeMap::new();
|
||||
for analysis in &majority_instances {
|
||||
let mut sorted: Vec<_> = analysis
|
||||
.field_parts
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone()))
|
||||
.collect();
|
||||
sorted.sort();
|
||||
*parts_counts.entry(sorted).or_insert(0) += 1;
|
||||
}
|
||||
|
||||
let (best_parts_vec, _count) = parts_counts.into_iter().max_by_key(|(_, count)| *count)?;
|
||||
let best_parts: BTreeMap<String, String> = best_parts_vec.into_iter().collect();
|
||||
// All instances of the majority mode must agree on field_parts
|
||||
let majority: Vec<_> = analyses
|
||||
.iter()
|
||||
.filter(|a| a.is_suffix_mode == is_suffix)
|
||||
.collect();
|
||||
let first_majority = majority.first()?;
|
||||
|
||||
// Verify all required fields have parts
|
||||
for field in fields {
|
||||
if !best_parts.contains_key(&field.name) {
|
||||
if !first_majority.field_parts.contains_key(&field.name) {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
let field_parts = best_parts;
|
||||
if majority
|
||||
.iter()
|
||||
.all(|a| a.field_parts == first_majority.field_parts)
|
||||
{
|
||||
let field_parts = first_majority.field_parts.clone();
|
||||
|
||||
return if is_suffix {
|
||||
Some(PatternMode::Suffix {
|
||||
relatives: field_parts,
|
||||
})
|
||||
} else {
|
||||
Some(PatternMode::Prefix {
|
||||
prefixes: field_parts,
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
// Instances disagree on field_parts. Try to detect a template pattern:
|
||||
// if each field's value varies by exactly one substring that's different
|
||||
// per instance, we can use a Templated mode with {disc} placeholder.
|
||||
if is_suffix {
|
||||
Some(PatternMode::Suffix {
|
||||
relatives: field_parts,
|
||||
})
|
||||
try_detect_template(&majority, fields)
|
||||
} else {
|
||||
Some(PatternMode::Prefix {
|
||||
prefixes: field_parts,
|
||||
})
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,9 +570,8 @@ mod tests {
|
||||
assert_eq!(relatives.get("min"), Some(&"min".to_string()));
|
||||
assert_eq!(relatives.get("percentiles"), Some(&"".to_string()));
|
||||
}
|
||||
PatternMode::Prefix { .. } => {
|
||||
panic!("Expected suffix mode, got prefix mode");
|
||||
}
|
||||
PatternMode::Prefix { .. } => panic!("Expected suffix mode, got prefix mode"),
|
||||
PatternMode::Templated { .. } => panic!("Expected suffix mode, got templated mode"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,9 +627,8 @@ mod tests {
|
||||
assert_eq!(relatives.get("max"), Some(&"max".to_string()));
|
||||
assert_eq!(relatives.get("min"), Some(&"min".to_string()));
|
||||
}
|
||||
PatternMode::Prefix { .. } => {
|
||||
panic!("Expected suffix mode");
|
||||
}
|
||||
PatternMode::Prefix { .. } => panic!("Expected suffix mode"),
|
||||
PatternMode::Templated { .. } => panic!("Expected suffix mode, got templated"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use super::{find_common_prefix, find_common_suffix, normalize_prefix};
|
||||
///
|
||||
/// This is useful for pattern base analysis where we want the "base" case
|
||||
/// (e.g., the leaf without suffix like `_btc` or `_usd`).
|
||||
fn get_shortest_leaf_name(node: &TreeNode) -> Option<String> {
|
||||
pub(super) fn get_shortest_leaf_name(node: &TreeNode) -> Option<String> {
|
||||
match node {
|
||||
TreeNode::Leaf(leaf) => Some(leaf.name().to_string()),
|
||||
TreeNode::Branch(children) => children
|
||||
|
||||
@@ -59,4 +59,52 @@ impl LanguageSyntax for JavaScriptSyntax {
|
||||
fn constructor_name(&self, type_name: &str) -> String {
|
||||
format!("create{}", type_name)
|
||||
}
|
||||
|
||||
fn disc_arg_expr(&self, template: &str) -> String {
|
||||
if template == "{disc}" {
|
||||
"disc".to_string()
|
||||
} else if template.is_empty() {
|
||||
"''".to_string()
|
||||
} else if !template.contains("{disc}") {
|
||||
format!("'{}'", template)
|
||||
} else if template.ends_with("{disc}") {
|
||||
let static_part = template.trim_end_matches("{disc}").trim_end_matches('_');
|
||||
format!("_m('{}', disc)", static_part)
|
||||
} else {
|
||||
let js_template = template.replace("{disc}", "${disc}");
|
||||
format!("`{}`", js_template)
|
||||
}
|
||||
}
|
||||
|
||||
fn template_expr(&self, acc_var: &str, template: &str) -> String {
|
||||
let var_name = to_camel_case(acc_var);
|
||||
if template.is_empty() {
|
||||
// Identity — just pass disc
|
||||
format!("_m({}, disc)", var_name)
|
||||
} else if template == "{disc}" {
|
||||
// Template IS the discriminator
|
||||
format!("_m({}, disc)", var_name)
|
||||
} else if !template.contains("{disc}") {
|
||||
// Static suffix — no disc involved
|
||||
format!("_m({}, '{}')", var_name, template)
|
||||
} else {
|
||||
// Template with {disc}: use nested _m for proper separator handling
|
||||
// "ratio_{disc}_bps" → split on {disc} → _m(_m(acc, 'ratio'), disc) then _bps
|
||||
// But this is complex. For embedded disc, use string interpolation.
|
||||
// For suffix disc (ends with {disc}), use _m composition.
|
||||
if template.ends_with("{disc}") {
|
||||
let static_part = &template[..template.len() - "{disc}".len()];
|
||||
if static_part.is_empty() {
|
||||
format!("_m({}, disc)", var_name)
|
||||
} else {
|
||||
let static_part = static_part.trim_end_matches('_');
|
||||
format!("_m(_m({}, '{}'), disc)", var_name, static_part)
|
||||
}
|
||||
} else {
|
||||
// Embedded disc — use template literal
|
||||
let js_template = template.replace("{disc}", "${disc}");
|
||||
format!("_m({}, `{}`)", var_name, js_template)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,4 +54,29 @@ impl LanguageSyntax for PythonSyntax {
|
||||
fn constructor_name(&self, type_name: &str) -> String {
|
||||
type_name.to_string()
|
||||
}
|
||||
|
||||
fn disc_arg_expr(&self, template: &str) -> String {
|
||||
if template == "{disc}" {
|
||||
"disc".to_string()
|
||||
} else if template.is_empty() {
|
||||
"''".to_string()
|
||||
} else if !template.contains("{disc}") {
|
||||
format!("'{}'", template)
|
||||
} else if template.ends_with("{disc}") {
|
||||
let static_part = template.trim_end_matches("{disc}").trim_end_matches('_');
|
||||
format!("_m('{}', disc)", static_part)
|
||||
} else {
|
||||
format!("f'{}'", template)
|
||||
}
|
||||
}
|
||||
|
||||
fn template_expr(&self, acc_var: &str, template: &str) -> String {
|
||||
if template == "{disc}" {
|
||||
format!("_m({}, disc)", acc_var)
|
||||
} else if !template.contains("{disc}") {
|
||||
format!("_m({}, '{}')", acc_var, template)
|
||||
} else {
|
||||
format!("_m({}, f'{}')", acc_var, template)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,4 +55,48 @@ impl LanguageSyntax for RustSyntax {
|
||||
fn constructor_name(&self, type_name: &str) -> String {
|
||||
format!("{}::new", type_name)
|
||||
}
|
||||
|
||||
fn disc_arg_expr(&self, template: &str) -> String {
|
||||
if template == "{disc}" {
|
||||
"disc.clone()".to_string()
|
||||
} else if template.is_empty() {
|
||||
"String::new()".to_string()
|
||||
} else if !template.contains("{disc}") {
|
||||
format!("\"{}\".to_string()", template)
|
||||
} else if template.ends_with("{disc}") {
|
||||
let static_part = template.trim_end_matches("{disc}").trim_end_matches('_');
|
||||
format!("_m(\"{}\", &disc)", static_part)
|
||||
} else {
|
||||
let rust_template = template
|
||||
.replace("{disc}", "{disc}")
|
||||
.replace('{', "{{")
|
||||
.replace('}', "}}")
|
||||
.replace("{{disc}}", "{disc}");
|
||||
format!("format!(\"{}\")", rust_template)
|
||||
}
|
||||
}
|
||||
|
||||
fn template_expr(&self, acc_var: &str, template: &str) -> String {
|
||||
if template == "{disc}" {
|
||||
// _m(acc, disc) in Rust
|
||||
format!("_m(&{}, &disc)", acc_var)
|
||||
} else if template.is_empty() {
|
||||
// Identity
|
||||
acc_var.to_string()
|
||||
} else if !template.contains("{disc}") {
|
||||
// Static suffix
|
||||
format!("_m(&{}, \"{}\")", acc_var, template)
|
||||
} else {
|
||||
// Template with disc: _m(&acc, &format!("ratio_{disc}_bps", disc=disc))
|
||||
let rust_template = template
|
||||
.replace("{disc}", "{disc}")
|
||||
.replace('{', "{{")
|
||||
.replace('}', "}}")
|
||||
.replace("{{disc}}", "{disc}");
|
||||
format!(
|
||||
"_m(&{}, &format!(\"{}\", disc=disc))",
|
||||
acc_var, rust_template
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@ fn compute_path_expr<S: LanguageSyntax>(
|
||||
) -> String {
|
||||
match pattern.get_field_part(&field.name) {
|
||||
Some(part) => {
|
||||
if pattern.is_suffix_mode() {
|
||||
if pattern.is_templated() {
|
||||
// Templated: replace {disc} with disc variable at runtime
|
||||
syntax.template_expr(base_var, part)
|
||||
} else if pattern.is_suffix_mode() {
|
||||
syntax.suffix_expr(base_var, part)
|
||||
} else {
|
||||
syntax.prefix_expr(part, base_var)
|
||||
@@ -76,7 +79,20 @@ pub fn generate_parameterized_field<S: LanguageSyntax>(
|
||||
let type_ann =
|
||||
metadata.field_type_annotation(field, pattern.is_generic, None, syntax.generic_syntax());
|
||||
let path_expr = compute_path_expr(syntax, pattern, field, "acc");
|
||||
let value = compute_field_value(syntax, field, metadata, &path_expr);
|
||||
|
||||
// When calling a templated child pattern, pass acc and disc separately
|
||||
let value = if let Some(child_pattern) = metadata.find_pattern(&field.rust_type)
|
||||
&& child_pattern.is_templated()
|
||||
{
|
||||
let disc_template = pattern
|
||||
.get_field_part(&field.name)
|
||||
.unwrap_or(&field.name);
|
||||
let disc_arg = syntax.disc_arg_expr(disc_template);
|
||||
let acc_arg = syntax.suffix_expr("acc", ""); // identity — returns acc or acc.clone()
|
||||
syntax.constructor(&field.rust_type, &format!("{acc_arg}, {disc_arg}"))
|
||||
} else {
|
||||
compute_field_value(syntax, field, metadata, &path_expr)
|
||||
};
|
||||
|
||||
writeln!(
|
||||
output,
|
||||
|
||||
@@ -701,7 +701,7 @@ pub fn generate_structural_patterns(
|
||||
}
|
||||
writeln!(output, " */\n").unwrap();
|
||||
|
||||
// Generate factory function for ALL patterns
|
||||
|
||||
writeln!(output, "/**").unwrap();
|
||||
writeln!(output, " * Create a {} pattern node", pattern.name).unwrap();
|
||||
if pattern.is_generic {
|
||||
@@ -709,6 +709,9 @@ pub fn generate_structural_patterns(
|
||||
}
|
||||
writeln!(output, " * @param {{BrkClientBase}} client").unwrap();
|
||||
writeln!(output, " * @param {{string}} acc - Accumulated metric name").unwrap();
|
||||
if pattern.is_templated() {
|
||||
writeln!(output, " * @param {{string}} disc - Discriminator suffix").unwrap();
|
||||
}
|
||||
let return_type = if pattern.is_generic {
|
||||
format!("{}<T>", pattern.name)
|
||||
} else {
|
||||
@@ -717,7 +720,11 @@ pub fn generate_structural_patterns(
|
||||
writeln!(output, " * @returns {{{}}}", return_type).unwrap();
|
||||
writeln!(output, " */").unwrap();
|
||||
|
||||
writeln!(output, "function create{}(client, acc) {{", pattern.name).unwrap();
|
||||
if pattern.is_templated() {
|
||||
writeln!(output, "function create{}(client, acc, disc) {{", pattern.name).unwrap();
|
||||
} else {
|
||||
writeln!(output, "function create{}(client, acc) {{", pattern.name).unwrap();
|
||||
}
|
||||
writeln!(output, " return {{").unwrap();
|
||||
|
||||
let syntax = JavaScriptSyntax;
|
||||
|
||||
@@ -221,12 +221,31 @@ fn generate_tree_initializer(
|
||||
writeln!(output, "{}}},", indent_str).unwrap();
|
||||
} else {
|
||||
// Use pattern factory
|
||||
writeln!(
|
||||
output,
|
||||
"{}{}: create{}(this, '{}'),",
|
||||
indent_str, field_name, child.field.rust_type, child.base_result.base
|
||||
)
|
||||
.unwrap();
|
||||
let pattern = metadata.find_pattern(&child.field.rust_type);
|
||||
if pattern.is_some_and(|p| p.is_templated()) {
|
||||
// Templated: extract discriminator from field_parts
|
||||
let disc = child
|
||||
.base_result
|
||||
.field_parts
|
||||
.values()
|
||||
.filter(|v| !v.is_empty())
|
||||
.min_by_key(|v| v.len())
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
writeln!(
|
||||
output,
|
||||
"{}{}: create{}(this, '{}', '{}'),",
|
||||
indent_str, field_name, child.field.rust_type, child.base_result.base, disc
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(
|
||||
output,
|
||||
"{}{}: create{}(this, '{}'),",
|
||||
indent_str, field_name, child.field.rust_type, child.base_result.base
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,6 +683,7 @@ pub fn generate_structural_patterns(
|
||||
writeln!(output, "# Reusable structural pattern classes\n").unwrap();
|
||||
|
||||
for pattern in patterns {
|
||||
|
||||
// Generate class
|
||||
if pattern.is_generic {
|
||||
writeln!(output, "class {}(Generic[T]):", pattern.name).unwrap();
|
||||
|
||||
@@ -552,11 +552,19 @@ pub fn generate_pattern_structs(
|
||||
" /// Create a new pattern node with accumulated metric name."
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
if pattern.is_templated() {
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, acc: String, disc: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(
|
||||
output,
|
||||
" pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {{"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(output, " Self {{").unwrap();
|
||||
|
||||
let syntax = RustSyntax;
|
||||
|
||||
@@ -98,17 +98,37 @@ fn generate_tree_node(
|
||||
.unwrap();
|
||||
} else {
|
||||
// Pattern type - use ::new() constructor
|
||||
// All patterns have ::new(), parameterizable ones use detected mode,
|
||||
// non-parameterizable ones use field name fallback
|
||||
generate_tree_node_field(
|
||||
output,
|
||||
&syntax,
|
||||
&child.field,
|
||||
metadata,
|
||||
" ",
|
||||
child.name,
|
||||
Some(&child.base_result.base),
|
||||
);
|
||||
let pattern = metadata.find_pattern(&child.field.rust_type);
|
||||
if pattern.is_some_and(|p| p.is_templated()) {
|
||||
// Templated pattern: pass base and disc
|
||||
let disc = child
|
||||
.base_result
|
||||
.field_parts
|
||||
.values()
|
||||
.filter(|v| !v.is_empty())
|
||||
.min_by_key(|v| v.len())
|
||||
.cloned()
|
||||
.unwrap_or_default();
|
||||
writeln!(
|
||||
output,
|
||||
" {}: {}::new(client.clone(), {}, {}.to_string()),",
|
||||
field_name,
|
||||
child.field.rust_type,
|
||||
syntax.string_literal(&child.base_result.base),
|
||||
syntax.string_literal(&disc),
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
generate_tree_node_field(
|
||||
output,
|
||||
&syntax,
|
||||
&child.field,
|
||||
metadata,
|
||||
" ",
|
||||
child.name,
|
||||
Some(&child.base_result.base),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,4 +92,23 @@ pub trait LanguageSyntax {
|
||||
/// - JavaScript: `createTypeName`
|
||||
/// - Rust: `TypeName::new`
|
||||
fn constructor_name(&self, type_name: &str) -> String;
|
||||
|
||||
/// Format a discriminator argument for passing to a templated child.
|
||||
///
|
||||
/// Returns an expression computing the disc value from a template.
|
||||
/// - `"pct99"` (static) → `'pct99'` (JS) / `"pct99".to_string()` (Rust)
|
||||
/// - `""` (empty) → `disc` (pass parent's disc through)
|
||||
/// - `"p1sd{disc}"` (suffix) → `_m('p1sd', disc)` (composed)
|
||||
/// - `"ratio_{disc}_bps"` (embedded) → `` `ratio_${disc}_bps` `` (template literal)
|
||||
fn disc_arg_expr(&self, template: &str) -> String;
|
||||
|
||||
/// Format a templated mode expression: substitute `{disc}` at runtime.
|
||||
///
|
||||
/// The template contains `{disc}` placeholder. The generated code should
|
||||
/// construct `_m(acc, template_with_disc_substituted)` at runtime.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `acc_var` - The accumulator variable (e.g., "acc")
|
||||
/// * `template` - Template like `"ratio_{disc}_bps"` or `"{disc}"`
|
||||
fn template_expr(&self, acc_var: &str, template: &str) -> String;
|
||||
}
|
||||
|
||||
@@ -69,26 +69,10 @@ impl ClientMetadata {
|
||||
self.find_pattern(name).is_some_and(|p| p.is_generic)
|
||||
}
|
||||
|
||||
/// Check if a pattern by name is fully parameterizable.
|
||||
/// A pattern is parameterizable if it has a mode AND all its branch fields
|
||||
/// are also parameterizable (or not patterns at all).
|
||||
/// Check if a pattern by name is parameterizable (has a mode).
|
||||
pub fn is_parameterizable(&self, name: &str) -> bool {
|
||||
self.find_pattern(name).is_some_and(|p| {
|
||||
if !p.is_parameterizable() {
|
||||
return false;
|
||||
}
|
||||
// Check all branch fields have parameterizable types (or are not patterns)
|
||||
p.fields.iter().all(|f| {
|
||||
if f.is_branch() {
|
||||
self.structural_patterns
|
||||
.iter()
|
||||
.find(|pat| pat.name == f.rust_type)
|
||||
.is_none_or(|pat| pat.is_parameterizable())
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
})
|
||||
self.find_pattern(name)
|
||||
.is_some_and(|p| p.is_parameterizable())
|
||||
}
|
||||
|
||||
/// Check if child fields match ANY pattern (parameterizable or not).
|
||||
|
||||
@@ -23,4 +23,12 @@ pub enum PatternMode {
|
||||
/// Maps field name to its prefix (empty string for identity)
|
||||
prefixes: BTreeMap<String, String>,
|
||||
},
|
||||
/// Fields construct metric names using a template with a discriminator placeholder.
|
||||
/// Factory takes two params: `acc` (base) and `disc` (discriminator).
|
||||
/// Formula: `_m(acc, template.replace("{disc}", disc))`
|
||||
/// Example: template `"ratio_{disc}_bps"` with disc `"pct99"` → `_m(acc, "ratio_pct99_bps")`
|
||||
Templated {
|
||||
/// Maps field name to its template string containing `{disc}` placeholder
|
||||
templates: BTreeMap<String, String>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -41,21 +41,30 @@ impl StructuralPattern {
|
||||
relatives.get(field_name).map(|s| s.as_str())
|
||||
}
|
||||
Some(PatternMode::Prefix { prefixes }) => prefixes.get(field_name).map(|s| s.as_str()),
|
||||
Some(PatternMode::Templated { templates }) => {
|
||||
templates.get(field_name).map(|s| s.as_str())
|
||||
}
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this pattern is in suffix mode.
|
||||
pub fn is_suffix_mode(&self) -> bool {
|
||||
matches!(&self.mode, Some(PatternMode::Suffix { .. }))
|
||||
matches!(
|
||||
&self.mode,
|
||||
Some(PatternMode::Suffix { .. } | PatternMode::Templated { .. })
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns true if this pattern uses templated mode with a discriminator.
|
||||
pub fn is_templated(&self) -> bool {
|
||||
matches!(&self.mode, Some(PatternMode::Templated { .. }))
|
||||
}
|
||||
|
||||
/// Check if the given instance field parts match this pattern's field parts.
|
||||
/// Returns true if all field parts in the pattern match the instance's field parts.
|
||||
pub fn field_parts_match(&self, instance_field_parts: &BTreeMap<String, String>) -> bool {
|
||||
match &self.mode {
|
||||
Some(PatternMode::Suffix { relatives }) => {
|
||||
// For each field in the pattern, check if the instance has the same suffix
|
||||
relatives.iter().all(|(field_name, pattern_suffix)| {
|
||||
instance_field_parts
|
||||
.get(field_name)
|
||||
@@ -63,18 +72,56 @@ impl StructuralPattern {
|
||||
})
|
||||
}
|
||||
Some(PatternMode::Prefix { prefixes }) => {
|
||||
// For each field in the pattern, check if the instance has the same prefix
|
||||
prefixes.iter().all(|(field_name, pattern_prefix)| {
|
||||
instance_field_parts
|
||||
.get(field_name)
|
||||
.is_some_and(|instance_prefix| instance_prefix == pattern_prefix)
|
||||
})
|
||||
}
|
||||
None => false, // Non-parameterizable patterns don't use field parts
|
||||
Some(PatternMode::Templated { templates }) => {
|
||||
// For templated patterns, check if the instance's field_parts
|
||||
// can be produced by substituting some discriminator into the templates
|
||||
let first_template_field = templates.iter().next();
|
||||
let Some((ref_field, ref_template)) = first_template_field else {
|
||||
return false;
|
||||
};
|
||||
let Some(ref_value) = instance_field_parts.get(ref_field) else {
|
||||
return false;
|
||||
};
|
||||
// Extract discriminator from the reference field
|
||||
let Some(disc) = extract_disc(ref_template, ref_value) else {
|
||||
return false;
|
||||
};
|
||||
// Verify all fields match with this discriminator
|
||||
templates.iter().all(|(field_name, template)| {
|
||||
instance_field_parts
|
||||
.get(field_name)
|
||||
.is_some_and(|value| *value == template.replace("{disc}", &disc))
|
||||
})
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract the discriminator value by matching a template against a concrete string.
|
||||
/// E.g., template `"ratio_{disc}_bps"` matched against `"ratio_pct99_bps"` yields `"pct99"`.
|
||||
fn extract_disc(template: &str, value: &str) -> Option<String> {
|
||||
let parts: Vec<&str> = template.split("{disc}").collect();
|
||||
if parts.len() != 2 {
|
||||
return None;
|
||||
}
|
||||
let prefix = parts[0];
|
||||
let suffix = parts[1];
|
||||
if value.starts_with(prefix) && value.ends_with(suffix) {
|
||||
let disc = &value[prefix.len()..value.len() - suffix.len()];
|
||||
if !disc.is_empty() {
|
||||
return Some(disc.to_string());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// A field in a structural pattern.
|
||||
#[derive(Debug, Clone, PartialOrd, Ord)]
|
||||
pub struct PatternField {
|
||||
|
||||
+222
-260
@@ -992,41 +992,41 @@ impl Pct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65Pct70Pct75
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern {
|
||||
pub _0sd: CentsSatsUsdPattern,
|
||||
pub m0_5sd: PriceValuePattern,
|
||||
pub m1_5sd: PriceValuePattern,
|
||||
pub m1sd: PriceValuePattern,
|
||||
pub m2_5sd: PriceValuePattern,
|
||||
pub m2sd: PriceValuePattern,
|
||||
pub m3sd: PriceValuePattern,
|
||||
pub p0_5sd: PriceValuePattern,
|
||||
pub p1_5sd: PriceValuePattern,
|
||||
pub p1sd: PriceValuePattern,
|
||||
pub p2_5sd: PriceValuePattern,
|
||||
pub p2sd: PriceValuePattern,
|
||||
pub p3sd: PriceValuePattern,
|
||||
pub m0_5sd: PriceRatioPattern,
|
||||
pub m1_5sd: PriceRatioPattern,
|
||||
pub m1sd: PriceRatioPattern,
|
||||
pub m2_5sd: PriceRatioPattern,
|
||||
pub m2sd: PriceRatioPattern,
|
||||
pub m3sd: PriceRatioPattern,
|
||||
pub p0_5sd: PriceRatioPattern,
|
||||
pub p1_5sd: PriceRatioPattern,
|
||||
pub p1sd: PriceRatioPattern,
|
||||
pub p2_5sd: PriceRatioPattern,
|
||||
pub p2sd: PriceRatioPattern,
|
||||
pub p3sd: PriceRatioPattern,
|
||||
pub sd: MetricPattern1<StoredF32>,
|
||||
pub zscore: MetricPattern1<StoredF32>,
|
||||
}
|
||||
|
||||
impl _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String, disc: String) -> Self {
|
||||
Self {
|
||||
_0sd: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "0sd_4y")),
|
||||
m0_5sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
m1_5sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
m1sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
m2_5sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
m2sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
m3sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
p0_5sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
p1_5sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
p1sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
p2_5sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
p2sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
p3sd: PriceValuePattern::new(client.clone(), acc.clone()),
|
||||
sd: MetricPattern1::new(client.clone(), _m(&acc, "sd_4y")),
|
||||
zscore: MetricPattern1::new(client.clone(), _m(&acc, "zscore_4y")),
|
||||
_0sd: CentsSatsUsdPattern::new(client.clone(), _m(&acc, &format!("0sd{disc}", disc=disc))),
|
||||
m0_5sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("m0_5sd", &disc)),
|
||||
m1_5sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("m1_5sd", &disc)),
|
||||
m1sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("m1sd", &disc)),
|
||||
m2_5sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("m2_5sd", &disc)),
|
||||
m2sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("m2sd", &disc)),
|
||||
m3sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("m3sd", &disc)),
|
||||
p0_5sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("p0_5sd", &disc)),
|
||||
p1_5sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("p1_5sd", &disc)),
|
||||
p1sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("p1sd", &disc)),
|
||||
p2_5sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("p2_5sd", &disc)),
|
||||
p2sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("p2sd", &disc)),
|
||||
p3sd: PriceRatioPattern::new(client.clone(), acc.clone(), _m("p3sd", &disc)),
|
||||
sd: MetricPattern1::new(client.clone(), _m(&acc, &format!("ratio_sd{disc}", disc=disc))),
|
||||
zscore: MetricPattern1::new(client.clone(), _m(&acc, &format!("ratio_zscore{disc}", disc=disc))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1123,18 +1123,18 @@ impl CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
cap: CentsDeltaRelUsdPattern::new(client.clone(), _m(&acc, "realized_cap")),
|
||||
gross_pnl: BaseCumulativeSumPattern3::new(client.clone(), _m(&acc, "realized_gross_pnl")),
|
||||
investor: LowerPriceUpperPattern::new(client.clone(), acc.clone()),
|
||||
loss: BaseCapitulationCumulativeNegativeRelSumValuePattern::new(client.clone(), acc.clone()),
|
||||
mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")),
|
||||
net_pnl: BaseChangeCumulativeDeltaRelSumPattern::new(client.clone(), _m(&acc, "net")),
|
||||
peak_regret: BaseCumulativeRelPattern::new(client.clone(), _m(&acc, "realized_peak_regret")),
|
||||
price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), _m(&acc, "realized_price")),
|
||||
profit: BaseCumulativeDistributionRelSumValuePattern::new(client.clone(), acc.clone()),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "realized_profit_to_loss_ratio")),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio")),
|
||||
sopr: AdjustedRatioValuePattern::new(client.clone(), acc.clone()),
|
||||
cap: CentsDeltaRelUsdPattern::new(client.clone(), format!("{acc}_cap")),
|
||||
gross_pnl: BaseCumulativeSumPattern3::new(client.clone(), format!("{acc}_gross_pnl")),
|
||||
investor: LowerPriceUpperPattern::new(client.clone(), format!("{acc}_investor")),
|
||||
loss: BaseCapitulationCumulativeNegativeRelSumValuePattern::new(client.clone(), format!("{acc}_loss")),
|
||||
mvrv: MetricPattern1::new(client.clone(), format!("{acc}_mvrv")),
|
||||
net_pnl: BaseChangeCumulativeDeltaRelSumPattern::new(client.clone(), format!("{acc}_net_pnl")),
|
||||
peak_regret: BaseCumulativeRelPattern::new(client.clone(), format!("{acc}_peak_regret")),
|
||||
price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), format!("{acc}_price")),
|
||||
profit: BaseCumulativeDistributionRelSumValuePattern::new(client.clone(), format!("{acc}_profit")),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), format!("{acc}_profit_to_loss_ratio")),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern6::new(client.clone(), format!("{acc}_sell_side_risk_ratio")),
|
||||
sopr: AdjustedRatioValuePattern::new(client.clone(), format!("{acc}_sopr")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1223,18 +1223,18 @@ pub struct AverageGainsLossesRsiStochPattern {
|
||||
|
||||
impl AverageGainsLossesRsiStochPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String, disc: String) -> Self {
|
||||
Self {
|
||||
average_gain: MetricPattern1::new(client.clone(), _m(&acc, "average_gain_24h")),
|
||||
average_loss: MetricPattern1::new(client.clone(), _m(&acc, "average_loss_24h")),
|
||||
gains: MetricPattern1::new(client.clone(), _m(&acc, "gains_24h")),
|
||||
losses: MetricPattern1::new(client.clone(), _m(&acc, "losses_24h")),
|
||||
rsi: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, "24h")),
|
||||
rsi_max: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, "max_24h")),
|
||||
rsi_min: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, "min_24h")),
|
||||
stoch_rsi: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, "stoch_24h")),
|
||||
stoch_rsi_d: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, "stoch_d_24h")),
|
||||
stoch_rsi_k: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, "stoch_k_24h")),
|
||||
average_gain: MetricPattern1::new(client.clone(), _m(&acc, &format!("average_gain_{disc}", disc=disc))),
|
||||
average_loss: MetricPattern1::new(client.clone(), _m(&acc, &format!("average_loss_{disc}", disc=disc))),
|
||||
gains: MetricPattern1::new(client.clone(), _m(&acc, &format!("gains_{disc}", disc=disc))),
|
||||
losses: MetricPattern1::new(client.clone(), _m(&acc, &format!("losses_{disc}", disc=disc))),
|
||||
rsi: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, &disc)),
|
||||
rsi_max: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, &format!("max_{disc}", disc=disc))),
|
||||
rsi_min: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, &format!("min_{disc}", disc=disc))),
|
||||
stoch_rsi: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, &format!("stoch_{disc}", disc=disc))),
|
||||
stoch_rsi_d: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, &format!("stoch_d_{disc}", disc=disc))),
|
||||
stoch_rsi_k: BpsPercentRatioPattern3::new(client.clone(), _m(&acc, &format!("stoch_k_{disc}", disc=disc))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1377,7 +1377,7 @@ impl BpsCentsPercentilesRatioSatsSmaStdUsdPattern {
|
||||
ratio: MetricPattern1::new(client.clone(), _m(&acc, "ratio")),
|
||||
sats: MetricPattern1::new(client.clone(), _m(&acc, "sats")),
|
||||
sma: _1m1w1y2y4yAllPattern::new(client.clone(), _m(&acc, "ratio_sma")),
|
||||
std_dev: _1y2y4yAllPattern::new(client.clone(), _m(&acc, "ratio")),
|
||||
std_dev: _1y2y4yAllPattern::new(client.clone(), acc.clone()),
|
||||
usd: MetricPattern1::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
@@ -1531,12 +1531,12 @@ impl CapLossMvrvNetPriceProfitSoprPattern {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
cap: CentsDeltaUsdPattern::new(client.clone(), _m(&acc, "realized_cap")),
|
||||
loss: BaseCumulativeNegativeSumPattern::new(client.clone(), acc.clone()),
|
||||
loss: BaseCumulativeNegativeSumPattern::new(client.clone(), acc.clone(), String::new()),
|
||||
mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")),
|
||||
net_pnl: BaseCumulativeDeltaSumPattern::new(client.clone(), _m(&acc, "net_realized_pnl")),
|
||||
price: BpsCentsRatioSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")),
|
||||
profit: BaseCumulativeSumPattern3::new(client.clone(), _m(&acc, "realized_profit")),
|
||||
sopr: RatioValuePattern::new(client.clone(), acc.clone()),
|
||||
sopr: RatioValuePattern::new(client.clone(), _m(&acc, "sopr_24h")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1773,12 +1773,12 @@ impl Pct1Pct2Pct5Pct95Pct98Pct99Pattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
pct1: BpsPriceRatioPattern::new(client.clone(), acc.clone()),
|
||||
pct2: BpsPriceRatioPattern::new(client.clone(), acc.clone()),
|
||||
pct5: BpsPriceRatioPattern::new(client.clone(), acc.clone()),
|
||||
pct95: BpsPriceRatioPattern::new(client.clone(), acc.clone()),
|
||||
pct98: BpsPriceRatioPattern::new(client.clone(), acc.clone()),
|
||||
pct99: BpsPriceRatioPattern::new(client.clone(), acc.clone()),
|
||||
pct1: BpsPriceRatioPattern::new(client.clone(), acc.clone(), "pct1".to_string()),
|
||||
pct2: BpsPriceRatioPattern::new(client.clone(), acc.clone(), "pct2".to_string()),
|
||||
pct5: BpsPriceRatioPattern::new(client.clone(), acc.clone(), "pct5".to_string()),
|
||||
pct95: BpsPriceRatioPattern::new(client.clone(), acc.clone(), "pct95".to_string()),
|
||||
pct98: BpsPriceRatioPattern::new(client.clone(), acc.clone(), "pct98".to_string()),
|
||||
pct99: BpsPriceRatioPattern::new(client.clone(), acc.clone(), "pct99".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1972,11 +1972,11 @@ impl EmaHistogramLineSignalPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ema_fast: MetricPattern1::new(client.clone(), _m(&acc, "ema_fast_24h")),
|
||||
ema_slow: MetricPattern1::new(client.clone(), _m(&acc, "ema_slow_24h")),
|
||||
histogram: MetricPattern1::new(client.clone(), _m(&acc, "histogram_24h")),
|
||||
line: MetricPattern1::new(client.clone(), _m(&acc, "line_24h")),
|
||||
signal: MetricPattern1::new(client.clone(), _m(&acc, "signal_24h")),
|
||||
ema_fast: MetricPattern1::new(client.clone(), format!("{acc}_ema_fast")),
|
||||
ema_slow: MetricPattern1::new(client.clone(), format!("{acc}_ema_slow")),
|
||||
histogram: MetricPattern1::new(client.clone(), format!("{acc}_histogram")),
|
||||
line: MetricPattern1::new(client.clone(), format!("{acc}_line")),
|
||||
signal: MetricPattern1::new(client.clone(), format!("{acc}_signal")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2018,9 +2018,9 @@ impl MvrvNuplRealizedSupplyPattern {
|
||||
Self {
|
||||
mvrv: MetricPattern1::new(client.clone(), _m(&acc, "mvrv")),
|
||||
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
|
||||
realized_cap: AllSthPattern::new(client.clone(), acc.clone()),
|
||||
realized_cap: AllSthPattern::new(client.clone(), _m(&acc, "realized_cap")),
|
||||
realized_price: BpsCentsRatioSatsUsdPattern::new(client.clone(), _m(&acc, "realized_price")),
|
||||
supply: AllSthPattern2::new(client.clone(), acc.clone()),
|
||||
supply: AllSthPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2201,10 +2201,10 @@ impl _1y2y4yAllPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
_1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone()),
|
||||
_2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone()),
|
||||
_4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone()),
|
||||
all: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone()),
|
||||
_1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone(), "1y".to_string()),
|
||||
_2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone(), "2y".to_string()),
|
||||
_4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone(), "4y".to_string()),
|
||||
all: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern::new(client.clone(), acc.clone(), String::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2259,12 +2259,12 @@ pub struct BaseCumulativeNegativeSumPattern {
|
||||
|
||||
impl BaseCumulativeNegativeSumPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String, disc: String) -> Self {
|
||||
Self {
|
||||
base: CentsUsdPattern2::new(client.clone(), _m(&acc, "unrealized_loss")),
|
||||
cumulative: CentsUsdPattern2::new(client.clone(), _m(&acc, "unrealized_loss_cumulative")),
|
||||
negative: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")),
|
||||
sum: _1m1w1y24hPattern4::new(client.clone(), _m(&acc, "unrealized_loss_sum")),
|
||||
base: CentsUsdPattern2::new(client.clone(), _m(&acc, &disc)),
|
||||
cumulative: CentsUsdPattern2::new(client.clone(), _m(&acc, &format!("{disc}_cumulative", disc=disc))),
|
||||
negative: MetricPattern1::new(client.clone(), _m(&acc, &format!("neg_{disc}", disc=disc))),
|
||||
sum: _1m1w1y24hPattern4::new(client.clone(), _m(&acc, &format!("{disc}_sum", disc=disc))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2381,7 +2381,7 @@ impl LossNetNuplProfitPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
loss: BaseCumulativeNegativeSumPattern::new(client.clone(), acc.clone()),
|
||||
loss: BaseCumulativeNegativeSumPattern::new(client.clone(), acc.clone(), String::new()),
|
||||
net_pnl: CentsUsdPattern::new(client.clone(), _m(&acc, "net_unrealized_pnl")),
|
||||
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
|
||||
profit: BaseCumulativeSumPattern3::new(client.clone(), _m(&acc, "unrealized_profit")),
|
||||
@@ -2584,11 +2584,11 @@ pub struct BpsPriceRatioPattern {
|
||||
|
||||
impl BpsPriceRatioPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String, disc: String) -> Self {
|
||||
Self {
|
||||
bps: MetricPattern1::new(client.clone(), _m(&acc, "ratio_pct99_bps")),
|
||||
price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "pct99")),
|
||||
ratio: MetricPattern1::new(client.clone(), _m(&acc, "ratio_pct99")),
|
||||
bps: MetricPattern1::new(client.clone(), _m(&acc, &format!("ratio_{disc}_bps", disc=disc))),
|
||||
price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, &disc)),
|
||||
ratio: MetricPattern1::new(client.clone(), _m(&acc, &format!("ratio_{disc}", disc=disc))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2730,7 +2730,7 @@ impl LossNuplProfitPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
loss: BaseCumulativeNegativeSumPattern::new(client.clone(), acc.clone()),
|
||||
loss: BaseCumulativeNegativeSumPattern::new(client.clone(), acc.clone(), String::new()),
|
||||
nupl: BpsRatioPattern::new(client.clone(), _m(&acc, "nupl")),
|
||||
profit: BaseCumulativeSumPattern3::new(client.clone(), _m(&acc, "unrealized_profit")),
|
||||
}
|
||||
@@ -2766,9 +2766,9 @@ impl RatioValuePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ratio: _1m1w1y24hPattern::new(client.clone(), _m(&acc, "asopr")),
|
||||
value_created: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "adj_value_created")),
|
||||
value_destroyed: BaseCumulativeSumPattern::new(client.clone(), _m(&acc, "adj_value_destroyed")),
|
||||
ratio: _1m1w1y24hPattern::new(client.clone(), format!("{acc}_ratio")),
|
||||
value_created: BaseCumulativeSumPattern::new(client.clone(), format!("{acc}_value_created")),
|
||||
value_destroyed: BaseCumulativeSumPattern::new(client.clone(), format!("{acc}_value_destroyed")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2838,7 +2838,7 @@ impl AbsoluteRatePattern {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
absolute: _1m1w1y24hPattern::new(client.clone(), acc.clone()),
|
||||
rate: _1m1w1y24hPattern2::new(client.clone(), acc.clone()),
|
||||
rate: _1m1w1y24hPattern2::new(client.clone(), _m(&acc, "rate")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2854,7 +2854,7 @@ impl AbsoluteRatePattern2 {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
absolute: _1m1w1y24hPattern3::new(client.clone(), acc.clone()),
|
||||
rate: _1m1w1y24hPattern2::new(client.clone(), acc.clone()),
|
||||
rate: _1m1w1y24hPattern2::new(client.clone(), _m(&acc, "rate")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3020,17 +3020,17 @@ impl InPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct PriceValuePattern {
|
||||
pub struct PriceRatioPattern {
|
||||
pub price: CentsSatsUsdPattern,
|
||||
pub value: MetricPattern1<StoredF32>,
|
||||
pub ratio: MetricPattern1<StoredF32>,
|
||||
}
|
||||
|
||||
impl PriceValuePattern {
|
||||
impl PriceRatioPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String, disc: String) -> Self {
|
||||
Self {
|
||||
price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, "p3sd_4y")),
|
||||
value: MetricPattern1::new(client.clone(), _m(&acc, "ratio_p3sd_4y")),
|
||||
price: CentsSatsUsdPattern::new(client.clone(), _m(&acc, &disc)),
|
||||
ratio: MetricPattern1::new(client.clone(), _m(&acc, &format!("ratio_{disc}", disc=disc))),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3061,8 +3061,8 @@ impl SdSmaPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
sd: MetricPattern1::new(client.clone(), _m(&acc, "sd_1y")),
|
||||
sma: MetricPattern1::new(client.clone(), _m(&acc, "sma_1y")),
|
||||
sd: MetricPattern1::new(client.clone(), format!("{acc}_sd")),
|
||||
sma: MetricPattern1::new(client.clone(), format!("{acc}_sma")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5338,7 +5338,7 @@ impl MetricsTree_Market_Returns_Periods {
|
||||
pub struct MetricsTree_Market_Returns_Sd24h {
|
||||
pub _1w: MetricsTree_Market_Returns_Sd24h_1w,
|
||||
pub _1m: MetricsTree_Market_Returns_Sd24h_1m,
|
||||
pub _1y: SdSmaPattern,
|
||||
pub _1y: MetricsTree_Market_Returns_Sd24h_1y,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Returns_Sd24h {
|
||||
@@ -5346,7 +5346,7 @@ impl MetricsTree_Market_Returns_Sd24h {
|
||||
Self {
|
||||
_1w: MetricsTree_Market_Returns_Sd24h_1w::new(client.clone(), format!("{base_path}_1w")),
|
||||
_1m: MetricsTree_Market_Returns_Sd24h_1m::new(client.clone(), format!("{base_path}_1m")),
|
||||
_1y: SdSmaPattern::new(client.clone(), "price_return_24h".to_string()),
|
||||
_1y: MetricsTree_Market_Returns_Sd24h_1y::new(client.clone(), format!("{base_path}_1y")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5381,6 +5381,21 @@ impl MetricsTree_Market_Returns_Sd24h_1m {
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Returns_Sd24h_1y {
|
||||
pub sma: MetricPattern1<StoredF32>,
|
||||
pub sd: MetricPattern1<StoredF32>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Returns_Sd24h_1y {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
sma: MetricPattern1::new(client.clone(), "price_return_24h_sma_1y".to_string()),
|
||||
sd: MetricPattern1::new(client.clone(), "price_return_24h_sd_1y".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Volatility {
|
||||
pub _1w: MetricPattern1<StoredF32>,
|
||||
@@ -5484,8 +5499,8 @@ pub struct MetricsTree_Market_MovingAverage_Sma_200d {
|
||||
pub sats: MetricPattern1<SatsFract>,
|
||||
pub bps: MetricPattern1<BasisPoints32>,
|
||||
pub ratio: MetricPattern1<StoredF32>,
|
||||
pub x2_4: MetricsTree_Market_MovingAverage_Sma_200d_X24,
|
||||
pub x0_8: MetricsTree_Market_MovingAverage_Sma_200d_X08,
|
||||
pub x2_4: CentsSatsUsdPattern,
|
||||
pub x0_8: CentsSatsUsdPattern,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_MovingAverage_Sma_200d {
|
||||
@@ -5496,42 +5511,8 @@ impl MetricsTree_Market_MovingAverage_Sma_200d {
|
||||
sats: MetricPattern1::new(client.clone(), "price_sma_200d_sats".to_string()),
|
||||
bps: MetricPattern1::new(client.clone(), "price_sma_200d_ratio_bps".to_string()),
|
||||
ratio: MetricPattern1::new(client.clone(), "price_sma_200d_ratio".to_string()),
|
||||
x2_4: MetricsTree_Market_MovingAverage_Sma_200d_X24::new(client.clone(), format!("{base_path}_x2_4")),
|
||||
x0_8: MetricsTree_Market_MovingAverage_Sma_200d_X08::new(client.clone(), format!("{base_path}_x0_8")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_MovingAverage_Sma_200d_X24 {
|
||||
pub usd: MetricPattern1<Dollars>,
|
||||
pub cents: MetricPattern1<Cents>,
|
||||
pub sats: MetricPattern1<SatsFract>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_MovingAverage_Sma_200d_X24 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
usd: MetricPattern1::new(client.clone(), "price_sma_200d_x2_4_usd".to_string()),
|
||||
cents: MetricPattern1::new(client.clone(), "price_sma_200d_x2_4_cents".to_string()),
|
||||
sats: MetricPattern1::new(client.clone(), "price_sma_200d_x2_4_sats".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_MovingAverage_Sma_200d_X08 {
|
||||
pub usd: MetricPattern1<Dollars>,
|
||||
pub cents: MetricPattern1<Cents>,
|
||||
pub sats: MetricPattern1<SatsFract>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_MovingAverage_Sma_200d_X08 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
usd: MetricPattern1::new(client.clone(), "price_sma_200d_x0_8_usd".to_string()),
|
||||
cents: MetricPattern1::new(client.clone(), "price_sma_200d_x0_8_cents".to_string()),
|
||||
sats: MetricPattern1::new(client.clone(), "price_sma_200d_x0_8_sats".to_string()),
|
||||
x2_4: CentsSatsUsdPattern::new(client.clone(), "price_sma_200d_x2_4".to_string()),
|
||||
x0_8: CentsSatsUsdPattern::new(client.clone(), "price_sma_200d_x0_8".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5543,7 +5524,7 @@ pub struct MetricsTree_Market_MovingAverage_Sma_350d {
|
||||
pub sats: MetricPattern1<SatsFract>,
|
||||
pub bps: MetricPattern1<BasisPoints32>,
|
||||
pub ratio: MetricPattern1<StoredF32>,
|
||||
pub x2: MetricsTree_Market_MovingAverage_Sma_350d_X2,
|
||||
pub x2: CentsSatsUsdPattern,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_MovingAverage_Sma_350d {
|
||||
@@ -5554,24 +5535,7 @@ impl MetricsTree_Market_MovingAverage_Sma_350d {
|
||||
sats: MetricPattern1::new(client.clone(), "price_sma_350d_sats".to_string()),
|
||||
bps: MetricPattern1::new(client.clone(), "price_sma_350d_ratio_bps".to_string()),
|
||||
ratio: MetricPattern1::new(client.clone(), "price_sma_350d_ratio".to_string()),
|
||||
x2: MetricsTree_Market_MovingAverage_Sma_350d_X2::new(client.clone(), format!("{base_path}_x2")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_MovingAverage_Sma_350d_X2 {
|
||||
pub usd: MetricPattern1<Dollars>,
|
||||
pub cents: MetricPattern1<Cents>,
|
||||
pub sats: MetricPattern1<SatsFract>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_MovingAverage_Sma_350d_X2 {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
usd: MetricPattern1::new(client.clone(), "price_sma_350d_x2_usd".to_string()),
|
||||
cents: MetricPattern1::new(client.clone(), "price_sma_350d_x2_cents".to_string()),
|
||||
sats: MetricPattern1::new(client.clone(), "price_sma_350d_x2_sats".to_string()),
|
||||
x2: CentsSatsUsdPattern::new(client.clone(), "price_sma_350d_x2".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5840,118 +5804,25 @@ impl MetricsTree_Market_Technical {
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Rsi {
|
||||
pub _24h: AverageGainsLossesRsiStochPattern,
|
||||
pub _1w: MetricsTree_Market_Technical_Rsi_1w,
|
||||
pub _1m: MetricsTree_Market_Technical_Rsi_1m,
|
||||
pub _1y: MetricsTree_Market_Technical_Rsi_1y,
|
||||
pub _1w: AverageGainsLossesRsiStochPattern,
|
||||
pub _1m: AverageGainsLossesRsiStochPattern,
|
||||
pub _1y: AverageGainsLossesRsiStochPattern,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Technical_Rsi {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
_24h: AverageGainsLossesRsiStochPattern::new(client.clone(), "rsi".to_string()),
|
||||
_1w: MetricsTree_Market_Technical_Rsi_1w::new(client.clone(), format!("{base_path}_1w")),
|
||||
_1m: MetricsTree_Market_Technical_Rsi_1m::new(client.clone(), format!("{base_path}_1m")),
|
||||
_1y: MetricsTree_Market_Technical_Rsi_1y::new(client.clone(), format!("{base_path}_1y")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Rsi_1w {
|
||||
pub gains: MetricPattern1<StoredF32>,
|
||||
pub losses: MetricPattern1<StoredF32>,
|
||||
pub average_gain: MetricPattern1<StoredF32>,
|
||||
pub average_loss: MetricPattern1<StoredF32>,
|
||||
pub rsi: BpsPercentRatioPattern3,
|
||||
pub rsi_min: BpsPercentRatioPattern3,
|
||||
pub rsi_max: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi_k: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi_d: BpsPercentRatioPattern3,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Technical_Rsi_1w {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
gains: MetricPattern1::new(client.clone(), "rsi_gains_1w".to_string()),
|
||||
losses: MetricPattern1::new(client.clone(), "rsi_losses_1w".to_string()),
|
||||
average_gain: MetricPattern1::new(client.clone(), "rsi_average_gain_1w".to_string()),
|
||||
average_loss: MetricPattern1::new(client.clone(), "rsi_average_loss_1w".to_string()),
|
||||
rsi: BpsPercentRatioPattern3::new(client.clone(), "rsi_1w".to_string()),
|
||||
rsi_min: BpsPercentRatioPattern3::new(client.clone(), "rsi_min_1w".to_string()),
|
||||
rsi_max: BpsPercentRatioPattern3::new(client.clone(), "rsi_max_1w".to_string()),
|
||||
stoch_rsi: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_1w".to_string()),
|
||||
stoch_rsi_k: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_k_1w".to_string()),
|
||||
stoch_rsi_d: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_d_1w".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Rsi_1m {
|
||||
pub gains: MetricPattern1<StoredF32>,
|
||||
pub losses: MetricPattern1<StoredF32>,
|
||||
pub average_gain: MetricPattern1<StoredF32>,
|
||||
pub average_loss: MetricPattern1<StoredF32>,
|
||||
pub rsi: BpsPercentRatioPattern3,
|
||||
pub rsi_min: BpsPercentRatioPattern3,
|
||||
pub rsi_max: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi_k: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi_d: BpsPercentRatioPattern3,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Technical_Rsi_1m {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
gains: MetricPattern1::new(client.clone(), "rsi_gains_1m".to_string()),
|
||||
losses: MetricPattern1::new(client.clone(), "rsi_losses_1m".to_string()),
|
||||
average_gain: MetricPattern1::new(client.clone(), "rsi_average_gain_1m".to_string()),
|
||||
average_loss: MetricPattern1::new(client.clone(), "rsi_average_loss_1m".to_string()),
|
||||
rsi: BpsPercentRatioPattern3::new(client.clone(), "rsi_1m".to_string()),
|
||||
rsi_min: BpsPercentRatioPattern3::new(client.clone(), "rsi_min_1m".to_string()),
|
||||
rsi_max: BpsPercentRatioPattern3::new(client.clone(), "rsi_max_1m".to_string()),
|
||||
stoch_rsi: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_1m".to_string()),
|
||||
stoch_rsi_k: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_k_1m".to_string()),
|
||||
stoch_rsi_d: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_d_1m".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Rsi_1y {
|
||||
pub gains: MetricPattern1<StoredF32>,
|
||||
pub losses: MetricPattern1<StoredF32>,
|
||||
pub average_gain: MetricPattern1<StoredF32>,
|
||||
pub average_loss: MetricPattern1<StoredF32>,
|
||||
pub rsi: BpsPercentRatioPattern3,
|
||||
pub rsi_min: BpsPercentRatioPattern3,
|
||||
pub rsi_max: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi_k: BpsPercentRatioPattern3,
|
||||
pub stoch_rsi_d: BpsPercentRatioPattern3,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Technical_Rsi_1y {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
gains: MetricPattern1::new(client.clone(), "rsi_gains_1y".to_string()),
|
||||
losses: MetricPattern1::new(client.clone(), "rsi_losses_1y".to_string()),
|
||||
average_gain: MetricPattern1::new(client.clone(), "rsi_average_gain_1y".to_string()),
|
||||
average_loss: MetricPattern1::new(client.clone(), "rsi_average_loss_1y".to_string()),
|
||||
rsi: BpsPercentRatioPattern3::new(client.clone(), "rsi_1y".to_string()),
|
||||
rsi_min: BpsPercentRatioPattern3::new(client.clone(), "rsi_min_1y".to_string()),
|
||||
rsi_max: BpsPercentRatioPattern3::new(client.clone(), "rsi_max_1y".to_string()),
|
||||
stoch_rsi: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_1y".to_string()),
|
||||
stoch_rsi_k: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_k_1y".to_string()),
|
||||
stoch_rsi_d: BpsPercentRatioPattern3::new(client.clone(), "rsi_stoch_d_1y".to_string()),
|
||||
_24h: AverageGainsLossesRsiStochPattern::new(client.clone(), "rsi".to_string(), "24h".to_string().to_string()),
|
||||
_1w: AverageGainsLossesRsiStochPattern::new(client.clone(), "rsi".to_string(), "1w".to_string().to_string()),
|
||||
_1m: AverageGainsLossesRsiStochPattern::new(client.clone(), "rsi".to_string(), "1m".to_string().to_string()),
|
||||
_1y: AverageGainsLossesRsiStochPattern::new(client.clone(), "rsi".to_string(), "1y".to_string().to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Macd {
|
||||
pub _24h: EmaHistogramLineSignalPattern,
|
||||
pub _24h: MetricsTree_Market_Technical_Macd_24h,
|
||||
pub _1w: MetricsTree_Market_Technical_Macd_1w,
|
||||
pub _1m: MetricsTree_Market_Technical_Macd_1m,
|
||||
pub _1y: MetricsTree_Market_Technical_Macd_1y,
|
||||
@@ -5960,7 +5831,7 @@ pub struct MetricsTree_Market_Technical_Macd {
|
||||
impl MetricsTree_Market_Technical_Macd {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
_24h: EmaHistogramLineSignalPattern::new(client.clone(), "macd".to_string()),
|
||||
_24h: MetricsTree_Market_Technical_Macd_24h::new(client.clone(), format!("{base_path}_24h")),
|
||||
_1w: MetricsTree_Market_Technical_Macd_1w::new(client.clone(), format!("{base_path}_1w")),
|
||||
_1m: MetricsTree_Market_Technical_Macd_1m::new(client.clone(), format!("{base_path}_1m")),
|
||||
_1y: MetricsTree_Market_Technical_Macd_1y::new(client.clone(), format!("{base_path}_1y")),
|
||||
@@ -5968,6 +5839,27 @@ impl MetricsTree_Market_Technical_Macd {
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Macd_24h {
|
||||
pub ema_fast: MetricPattern1<StoredF32>,
|
||||
pub ema_slow: MetricPattern1<StoredF32>,
|
||||
pub line: MetricPattern1<StoredF32>,
|
||||
pub signal: MetricPattern1<StoredF32>,
|
||||
pub histogram: MetricPattern1<StoredF32>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Market_Technical_Macd_24h {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
ema_fast: MetricPattern1::new(client.clone(), "macd_ema_fast_24h".to_string()),
|
||||
ema_slow: MetricPattern1::new(client.clone(), "macd_ema_slow_24h".to_string()),
|
||||
line: MetricPattern1::new(client.clone(), "macd_line_24h".to_string()),
|
||||
signal: MetricPattern1::new(client.clone(), "macd_signal_24h".to_string()),
|
||||
histogram: MetricPattern1::new(client.clone(), "macd_histogram_24h".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Market_Technical_Macd_1w {
|
||||
pub ema_fast: MetricPattern1<StoredF32>,
|
||||
@@ -6578,7 +6470,7 @@ pub struct MetricsTree_Cohorts_Utxo_All {
|
||||
pub supply: MetricsTree_Cohorts_Utxo_All_Supply,
|
||||
pub outputs: UnspentPattern,
|
||||
pub activity: CoindaysCoinyearsDormancySentPattern,
|
||||
pub realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern,
|
||||
pub realized: MetricsTree_Cohorts_Utxo_All_Realized,
|
||||
pub cost_basis: InvestedMaxMinPercentilesSupplyPattern,
|
||||
pub unrealized: MetricsTree_Cohorts_Utxo_All_Unrealized,
|
||||
}
|
||||
@@ -6589,7 +6481,7 @@ impl MetricsTree_Cohorts_Utxo_All {
|
||||
supply: MetricsTree_Cohorts_Utxo_All_Supply::new(client.clone(), format!("{base_path}_supply")),
|
||||
outputs: UnspentPattern::new(client.clone(), "utxo_count".to_string()),
|
||||
activity: CoindaysCoinyearsDormancySentPattern::new(client.clone(), "".to_string()),
|
||||
realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern::new(client.clone(), "".to_string()),
|
||||
realized: MetricsTree_Cohorts_Utxo_All_Realized::new(client.clone(), format!("{base_path}_realized")),
|
||||
cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "".to_string()),
|
||||
unrealized: MetricsTree_Cohorts_Utxo_All_Unrealized::new(client.clone(), format!("{base_path}_unrealized")),
|
||||
}
|
||||
@@ -6617,6 +6509,41 @@ impl MetricsTree_Cohorts_Utxo_All_Supply {
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Cohorts_Utxo_All_Realized {
|
||||
pub cap: CentsDeltaRelUsdPattern,
|
||||
pub profit: BaseCumulativeDistributionRelSumValuePattern,
|
||||
pub loss: BaseCapitulationCumulativeNegativeRelSumValuePattern,
|
||||
pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern,
|
||||
pub mvrv: MetricPattern1<StoredF32>,
|
||||
pub sopr: AdjustedRatioValuePattern,
|
||||
pub net_pnl: BaseChangeCumulativeDeltaRelSumPattern,
|
||||
pub gross_pnl: BaseCumulativeSumPattern3,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern6,
|
||||
pub peak_regret: BaseCumulativeRelPattern,
|
||||
pub investor: LowerPriceUpperPattern,
|
||||
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Cohorts_Utxo_All_Realized {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
cap: CentsDeltaRelUsdPattern::new(client.clone(), "realized_cap".to_string()),
|
||||
profit: BaseCumulativeDistributionRelSumValuePattern::new(client.clone(), "".to_string()),
|
||||
loss: BaseCapitulationCumulativeNegativeRelSumValuePattern::new(client.clone(), "".to_string()),
|
||||
price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), "realized_price".to_string()),
|
||||
mvrv: MetricPattern1::new(client.clone(), "mvrv".to_string()),
|
||||
sopr: AdjustedRatioValuePattern::new(client.clone(), "".to_string()),
|
||||
net_pnl: BaseChangeCumulativeDeltaRelSumPattern::new(client.clone(), "net".to_string()),
|
||||
gross_pnl: BaseCumulativeSumPattern3::new(client.clone(), "realized_gross_pnl".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern6::new(client.clone(), "sell_side_risk_ratio".to_string()),
|
||||
peak_regret: BaseCumulativeRelPattern::new(client.clone(), "realized_peak_regret".to_string()),
|
||||
investor: LowerPriceUpperPattern::new(client.clone(), "".to_string()),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "realized_profit_to_loss_ratio".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Cohorts_Utxo_All_Unrealized {
|
||||
pub nupl: BpsRatioPattern,
|
||||
@@ -6708,7 +6635,7 @@ pub struct MetricsTree_Cohorts_Utxo_Sth {
|
||||
pub supply: DeltaHalfInRelTotalPattern2,
|
||||
pub outputs: UnspentPattern,
|
||||
pub activity: CoindaysCoinyearsDormancySentPattern,
|
||||
pub realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern,
|
||||
pub realized: MetricsTree_Cohorts_Utxo_Sth_Realized,
|
||||
pub cost_basis: InvestedMaxMinPercentilesSupplyPattern,
|
||||
pub unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2,
|
||||
}
|
||||
@@ -6719,13 +6646,48 @@ impl MetricsTree_Cohorts_Utxo_Sth {
|
||||
supply: DeltaHalfInRelTotalPattern2::new(client.clone(), "sth_supply".to_string()),
|
||||
outputs: UnspentPattern::new(client.clone(), "sth_utxo_count".to_string()),
|
||||
activity: CoindaysCoinyearsDormancySentPattern::new(client.clone(), "sth".to_string()),
|
||||
realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern::new(client.clone(), "sth".to_string()),
|
||||
realized: MetricsTree_Cohorts_Utxo_Sth_Realized::new(client.clone(), format!("{base_path}_realized")),
|
||||
cost_basis: InvestedMaxMinPercentilesSupplyPattern::new(client.clone(), "sth".to_string()),
|
||||
unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2::new(client.clone(), "sth".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Cohorts_Utxo_Sth_Realized {
|
||||
pub cap: CentsDeltaRelUsdPattern,
|
||||
pub profit: BaseCumulativeDistributionRelSumValuePattern,
|
||||
pub loss: BaseCapitulationCumulativeNegativeRelSumValuePattern,
|
||||
pub price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern,
|
||||
pub mvrv: MetricPattern1<StoredF32>,
|
||||
pub sopr: AdjustedRatioValuePattern,
|
||||
pub net_pnl: BaseChangeCumulativeDeltaRelSumPattern,
|
||||
pub gross_pnl: BaseCumulativeSumPattern3,
|
||||
pub sell_side_risk_ratio: _1m1w1y24hPattern6,
|
||||
pub peak_regret: BaseCumulativeRelPattern,
|
||||
pub investor: LowerPriceUpperPattern,
|
||||
pub profit_to_loss_ratio: _1m1w1y24hPattern<StoredF64>,
|
||||
}
|
||||
|
||||
impl MetricsTree_Cohorts_Utxo_Sth_Realized {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
cap: CentsDeltaRelUsdPattern::new(client.clone(), "sth_realized_cap".to_string()),
|
||||
profit: BaseCumulativeDistributionRelSumValuePattern::new(client.clone(), "sth".to_string()),
|
||||
loss: BaseCapitulationCumulativeNegativeRelSumValuePattern::new(client.clone(), "sth".to_string()),
|
||||
price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern::new(client.clone(), "sth_realized_price".to_string()),
|
||||
mvrv: MetricPattern1::new(client.clone(), "sth_mvrv".to_string()),
|
||||
sopr: AdjustedRatioValuePattern::new(client.clone(), "sth".to_string()),
|
||||
net_pnl: BaseChangeCumulativeDeltaRelSumPattern::new(client.clone(), "sth_net".to_string()),
|
||||
gross_pnl: BaseCumulativeSumPattern3::new(client.clone(), "sth_realized_gross_pnl".to_string()),
|
||||
sell_side_risk_ratio: _1m1w1y24hPattern6::new(client.clone(), "sth_sell_side_risk_ratio".to_string()),
|
||||
peak_regret: BaseCumulativeRelPattern::new(client.clone(), "sth_realized_peak_regret".to_string()),
|
||||
investor: LowerPriceUpperPattern::new(client.clone(), "sth".to_string()),
|
||||
profit_to_loss_ratio: _1m1w1y24hPattern::new(client.clone(), "sth_realized_profit_to_loss_ratio".to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Metrics tree node.
|
||||
pub struct MetricsTree_Cohorts_Utxo_Lth {
|
||||
pub supply: DeltaHalfInRelTotalPattern2,
|
||||
|
||||
@@ -10,7 +10,7 @@ use brk_types::{Cents, Dollars, SatsFract, Version};
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{Database, ReadableCloneableVec, UnaryTransform};
|
||||
|
||||
use super::{PerBlock, LazyPerBlock};
|
||||
use super::{LazyPerBlock, PerBlock};
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{CentsUnsignedToDollars, ComputedVecValue, DollarsToSatsFract, NumericValue},
|
||||
@@ -32,8 +32,7 @@ impl Price<PerBlock<Cents>> {
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let cents =
|
||||
PerBlock::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
||||
let cents = PerBlock::forced_import(db, &format!("{name}_cents"), version, indexes)?;
|
||||
let usd = LazyPerBlock::from_computed::<CentsUnsignedToDollars>(
|
||||
name,
|
||||
version,
|
||||
@@ -65,11 +64,7 @@ where
|
||||
source.height.read_only_boxed_clone(),
|
||||
source,
|
||||
);
|
||||
let usd = LazyPerBlock::from_lazy::<CentsUnsignedToDollars, ST>(
|
||||
&format!("{name}_usd"),
|
||||
version,
|
||||
¢s,
|
||||
);
|
||||
let usd = LazyPerBlock::from_lazy::<CentsUnsignedToDollars, ST>(name, version, ¢s);
|
||||
let sats = LazyPerBlock::from_lazy::<DollarsToSatsFract, Cents>(
|
||||
&format!("{name}_sats"),
|
||||
version,
|
||||
|
||||
@@ -27,10 +27,10 @@ impl RatioPerBlockStdDevBands {
|
||||
let v = version + VERSION;
|
||||
|
||||
macro_rules! import_sd {
|
||||
($suffix:expr, $period:expr, $days:expr) => {
|
||||
($period:expr, $days:expr) => {
|
||||
StdDevPerBlockExtended::forced_import(
|
||||
db,
|
||||
&format!("{name}_{}", $suffix),
|
||||
name,
|
||||
$period,
|
||||
$days,
|
||||
v,
|
||||
@@ -40,10 +40,10 @@ impl RatioPerBlockStdDevBands {
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
all: import_sd!("ratio", "", usize::MAX),
|
||||
_1y: import_sd!("ratio", "1y", 365),
|
||||
_2y: import_sd!("ratio", "2y", 2 * 365),
|
||||
_4y: import_sd!("ratio", "4y", 4 * 365),
|
||||
all: import_sd!("", usize::MAX),
|
||||
_1y: import_sd!("1y", 365),
|
||||
_2y: import_sd!("2y", 2 * 365),
|
||||
_4y: import_sd!("4y", 4 * 365),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -8,13 +8,13 @@ use vecdb::{
|
||||
|
||||
use crate::{
|
||||
blocks, indexes,
|
||||
internal::{PerBlock, Price, PriceTimesRatioCents},
|
||||
internal::{PerBlock, Price, PriceTimesRatioCents, per_block::stddev::period_suffix},
|
||||
};
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct StdDevBand<M: StorageMode = Rw> {
|
||||
#[traversable(flatten)]
|
||||
pub value: PerBlock<StoredF32, M>,
|
||||
pub ratio: PerBlock<StoredF32, M>,
|
||||
pub price: Price<PerBlock<Cents, M>>,
|
||||
}
|
||||
|
||||
@@ -49,16 +49,11 @@ impl StdDevPerBlockExtended {
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let version = parent_version + Version::TWO;
|
||||
let p = super::period_suffix(period);
|
||||
let p = period_suffix(period);
|
||||
|
||||
macro_rules! import {
|
||||
($suffix:expr) => {
|
||||
PerBlock::forced_import(
|
||||
db,
|
||||
&format!("{name}_{}{p}", $suffix),
|
||||
version,
|
||||
indexes,
|
||||
)?
|
||||
PerBlock::forced_import(db, &format!("{name}_{}{p}", $suffix), version, indexes)?
|
||||
};
|
||||
}
|
||||
|
||||
@@ -69,18 +64,18 @@ impl StdDevPerBlockExtended {
|
||||
}
|
||||
|
||||
macro_rules! import_band {
|
||||
($suffix:expr) => {
|
||||
($suffix:expr) => {{
|
||||
StdDevBand {
|
||||
value: import!(concat!("ratio_", $suffix)),
|
||||
ratio: import!(concat!("ratio_", $suffix)),
|
||||
price: import_price!($suffix),
|
||||
}
|
||||
};
|
||||
}};
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
days,
|
||||
sd: import!("sd"),
|
||||
zscore: import!("zscore"),
|
||||
sd: import!("ratio_sd"),
|
||||
zscore: import!("ratio_zscore"),
|
||||
_0sd: import_price!("0sd"),
|
||||
p0_5sd: import_band!("p0_5sd"),
|
||||
p1sd: import_band!("p1sd"),
|
||||
@@ -106,12 +101,9 @@ impl StdDevPerBlockExtended {
|
||||
sma: &impl ReadableVec<Height, StoredF32>,
|
||||
) -> Result<()> {
|
||||
if self.days == usize::MAX {
|
||||
self.sd.height.compute_expanding_sd(
|
||||
starting_indexes.height,
|
||||
source,
|
||||
sma,
|
||||
exit,
|
||||
)?;
|
||||
self.sd
|
||||
.height
|
||||
.compute_expanding_sd(starting_indexes.height, source, sma, exit)?;
|
||||
} else {
|
||||
let window_starts = blocks.lookback.start_vec(self.days);
|
||||
self.sd.height.compute_rolling_sd(
|
||||
@@ -154,10 +146,7 @@ impl StdDevPerBlockExtended {
|
||||
let source_data = source.collect_range_at(start, source_len);
|
||||
|
||||
let sma_data = sma.collect_range_at(start, sma.len());
|
||||
let sd_data = self
|
||||
.sd
|
||||
.height
|
||||
.collect_range_at(start, self.sd.height.len());
|
||||
let sd_data = self.sd.height.collect_range_at(start, self.sd.height.len());
|
||||
|
||||
const MULTIPLIERS: [f32; 12] = [
|
||||
0.5, 1.0, 1.5, 2.0, 2.5, 3.0, -0.5, -1.0, -1.5, -2.0, -2.5, -3.0,
|
||||
@@ -208,18 +197,18 @@ impl StdDevPerBlockExtended {
|
||||
}
|
||||
|
||||
compute_band_price!(&mut self._0sd, sma);
|
||||
compute_band_price!(&mut self.p0_5sd.price, &self.p0_5sd.value.height);
|
||||
compute_band_price!(&mut self.p1sd.price, &self.p1sd.value.height);
|
||||
compute_band_price!(&mut self.p1_5sd.price, &self.p1_5sd.value.height);
|
||||
compute_band_price!(&mut self.p2sd.price, &self.p2sd.value.height);
|
||||
compute_band_price!(&mut self.p2_5sd.price, &self.p2_5sd.value.height);
|
||||
compute_band_price!(&mut self.p3sd.price, &self.p3sd.value.height);
|
||||
compute_band_price!(&mut self.m0_5sd.price, &self.m0_5sd.value.height);
|
||||
compute_band_price!(&mut self.m1sd.price, &self.m1sd.value.height);
|
||||
compute_band_price!(&mut self.m1_5sd.price, &self.m1_5sd.value.height);
|
||||
compute_band_price!(&mut self.m2sd.price, &self.m2sd.value.height);
|
||||
compute_band_price!(&mut self.m2_5sd.price, &self.m2_5sd.value.height);
|
||||
compute_band_price!(&mut self.m3sd.price, &self.m3sd.value.height);
|
||||
compute_band_price!(&mut self.p0_5sd.price, &self.p0_5sd.ratio.height);
|
||||
compute_band_price!(&mut self.p1sd.price, &self.p1sd.ratio.height);
|
||||
compute_band_price!(&mut self.p1_5sd.price, &self.p1_5sd.ratio.height);
|
||||
compute_band_price!(&mut self.p2sd.price, &self.p2sd.ratio.height);
|
||||
compute_band_price!(&mut self.p2_5sd.price, &self.p2_5sd.ratio.height);
|
||||
compute_band_price!(&mut self.p3sd.price, &self.p3sd.ratio.height);
|
||||
compute_band_price!(&mut self.m0_5sd.price, &self.m0_5sd.ratio.height);
|
||||
compute_band_price!(&mut self.m1sd.price, &self.m1sd.ratio.height);
|
||||
compute_band_price!(&mut self.m1_5sd.price, &self.m1_5sd.ratio.height);
|
||||
compute_band_price!(&mut self.m2sd.price, &self.m2sd.ratio.height);
|
||||
compute_band_price!(&mut self.m2_5sd.price, &self.m2_5sd.ratio.height);
|
||||
compute_band_price!(&mut self.m3sd.price, &self.m3sd.ratio.height);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -228,18 +217,18 @@ impl StdDevPerBlockExtended {
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = &mut EagerVec<PcoVec<Height, StoredF32>>> {
|
||||
[
|
||||
&mut self.p0_5sd.value.height,
|
||||
&mut self.p1sd.value.height,
|
||||
&mut self.p1_5sd.value.height,
|
||||
&mut self.p2sd.value.height,
|
||||
&mut self.p2_5sd.value.height,
|
||||
&mut self.p3sd.value.height,
|
||||
&mut self.m0_5sd.value.height,
|
||||
&mut self.m1sd.value.height,
|
||||
&mut self.m1_5sd.value.height,
|
||||
&mut self.m2sd.value.height,
|
||||
&mut self.m2_5sd.value.height,
|
||||
&mut self.m3sd.value.height,
|
||||
&mut self.p0_5sd.ratio.height,
|
||||
&mut self.p1sd.ratio.height,
|
||||
&mut self.p1_5sd.ratio.height,
|
||||
&mut self.p2sd.ratio.height,
|
||||
&mut self.p2_5sd.ratio.height,
|
||||
&mut self.p3sd.ratio.height,
|
||||
&mut self.m0_5sd.ratio.height,
|
||||
&mut self.m1sd.ratio.height,
|
||||
&mut self.m1_5sd.ratio.height,
|
||||
&mut self.m2sd.ratio.height,
|
||||
&mut self.m2_5sd.ratio.height,
|
||||
&mut self.m3sd.ratio.height,
|
||||
]
|
||||
.into_iter()
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ pub fn main() -> color_eyre::Result<()> {
|
||||
.to_path_buf();
|
||||
|
||||
let output_paths = brk_bindgen::ClientOutputPaths::new()
|
||||
.rust(workspace_root.join("crates/brk_client/src/lib.rs"))
|
||||
.javascript(workspace_root.join("website/scripts/modules/brk-client/index.js"));
|
||||
|
||||
generate_bindings(&vecs, &openapi, &output_paths)?;
|
||||
|
||||
+125
-204
@@ -1656,18 +1656,18 @@ function createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65
|
||||
/**
|
||||
* @typedef {Object} _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern
|
||||
* @property {CentsSatsUsdPattern} _0sd
|
||||
* @property {PriceValuePattern} m05sd
|
||||
* @property {PriceValuePattern} m15sd
|
||||
* @property {PriceValuePattern} m1sd
|
||||
* @property {PriceValuePattern} m25sd
|
||||
* @property {PriceValuePattern} m2sd
|
||||
* @property {PriceValuePattern} m3sd
|
||||
* @property {PriceValuePattern} p05sd
|
||||
* @property {PriceValuePattern} p15sd
|
||||
* @property {PriceValuePattern} p1sd
|
||||
* @property {PriceValuePattern} p25sd
|
||||
* @property {PriceValuePattern} p2sd
|
||||
* @property {PriceValuePattern} p3sd
|
||||
* @property {PriceRatioPattern} m05sd
|
||||
* @property {PriceRatioPattern} m15sd
|
||||
* @property {PriceRatioPattern} m1sd
|
||||
* @property {PriceRatioPattern} m25sd
|
||||
* @property {PriceRatioPattern} m2sd
|
||||
* @property {PriceRatioPattern} m3sd
|
||||
* @property {PriceRatioPattern} p05sd
|
||||
* @property {PriceRatioPattern} p15sd
|
||||
* @property {PriceRatioPattern} p1sd
|
||||
* @property {PriceRatioPattern} p25sd
|
||||
* @property {PriceRatioPattern} p2sd
|
||||
* @property {PriceRatioPattern} p3sd
|
||||
* @property {MetricPattern1<StoredF32>} sd
|
||||
* @property {MetricPattern1<StoredF32>} zscore
|
||||
*/
|
||||
@@ -1676,25 +1676,26 @@ function createPct05Pct10Pct15Pct20Pct25Pct30Pct35Pct40Pct45Pct50Pct55Pct60Pct65
|
||||
* Create a _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @param {string} disc - Discriminator suffix
|
||||
* @returns {_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern}
|
||||
*/
|
||||
function create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc) {
|
||||
function create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, disc) {
|
||||
return {
|
||||
_0sd: createCentsSatsUsdPattern(client, _m(acc, '0sd_4y')),
|
||||
m05sd: createPriceValuePattern(client, acc),
|
||||
m15sd: createPriceValuePattern(client, acc),
|
||||
m1sd: createPriceValuePattern(client, acc),
|
||||
m25sd: createPriceValuePattern(client, acc),
|
||||
m2sd: createPriceValuePattern(client, acc),
|
||||
m3sd: createPriceValuePattern(client, acc),
|
||||
p05sd: createPriceValuePattern(client, acc),
|
||||
p15sd: createPriceValuePattern(client, acc),
|
||||
p1sd: createPriceValuePattern(client, acc),
|
||||
p25sd: createPriceValuePattern(client, acc),
|
||||
p2sd: createPriceValuePattern(client, acc),
|
||||
p3sd: createPriceValuePattern(client, acc),
|
||||
sd: createMetricPattern1(client, _m(acc, 'sd_4y')),
|
||||
zscore: createMetricPattern1(client, _m(acc, 'zscore_4y')),
|
||||
_0sd: createCentsSatsUsdPattern(client, _m(_m(acc, '0sd'), disc)),
|
||||
m05sd: createPriceRatioPattern(client, acc, _m('m0_5sd', disc)),
|
||||
m15sd: createPriceRatioPattern(client, acc, _m('m1_5sd', disc)),
|
||||
m1sd: createPriceRatioPattern(client, acc, _m('m1sd', disc)),
|
||||
m25sd: createPriceRatioPattern(client, acc, _m('m2_5sd', disc)),
|
||||
m2sd: createPriceRatioPattern(client, acc, _m('m2sd', disc)),
|
||||
m3sd: createPriceRatioPattern(client, acc, _m('m3sd', disc)),
|
||||
p05sd: createPriceRatioPattern(client, acc, _m('p0_5sd', disc)),
|
||||
p15sd: createPriceRatioPattern(client, acc, _m('p1_5sd', disc)),
|
||||
p1sd: createPriceRatioPattern(client, acc, _m('p1sd', disc)),
|
||||
p25sd: createPriceRatioPattern(client, acc, _m('p2_5sd', disc)),
|
||||
p2sd: createPriceRatioPattern(client, acc, _m('p2sd', disc)),
|
||||
p3sd: createPriceRatioPattern(client, acc, _m('p3sd', disc)),
|
||||
sd: createMetricPattern1(client, _m(_m(acc, 'ratio_sd'), disc)),
|
||||
zscore: createMetricPattern1(client, _m(_m(acc, 'ratio_zscore'), disc)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1907,20 +1908,21 @@ function createAverageBaseCumulativeMaxMedianMinPct10Pct25Pct75Pct90SumPattern(c
|
||||
* Create a AverageGainsLossesRsiStochPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @param {string} disc - Discriminator suffix
|
||||
* @returns {AverageGainsLossesRsiStochPattern}
|
||||
*/
|
||||
function createAverageGainsLossesRsiStochPattern(client, acc) {
|
||||
function createAverageGainsLossesRsiStochPattern(client, acc, disc) {
|
||||
return {
|
||||
averageGain: createMetricPattern1(client, _m(acc, 'average_gain_24h')),
|
||||
averageLoss: createMetricPattern1(client, _m(acc, 'average_loss_24h')),
|
||||
gains: createMetricPattern1(client, _m(acc, 'gains_24h')),
|
||||
losses: createMetricPattern1(client, _m(acc, 'losses_24h')),
|
||||
rsi: createBpsPercentRatioPattern3(client, _m(acc, '24h')),
|
||||
rsiMax: createBpsPercentRatioPattern3(client, _m(acc, 'max_24h')),
|
||||
rsiMin: createBpsPercentRatioPattern3(client, _m(acc, 'min_24h')),
|
||||
stochRsi: createBpsPercentRatioPattern3(client, _m(acc, 'stoch_24h')),
|
||||
stochRsiD: createBpsPercentRatioPattern3(client, _m(acc, 'stoch_d_24h')),
|
||||
stochRsiK: createBpsPercentRatioPattern3(client, _m(acc, 'stoch_k_24h')),
|
||||
averageGain: createMetricPattern1(client, _m(_m(acc, 'average_gain'), disc)),
|
||||
averageLoss: createMetricPattern1(client, _m(_m(acc, 'average_loss'), disc)),
|
||||
gains: createMetricPattern1(client, _m(_m(acc, 'gains'), disc)),
|
||||
losses: createMetricPattern1(client, _m(_m(acc, 'losses'), disc)),
|
||||
rsi: createBpsPercentRatioPattern3(client, _m(acc, disc)),
|
||||
rsiMax: createBpsPercentRatioPattern3(client, _m(_m(acc, 'max'), disc)),
|
||||
rsiMin: createBpsPercentRatioPattern3(client, _m(_m(acc, 'min'), disc)),
|
||||
stochRsi: createBpsPercentRatioPattern3(client, _m(_m(acc, 'stoch'), disc)),
|
||||
stochRsiD: createBpsPercentRatioPattern3(client, _m(_m(acc, 'stoch_d'), disc)),
|
||||
stochRsiK: createBpsPercentRatioPattern3(client, _m(_m(acc, 'stoch_k'), disc)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2078,7 +2080,7 @@ function createBpsCentsPercentilesRatioSatsSmaStdUsdPattern(client, acc) {
|
||||
ratio: createMetricPattern1(client, _m(acc, 'ratio')),
|
||||
sats: createMetricPattern1(client, _m(acc, 'sats')),
|
||||
sma: create_1m1w1y2y4yAllPattern(client, _m(acc, 'ratio_sma')),
|
||||
stdDev: create_1y2y4yAllPattern(client, _m(acc, 'ratio')),
|
||||
stdDev: create_1y2y4yAllPattern(client, acc),
|
||||
usd: createMetricPattern1(client, acc),
|
||||
};
|
||||
}
|
||||
@@ -2252,7 +2254,7 @@ function createBaseCumulativeNegativeRelSumPattern2(client, acc) {
|
||||
function createCapLossMvrvNetPriceProfitSoprPattern(client, acc) {
|
||||
return {
|
||||
cap: createCentsDeltaUsdPattern(client, _m(acc, 'realized_cap')),
|
||||
loss: createBaseCumulativeNegativeSumPattern(client, acc),
|
||||
loss: createBaseCumulativeNegativeSumPattern(client, acc, ''),
|
||||
mvrv: createMetricPattern1(client, _m(acc, 'mvrv')),
|
||||
netPnl: createBaseCumulativeDeltaSumPattern(client, _m(acc, 'net_realized_pnl')),
|
||||
price: createBpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price')),
|
||||
@@ -2524,12 +2526,12 @@ function createDeltaHalfInRelTotalPattern2(client, acc) {
|
||||
*/
|
||||
function createPct1Pct2Pct5Pct95Pct98Pct99Pattern(client, acc) {
|
||||
return {
|
||||
pct1: createBpsPriceRatioPattern(client, acc),
|
||||
pct2: createBpsPriceRatioPattern(client, acc),
|
||||
pct5: createBpsPriceRatioPattern(client, acc),
|
||||
pct95: createBpsPriceRatioPattern(client, acc),
|
||||
pct98: createBpsPriceRatioPattern(client, acc),
|
||||
pct99: createBpsPriceRatioPattern(client, acc),
|
||||
pct1: createBpsPriceRatioPattern(client, acc, 'pct1'),
|
||||
pct2: createBpsPriceRatioPattern(client, acc, 'pct2'),
|
||||
pct5: createBpsPriceRatioPattern(client, acc, 'pct5'),
|
||||
pct95: createBpsPriceRatioPattern(client, acc, 'pct95'),
|
||||
pct98: createBpsPriceRatioPattern(client, acc, 'pct98'),
|
||||
pct99: createBpsPriceRatioPattern(client, acc, 'pct99'),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2750,11 +2752,11 @@ function createDeltaHalfInTotalPattern2(client, acc) {
|
||||
*/
|
||||
function createEmaHistogramLineSignalPattern(client, acc) {
|
||||
return {
|
||||
emaFast: createMetricPattern1(client, _m(acc, 'ema_fast_24h')),
|
||||
emaSlow: createMetricPattern1(client, _m(acc, 'ema_slow_24h')),
|
||||
histogram: createMetricPattern1(client, _m(acc, 'histogram_24h')),
|
||||
line: createMetricPattern1(client, _m(acc, 'line_24h')),
|
||||
signal: createMetricPattern1(client, _m(acc, 'signal_24h')),
|
||||
emaFast: createMetricPattern1(client, `${acc}_ema_fast`),
|
||||
emaSlow: createMetricPattern1(client, `${acc}_ema_slow`),
|
||||
histogram: createMetricPattern1(client, `${acc}_histogram`),
|
||||
line: createMetricPattern1(client, `${acc}_line`),
|
||||
signal: createMetricPattern1(client, `${acc}_signal`),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3014,10 +3016,10 @@ function create_1m1w1y24hPattern4(client, acc) {
|
||||
*/
|
||||
function create_1y2y4yAllPattern(client, acc) {
|
||||
return {
|
||||
_1y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc),
|
||||
_2y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc),
|
||||
_4y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc),
|
||||
all: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc),
|
||||
_1y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, ''),
|
||||
_2y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, ''),
|
||||
_4y: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, ''),
|
||||
all: create_0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, ''),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3079,14 +3081,15 @@ function createBaseCumulativeDeltaSumPattern(client, acc) {
|
||||
* Create a BaseCumulativeNegativeSumPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @param {string} disc - Discriminator suffix
|
||||
* @returns {BaseCumulativeNegativeSumPattern}
|
||||
*/
|
||||
function createBaseCumulativeNegativeSumPattern(client, acc) {
|
||||
function createBaseCumulativeNegativeSumPattern(client, acc, disc) {
|
||||
return {
|
||||
base: createCentsUsdPattern2(client, _m(acc, 'unrealized_loss')),
|
||||
cumulative: createCentsUsdPattern2(client, _m(acc, 'unrealized_loss_cumulative')),
|
||||
negative: createMetricPattern1(client, _m(acc, 'neg_unrealized_loss')),
|
||||
sum: create_1m1w1y24hPattern4(client, _m(acc, 'unrealized_loss_sum')),
|
||||
base: createCentsUsdPattern2(client, _m(acc, disc)),
|
||||
cumulative: createCentsUsdPattern2(client, _m(acc, `${disc}_cumulative`)),
|
||||
negative: createMetricPattern1(client, _m(_m(acc, 'neg'), disc)),
|
||||
sum: create_1m1w1y24hPattern4(client, _m(acc, `${disc}_sum`)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3221,7 +3224,7 @@ function createCoindaysCoinyearsDormancySentPattern(client, acc) {
|
||||
*/
|
||||
function createLossNetNuplProfitPattern(client, acc) {
|
||||
return {
|
||||
loss: createBaseCumulativeNegativeSumPattern(client, acc),
|
||||
loss: createBaseCumulativeNegativeSumPattern(client, acc, ''),
|
||||
netPnl: createCentsUsdPattern(client, _m(acc, 'net_unrealized_pnl')),
|
||||
nupl: createBpsRatioPattern(client, _m(acc, 'nupl')),
|
||||
profit: createBaseCumulativeSumPattern3(client, _m(acc, 'unrealized_profit')),
|
||||
@@ -3457,13 +3460,14 @@ function createBpsPercentRatioPattern4(client, acc) {
|
||||
* Create a BpsPriceRatioPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @param {string} disc - Discriminator suffix
|
||||
* @returns {BpsPriceRatioPattern}
|
||||
*/
|
||||
function createBpsPriceRatioPattern(client, acc) {
|
||||
function createBpsPriceRatioPattern(client, acc, disc) {
|
||||
return {
|
||||
bps: createMetricPattern1(client, _m(acc, 'ratio_pct99_bps')),
|
||||
price: createCentsSatsUsdPattern(client, _m(acc, 'pct99')),
|
||||
ratio: createMetricPattern1(client, _m(acc, 'ratio_pct99')),
|
||||
bps: createMetricPattern1(client, _m(acc, `ratio_${disc}_bps`)),
|
||||
price: createCentsSatsUsdPattern(client, _m(acc, disc)),
|
||||
ratio: createMetricPattern1(client, _m(_m(acc, 'ratio'), disc)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3629,7 +3633,7 @@ function createGreedNetPainPattern(client, acc) {
|
||||
*/
|
||||
function createLossNuplProfitPattern(client, acc) {
|
||||
return {
|
||||
loss: createBaseCumulativeNegativeSumPattern(client, acc),
|
||||
loss: createBaseCumulativeNegativeSumPattern(client, acc, ''),
|
||||
nupl: createBpsRatioPattern(client, _m(acc, 'nupl')),
|
||||
profit: createBaseCumulativeSumPattern3(client, _m(acc, 'unrealized_profit')),
|
||||
};
|
||||
@@ -3671,9 +3675,9 @@ function createLowerPriceUpperPattern(client, acc) {
|
||||
*/
|
||||
function createRatioValuePattern2(client, acc) {
|
||||
return {
|
||||
ratio: create_1m1w1y24hPattern(client, _m(acc, 'asopr')),
|
||||
valueCreated: createBaseCumulativeSumPattern(client, _m(acc, 'adj_value_created')),
|
||||
valueDestroyed: createBaseCumulativeSumPattern(client, _m(acc, 'adj_value_destroyed')),
|
||||
ratio: create_1m1w1y24hPattern(client, `${acc}_ratio`),
|
||||
valueCreated: createBaseCumulativeSumPattern(client, `${acc}_value_created`),
|
||||
valueDestroyed: createBaseCumulativeSumPattern(client, `${acc}_value_destroyed`),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3973,21 +3977,22 @@ function createInPattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} PriceValuePattern
|
||||
* @typedef {Object} PriceRatioPattern
|
||||
* @property {CentsSatsUsdPattern} price
|
||||
* @property {MetricPattern1<StoredF32>} value
|
||||
* @property {MetricPattern1<StoredF32>} ratio
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a PriceValuePattern pattern node
|
||||
* Create a PriceRatioPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {PriceValuePattern}
|
||||
* @param {string} disc - Discriminator suffix
|
||||
* @returns {PriceRatioPattern}
|
||||
*/
|
||||
function createPriceValuePattern(client, acc) {
|
||||
function createPriceRatioPattern(client, acc, disc) {
|
||||
return {
|
||||
price: createCentsSatsUsdPattern(client, _m(acc, 'p3sd_4y')),
|
||||
value: createMetricPattern1(client, _m(acc, 'ratio_p3sd_4y')),
|
||||
price: createCentsSatsUsdPattern(client, _m(acc, disc)),
|
||||
ratio: createMetricPattern1(client, _m(_m(acc, 'ratio'), disc)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4024,8 +4029,8 @@ function createRelPattern(client, acc) {
|
||||
*/
|
||||
function createSdSmaPattern(client, acc) {
|
||||
return {
|
||||
sd: createMetricPattern1(client, _m(acc, 'sd_1y')),
|
||||
sma: createMetricPattern1(client, _m(acc, 'sma_1y')),
|
||||
sd: createMetricPattern1(client, `${acc}_sd`),
|
||||
sma: createMetricPattern1(client, `${acc}_sma`),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5051,7 +5056,7 @@ function createUnspentPattern(client, acc) {
|
||||
* @typedef {Object} MetricsTree_Market_Returns_Sd24h
|
||||
* @property {MetricsTree_Market_Returns_Sd24h_1w} _1w
|
||||
* @property {MetricsTree_Market_Returns_Sd24h_1m} _1m
|
||||
* @property {SdSmaPattern} _1y
|
||||
* @property {MetricsTree_Market_Returns_Sd24h_1y} _1y
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -5066,6 +5071,12 @@ function createUnspentPattern(client, acc) {
|
||||
* @property {MetricPattern1<StoredF32>} sd
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Returns_Sd24h_1y
|
||||
* @property {MetricPattern1<StoredF32>} sma
|
||||
* @property {MetricPattern1<StoredF32>} sd
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Volatility
|
||||
* @property {MetricPattern1<StoredF32>} _1w
|
||||
@@ -5115,22 +5126,8 @@ function createUnspentPattern(client, acc) {
|
||||
* @property {MetricPattern1<SatsFract>} sats
|
||||
* @property {MetricPattern1<BasisPoints32>} bps
|
||||
* @property {MetricPattern1<StoredF32>} ratio
|
||||
* @property {MetricsTree_Market_MovingAverage_Sma_200d_X24} x24
|
||||
* @property {MetricsTree_Market_MovingAverage_Sma_200d_X08} x08
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_MovingAverage_Sma_200d_X24
|
||||
* @property {MetricPattern1<Dollars>} usd
|
||||
* @property {MetricPattern1<Cents>} cents
|
||||
* @property {MetricPattern1<SatsFract>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_MovingAverage_Sma_200d_X08
|
||||
* @property {MetricPattern1<Dollars>} usd
|
||||
* @property {MetricPattern1<Cents>} cents
|
||||
* @property {MetricPattern1<SatsFract>} sats
|
||||
* @property {CentsSatsUsdPattern} x24
|
||||
* @property {CentsSatsUsdPattern} x08
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -5140,14 +5137,7 @@ function createUnspentPattern(client, acc) {
|
||||
* @property {MetricPattern1<SatsFract>} sats
|
||||
* @property {MetricPattern1<BasisPoints32>} bps
|
||||
* @property {MetricPattern1<StoredF32>} ratio
|
||||
* @property {MetricsTree_Market_MovingAverage_Sma_350d_X2} x2
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_MovingAverage_Sma_350d_X2
|
||||
* @property {MetricPattern1<Dollars>} usd
|
||||
* @property {MetricPattern1<Cents>} cents
|
||||
* @property {MetricPattern1<SatsFract>} sats
|
||||
* @property {CentsSatsUsdPattern} x2
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -5270,61 +5260,28 @@ function createUnspentPattern(client, acc) {
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Rsi
|
||||
* @property {AverageGainsLossesRsiStochPattern} _24h
|
||||
* @property {MetricsTree_Market_Technical_Rsi_1w} _1w
|
||||
* @property {MetricsTree_Market_Technical_Rsi_1m} _1m
|
||||
* @property {MetricsTree_Market_Technical_Rsi_1y} _1y
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Rsi_1w
|
||||
* @property {MetricPattern1<StoredF32>} gains
|
||||
* @property {MetricPattern1<StoredF32>} losses
|
||||
* @property {MetricPattern1<StoredF32>} averageGain
|
||||
* @property {MetricPattern1<StoredF32>} averageLoss
|
||||
* @property {BpsPercentRatioPattern3} rsi
|
||||
* @property {BpsPercentRatioPattern3} rsiMin
|
||||
* @property {BpsPercentRatioPattern3} rsiMax
|
||||
* @property {BpsPercentRatioPattern3} stochRsi
|
||||
* @property {BpsPercentRatioPattern3} stochRsiK
|
||||
* @property {BpsPercentRatioPattern3} stochRsiD
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Rsi_1m
|
||||
* @property {MetricPattern1<StoredF32>} gains
|
||||
* @property {MetricPattern1<StoredF32>} losses
|
||||
* @property {MetricPattern1<StoredF32>} averageGain
|
||||
* @property {MetricPattern1<StoredF32>} averageLoss
|
||||
* @property {BpsPercentRatioPattern3} rsi
|
||||
* @property {BpsPercentRatioPattern3} rsiMin
|
||||
* @property {BpsPercentRatioPattern3} rsiMax
|
||||
* @property {BpsPercentRatioPattern3} stochRsi
|
||||
* @property {BpsPercentRatioPattern3} stochRsiK
|
||||
* @property {BpsPercentRatioPattern3} stochRsiD
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Rsi_1y
|
||||
* @property {MetricPattern1<StoredF32>} gains
|
||||
* @property {MetricPattern1<StoredF32>} losses
|
||||
* @property {MetricPattern1<StoredF32>} averageGain
|
||||
* @property {MetricPattern1<StoredF32>} averageLoss
|
||||
* @property {BpsPercentRatioPattern3} rsi
|
||||
* @property {BpsPercentRatioPattern3} rsiMin
|
||||
* @property {BpsPercentRatioPattern3} rsiMax
|
||||
* @property {BpsPercentRatioPattern3} stochRsi
|
||||
* @property {BpsPercentRatioPattern3} stochRsiK
|
||||
* @property {BpsPercentRatioPattern3} stochRsiD
|
||||
* @property {AverageGainsLossesRsiStochPattern} _1w
|
||||
* @property {AverageGainsLossesRsiStochPattern} _1m
|
||||
* @property {AverageGainsLossesRsiStochPattern} _1y
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Macd
|
||||
* @property {EmaHistogramLineSignalPattern} _24h
|
||||
* @property {MetricsTree_Market_Technical_Macd_24h} _24h
|
||||
* @property {MetricsTree_Market_Technical_Macd_1w} _1w
|
||||
* @property {MetricsTree_Market_Technical_Macd_1m} _1m
|
||||
* @property {MetricsTree_Market_Technical_Macd_1y} _1y
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Macd_24h
|
||||
* @property {MetricPattern1<StoredF32>} emaFast
|
||||
* @property {MetricPattern1<StoredF32>} emaSlow
|
||||
* @property {MetricPattern1<StoredF32>} line
|
||||
* @property {MetricPattern1<StoredF32>} signal
|
||||
* @property {MetricPattern1<StoredF32>} histogram
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} MetricsTree_Market_Technical_Macd_1w
|
||||
* @property {MetricPattern1<StoredF32>} emaFast
|
||||
@@ -7845,7 +7802,10 @@ class BrkClient extends BrkClientBase {
|
||||
sma: createMetricPattern1(this, 'price_return_24h_sma_1m'),
|
||||
sd: createMetricPattern1(this, 'price_return_24h_sd_1m'),
|
||||
},
|
||||
_1y: createSdSmaPattern(this, 'price_return_24h'),
|
||||
_1y: {
|
||||
sma: createMetricPattern1(this, 'price_return_24h_sma_1y'),
|
||||
sd: createMetricPattern1(this, 'price_return_24h_sd_1y'),
|
||||
},
|
||||
},
|
||||
},
|
||||
volatility: {
|
||||
@@ -7878,16 +7838,8 @@ class BrkClient extends BrkClientBase {
|
||||
sats: createMetricPattern1(this, 'price_sma_200d_sats'),
|
||||
bps: createMetricPattern1(this, 'price_sma_200d_ratio_bps'),
|
||||
ratio: createMetricPattern1(this, 'price_sma_200d_ratio'),
|
||||
x24: {
|
||||
usd: createMetricPattern1(this, 'price_sma_200d_x2_4_usd'),
|
||||
cents: createMetricPattern1(this, 'price_sma_200d_x2_4_cents'),
|
||||
sats: createMetricPattern1(this, 'price_sma_200d_x2_4_sats'),
|
||||
},
|
||||
x08: {
|
||||
usd: createMetricPattern1(this, 'price_sma_200d_x0_8_usd'),
|
||||
cents: createMetricPattern1(this, 'price_sma_200d_x0_8_cents'),
|
||||
sats: createMetricPattern1(this, 'price_sma_200d_x0_8_sats'),
|
||||
},
|
||||
x24: createCentsSatsUsdPattern(this, 'price_sma_200d_x2_4'),
|
||||
x08: createCentsSatsUsdPattern(this, 'price_sma_200d_x0_8'),
|
||||
},
|
||||
_350d: {
|
||||
usd: createMetricPattern1(this, 'price_sma_350d'),
|
||||
@@ -7895,11 +7847,7 @@ class BrkClient extends BrkClientBase {
|
||||
sats: createMetricPattern1(this, 'price_sma_350d_sats'),
|
||||
bps: createMetricPattern1(this, 'price_sma_350d_ratio_bps'),
|
||||
ratio: createMetricPattern1(this, 'price_sma_350d_ratio'),
|
||||
x2: {
|
||||
usd: createMetricPattern1(this, 'price_sma_350d_x2_usd'),
|
||||
cents: createMetricPattern1(this, 'price_sma_350d_x2_cents'),
|
||||
sats: createMetricPattern1(this, 'price_sma_350d_x2_sats'),
|
||||
},
|
||||
x2: createCentsSatsUsdPattern(this, 'price_sma_350d_x2'),
|
||||
},
|
||||
_1y: createBpsCentsRatioSatsUsdPattern(this, 'price_sma_1y'),
|
||||
_2y: createBpsCentsRatioSatsUsdPattern(this, 'price_sma_2y'),
|
||||
@@ -7995,49 +7943,22 @@ class BrkClient extends BrkClientBase {
|
||||
},
|
||||
technical: {
|
||||
rsi: {
|
||||
_24h: createAverageGainsLossesRsiStochPattern(this, 'rsi'),
|
||||
_1w: {
|
||||
gains: createMetricPattern1(this, 'rsi_gains_1w'),
|
||||
losses: createMetricPattern1(this, 'rsi_losses_1w'),
|
||||
averageGain: createMetricPattern1(this, 'rsi_average_gain_1w'),
|
||||
averageLoss: createMetricPattern1(this, 'rsi_average_loss_1w'),
|
||||
rsi: createBpsPercentRatioPattern3(this, 'rsi_1w'),
|
||||
rsiMin: createBpsPercentRatioPattern3(this, 'rsi_min_1w'),
|
||||
rsiMax: createBpsPercentRatioPattern3(this, 'rsi_max_1w'),
|
||||
stochRsi: createBpsPercentRatioPattern3(this, 'rsi_stoch_1w'),
|
||||
stochRsiK: createBpsPercentRatioPattern3(this, 'rsi_stoch_k_1w'),
|
||||
stochRsiD: createBpsPercentRatioPattern3(this, 'rsi_stoch_d_1w'),
|
||||
},
|
||||
_1m: {
|
||||
gains: createMetricPattern1(this, 'rsi_gains_1m'),
|
||||
losses: createMetricPattern1(this, 'rsi_losses_1m'),
|
||||
averageGain: createMetricPattern1(this, 'rsi_average_gain_1m'),
|
||||
averageLoss: createMetricPattern1(this, 'rsi_average_loss_1m'),
|
||||
rsi: createBpsPercentRatioPattern3(this, 'rsi_1m'),
|
||||
rsiMin: createBpsPercentRatioPattern3(this, 'rsi_min_1m'),
|
||||
rsiMax: createBpsPercentRatioPattern3(this, 'rsi_max_1m'),
|
||||
stochRsi: createBpsPercentRatioPattern3(this, 'rsi_stoch_1m'),
|
||||
stochRsiK: createBpsPercentRatioPattern3(this, 'rsi_stoch_k_1m'),
|
||||
stochRsiD: createBpsPercentRatioPattern3(this, 'rsi_stoch_d_1m'),
|
||||
},
|
||||
_1y: {
|
||||
gains: createMetricPattern1(this, 'rsi_gains_1y'),
|
||||
losses: createMetricPattern1(this, 'rsi_losses_1y'),
|
||||
averageGain: createMetricPattern1(this, 'rsi_average_gain_1y'),
|
||||
averageLoss: createMetricPattern1(this, 'rsi_average_loss_1y'),
|
||||
rsi: createBpsPercentRatioPattern3(this, 'rsi_1y'),
|
||||
rsiMin: createBpsPercentRatioPattern3(this, 'rsi_min_1y'),
|
||||
rsiMax: createBpsPercentRatioPattern3(this, 'rsi_max_1y'),
|
||||
stochRsi: createBpsPercentRatioPattern3(this, 'rsi_stoch_1y'),
|
||||
stochRsiK: createBpsPercentRatioPattern3(this, 'rsi_stoch_k_1y'),
|
||||
stochRsiD: createBpsPercentRatioPattern3(this, 'rsi_stoch_d_1y'),
|
||||
},
|
||||
_24h: createAverageGainsLossesRsiStochPattern(this, 'rsi', '24h'),
|
||||
_1w: createAverageGainsLossesRsiStochPattern(this, 'rsi', '1w'),
|
||||
_1m: createAverageGainsLossesRsiStochPattern(this, 'rsi', '1m'),
|
||||
_1y: createAverageGainsLossesRsiStochPattern(this, 'rsi', '1y'),
|
||||
},
|
||||
stochK: createBpsPercentRatioPattern3(this, 'stoch_k'),
|
||||
stochD: createBpsPercentRatioPattern3(this, 'stoch_d'),
|
||||
piCycle: createBpsRatioPattern2(this, 'pi_cycle'),
|
||||
macd: {
|
||||
_24h: createEmaHistogramLineSignalPattern(this, 'macd'),
|
||||
_24h: {
|
||||
emaFast: createMetricPattern1(this, 'macd_ema_fast_24h'),
|
||||
emaSlow: createMetricPattern1(this, 'macd_ema_slow_24h'),
|
||||
line: createMetricPattern1(this, 'macd_line_24h'),
|
||||
signal: createMetricPattern1(this, 'macd_signal_24h'),
|
||||
histogram: createMetricPattern1(this, 'macd_histogram_24h'),
|
||||
},
|
||||
_1w: {
|
||||
emaFast: createMetricPattern1(this, 'macd_ema_fast_1w'),
|
||||
emaSlow: createMetricPattern1(this, 'macd_ema_slow_1w'),
|
||||
|
||||
@@ -2149,21 +2149,21 @@ class _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self._0sd: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, '0sd_4y'))
|
||||
self.m0_5sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.m1_5sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.m1sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.m2_5sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.m2sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.m3sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.p0_5sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.p1_5sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.p1sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.p2_5sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.p2sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.p3sd: PriceValuePattern = PriceValuePattern(client, acc)
|
||||
self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sd_4y'))
|
||||
self.zscore: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'zscore_4y'))
|
||||
self._0sd: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, f'0sd{disc}'))
|
||||
self.m0_5sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('m0_5sd', disc))
|
||||
self.m1_5sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('m1_5sd', disc))
|
||||
self.m1sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('m1sd', disc))
|
||||
self.m2_5sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('m2_5sd', disc))
|
||||
self.m2sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('m2sd', disc))
|
||||
self.m3sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('m3sd', disc))
|
||||
self.p0_5sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('p0_5sd', disc))
|
||||
self.p1_5sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('p1_5sd', disc))
|
||||
self.p1sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('p1sd', disc))
|
||||
self.p2_5sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('p2_5sd', disc))
|
||||
self.p2sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('p2sd', disc))
|
||||
self.p3sd: PriceRatioPattern = PriceRatioPattern(client, acc, _m('p3sd', disc))
|
||||
self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'ratio_sd{disc}'))
|
||||
self.zscore: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'ratio_zscore{disc}'))
|
||||
|
||||
class _10y1m1w1y2y3m3y4y5y6m6y8yPattern2:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2206,18 +2206,18 @@ class CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.cap: CentsDeltaRelUsdPattern = CentsDeltaRelUsdPattern(client, _m(acc, 'realized_cap'))
|
||||
self.gross_pnl: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, _m(acc, 'realized_gross_pnl'))
|
||||
self.investor: LowerPriceUpperPattern = LowerPriceUpperPattern(client, acc)
|
||||
self.loss: BaseCapitulationCumulativeNegativeRelSumValuePattern = BaseCapitulationCumulativeNegativeRelSumValuePattern(client, acc)
|
||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
||||
self.net_pnl: BaseChangeCumulativeDeltaRelSumPattern = BaseChangeCumulativeDeltaRelSumPattern(client, _m(acc, 'net'))
|
||||
self.peak_regret: BaseCumulativeRelPattern = BaseCumulativeRelPattern(client, _m(acc, 'realized_peak_regret'))
|
||||
self.price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern = BpsCentsPercentilesRatioSatsSmaStdUsdPattern(client, _m(acc, 'realized_price'))
|
||||
self.profit: BaseCumulativeDistributionRelSumValuePattern = BaseCumulativeDistributionRelSumValuePattern(client, acc)
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'realized_profit_to_loss_ratio'))
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern6 = _1m1w1y24hPattern6(client, _m(acc, 'sell_side_risk_ratio'))
|
||||
self.sopr: AdjustedRatioValuePattern = AdjustedRatioValuePattern(client, acc)
|
||||
self.cap: CentsDeltaRelUsdPattern = CentsDeltaRelUsdPattern(client, f'{acc}_cap')
|
||||
self.gross_pnl: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, f'{acc}_gross_pnl')
|
||||
self.investor: LowerPriceUpperPattern = LowerPriceUpperPattern(client, f'{acc}_investor')
|
||||
self.loss: BaseCapitulationCumulativeNegativeRelSumValuePattern = BaseCapitulationCumulativeNegativeRelSumValuePattern(client, f'{acc}_loss')
|
||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_mvrv')
|
||||
self.net_pnl: BaseChangeCumulativeDeltaRelSumPattern = BaseChangeCumulativeDeltaRelSumPattern(client, f'{acc}_net_pnl')
|
||||
self.peak_regret: BaseCumulativeRelPattern = BaseCumulativeRelPattern(client, f'{acc}_peak_regret')
|
||||
self.price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern = BpsCentsPercentilesRatioSatsSmaStdUsdPattern(client, f'{acc}_price')
|
||||
self.profit: BaseCumulativeDistributionRelSumValuePattern = BaseCumulativeDistributionRelSumValuePattern(client, f'{acc}_profit')
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, f'{acc}_profit_to_loss_ratio')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern6 = _1m1w1y24hPattern6(client, f'{acc}_sell_side_risk_ratio')
|
||||
self.sopr: AdjustedRatioValuePattern = AdjustedRatioValuePattern(client, f'{acc}_sopr')
|
||||
|
||||
class AverageCumulativeMaxMedianMinPct10Pct25Pct75Pct90RollingSumPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2258,16 +2258,16 @@ class AverageGainsLossesRsiStochPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.average_gain: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'average_gain_24h'))
|
||||
self.average_loss: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'average_loss_24h'))
|
||||
self.gains: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'gains_24h'))
|
||||
self.losses: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'losses_24h'))
|
||||
self.rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, '24h'))
|
||||
self.rsi_max: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, 'max_24h'))
|
||||
self.rsi_min: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, 'min_24h'))
|
||||
self.stoch_rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, 'stoch_24h'))
|
||||
self.stoch_rsi_d: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, 'stoch_d_24h'))
|
||||
self.stoch_rsi_k: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, 'stoch_k_24h'))
|
||||
self.average_gain: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'average_gain_{disc}'))
|
||||
self.average_loss: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'average_loss_{disc}'))
|
||||
self.gains: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'gains_{disc}'))
|
||||
self.losses: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'losses_{disc}'))
|
||||
self.rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, disc))
|
||||
self.rsi_max: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, f'max_{disc}'))
|
||||
self.rsi_min: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, f'min_{disc}'))
|
||||
self.stoch_rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, f'stoch_{disc}'))
|
||||
self.stoch_rsi_d: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, f'stoch_d_{disc}'))
|
||||
self.stoch_rsi_k: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, _m(acc, f'stoch_k_{disc}'))
|
||||
|
||||
class AllP2aP2pk33P2pk65P2pkhP2shP2trP2wpkhP2wshPattern3:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2338,7 +2338,7 @@ class BpsCentsPercentilesRatioSatsSmaStdUsdPattern:
|
||||
self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ratio'))
|
||||
self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, _m(acc, 'sats'))
|
||||
self.sma: _1m1w1y2y4yAllPattern = _1m1w1y2y4yAllPattern(client, _m(acc, 'ratio_sma'))
|
||||
self.std_dev: _1y2y4yAllPattern = _1y2y4yAllPattern(client, _m(acc, 'ratio'))
|
||||
self.std_dev: _1y2y4yAllPattern = _1y2y4yAllPattern(client, acc)
|
||||
self.usd: MetricPattern1[Dollars] = MetricPattern1(client, acc)
|
||||
|
||||
class AverageMaxMedianMinPct10Pct25Pct75Pct90Pattern2(Generic[T]):
|
||||
@@ -2413,12 +2413,12 @@ class CapLossMvrvNetPriceProfitSoprPattern:
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.cap: CentsDeltaUsdPattern = CentsDeltaUsdPattern(client, _m(acc, 'realized_cap'))
|
||||
self.loss: BaseCumulativeNegativeSumPattern = BaseCumulativeNegativeSumPattern(client, acc)
|
||||
self.loss: BaseCumulativeNegativeSumPattern = BaseCumulativeNegativeSumPattern(client, acc, '')
|
||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
||||
self.net_pnl: BaseCumulativeDeltaSumPattern = BaseCumulativeDeltaSumPattern(client, _m(acc, 'net_realized_pnl'))
|
||||
self.price: BpsCentsRatioSatsUsdPattern = BpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price'))
|
||||
self.profit: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, _m(acc, 'realized_profit'))
|
||||
self.sopr: RatioValuePattern = RatioValuePattern(client, acc)
|
||||
self.sopr: RatioValuePattern = RatioValuePattern(client, _m(acc, 'sopr_24h'))
|
||||
|
||||
class GrossInvestedLossNetNuplProfitSentimentPattern2:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2534,12 +2534,12 @@ class Pct1Pct2Pct5Pct95Pct98Pct99Pattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.pct1: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc)
|
||||
self.pct2: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc)
|
||||
self.pct5: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc)
|
||||
self.pct95: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc)
|
||||
self.pct98: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc)
|
||||
self.pct99: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc)
|
||||
self.pct1: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc, 'pct1')
|
||||
self.pct2: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc, 'pct2')
|
||||
self.pct5: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc, 'pct5')
|
||||
self.pct95: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc, 'pct95')
|
||||
self.pct98: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc, 'pct98')
|
||||
self.pct99: BpsPriceRatioPattern = BpsPriceRatioPattern(client, acc, 'pct99')
|
||||
|
||||
class ActivityOutputsRealizedSupplyUnrealizedPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2634,11 +2634,11 @@ class EmaHistogramLineSignalPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.ema_fast: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ema_fast_24h'))
|
||||
self.ema_slow: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ema_slow_24h'))
|
||||
self.histogram: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'histogram_24h'))
|
||||
self.line: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'line_24h'))
|
||||
self.signal: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'signal_24h'))
|
||||
self.ema_fast: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_ema_fast')
|
||||
self.ema_slow: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_ema_slow')
|
||||
self.histogram: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_histogram')
|
||||
self.line: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_line')
|
||||
self.signal: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_signal')
|
||||
|
||||
class InvestedMaxMinPercentilesSupplyPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2658,9 +2658,9 @@ class MvrvNuplRealizedSupplyPattern:
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'mvrv'))
|
||||
self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl'))
|
||||
self.realized_cap: AllSthPattern = AllSthPattern(client, acc)
|
||||
self.realized_cap: AllSthPattern = AllSthPattern(client, _m(acc, 'realized_cap'))
|
||||
self.realized_price: BpsCentsRatioSatsUsdPattern = BpsCentsRatioSatsUsdPattern(client, _m(acc, 'realized_price'))
|
||||
self.supply: AllSthPattern2 = AllSthPattern2(client, acc)
|
||||
self.supply: AllSthPattern2 = AllSthPattern2(client, _m(acc, 'supply'))
|
||||
|
||||
class PhsReboundThsPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2749,10 +2749,10 @@ class _1y2y4yAllPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self._1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc)
|
||||
self._2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc)
|
||||
self._4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc)
|
||||
self.all: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc)
|
||||
self._1y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, '1y')
|
||||
self._2y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, '2y')
|
||||
self._4y: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, '4y')
|
||||
self.all: _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern = _0sdM0M1M1sdM2M2sdM3sdP0P1P1sdP2P2sdP3sdSdZscorePattern(client, acc, '')
|
||||
|
||||
class AdjustedRatioValuePattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2779,10 +2779,10 @@ class BaseCumulativeNegativeSumPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.base: CentsUsdPattern2 = CentsUsdPattern2(client, _m(acc, 'unrealized_loss'))
|
||||
self.cumulative: CentsUsdPattern2 = CentsUsdPattern2(client, _m(acc, 'unrealized_loss_cumulative'))
|
||||
self.negative: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'neg_unrealized_loss'))
|
||||
self.sum: _1m1w1y24hPattern4 = _1m1w1y24hPattern4(client, _m(acc, 'unrealized_loss_sum'))
|
||||
self.base: CentsUsdPattern2 = CentsUsdPattern2(client, _m(acc, disc))
|
||||
self.cumulative: CentsUsdPattern2 = CentsUsdPattern2(client, _m(acc, f'{disc}_cumulative'))
|
||||
self.negative: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, f'neg_{disc}'))
|
||||
self.sum: _1m1w1y24hPattern4 = _1m1w1y24hPattern4(client, _m(acc, f'{disc}_sum'))
|
||||
|
||||
class BothReactivatedReceivingSendingPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -2839,7 +2839,7 @@ class LossNetNuplProfitPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.loss: BaseCumulativeNegativeSumPattern = BaseCumulativeNegativeSumPattern(client, acc)
|
||||
self.loss: BaseCumulativeNegativeSumPattern = BaseCumulativeNegativeSumPattern(client, acc, '')
|
||||
self.net_pnl: CentsUsdPattern = CentsUsdPattern(client, _m(acc, 'net_unrealized_pnl'))
|
||||
self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl'))
|
||||
self.profit: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, _m(acc, 'unrealized_profit'))
|
||||
@@ -2942,9 +2942,9 @@ class BpsPriceRatioPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.bps: MetricPattern1[BasisPoints32] = MetricPattern1(client, _m(acc, 'ratio_pct99_bps'))
|
||||
self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'pct99'))
|
||||
self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ratio_pct99'))
|
||||
self.bps: MetricPattern1[BasisPoints32] = MetricPattern1(client, _m(acc, f'ratio_{disc}_bps'))
|
||||
self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, disc))
|
||||
self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'ratio_{disc}'))
|
||||
|
||||
class BpsPercentRatioPattern5:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -3014,7 +3014,7 @@ class LossNuplProfitPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.loss: BaseCumulativeNegativeSumPattern = BaseCumulativeNegativeSumPattern(client, acc)
|
||||
self.loss: BaseCumulativeNegativeSumPattern = BaseCumulativeNegativeSumPattern(client, acc, '')
|
||||
self.nupl: BpsRatioPattern = BpsRatioPattern(client, _m(acc, 'nupl'))
|
||||
self.profit: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, _m(acc, 'unrealized_profit'))
|
||||
|
||||
@@ -3032,9 +3032,9 @@ class RatioValuePattern2:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, _m(acc, 'asopr'))
|
||||
self.value_created: BaseCumulativeSumPattern[Cents] = BaseCumulativeSumPattern(client, _m(acc, 'adj_value_created'))
|
||||
self.value_destroyed: BaseCumulativeSumPattern[Cents] = BaseCumulativeSumPattern(client, _m(acc, 'adj_value_destroyed'))
|
||||
self.ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, f'{acc}_ratio')
|
||||
self.value_created: BaseCumulativeSumPattern[Cents] = BaseCumulativeSumPattern(client, f'{acc}_value_created')
|
||||
self.value_destroyed: BaseCumulativeSumPattern[Cents] = BaseCumulativeSumPattern(client, f'{acc}_value_destroyed')
|
||||
|
||||
class RatioValuePattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -3069,7 +3069,7 @@ class AbsoluteRatePattern:
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.absolute: _1m1w1y24hPattern[StoredI64] = _1m1w1y24hPattern(client, acc)
|
||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, acc)
|
||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, _m(acc, 'rate'))
|
||||
|
||||
class AbsoluteRatePattern2:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -3077,7 +3077,7 @@ class AbsoluteRatePattern2:
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.absolute: _1m1w1y24hPattern3 = _1m1w1y24hPattern3(client, acc)
|
||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, acc)
|
||||
self.rate: _1m1w1y24hPattern2 = _1m1w1y24hPattern2(client, _m(acc, 'rate'))
|
||||
|
||||
class AllSthPattern2:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -3159,13 +3159,13 @@ class InPattern:
|
||||
self.in_loss: CentsUsdPattern2 = CentsUsdPattern2(client, _m(acc, 'loss'))
|
||||
self.in_profit: CentsUsdPattern2 = CentsUsdPattern2(client, _m(acc, 'profit'))
|
||||
|
||||
class PriceValuePattern:
|
||||
class PriceRatioPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, 'p3sd_4y'))
|
||||
self.value: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'ratio_p3sd_4y'))
|
||||
self.price: CentsSatsUsdPattern = CentsSatsUsdPattern(client, _m(acc, disc))
|
||||
self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, f'ratio_{disc}'))
|
||||
|
||||
class RelPattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -3180,8 +3180,8 @@ class SdSmaPattern:
|
||||
|
||||
def __init__(self, client: BrkClientBase, acc: str):
|
||||
"""Create pattern node with accumulated metric name."""
|
||||
self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sd_1y'))
|
||||
self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, _m(acc, 'sma_1y'))
|
||||
self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_sd')
|
||||
self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, f'{acc}_sma')
|
||||
|
||||
class ValuePattern:
|
||||
"""Pattern struct for repeated tree structure."""
|
||||
@@ -4237,13 +4237,20 @@ class MetricsTree_Market_Returns_Sd24h_1m:
|
||||
self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_return_24h_sma_1m')
|
||||
self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_return_24h_sd_1m')
|
||||
|
||||
class MetricsTree_Market_Returns_Sd24h_1y:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.sma: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_return_24h_sma_1y')
|
||||
self.sd: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_return_24h_sd_1y')
|
||||
|
||||
class MetricsTree_Market_Returns_Sd24h:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self._1w: MetricsTree_Market_Returns_Sd24h_1w = MetricsTree_Market_Returns_Sd24h_1w(client)
|
||||
self._1m: MetricsTree_Market_Returns_Sd24h_1m = MetricsTree_Market_Returns_Sd24h_1m(client)
|
||||
self._1y: SdSmaPattern = SdSmaPattern(client, 'price_return_24h')
|
||||
self._1y: MetricsTree_Market_Returns_Sd24h_1y = MetricsTree_Market_Returns_Sd24h_1y(client)
|
||||
|
||||
class MetricsTree_Market_Returns:
|
||||
"""Metrics tree node."""
|
||||
@@ -4271,22 +4278,6 @@ class MetricsTree_Market_Range:
|
||||
self.true_range_sum_2w: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_true_range_sum_2w')
|
||||
self.choppiness_index_2w: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'price_choppiness_index_2w')
|
||||
|
||||
class MetricsTree_Market_MovingAverage_Sma_200d_X24:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.usd: MetricPattern1[Dollars] = MetricPattern1(client, 'price_sma_200d_x2_4_usd')
|
||||
self.cents: MetricPattern1[Cents] = MetricPattern1(client, 'price_sma_200d_x2_4_cents')
|
||||
self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, 'price_sma_200d_x2_4_sats')
|
||||
|
||||
class MetricsTree_Market_MovingAverage_Sma_200d_X08:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.usd: MetricPattern1[Dollars] = MetricPattern1(client, 'price_sma_200d_x0_8_usd')
|
||||
self.cents: MetricPattern1[Cents] = MetricPattern1(client, 'price_sma_200d_x0_8_cents')
|
||||
self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, 'price_sma_200d_x0_8_sats')
|
||||
|
||||
class MetricsTree_Market_MovingAverage_Sma_200d:
|
||||
"""Metrics tree node."""
|
||||
|
||||
@@ -4296,16 +4287,8 @@ class MetricsTree_Market_MovingAverage_Sma_200d:
|
||||
self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, 'price_sma_200d_sats')
|
||||
self.bps: MetricPattern1[BasisPoints32] = MetricPattern1(client, 'price_sma_200d_ratio_bps')
|
||||
self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sma_200d_ratio')
|
||||
self.x2_4: MetricsTree_Market_MovingAverage_Sma_200d_X24 = MetricsTree_Market_MovingAverage_Sma_200d_X24(client)
|
||||
self.x0_8: MetricsTree_Market_MovingAverage_Sma_200d_X08 = MetricsTree_Market_MovingAverage_Sma_200d_X08(client)
|
||||
|
||||
class MetricsTree_Market_MovingAverage_Sma_350d_X2:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.usd: MetricPattern1[Dollars] = MetricPattern1(client, 'price_sma_350d_x2_usd')
|
||||
self.cents: MetricPattern1[Cents] = MetricPattern1(client, 'price_sma_350d_x2_cents')
|
||||
self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, 'price_sma_350d_x2_sats')
|
||||
self.x2_4: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_sma_200d_x2_4')
|
||||
self.x0_8: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_sma_200d_x0_8')
|
||||
|
||||
class MetricsTree_Market_MovingAverage_Sma_350d:
|
||||
"""Metrics tree node."""
|
||||
@@ -4316,7 +4299,7 @@ class MetricsTree_Market_MovingAverage_Sma_350d:
|
||||
self.sats: MetricPattern1[SatsFract] = MetricPattern1(client, 'price_sma_350d_sats')
|
||||
self.bps: MetricPattern1[BasisPoints32] = MetricPattern1(client, 'price_sma_350d_ratio_bps')
|
||||
self.ratio: MetricPattern1[StoredF32] = MetricPattern1(client, 'price_sma_350d_ratio')
|
||||
self.x2: MetricsTree_Market_MovingAverage_Sma_350d_X2 = MetricsTree_Market_MovingAverage_Sma_350d_X2(client)
|
||||
self.x2: CentsSatsUsdPattern = CentsSatsUsdPattern(client, 'price_sma_350d_x2')
|
||||
|
||||
class MetricsTree_Market_MovingAverage_Sma:
|
||||
"""Metrics tree node."""
|
||||
@@ -4462,59 +4445,24 @@ class MetricsTree_Market_Dca:
|
||||
self.period: MetricsTree_Market_Dca_Period = MetricsTree_Market_Dca_Period(client)
|
||||
self.class_: MetricsTree_Market_Dca_Class = MetricsTree_Market_Dca_Class(client)
|
||||
|
||||
class MetricsTree_Market_Technical_Rsi_1w:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.gains: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_gains_1w')
|
||||
self.losses: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_losses_1w')
|
||||
self.average_gain: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_average_gain_1w')
|
||||
self.average_loss: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_average_loss_1w')
|
||||
self.rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_1w')
|
||||
self.rsi_min: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_min_1w')
|
||||
self.rsi_max: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_max_1w')
|
||||
self.stoch_rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_1w')
|
||||
self.stoch_rsi_k: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_k_1w')
|
||||
self.stoch_rsi_d: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_d_1w')
|
||||
|
||||
class MetricsTree_Market_Technical_Rsi_1m:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.gains: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_gains_1m')
|
||||
self.losses: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_losses_1m')
|
||||
self.average_gain: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_average_gain_1m')
|
||||
self.average_loss: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_average_loss_1m')
|
||||
self.rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_1m')
|
||||
self.rsi_min: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_min_1m')
|
||||
self.rsi_max: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_max_1m')
|
||||
self.stoch_rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_1m')
|
||||
self.stoch_rsi_k: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_k_1m')
|
||||
self.stoch_rsi_d: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_d_1m')
|
||||
|
||||
class MetricsTree_Market_Technical_Rsi_1y:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.gains: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_gains_1y')
|
||||
self.losses: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_losses_1y')
|
||||
self.average_gain: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_average_gain_1y')
|
||||
self.average_loss: MetricPattern1[StoredF32] = MetricPattern1(client, 'rsi_average_loss_1y')
|
||||
self.rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_1y')
|
||||
self.rsi_min: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_min_1y')
|
||||
self.rsi_max: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_max_1y')
|
||||
self.stoch_rsi: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_1y')
|
||||
self.stoch_rsi_k: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_k_1y')
|
||||
self.stoch_rsi_d: BpsPercentRatioPattern3 = BpsPercentRatioPattern3(client, 'rsi_stoch_d_1y')
|
||||
|
||||
class MetricsTree_Market_Technical_Rsi:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self._24h: AverageGainsLossesRsiStochPattern = AverageGainsLossesRsiStochPattern(client, 'rsi')
|
||||
self._1w: MetricsTree_Market_Technical_Rsi_1w = MetricsTree_Market_Technical_Rsi_1w(client)
|
||||
self._1m: MetricsTree_Market_Technical_Rsi_1m = MetricsTree_Market_Technical_Rsi_1m(client)
|
||||
self._1y: MetricsTree_Market_Technical_Rsi_1y = MetricsTree_Market_Technical_Rsi_1y(client)
|
||||
self._1w: AverageGainsLossesRsiStochPattern = AverageGainsLossesRsiStochPattern(client, 'rsi')
|
||||
self._1m: AverageGainsLossesRsiStochPattern = AverageGainsLossesRsiStochPattern(client, 'rsi')
|
||||
self._1y: AverageGainsLossesRsiStochPattern = AverageGainsLossesRsiStochPattern(client, 'rsi')
|
||||
|
||||
class MetricsTree_Market_Technical_Macd_24h:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.ema_fast: MetricPattern1[StoredF32] = MetricPattern1(client, 'macd_ema_fast_24h')
|
||||
self.ema_slow: MetricPattern1[StoredF32] = MetricPattern1(client, 'macd_ema_slow_24h')
|
||||
self.line: MetricPattern1[StoredF32] = MetricPattern1(client, 'macd_line_24h')
|
||||
self.signal: MetricPattern1[StoredF32] = MetricPattern1(client, 'macd_signal_24h')
|
||||
self.histogram: MetricPattern1[StoredF32] = MetricPattern1(client, 'macd_histogram_24h')
|
||||
|
||||
class MetricsTree_Market_Technical_Macd_1w:
|
||||
"""Metrics tree node."""
|
||||
@@ -4550,7 +4498,7 @@ class MetricsTree_Market_Technical_Macd:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self._24h: EmaHistogramLineSignalPattern = EmaHistogramLineSignalPattern(client, 'macd')
|
||||
self._24h: MetricsTree_Market_Technical_Macd_24h = MetricsTree_Market_Technical_Macd_24h(client)
|
||||
self._1w: MetricsTree_Market_Technical_Macd_1w = MetricsTree_Market_Technical_Macd_1w(client)
|
||||
self._1m: MetricsTree_Market_Technical_Macd_1m = MetricsTree_Market_Technical_Macd_1m(client)
|
||||
self._1y: MetricsTree_Market_Technical_Macd_1y = MetricsTree_Market_Technical_Macd_1y(client)
|
||||
@@ -4827,6 +4775,23 @@ class MetricsTree_Cohorts_Utxo_All_Supply:
|
||||
self.in_profit: BtcCentsRelSatsUsdPattern2 = BtcCentsRelSatsUsdPattern2(client, 'supply_in_profit')
|
||||
self.in_loss: BtcCentsRelSatsUsdPattern2 = BtcCentsRelSatsUsdPattern2(client, 'supply_in_loss')
|
||||
|
||||
class MetricsTree_Cohorts_Utxo_All_Realized:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.cap: CentsDeltaRelUsdPattern = CentsDeltaRelUsdPattern(client, 'realized_cap')
|
||||
self.profit: BaseCumulativeDistributionRelSumValuePattern = BaseCumulativeDistributionRelSumValuePattern(client, '')
|
||||
self.loss: BaseCapitulationCumulativeNegativeRelSumValuePattern = BaseCapitulationCumulativeNegativeRelSumValuePattern(client, '')
|
||||
self.price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern = BpsCentsPercentilesRatioSatsSmaStdUsdPattern(client, 'realized_price')
|
||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, 'mvrv')
|
||||
self.sopr: AdjustedRatioValuePattern = AdjustedRatioValuePattern(client, '')
|
||||
self.net_pnl: BaseChangeCumulativeDeltaRelSumPattern = BaseChangeCumulativeDeltaRelSumPattern(client, 'net')
|
||||
self.gross_pnl: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, 'realized_gross_pnl')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern6 = _1m1w1y24hPattern6(client, 'sell_side_risk_ratio')
|
||||
self.peak_regret: BaseCumulativeRelPattern = BaseCumulativeRelPattern(client, 'realized_peak_regret')
|
||||
self.investor: LowerPriceUpperPattern = LowerPriceUpperPattern(client, '')
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'realized_profit_to_loss_ratio')
|
||||
|
||||
class MetricsTree_Cohorts_Utxo_All_Unrealized_Profit:
|
||||
"""Metrics tree node."""
|
||||
|
||||
@@ -4875,10 +4840,27 @@ class MetricsTree_Cohorts_Utxo_All:
|
||||
self.supply: MetricsTree_Cohorts_Utxo_All_Supply = MetricsTree_Cohorts_Utxo_All_Supply(client)
|
||||
self.outputs: UnspentPattern = UnspentPattern(client, 'utxo_count')
|
||||
self.activity: CoindaysCoinyearsDormancySentPattern = CoindaysCoinyearsDormancySentPattern(client, '')
|
||||
self.realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern = CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern(client, '')
|
||||
self.realized: MetricsTree_Cohorts_Utxo_All_Realized = MetricsTree_Cohorts_Utxo_All_Realized(client)
|
||||
self.cost_basis: InvestedMaxMinPercentilesSupplyPattern = InvestedMaxMinPercentilesSupplyPattern(client, '')
|
||||
self.unrealized: MetricsTree_Cohorts_Utxo_All_Unrealized = MetricsTree_Cohorts_Utxo_All_Unrealized(client)
|
||||
|
||||
class MetricsTree_Cohorts_Utxo_Sth_Realized:
|
||||
"""Metrics tree node."""
|
||||
|
||||
def __init__(self, client: BrkClientBase, base_path: str = ''):
|
||||
self.cap: CentsDeltaRelUsdPattern = CentsDeltaRelUsdPattern(client, 'sth_realized_cap')
|
||||
self.profit: BaseCumulativeDistributionRelSumValuePattern = BaseCumulativeDistributionRelSumValuePattern(client, 'sth')
|
||||
self.loss: BaseCapitulationCumulativeNegativeRelSumValuePattern = BaseCapitulationCumulativeNegativeRelSumValuePattern(client, 'sth')
|
||||
self.price: BpsCentsPercentilesRatioSatsSmaStdUsdPattern = BpsCentsPercentilesRatioSatsSmaStdUsdPattern(client, 'sth_realized_price')
|
||||
self.mvrv: MetricPattern1[StoredF32] = MetricPattern1(client, 'sth_mvrv')
|
||||
self.sopr: AdjustedRatioValuePattern = AdjustedRatioValuePattern(client, 'sth')
|
||||
self.net_pnl: BaseChangeCumulativeDeltaRelSumPattern = BaseChangeCumulativeDeltaRelSumPattern(client, 'sth_net')
|
||||
self.gross_pnl: BaseCumulativeSumPattern3 = BaseCumulativeSumPattern3(client, 'sth_realized_gross_pnl')
|
||||
self.sell_side_risk_ratio: _1m1w1y24hPattern6 = _1m1w1y24hPattern6(client, 'sth_sell_side_risk_ratio')
|
||||
self.peak_regret: BaseCumulativeRelPattern = BaseCumulativeRelPattern(client, 'sth_realized_peak_regret')
|
||||
self.investor: LowerPriceUpperPattern = LowerPriceUpperPattern(client, 'sth')
|
||||
self.profit_to_loss_ratio: _1m1w1y24hPattern[StoredF64] = _1m1w1y24hPattern(client, 'sth_realized_profit_to_loss_ratio')
|
||||
|
||||
class MetricsTree_Cohorts_Utxo_Sth:
|
||||
"""Metrics tree node."""
|
||||
|
||||
@@ -4886,7 +4868,7 @@ class MetricsTree_Cohorts_Utxo_Sth:
|
||||
self.supply: DeltaHalfInRelTotalPattern2 = DeltaHalfInRelTotalPattern2(client, 'sth_supply')
|
||||
self.outputs: UnspentPattern = UnspentPattern(client, 'sth_utxo_count')
|
||||
self.activity: CoindaysCoinyearsDormancySentPattern = CoindaysCoinyearsDormancySentPattern(client, 'sth')
|
||||
self.realized: CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern = CapGrossInvestorLossMvrvNetPeakPriceProfitSellSoprPattern(client, 'sth')
|
||||
self.realized: MetricsTree_Cohorts_Utxo_Sth_Realized = MetricsTree_Cohorts_Utxo_Sth_Realized(client)
|
||||
self.cost_basis: InvestedMaxMinPercentilesSupplyPattern = InvestedMaxMinPercentilesSupplyPattern(client, 'sth')
|
||||
self.unrealized: GrossInvestedLossNetNuplProfitSentimentPattern2 = GrossInvestedLossNetNuplProfitSentimentPattern2(client, 'sth')
|
||||
|
||||
|
||||
@@ -46,7 +46,10 @@ export function flatMapCohorts(list, fn) {
|
||||
* @returns {R[]}
|
||||
*/
|
||||
export function mapCohortsWithAll(list, all, fn) {
|
||||
return [...list.map(fn), { ...fn({ ...all, name: "All" }), defaultActive: false }];
|
||||
return [
|
||||
...list.map(fn),
|
||||
{ ...fn({ ...all, name: "All" }), defaultActive: false },
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,7 +63,10 @@ export function mapCohortsWithAll(list, all, fn) {
|
||||
* @returns {R[]}
|
||||
*/
|
||||
export function flatMapCohortsWithAll(list, all, fn) {
|
||||
return [...list.flatMap(fn), ...fn({ ...all, name: "All" }).map((s) => ({ ...s, defaultActive: false }))];
|
||||
return [
|
||||
...list.flatMap(fn),
|
||||
...fn({ ...all, name: "All" }).map((s) => ({ ...s, defaultActive: false })),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,20 +263,32 @@ export function satsBtcUsdFullTree({ pattern, name, title, color }) {
|
||||
name: "Compare",
|
||||
title: `${title} Rolling Sum`,
|
||||
bottom: ROLLING_WINDOWS.flatMap((w) =>
|
||||
satsBtcUsd({ pattern: pattern.sum[w.key], name: w.name, color: w.color }),
|
||||
satsBtcUsd({
|
||||
pattern: pattern.sum[w.key],
|
||||
name: w.name,
|
||||
color: w.color,
|
||||
}),
|
||||
),
|
||||
},
|
||||
...ROLLING_WINDOWS.map((w) => ({
|
||||
name: w.name,
|
||||
title: `${title} ${w.name} Rolling Sum`,
|
||||
bottom: satsBtcUsd({ pattern: pattern.sum[w.key], name: w.name, color: w.color }),
|
||||
bottom: satsBtcUsd({
|
||||
pattern: pattern.sum[w.key],
|
||||
name: w.name,
|
||||
color: w.color,
|
||||
}),
|
||||
})),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Cumulative",
|
||||
title: `${title} (Total)`,
|
||||
bottom: satsBtcUsd({ pattern: pattern.cumulative, name: "all-time", color }),
|
||||
bottom: satsBtcUsd({
|
||||
pattern: pattern.cumulative,
|
||||
name: "all-time",
|
||||
color,
|
||||
}),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -296,7 +314,12 @@ export function simplePriceRatioTree({ pattern, title, legend, color }) {
|
||||
title: `${title} Ratio`,
|
||||
top: [price({ metric: pattern, name: legend, color })],
|
||||
bottom: [
|
||||
baseline({ metric: pattern.ratio, name: "Ratio", unit: Unit.ratio, base: 1 }),
|
||||
baseline({
|
||||
metric: pattern.ratio,
|
||||
name: "Ratio",
|
||||
unit: Unit.ratio,
|
||||
base: 1,
|
||||
}),
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -312,7 +335,13 @@ export function simplePriceRatioTree({ pattern, title, legend, color }) {
|
||||
* @param {FetchedPriceSeriesBlueprint[]} [args.priceReferences]
|
||||
* @returns {PartialOptionsTree}
|
||||
*/
|
||||
export function priceRatioPercentilesTree({ pattern, title, legend, color, priceReferences }) {
|
||||
export function priceRatioPercentilesTree({
|
||||
pattern,
|
||||
title,
|
||||
legend,
|
||||
color,
|
||||
priceReferences,
|
||||
}) {
|
||||
const p = pattern.percentiles;
|
||||
const pctUsd = [
|
||||
{ name: "pct95", prop: p.pct95.price, color: colors.ratioPct._95 },
|
||||
@@ -338,7 +367,13 @@ export function priceRatioPercentilesTree({ pattern, title, legend, color, price
|
||||
price({ metric: pattern, name: legend, color }),
|
||||
...(priceReferences ?? []),
|
||||
...pctUsd.map(({ name, prop, color }) =>
|
||||
price({ metric: prop, name, color, defaultActive: false, options: { lineStyle: 1 } }),
|
||||
price({
|
||||
metric: prop,
|
||||
name,
|
||||
color,
|
||||
defaultActive: false,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
),
|
||||
],
|
||||
},
|
||||
@@ -348,13 +383,31 @@ export function priceRatioPercentilesTree({ pattern, title, legend, color, price
|
||||
top: [
|
||||
price({ metric: pattern, name: legend, color }),
|
||||
...pctUsd.map(({ name, prop, color }) =>
|
||||
price({ metric: prop, name, color, defaultActive: false, options: { lineStyle: 1 } }),
|
||||
price({
|
||||
metric: prop,
|
||||
name,
|
||||
color,
|
||||
defaultActive: false,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
),
|
||||
],
|
||||
bottom: [
|
||||
baseline({ metric: pattern.ratio, name: "Ratio", unit: Unit.ratio, base: 1 }),
|
||||
baseline({
|
||||
metric: pattern.ratio,
|
||||
name: "Ratio",
|
||||
unit: Unit.ratio,
|
||||
base: 1,
|
||||
}),
|
||||
...pctRatio.map(({ name, prop, color }) =>
|
||||
line({ metric: prop, name, color, defaultActive: false, unit: Unit.ratio, options: { lineStyle: 1 } }),
|
||||
line({
|
||||
metric: prop,
|
||||
name,
|
||||
color,
|
||||
defaultActive: false,
|
||||
unit: Unit.ratio,
|
||||
options: { lineStyle: 1 },
|
||||
}),
|
||||
),
|
||||
],
|
||||
},
|
||||
@@ -381,7 +434,13 @@ export function groupedSimplePriceRatioTree({ list, title }) {
|
||||
name: "Ratio",
|
||||
title: `${title} Ratio`,
|
||||
bottom: list.map(({ name, color, pattern }) =>
|
||||
baseline({ metric: pattern.ratio, name, color, unit: Unit.ratio, base: 1 }),
|
||||
baseline({
|
||||
metric: pattern.ratio,
|
||||
name,
|
||||
color,
|
||||
unit: Unit.ratio,
|
||||
base: 1,
|
||||
}),
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -453,10 +512,30 @@ export function percentileMap(ratio) {
|
||||
*/
|
||||
export function sdPatterns(ratio) {
|
||||
return /** @type {const} */ ([
|
||||
{ nameAddon: "All Time", titleAddon: "", sd: ratio.stdDev.all, smaRatio: ratio.sma.all.ratio },
|
||||
{ nameAddon: "4y", titleAddon: "4y", sd: ratio.stdDev._4y, smaRatio: ratio.sma._4y.ratio },
|
||||
{ nameAddon: "2y", titleAddon: "2y", sd: ratio.stdDev._2y, smaRatio: ratio.sma._2y.ratio },
|
||||
{ nameAddon: "1y", titleAddon: "1y", sd: ratio.stdDev._1y, smaRatio: ratio.sma._1y.ratio },
|
||||
{
|
||||
nameAddon: "All Time",
|
||||
titleAddon: "",
|
||||
sd: ratio.stdDev.all,
|
||||
smaRatio: ratio.sma.all.ratio,
|
||||
},
|
||||
{
|
||||
nameAddon: "4y",
|
||||
titleAddon: "4y",
|
||||
sd: ratio.stdDev._4y,
|
||||
smaRatio: ratio.sma._4y.ratio,
|
||||
},
|
||||
{
|
||||
nameAddon: "2y",
|
||||
titleAddon: "2y",
|
||||
sd: ratio.stdDev._2y,
|
||||
smaRatio: ratio.sma._2y.ratio,
|
||||
},
|
||||
{
|
||||
nameAddon: "1y",
|
||||
titleAddon: "1y",
|
||||
sd: ratio.stdDev._1y,
|
||||
smaRatio: ratio.sma._1y.ratio,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -490,18 +569,18 @@ export function sdBandsUsd(sd) {
|
||||
export function sdBandsRatio(sd, smaRatio) {
|
||||
return /** @type {const} */ ([
|
||||
{ name: "0σ", prop: smaRatio, color: colors.sd._0 },
|
||||
{ name: "+0.5σ", prop: sd.p05sd.value, color: colors.sd.p05 },
|
||||
{ name: "−0.5σ", prop: sd.m05sd.value, color: colors.sd.m05 },
|
||||
{ name: "+1σ", prop: sd.p1sd.value, color: colors.sd.p1 },
|
||||
{ name: "−1σ", prop: sd.m1sd.value, color: colors.sd.m1 },
|
||||
{ name: "+1.5σ", prop: sd.p15sd.value, color: colors.sd.p15 },
|
||||
{ name: "−1.5σ", prop: sd.m15sd.value, color: colors.sd.m15 },
|
||||
{ name: "+2σ", prop: sd.p2sd.value, color: colors.sd.p2 },
|
||||
{ name: "−2σ", prop: sd.m2sd.value, color: colors.sd.m2 },
|
||||
{ name: "+2.5σ", prop: sd.p25sd.value, color: colors.sd.p25 },
|
||||
{ name: "−2.5σ", prop: sd.m25sd.value, color: colors.sd.m25 },
|
||||
{ name: "+3σ", prop: sd.p3sd.value, color: colors.sd.p3 },
|
||||
{ name: "−3σ", prop: sd.m3sd.value, color: colors.sd.m3 },
|
||||
{ name: "+0.5σ", prop: sd.p05sd.ratio, color: colors.sd.p05 },
|
||||
{ name: "−0.5σ", prop: sd.m05sd.ratio, color: colors.sd.m05 },
|
||||
{ name: "+1σ", prop: sd.p1sd.ratio, color: colors.sd.p1 },
|
||||
{ name: "−1σ", prop: sd.m1sd.ratio, color: colors.sd.m1 },
|
||||
{ name: "+1.5σ", prop: sd.p15sd.ratio, color: colors.sd.p15 },
|
||||
{ name: "−1.5σ", prop: sd.m15sd.ratio, color: colors.sd.m15 },
|
||||
{ name: "+2σ", prop: sd.p2sd.ratio, color: colors.sd.p2 },
|
||||
{ name: "−2σ", prop: sd.m2sd.ratio, color: colors.sd.m2 },
|
||||
{ name: "+2.5σ", prop: sd.p25sd.ratio, color: colors.sd.p25 },
|
||||
{ name: "−2.5σ", prop: sd.m25sd.ratio, color: colors.sd.m25 },
|
||||
{ name: "+3σ", prop: sd.p3sd.ratio, color: colors.sd.p3 },
|
||||
{ name: "−3σ", prop: sd.m3sd.ratio, color: colors.sd.m3 },
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user