mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-21 16:08:10 -07:00
global: replace most bps with ppm
This commit is contained in:
@@ -291,7 +291,7 @@ fn collect_instance_analyses(
|
||||
///
|
||||
/// 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`
|
||||
/// E.g., `ratio_pct99_ppm` vs `ratio_pct1_ppm` → template `ratio_{disc}_ppm`
|
||||
/// 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(
|
||||
@@ -307,11 +307,11 @@ fn try_detect_template(
|
||||
return Some(mode);
|
||||
}
|
||||
|
||||
// Strategy 2: embedded discriminator (e.g., ratio_pct99_bps vs ratio_pct1_bps)
|
||||
// Strategy 2: embedded discriminator (e.g., ratio_pct99_ppm vs ratio_pct1_ppm)
|
||||
try_embedded_disc(majority, fields)
|
||||
}
|
||||
|
||||
/// Strategy 1: embedded discriminator (e.g., pct99 inside ratio_pct99_bps)
|
||||
/// Strategy 1: embedded discriminator (e.g., pct99 inside ratio_pct99_ppm)
|
||||
fn try_embedded_disc(
|
||||
majority: &[&InstanceAnalysis],
|
||||
fields: &[PatternField],
|
||||
@@ -772,7 +772,7 @@ mod tests {
|
||||
use std::collections::BTreeSet;
|
||||
let fields = vec![
|
||||
PatternField {
|
||||
name: "bps".into(),
|
||||
name: "ppm".into(),
|
||||
rust_type: "T".into(),
|
||||
json_type: "n".into(),
|
||||
indexes: BTreeSet::new(),
|
||||
@@ -796,7 +796,7 @@ mod tests {
|
||||
let pct99 = InstanceAnalysis {
|
||||
base: "realized_price".into(),
|
||||
field_parts: [
|
||||
("bps".into(), "ratio_pct99_bps".into()),
|
||||
("ppm".into(), "ratio_pct99_ppm".into()),
|
||||
("price".into(), "pct99".into()),
|
||||
("ratio".into(), "ratio_pct99".into()),
|
||||
]
|
||||
@@ -808,7 +808,7 @@ mod tests {
|
||||
let pct1 = InstanceAnalysis {
|
||||
base: "realized_price".into(),
|
||||
field_parts: [
|
||||
("bps".into(), "ratio_pct1_bps".into()),
|
||||
("ppm".into(), "ratio_pct1_ppm".into()),
|
||||
("price".into(), "pct1".into()),
|
||||
("ratio".into(), "ratio_pct1".into()),
|
||||
]
|
||||
@@ -821,7 +821,7 @@ mod tests {
|
||||
assert!(mode.is_some());
|
||||
match mode.unwrap() {
|
||||
PatternMode::Templated { templates } => {
|
||||
assert_eq!(templates.get("bps").unwrap(), "ratio_{disc}_bps");
|
||||
assert_eq!(templates.get("ppm").unwrap(), "ratio_{disc}_ppm");
|
||||
assert_eq!(templates.get("price").unwrap(), "{disc}");
|
||||
assert_eq!(templates.get("ratio").unwrap(), "ratio_{disc}");
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ impl LanguageSyntax for JavaScriptSyntax {
|
||||
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
|
||||
// "ratio_{disc}_ppm" → split on {disc} → _m(_m(acc, 'ratio'), disc) then _ppm
|
||||
// But this is complex. For embedded disc, use string interpolation.
|
||||
// For suffix disc (ends with {disc}), use _m composition.
|
||||
if let Some(static_part) = template.strip_suffix("{disc}") {
|
||||
|
||||
@@ -107,7 +107,7 @@ pub trait LanguageSyntax {
|
||||
/// - `"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)
|
||||
/// - `"ratio_{disc}_ppm"` (embedded) → `` `ratio_${disc}_ppm` `` (template literal)
|
||||
fn disc_arg_expr(&self, template: &str) -> String;
|
||||
|
||||
/// Format a templated mode expression: substitute `{disc}` at runtime.
|
||||
@@ -117,6 +117,6 @@ pub trait LanguageSyntax {
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `acc_var` - The accumulator variable (e.g., "acc")
|
||||
/// * `template` - Template like `"ratio_{disc}_bps"` or `"{disc}"`
|
||||
/// * `template` - Template like `"ratio_{disc}_ppm"` or `"{disc}"`
|
||||
fn template_expr(&self, acc_var: &str, template: &str) -> String;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ pub enum PatternMode {
|
||||
/// Fields construct series 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")`
|
||||
/// Example: template `"ratio_{disc}_ppm"` with disc `"pct99"` → `_m(acc, "ratio_pct99_ppm")`
|
||||
Templated {
|
||||
/// Maps field name to its template string containing `{disc}` placeholder
|
||||
templates: BTreeMap<String, String>,
|
||||
|
||||
@@ -128,7 +128,7 @@ impl StructuralPattern {
|
||||
}
|
||||
|
||||
/// 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"`.
|
||||
/// E.g., template `"ratio_{disc}_ppm"` matched against `"ratio_pct99_ppm"` yields `"pct99"`.
|
||||
fn extract_disc(template: &str, value: &str) -> Option<String> {
|
||||
let (prefix, suffix) = template.split_once("{disc}")?;
|
||||
if value.starts_with(prefix) && value.ends_with(suffix) {
|
||||
|
||||
Reference in New Issue
Block a user