按表达式需求构建运行作用域
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")
|
|| 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 {
|
pub struct PlatformExprStrategy {
|
||||||
config: PlatformExprStrategyConfig,
|
config: PlatformExprStrategyConfig,
|
||||||
engine: Engine,
|
engine: Engine,
|
||||||
@@ -3732,7 +3775,8 @@ impl PlatformExprStrategy {
|
|||||||
include_factors_map: bool,
|
include_factors_map: bool,
|
||||||
include_process_event_counts: bool,
|
include_process_event_counts: bool,
|
||||||
) -> Scope<'static> {
|
) -> 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 trade_date = day.date.format("%Y-%m-%d").to_string();
|
||||||
let decision_date = ctx.decision_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();
|
let execution_date = ctx.execution_date.format("%Y-%m-%d").to_string();
|
||||||
@@ -3765,7 +3809,7 @@ impl PlatformExprStrategy {
|
|||||||
"price_tick",
|
"price_tick",
|
||||||
] {
|
] {
|
||||||
self.push_market_scope_map(
|
self.push_market_scope_map(
|
||||||
&mut scope,
|
scope.inner_mut(),
|
||||||
ctx,
|
ctx,
|
||||||
ctx.decision_date,
|
ctx.decision_date,
|
||||||
"decision",
|
"decision",
|
||||||
@@ -3773,7 +3817,7 @@ impl PlatformExprStrategy {
|
|||||||
identifiers,
|
identifiers,
|
||||||
);
|
);
|
||||||
self.push_market_scope_map(
|
self.push_market_scope_map(
|
||||||
&mut scope,
|
scope.inner_mut(),
|
||||||
ctx,
|
ctx,
|
||||||
ctx.execution_date,
|
ctx.execution_date,
|
||||||
"execution",
|
"execution",
|
||||||
@@ -3898,7 +3942,7 @@ impl PlatformExprStrategy {
|
|||||||
for (key, value) in ctx.process_event_counts() {
|
for (key, value) in ctx.process_event_counts() {
|
||||||
counts.insert(key.into(), Dynamic::from(value));
|
counts.insert(key.into(), Dynamic::from(value));
|
||||||
}
|
}
|
||||||
scope.push("process_event_counts", counts.clone());
|
scope.push_required("process_event_counts", counts.clone());
|
||||||
Some(counts)
|
Some(counts)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -4085,7 +4129,7 @@ impl PlatformExprStrategy {
|
|||||||
if let Some(counts) = process_event_counts {
|
if let Some(counts) = process_event_counts {
|
||||||
day_factors.insert("process_event_counts".into(), Dynamic::from(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 {
|
if let Some(stock) = stock {
|
||||||
let at_upper_limit = Self::price_is_at_or_above_upper_limit(
|
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 {
|
for (key, value) in &stock.extra_text_factors {
|
||||||
factors.insert(key.clone().into(), Dynamic::from(value.clone()));
|
factors.insert(key.clone().into(), Dynamic::from(value.clone()));
|
||||||
}
|
}
|
||||||
scope.push("factors", factors);
|
scope.push_required("factors", factors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(position) = position {
|
if let Some(position) = position {
|
||||||
@@ -4398,7 +4442,7 @@ impl PlatformExprStrategy {
|
|||||||
);
|
);
|
||||||
scope.push("profit_pct", position.holding_return * 100.0);
|
scope.push("profit_pct", position.holding_return * 100.0);
|
||||||
}
|
}
|
||||||
scope
|
scope.into_inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_dynamic(
|
fn eval_dynamic(
|
||||||
|
|||||||
Reference in New Issue
Block a user