perf(strategy): retain compact factor values in expression contexts
This commit is contained in:
@@ -27,6 +27,7 @@ use crate::numeric_expr_vm::{
|
||||
self, EvalError as NumericVmEvalError, Program as NumericVmProgram,
|
||||
Scratch as NumericVmScratch, Value as NumericVmValue, ValueType as NumericVmValueType,
|
||||
};
|
||||
use crate::numeric_factors::NumericFactorMap;
|
||||
use crate::portfolio::PortfolioState;
|
||||
use crate::holding_policy::{AutomaticTradeProtection, AutomaticTradePermission, HoldingLifecycleEvidence};
|
||||
|
||||
@@ -1010,7 +1011,7 @@ struct StockExpressionState {
|
||||
stock_volume_ma60: f64,
|
||||
stock_volume_ma100: f64,
|
||||
current_series_end: Option<usize>,
|
||||
extra_factors: BTreeMap<String, f64>,
|
||||
extra_factors: NumericFactorMap,
|
||||
extra_text_factors: BTreeMap<String, String>,
|
||||
}
|
||||
|
||||
@@ -4390,11 +4391,14 @@ impl PlatformExprStrategy {
|
||||
.factor_snapshot_rows_on(date)
|
||||
.iter()
|
||||
.flat_map(|row| {
|
||||
row.extra_factors.keys().map(|key| key.to_string()).chain(
|
||||
row.extra_factors.keys().map(|key| key.as_ref()).chain(
|
||||
row.adjustment_factor_backward1
|
||||
.map(|_| BACKWARD_ADJUSTMENT_FACTOR_FIELD.to_string()),
|
||||
.map(|_| BACKWARD_ADJUSTMENT_FACTOR_FIELD),
|
||||
)
|
||||
})
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.map(str::to_owned)
|
||||
.collect()
|
||||
} else {
|
||||
BTreeSet::new()
|
||||
@@ -4403,7 +4407,10 @@ impl PlatformExprStrategy {
|
||||
ctx.data
|
||||
.factor_text_rows_on(date)
|
||||
.iter()
|
||||
.map(|row| row.field.clone())
|
||||
.map(|row| row.field.as_str())
|
||||
.collect::<BTreeSet<_>>()
|
||||
.into_iter()
|
||||
.map(str::to_owned)
|
||||
.collect()
|
||||
} else {
|
||||
BTreeSet::new()
|
||||
@@ -4896,10 +4903,10 @@ impl PlatformExprStrategy {
|
||||
self.stock_extra_factor_map_required
|
||||
|| self.stock_extra_factor_identifiers.contains(field.as_ref())
|
||||
})
|
||||
.map(|(field, value)| (field.to_string(), *value))
|
||||
.map(|(field, value)| (field.clone(), *value))
|
||||
.collect()
|
||||
} else {
|
||||
BTreeMap::new()
|
||||
NumericFactorMap::new()
|
||||
};
|
||||
if !self.config.completed_session_factor_fields.is_empty() {
|
||||
let visible_date = completed_session_factor_date(
|
||||
@@ -4914,7 +4921,7 @@ impl PlatformExprStrategy {
|
||||
.and_then(|row| row.extra_factors.get(field.as_str()))
|
||||
.copied()
|
||||
.unwrap_or(f64::NAN);
|
||||
extra_factors.insert(field.clone(), value);
|
||||
extra_factors.insert(field.clone().into(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4925,7 +4932,7 @@ impl PlatformExprStrategy {
|
||||
.contains(BACKWARD_ADJUSTMENT_FACTOR_FIELD))
|
||||
&& let Some(value) = factor.adjustment_factor_backward1
|
||||
{
|
||||
extra_factors.insert(BACKWARD_ADJUSTMENT_FACTOR_FIELD.to_string(), value);
|
||||
extra_factors.insert(BACKWARD_ADJUSTMENT_FACTOR_FIELD.into(), value);
|
||||
}
|
||||
|
||||
let state = StockExpressionState {
|
||||
@@ -5642,7 +5649,7 @@ impl PlatformExprStrategy {
|
||||
Dynamic::from(stock.stock_volume_ma100),
|
||||
);
|
||||
for (key, value) in &stock.extra_factors {
|
||||
factors.insert(key.clone().into(), Dynamic::from(*value));
|
||||
factors.insert(key.as_ref().into(), Dynamic::from(*value));
|
||||
}
|
||||
for (key, value) in &stock.extra_text_factors {
|
||||
factors.insert(key.clone().into(), Dynamic::from(value.clone()));
|
||||
@@ -14546,6 +14553,7 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use chrono::{NaiveDate, NaiveTime};
|
||||
use rhai::{Dynamic, Map};
|
||||
|
||||
use super::{
|
||||
CompiledRuntimeHelperArgs, PlatformAccountActionKind, PlatformExplicitActionStage,
|
||||
@@ -17542,6 +17550,18 @@ mod tests {
|
||||
.stock_state_with_factor_date(&ctx, date, date, present_symbol)
|
||||
.expect("factor map stock state");
|
||||
assert!(map_stock.extra_factors.contains_key("unused_factor"));
|
||||
let mut numeric_state = (*map_stock).clone();
|
||||
numeric_state.extra_factors.insert("negative_zero".into(), -0.0);
|
||||
numeric_state.extra_factors.insert("undefined_value".into(), f64::NAN);
|
||||
let copied_state = numeric_state.clone();
|
||||
assert_eq!(copied_state.extra_factors["negative_zero"].to_bits(), (-0.0_f64).to_bits());
|
||||
assert!(copied_state.extra_factors["undefined_value"].is_nan());
|
||||
let exposed = copied_state.extra_factors.iter()
|
||||
.map(|(key, value)| (key.as_ref().into(), Dynamic::from(*value)))
|
||||
.collect::<Map>();
|
||||
assert_eq!(exposed["negative_zero"].as_float().unwrap().to_bits(), (-0.0_f64).to_bits());
|
||||
assert!(exposed["undefined_value"].as_float().unwrap().is_nan());
|
||||
assert!(!exposed.contains_key("missing_factor"));
|
||||
let map_day = map_strategy
|
||||
.day_state(&ctx, date)
|
||||
.expect("factor map day state");
|
||||
|
||||
Reference in New Issue
Block a user