Revert "perf: build expression scope values lazily"
This reverts commit 1b449287fd.
This commit is contained in:
@@ -917,17 +917,6 @@ impl<'a> SelectiveExpressionScope<'a> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_lazy<T, F>(&mut self, name: &str, build: F) -> &mut Self
|
|
||||||
where
|
|
||||||
T: Into<Dynamic>,
|
|
||||||
F: FnOnce() -> T,
|
|
||||||
{
|
|
||||||
if self.requires(name) {
|
|
||||||
self.inner.push_dynamic(name.to_string(), build().into());
|
|
||||||
}
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_required<T: Into<Dynamic>>(&mut self, name: &str, value: T) -> &mut 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.inner.push_dynamic(name.to_string(), value.into());
|
||||||
self
|
self
|
||||||
@@ -4459,15 +4448,14 @@ impl PlatformExprStrategy {
|
|||||||
include_process_event_counts: bool,
|
include_process_event_counts: bool,
|
||||||
) -> Scope<'static> {
|
) -> Scope<'static> {
|
||||||
let mut scope = SelectiveExpressionScope::new(scope_identifiers);
|
let mut scope = SelectiveExpressionScope::new(scope_identifiers);
|
||||||
scope.push_lazy("trade_date", || day.date.format("%Y-%m-%d").to_string());
|
let trade_date = day.date.format("%Y-%m-%d").to_string();
|
||||||
scope.push_lazy("current_date", || day.date.format("%Y-%m-%d").to_string());
|
let decision_date = ctx.decision_date.format("%Y-%m-%d").to_string();
|
||||||
scope.push_lazy("date", || day.date.format("%Y-%m-%d").to_string());
|
let execution_date = ctx.execution_date.format("%Y-%m-%d").to_string();
|
||||||
scope.push_lazy("decision_date", || {
|
scope.push("trade_date", trade_date.clone());
|
||||||
ctx.decision_date.format("%Y-%m-%d").to_string()
|
scope.push("current_date", trade_date.clone());
|
||||||
});
|
scope.push("date", trade_date);
|
||||||
scope.push_lazy("execution_date", || {
|
scope.push("decision_date", decision_date);
|
||||||
ctx.execution_date.format("%Y-%m-%d").to_string()
|
scope.push("execution_date", execution_date);
|
||||||
});
|
|
||||||
scope.push("signal_open", day.signal_open);
|
scope.push("signal_open", day.signal_open);
|
||||||
scope.push("signal_close", day.signal_close);
|
scope.push("signal_close", day.signal_close);
|
||||||
scope.push("benchmark_open", day.benchmark_open);
|
scope.push("benchmark_open", day.benchmark_open);
|
||||||
@@ -4554,63 +4542,74 @@ impl PlatformExprStrategy {
|
|||||||
scope.push("is_month_start", day.is_month_start);
|
scope.push("is_month_start", day.is_month_start);
|
||||||
scope.push("is_month_end", day.is_month_end);
|
scope.push("is_month_end", day.is_month_end);
|
||||||
scope.push("signal_ma30", day.signal_ma30);
|
scope.push("signal_ma30", day.signal_ma30);
|
||||||
scope.push_lazy("has_open_orders", || ctx.has_open_orders());
|
scope.push("has_open_orders", ctx.has_open_orders());
|
||||||
scope.push_lazy("open_order_count", || ctx.open_order_count() as i64);
|
scope.push("open_order_count", ctx.open_order_count() as i64);
|
||||||
scope.push_lazy("open_buy_order_count", || ctx.open_buy_order_count() as i64);
|
scope.push("open_buy_order_count", ctx.open_buy_order_count() as i64);
|
||||||
scope.push_lazy("open_sell_order_count", || {
|
scope.push("open_sell_order_count", ctx.open_sell_order_count() as i64);
|
||||||
ctx.open_sell_order_count() as i64
|
scope.push("open_buy_qty", ctx.open_buy_quantity() as i64);
|
||||||
});
|
scope.push("open_sell_qty", ctx.open_sell_quantity() as i64);
|
||||||
scope.push_lazy("open_buy_qty", || ctx.open_buy_quantity() as i64);
|
scope.push("latest_open_order_id", ctx.latest_open_order_id() as i64);
|
||||||
scope.push_lazy("open_sell_qty", || ctx.open_sell_quantity() as i64);
|
scope.push(
|
||||||
scope.push_lazy("latest_open_order_id", || ctx.latest_open_order_id() as i64);
|
"latest_open_order_status",
|
||||||
scope.push_lazy("latest_open_order_status", || {
|
ctx.latest_open_order_status().to_string(),
|
||||||
ctx.latest_open_order_status().to_string()
|
);
|
||||||
});
|
scope.push(
|
||||||
scope.push_lazy("latest_open_order_unfilled_qty", || {
|
"latest_open_order_unfilled_qty",
|
||||||
ctx.latest_open_order_unfilled_quantity() as i64
|
ctx.latest_open_order_unfilled_quantity() as i64,
|
||||||
});
|
);
|
||||||
scope.push_lazy("has_dynamic_universe", || ctx.has_dynamic_universe());
|
scope.push("has_dynamic_universe", ctx.has_dynamic_universe());
|
||||||
scope.push_lazy("dynamic_universe_count", || {
|
scope.push(
|
||||||
ctx.dynamic_universe_count() as i64
|
"dynamic_universe_count",
|
||||||
});
|
ctx.dynamic_universe_count() as i64,
|
||||||
scope.push_lazy("has_subscriptions", || ctx.has_subscriptions());
|
);
|
||||||
scope.push_lazy("subscription_count", || ctx.subscription_count() as i64);
|
scope.push("has_subscriptions", ctx.has_subscriptions());
|
||||||
|
scope.push("subscription_count", ctx.subscription_count() as i64);
|
||||||
scope.push(
|
scope.push(
|
||||||
"subscription_guard_required",
|
"subscription_guard_required",
|
||||||
self.config.subscription_guard_required,
|
self.config.subscription_guard_required,
|
||||||
);
|
);
|
||||||
scope.push_lazy("has_process_events", || ctx.has_process_events());
|
scope.push("has_process_events", ctx.has_process_events());
|
||||||
scope.push_lazy("process_event_count", || ctx.process_event_count() as i64);
|
scope.push("process_event_count", ctx.process_event_count() as i64);
|
||||||
scope.push_lazy("current_process_kind", || {
|
scope.push(
|
||||||
ctx.current_process_event_kind().to_string()
|
"current_process_kind",
|
||||||
});
|
ctx.current_process_event_kind().to_string(),
|
||||||
scope.push_lazy("current_process_order_id", || {
|
);
|
||||||
ctx.current_process_event_order_id() as i64
|
scope.push(
|
||||||
});
|
"current_process_order_id",
|
||||||
scope.push_lazy("current_process_symbol", || {
|
ctx.current_process_event_order_id() as i64,
|
||||||
ctx.current_process_event_symbol().to_string()
|
);
|
||||||
});
|
scope.push(
|
||||||
scope.push_lazy("current_process_side", || {
|
"current_process_symbol",
|
||||||
ctx.current_process_event_side().to_string()
|
ctx.current_process_event_symbol().to_string(),
|
||||||
});
|
);
|
||||||
scope.push_lazy("current_process_detail", || {
|
scope.push(
|
||||||
ctx.current_process_event_detail().to_string()
|
"current_process_side",
|
||||||
});
|
ctx.current_process_event_side().to_string(),
|
||||||
scope.push_lazy("latest_process_kind", || {
|
);
|
||||||
ctx.latest_process_event_kind().to_string()
|
scope.push(
|
||||||
});
|
"current_process_detail",
|
||||||
scope.push_lazy("latest_process_order_id", || {
|
ctx.current_process_event_detail().to_string(),
|
||||||
ctx.latest_process_event_order_id() as i64
|
);
|
||||||
});
|
scope.push(
|
||||||
scope.push_lazy("latest_process_symbol", || {
|
"latest_process_kind",
|
||||||
ctx.latest_process_event_symbol().to_string()
|
ctx.latest_process_event_kind().to_string(),
|
||||||
});
|
);
|
||||||
scope.push_lazy("latest_process_side", || {
|
scope.push(
|
||||||
ctx.latest_process_event_side().to_string()
|
"latest_process_order_id",
|
||||||
});
|
ctx.latest_process_event_order_id() as i64,
|
||||||
scope.push_lazy("latest_process_detail", || {
|
);
|
||||||
ctx.latest_process_event_detail().to_string()
|
scope.push(
|
||||||
});
|
"latest_process_symbol",
|
||||||
|
ctx.latest_process_event_symbol().to_string(),
|
||||||
|
);
|
||||||
|
scope.push(
|
||||||
|
"latest_process_side",
|
||||||
|
ctx.latest_process_event_side().to_string(),
|
||||||
|
);
|
||||||
|
scope.push(
|
||||||
|
"latest_process_detail",
|
||||||
|
ctx.latest_process_event_detail().to_string(),
|
||||||
|
);
|
||||||
let process_event_counts = if include_day_factors || include_process_event_counts {
|
let process_event_counts = if include_day_factors || include_process_event_counts {
|
||||||
let mut counts = Map::new();
|
let mut counts = Map::new();
|
||||||
for (key, value) in ctx.process_event_counts() {
|
for (key, value) in ctx.process_event_counts() {
|
||||||
@@ -4821,7 +4820,7 @@ impl PlatformExprStrategy {
|
|||||||
stock.lower_limit,
|
stock.lower_limit,
|
||||||
stock.price_tick,
|
stock.price_tick,
|
||||||
);
|
);
|
||||||
scope.push_lazy("symbol", || stock.symbol.to_string());
|
scope.push("symbol", stock.symbol.to_string());
|
||||||
scope.push("market_cap", stock.market_cap);
|
scope.push("market_cap", stock.market_cap);
|
||||||
scope.push("market_cap_bn", stock.market_cap_bn);
|
scope.push("market_cap_bn", stock.market_cap_bn);
|
||||||
scope.push("free_float_cap", stock.free_float_cap);
|
scope.push("free_float_cap", stock.free_float_cap);
|
||||||
@@ -4867,29 +4866,36 @@ impl PlatformExprStrategy {
|
|||||||
scope.push("listed_days", stock.listed_days);
|
scope.push("listed_days", stock.listed_days);
|
||||||
scope.push("at_upper_limit", at_upper_limit);
|
scope.push("at_upper_limit", at_upper_limit);
|
||||||
scope.push("at_lower_limit", at_lower_limit);
|
scope.push("at_lower_limit", at_lower_limit);
|
||||||
scope.push_lazy("symbol_open_order_count", || {
|
scope.push(
|
||||||
ctx.symbol_open_order_count(&stock.symbol) as i64
|
"symbol_open_order_count",
|
||||||
});
|
ctx.symbol_open_order_count(&stock.symbol) as i64,
|
||||||
scope.push_lazy("symbol_open_buy_qty", || {
|
);
|
||||||
ctx.symbol_open_buy_quantity(&stock.symbol) as i64
|
scope.push(
|
||||||
});
|
"symbol_open_buy_qty",
|
||||||
scope.push_lazy("symbol_open_sell_qty", || {
|
ctx.symbol_open_buy_quantity(&stock.symbol) as i64,
|
||||||
ctx.symbol_open_sell_quantity(&stock.symbol) as i64
|
);
|
||||||
});
|
scope.push(
|
||||||
scope.push_lazy("latest_symbol_open_order_id", || {
|
"symbol_open_sell_qty",
|
||||||
ctx.latest_symbol_open_order_id(&stock.symbol) as i64
|
ctx.symbol_open_sell_quantity(&stock.symbol) as i64,
|
||||||
});
|
);
|
||||||
scope.push_lazy("latest_symbol_open_order_status", || {
|
scope.push(
|
||||||
|
"latest_symbol_open_order_id",
|
||||||
|
ctx.latest_symbol_open_order_id(&stock.symbol) as i64,
|
||||||
|
);
|
||||||
|
scope.push(
|
||||||
|
"latest_symbol_open_order_status",
|
||||||
ctx.latest_symbol_open_order_status(&stock.symbol)
|
ctx.latest_symbol_open_order_status(&stock.symbol)
|
||||||
.to_string()
|
.to_string(),
|
||||||
});
|
);
|
||||||
scope.push_lazy("latest_symbol_open_order_unfilled_qty", || {
|
scope.push(
|
||||||
ctx.latest_symbol_open_order_unfilled_quantity(&stock.symbol) as i64
|
"latest_symbol_open_order_unfilled_qty",
|
||||||
});
|
ctx.latest_symbol_open_order_unfilled_quantity(&stock.symbol) as i64,
|
||||||
scope.push_lazy("in_dynamic_universe", || {
|
);
|
||||||
ctx.dynamic_universe_contains(&stock.symbol)
|
scope.push(
|
||||||
});
|
"in_dynamic_universe",
|
||||||
scope.push_lazy("is_subscribed", || ctx.is_subscribed(&stock.symbol));
|
ctx.dynamic_universe_contains(&stock.symbol),
|
||||||
|
);
|
||||||
|
scope.push("is_subscribed", ctx.is_subscribed(&stock.symbol));
|
||||||
scope.push("stock_ma_short", stock.stock_ma_short);
|
scope.push("stock_ma_short", stock.stock_ma_short);
|
||||||
scope.push("stock_ma_mid", stock.stock_ma_mid);
|
scope.push("stock_ma_mid", stock.stock_ma_mid);
|
||||||
scope.push("stock_ma_long", stock.stock_ma_long);
|
scope.push("stock_ma_long", stock.stock_ma_long);
|
||||||
@@ -5071,7 +5077,7 @@ impl PlatformExprStrategy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(position) = position {
|
if let Some(position) = position {
|
||||||
scope.push_lazy("order_book_id", || position.order_book_id.clone());
|
scope.push("order_book_id", position.order_book_id.clone());
|
||||||
scope.push("avg_cost", position.avg_cost);
|
scope.push("avg_cost", position.avg_cost);
|
||||||
scope.push("avg_price", position.avg_price);
|
scope.push("avg_price", position.avg_price);
|
||||||
scope.push("current_price", position.current_price);
|
scope.push("current_price", position.current_price);
|
||||||
@@ -5105,19 +5111,18 @@ impl PlatformExprStrategy {
|
|||||||
scope.push("trading_pnl", position.trading_pnl);
|
scope.push("trading_pnl", position.trading_pnl);
|
||||||
scope.push("position_pnl", position.position_pnl);
|
scope.push("position_pnl", position.position_pnl);
|
||||||
scope.push("dividend_receivable", position.dividend_receivable);
|
scope.push("dividend_receivable", position.dividend_receivable);
|
||||||
scope.push_lazy("available_sellable_qty", || {
|
let available_sellable_qty = stock
|
||||||
stock
|
.map(|stock| {
|
||||||
.map(|stock| {
|
ctx.available_sellable_qty(&stock.symbol, position.sellable_qty as u32)
|
||||||
ctx.available_sellable_qty(&stock.symbol, position.sellable_qty as u32)
|
})
|
||||||
as i64
|
.unwrap_or(position.sellable_qty.max(0) as u32);
|
||||||
})
|
scope.push("available_sellable_qty", available_sellable_qty as i64);
|
||||||
.unwrap_or(position.sellable_qty.max(0))
|
scope.push(
|
||||||
});
|
"reserved_open_sell_qty",
|
||||||
scope.push_lazy("reserved_open_sell_qty", || {
|
|
||||||
stock
|
stock
|
||||||
.map(|stock| ctx.symbol_open_sell_quantity(&stock.symbol) as i64)
|
.map(|stock| ctx.symbol_open_sell_quantity(&stock.symbol) as i64)
|
||||||
.unwrap_or(0)
|
.unwrap_or(0),
|
||||||
});
|
);
|
||||||
scope.push("profit_pct", position.holding_return * 100.0);
|
scope.push("profit_pct", position.holding_return * 100.0);
|
||||||
}
|
}
|
||||||
scope.into_inner()
|
scope.into_inner()
|
||||||
@@ -12828,11 +12833,9 @@ fn code_number_value(value: &str) -> i64 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::cell::Cell;
|
|
||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use ahash::AHashSet;
|
|
||||||
use chrono::{NaiveDate, NaiveTime};
|
use chrono::{NaiveDate, NaiveTime};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@@ -12841,9 +12844,9 @@ mod tests {
|
|||||||
PlatformExprStrategyConfig, PlatformPortfolioDrawdownControlConfig,
|
PlatformExprStrategyConfig, PlatformPortfolioDrawdownControlConfig,
|
||||||
PlatformPortfolioDrawdownController, PlatformRebalanceSchedule, PlatformScheduleFrequency,
|
PlatformPortfolioDrawdownController, PlatformRebalanceSchedule, PlatformScheduleFrequency,
|
||||||
PlatformStopTakeReferencePriceMode, PlatformTradeAction, PlatformUniverseActionKind,
|
PlatformStopTakeReferencePriceMode, PlatformTradeAction, PlatformUniverseActionKind,
|
||||||
RuntimeHelperResolution, SelectionRiskDeferral, SelectiveExpressionScope,
|
RuntimeHelperResolution, SelectionRiskDeferral, StockFilterQuoteUsage, StockRollingField,
|
||||||
StockFilterQuoteUsage, StockRollingField, StockSnapshotFieldRequirements,
|
StockSnapshotFieldRequirements, framework_stock_rolling_factor_requirement,
|
||||||
framework_stock_rolling_factor_requirement, scheduled_position_exposure,
|
scheduled_position_exposure,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
AlgoOrderStyle, BenchmarkSnapshot, CandidateEligibility, CorporateAction,
|
AlgoOrderStyle, BenchmarkSnapshot, CandidateEligibility, CorporateAction,
|
||||||
@@ -12859,25 +12862,6 @@ mod tests {
|
|||||||
NaiveDate::from_ymd_opt(year, month, day).expect("valid date")
|
NaiveDate::from_ymd_opt(year, month, day).expect("valid date")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn selective_expression_scope_does_not_build_unreferenced_values() {
|
|
||||||
let required = AHashSet::from_iter(["needed".to_string()]);
|
|
||||||
let builds = Cell::new(0);
|
|
||||||
let mut scope = SelectiveExpressionScope::new(&required);
|
|
||||||
|
|
||||||
scope.push_lazy("unused", || {
|
|
||||||
builds.set(builds.get() + 1);
|
|
||||||
"unused".to_string()
|
|
||||||
});
|
|
||||||
scope.push_lazy("needed", || {
|
|
||||||
builds.set(builds.get() + 1);
|
|
||||||
"value".to_string()
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(builds.get(), 1);
|
|
||||||
assert!(scope.into_inner().contains("needed"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn stock_state_cache_resets_before_reusing_compact_keys_on_another_date() {
|
fn stock_state_cache_resets_before_reusing_compact_keys_on_another_date() {
|
||||||
let dates = [d(2025, 1, 2), d(2025, 1, 3)];
|
let dates = [d(2025, 1, 2), d(2025, 1, 3)];
|
||||||
|
|||||||
Reference in New Issue
Block a user