按表达式需求构建运行作用域
This commit is contained in:
@@ -792,6 +792,49 @@ fn is_precomputed_stock_current_rolling_key(key: &str) -> bool {
|
||||
|| has_numeric_window(key, "avg_volume", "_current")
|
||||
}
|
||||
|
||||
struct SelectiveExpressionScope<'a> {
|
||||
inner: Scope<'static>,
|
||||
expression_identifiers: &'a BTreeSet<String>,
|
||||
prelude_identifiers: &'a BTreeSet<String>,
|
||||
}
|
||||
|
||||
impl<'a> SelectiveExpressionScope<'a> {
|
||||
fn new(
|
||||
expression_identifiers: &'a BTreeSet<String>,
|
||||
prelude_identifiers: &'a BTreeSet<String>,
|
||||
) -> Self {
|
||||
Self {
|
||||
inner: Scope::new(),
|
||||
expression_identifiers,
|
||||
prelude_identifiers,
|
||||
}
|
||||
}
|
||||
|
||||
fn requires(&self, name: &str) -> bool {
|
||||
self.expression_identifiers.contains(name) || self.prelude_identifiers.contains(name)
|
||||
}
|
||||
|
||||
fn push<T: Into<Dynamic>>(&mut self, name: &str, value: T) -> &mut Self {
|
||||
if self.requires(name) {
|
||||
self.inner.push_dynamic(name.to_string(), value.into());
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
fn push_required<T: Into<Dynamic>>(&mut self, name: &str, value: T) -> &mut Self {
|
||||
self.inner.push_dynamic(name.to_string(), value.into());
|
||||
self
|
||||
}
|
||||
|
||||
fn inner_mut(&mut self) -> &mut Scope<'static> {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
fn into_inner(self) -> Scope<'static> {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PlatformExprStrategy {
|
||||
config: PlatformExprStrategyConfig,
|
||||
engine: Engine,
|
||||
@@ -3732,7 +3775,8 @@ impl PlatformExprStrategy {
|
||||
include_factors_map: bool,
|
||||
include_process_event_counts: bool,
|
||||
) -> Scope<'static> {
|
||||
let mut scope = Scope::new();
|
||||
let mut scope =
|
||||
SelectiveExpressionScope::new(identifiers, &self.prelude_identifier_candidates);
|
||||
let trade_date = day.date.format("%Y-%m-%d").to_string();
|
||||
let decision_date = ctx.decision_date.format("%Y-%m-%d").to_string();
|
||||
let execution_date = ctx.execution_date.format("%Y-%m-%d").to_string();
|
||||
@@ -3765,7 +3809,7 @@ impl PlatformExprStrategy {
|
||||
"price_tick",
|
||||
] {
|
||||
self.push_market_scope_map(
|
||||
&mut scope,
|
||||
scope.inner_mut(),
|
||||
ctx,
|
||||
ctx.decision_date,
|
||||
"decision",
|
||||
@@ -3773,7 +3817,7 @@ impl PlatformExprStrategy {
|
||||
identifiers,
|
||||
);
|
||||
self.push_market_scope_map(
|
||||
&mut scope,
|
||||
scope.inner_mut(),
|
||||
ctx,
|
||||
ctx.execution_date,
|
||||
"execution",
|
||||
@@ -3898,7 +3942,7 @@ impl PlatformExprStrategy {
|
||||
for (key, value) in ctx.process_event_counts() {
|
||||
counts.insert(key.into(), Dynamic::from(value));
|
||||
}
|
||||
scope.push("process_event_counts", counts.clone());
|
||||
scope.push_required("process_event_counts", counts.clone());
|
||||
Some(counts)
|
||||
} else {
|
||||
None
|
||||
@@ -4085,7 +4129,7 @@ impl PlatformExprStrategy {
|
||||
if let Some(counts) = process_event_counts {
|
||||
day_factors.insert("process_event_counts".into(), Dynamic::from(counts));
|
||||
}
|
||||
scope.push("day_factors", day_factors);
|
||||
scope.push_required("day_factors", day_factors);
|
||||
}
|
||||
if let Some(stock) = stock {
|
||||
let at_upper_limit = Self::price_is_at_or_above_upper_limit(
|
||||
@@ -4346,7 +4390,7 @@ impl PlatformExprStrategy {
|
||||
for (key, value) in &stock.extra_text_factors {
|
||||
factors.insert(key.clone().into(), Dynamic::from(value.clone()));
|
||||
}
|
||||
scope.push("factors", factors);
|
||||
scope.push_required("factors", factors);
|
||||
}
|
||||
}
|
||||
if let Some(position) = position {
|
||||
@@ -4398,7 +4442,7 @@ impl PlatformExprStrategy {
|
||||
);
|
||||
scope.push("profit_pct", position.holding_return * 100.0);
|
||||
}
|
||||
scope
|
||||
scope.into_inner()
|
||||
}
|
||||
|
||||
fn eval_dynamic(
|
||||
|
||||
Reference in New Issue
Block a user