1 Commits

Author SHA1 Message Date
boris
616cab0e7e chore: 更新 fidc-backtest-engine - 2026-05-13 2026-05-13 21:57:57 +08:00
3 changed files with 39 additions and 12 deletions

View File

@@ -196,7 +196,7 @@ pub struct PlatformExprStrategyConfig {
pub stock_short_ma_days: usize, pub stock_short_ma_days: usize,
pub stock_mid_ma_days: usize, pub stock_mid_ma_days: usize,
pub stock_long_ma_days: usize, pub stock_long_ma_days: usize,
pub skip_month_day_ranges: Vec<(u32, u32, u32)>, pub skip_month_day_ranges: Vec<(Option<u32>, u32, u32, u32)>,
pub rebalance_schedule: Option<PlatformRebalanceSchedule>, pub rebalance_schedule: Option<PlatformRebalanceSchedule>,
pub rotation_enabled: bool, pub rotation_enabled: bool,
pub daily_top_up_enabled: bool, pub daily_top_up_enabled: bool,
@@ -263,11 +263,17 @@ fn band_low(index_close) {
} }
fn in_skip_window(&self, date: NaiveDate) -> bool { fn in_skip_window(&self, date: NaiveDate) -> bool {
let year = date.year() as u32;
let month = date.month(); let month = date.month();
let day = date.day(); let day = date.day();
self.skip_month_day_ranges self.skip_month_day_ranges
.iter() .iter()
.any(|(m, start_day, end_day)| month == *m && day >= *start_day && day <= *end_day) .any(|(window_year, m, start_day, end_day)| {
window_year.map(|value| value == year).unwrap_or(true)
&& month == *m
&& day >= *start_day
&& day <= *end_day
})
} }
} }

View File

@@ -156,6 +156,8 @@ pub struct IndexThrottleConfig {
#[derive(Debug, Clone, Default, Deserialize, Serialize)] #[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SkipWindowConfig { pub struct SkipWindowConfig {
#[serde(default)]
pub year: Option<u32>,
#[serde(default)] #[serde(default)]
pub month: Option<u32>, pub month: Option<u32>,
#[serde(default)] #[serde(default)]
@@ -391,7 +393,14 @@ pub fn platform_expr_config_from_spec(
cfg.skip_month_day_ranges = engine cfg.skip_month_day_ranges = engine
.skip_windows .skip_windows
.iter() .iter()
.filter_map(|window| Some((window.month?, window.start_day?, window.end_day?))) .filter_map(|window| {
Some((
window.year,
window.month?,
window.start_day?,
window.end_day?,
))
})
.collect(); .collect();
} }
if let Some(spec_signal_symbol) = engine if let Some(spec_signal_symbol) = engine

View File

@@ -1104,7 +1104,7 @@ pub struct CnSmallCapRotationConfig {
pub take_profit_pct: f64, pub take_profit_pct: f64,
pub signal_symbol: Option<String>, pub signal_symbol: Option<String>,
pub skip_months: Vec<u32>, pub skip_months: Vec<u32>,
pub skip_month_day_ranges: Vec<(u32, u32, u32)>, pub skip_month_day_ranges: Vec<(Option<u32>, u32, u32, u32)>,
} }
impl CnSmallCapRotationConfig { impl CnSmallCapRotationConfig {
@@ -1159,23 +1159,29 @@ impl CnSmallCapRotationConfig {
signal_symbol: Some("000852.SH".to_string()), signal_symbol: Some("000852.SH".to_string()),
skip_months: vec![], skip_months: vec![],
skip_month_day_ranges: vec![ skip_month_day_ranges: vec![
(1, 15, 30), (None, 1, 15, 30),
(4, 15, 29), (None, 4, 15, 29),
(8, 15, 31), (None, 8, 15, 31),
(10, 20, 30), (None, 10, 20, 30),
(12, 20, 30), (None, 12, 20, 30),
], ],
} }
} }
fn in_skip_window(&self, date: NaiveDate) -> bool { fn in_skip_window(&self, date: NaiveDate) -> bool {
let year = date.year() as u32;
let month = date.month(); let month = date.month();
let day = date.day(); let day = date.day();
self.skip_months.contains(&month) self.skip_months.contains(&month)
|| self || self
.skip_month_day_ranges .skip_month_day_ranges
.iter() .iter()
.any(|(m, start_day, end_day)| month == *m && day >= *start_day && day <= *end_day) .any(|(window_year, m, start_day, end_day)| {
window_year.map(|value| value == year).unwrap_or(true)
&& month == *m
&& day >= *start_day
&& day <= *end_day
})
} }
} }
@@ -1533,7 +1539,7 @@ pub struct OmniMicroCapConfig {
pub trade_rate: f64, pub trade_rate: f64,
pub stop_loss_ratio: f64, pub stop_loss_ratio: f64,
pub take_profit_ratio: f64, pub take_profit_ratio: f64,
pub skip_month_day_ranges: Vec<(u32, u32, u32)>, pub skip_month_day_ranges: Vec<(Option<u32>, u32, u32, u32)>,
} }
impl OmniMicroCapConfig { impl OmniMicroCapConfig {
@@ -1592,11 +1598,17 @@ impl OmniMicroCapConfig {
} }
fn in_skip_window(&self, date: NaiveDate) -> bool { fn in_skip_window(&self, date: NaiveDate) -> bool {
let year = date.year() as u32;
let month = date.month(); let month = date.month();
let day = date.day(); let day = date.day();
self.skip_month_day_ranges self.skip_month_day_ranges
.iter() .iter()
.any(|(m, start_day, end_day)| month == *m && day >= *start_day && day <= *end_day) .any(|(window_year, m, start_day, end_day)| {
window_year.map(|value| value == year).unwrap_or(true)
&& month == *m
&& day >= *start_day
&& day <= *end_day
})
} }
} }