减少策略股票状态的字符串分配
This commit is contained in:
@@ -1332,6 +1332,9 @@ pub struct DataSet {
|
||||
market_series_end_positions_by_symbol_id: Arc<Option<SymbolSeriesEndPositionIndex>>,
|
||||
benchmark_series_cache: Arc<BenchmarkPriceSeries>,
|
||||
symbol_id_by_code: Arc<AHashMap<String, u32>>,
|
||||
/// Interned symbol text indexed by immutable symbol id so per-day
|
||||
/// expression states can share the same allocation.
|
||||
symbol_text_by_id: Arc<Vec<Arc<str>>>,
|
||||
eligible_universe_by_date: Arc<OnceLock<BTreeMap<NaiveDate, Vec<EligibleUniverseSnapshot>>>>,
|
||||
benchmark_code: String,
|
||||
futures_params_by_symbol: Arc<HashMap<String, Vec<FuturesTradingParameter>>>,
|
||||
@@ -1737,6 +1740,12 @@ impl DataSet {
|
||||
&factor_by_date,
|
||||
&candidate_by_date,
|
||||
);
|
||||
let mut symbol_text_by_id = vec![Arc::<str>::from(""); symbol_id_by_code.len()];
|
||||
for (symbol, symbol_id) in &symbol_id_by_code {
|
||||
if let Some(slot) = symbol_text_by_id.get_mut(*symbol_id as usize) {
|
||||
*slot = Arc::<str>::from(symbol.as_str());
|
||||
}
|
||||
}
|
||||
let market_symbol_ids_by_date =
|
||||
build_group_symbol_ids(&market_by_date, &symbol_id_by_code, |item| {
|
||||
item.symbol.as_str()
|
||||
@@ -1815,6 +1824,7 @@ impl DataSet {
|
||||
),
|
||||
benchmark_series_cache: Arc::new(benchmark_series_cache),
|
||||
symbol_id_by_code: Arc::new(symbol_id_by_code),
|
||||
symbol_text_by_id: Arc::new(symbol_text_by_id),
|
||||
eligible_universe_by_date: Arc::new(OnceLock::new()),
|
||||
benchmark_code,
|
||||
futures_params_by_symbol: Arc::new(futures_params_by_symbol),
|
||||
@@ -1862,6 +1872,10 @@ impl DataSet {
|
||||
self.symbol_id_by_code.get(symbol).copied()
|
||||
}
|
||||
|
||||
pub(crate) fn symbol_text_by_id(&self, symbol_id: u32) -> Option<&Arc<str>> {
|
||||
self.symbol_text_by_id.get(symbol_id as usize)
|
||||
}
|
||||
|
||||
pub fn market(&self, date: NaiveDate, symbol: &str) -> Option<&DailyMarketSnapshot> {
|
||||
let symbol_id = self.symbol_id(symbol)?;
|
||||
self.market_by_symbol_id(date, symbol_id)
|
||||
|
||||
@@ -656,7 +656,7 @@ struct DayExpressionState {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct StockExpressionState {
|
||||
symbol: String,
|
||||
symbol: Arc<str>,
|
||||
symbol_id: u32,
|
||||
market_cap: f64,
|
||||
market_cap_bn: f64,
|
||||
@@ -4169,7 +4169,17 @@ impl PlatformExprStrategy {
|
||||
};
|
||||
|
||||
let state = Arc::new(StockExpressionState {
|
||||
symbol: symbol.to_string(),
|
||||
symbol: ctx
|
||||
.data
|
||||
.symbol_text_by_id(symbol_id)
|
||||
.cloned()
|
||||
.ok_or_else(|| {
|
||||
BacktestError::Data(crate::data::DataSetError::MissingSnapshot {
|
||||
kind: "symbol_text_index",
|
||||
date,
|
||||
symbol: symbol.to_string(),
|
||||
})
|
||||
})?,
|
||||
symbol_id,
|
||||
market_cap,
|
||||
market_cap_bn,
|
||||
@@ -4640,7 +4650,7 @@ impl PlatformExprStrategy {
|
||||
stock.lower_limit,
|
||||
stock.price_tick,
|
||||
);
|
||||
scope.push("symbol", stock.symbol.clone());
|
||||
scope.push("symbol", stock.symbol.as_ref());
|
||||
scope.push("market_cap", stock.market_cap);
|
||||
scope.push("market_cap_bn", stock.market_cap_bn);
|
||||
scope.push("free_float_cap", stock.free_float_cap);
|
||||
@@ -4739,7 +4749,10 @@ impl PlatformExprStrategy {
|
||||
scope.push("volume_ma100", stock.stock_volume_ma100);
|
||||
if include_factors_map {
|
||||
let mut factors = Map::new();
|
||||
factors.insert("symbol".into(), Dynamic::from(stock.symbol.clone()));
|
||||
factors.insert(
|
||||
"symbol".into(),
|
||||
Dynamic::from(stock.symbol.as_ref().to_string()),
|
||||
);
|
||||
factors.insert("market_cap".into(), Dynamic::from(stock.market_cap));
|
||||
factors.insert("market_cap_bn".into(), Dynamic::from(stock.market_cap_bn));
|
||||
factors.insert("free_float_cap".into(), Dynamic::from(stock.free_float_cap));
|
||||
@@ -6586,7 +6599,7 @@ impl PlatformExprStrategy {
|
||||
let matched = ctx
|
||||
.get_margin_stocks(&margin_type)
|
||||
.iter()
|
||||
.any(|symbol| symbol == &stock.symbol);
|
||||
.any(|symbol| symbol.as_str() == stock.symbol.as_ref());
|
||||
Ok(RuntimeHelperResolution::Boolean(matched))
|
||||
}
|
||||
"dominant_future" | "get_dominant_future" => {
|
||||
@@ -6656,14 +6669,14 @@ impl PlatformExprStrategy {
|
||||
let stock = stock.ok_or_else(|| {
|
||||
BacktestError::Execution(format!("{helper} requires stock context"))
|
||||
})?;
|
||||
return Ok((stock.symbol.clone(), default_lookback));
|
||||
return Ok((stock.symbol.as_ref().to_string(), default_lookback));
|
||||
}
|
||||
if args.len() == 1 {
|
||||
if let Ok(lookback) = Self::parse_positive_usize(&args[0]) {
|
||||
let stock = stock.ok_or_else(|| {
|
||||
BacktestError::Execution(format!("{helper} requires stock context"))
|
||||
})?;
|
||||
return Ok((stock.symbol.clone(), lookback));
|
||||
return Ok((stock.symbol.as_ref().to_string(), lookback));
|
||||
}
|
||||
return Ok((
|
||||
Self::parse_string_or_identifier(&args[0])?,
|
||||
|
||||
Reference in New Issue
Block a user