95 lines
3.1 KiB
Rust
95 lines
3.1 KiB
Rust
use chrono::NaiveDate;
|
|
use fidc_core::{
|
|
CnSmallCapRotationConfig, CnSmallCapRotationStrategy, DataSet, JqMicroCapConfig,
|
|
JqMicroCapStrategy, PortfolioState, Strategy, StrategyContext,
|
|
};
|
|
use std::collections::BTreeSet;
|
|
use std::path::PathBuf;
|
|
|
|
#[test]
|
|
fn strategy_emits_target_weights_and_diagnostics() {
|
|
let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../data/demo");
|
|
let data = DataSet::from_csv_dir(&data_dir).expect("demo data");
|
|
let decision_date = NaiveDate::from_ymd_opt(2024, 1, 10).unwrap();
|
|
let execution_date = NaiveDate::from_ymd_opt(2024, 1, 11).unwrap();
|
|
let portfolio = PortfolioState::new(1_000_000.0);
|
|
let mut cfg = CnSmallCapRotationConfig::cn_dyn_smallcap_band();
|
|
cfg.signal_symbol = Some("000001.SZ".to_string());
|
|
cfg.short_ma_days = 3;
|
|
cfg.long_ma_days = 5;
|
|
let mut strategy = CnSmallCapRotationStrategy::new(cfg);
|
|
let subscriptions = BTreeSet::new();
|
|
|
|
let decision = strategy
|
|
.on_day(&StrategyContext {
|
|
execution_date,
|
|
decision_date,
|
|
decision_index: 0,
|
|
data: &data,
|
|
portfolio: &portfolio,
|
|
open_orders: &[],
|
|
dynamic_universe: None,
|
|
subscriptions: &subscriptions,
|
|
process_events: &[],
|
|
active_process_event: None,
|
|
})
|
|
.expect("decision");
|
|
|
|
assert!(decision.rebalance);
|
|
assert!(decision.rebalance);
|
|
assert!(!decision.diagnostics.is_empty());
|
|
assert!(
|
|
decision
|
|
.diagnostics
|
|
.iter()
|
|
.any(|line| line.contains("signal_symbol="))
|
|
);
|
|
assert_eq!(strategy.name(), "cn-dyn-smallcap-band");
|
|
}
|
|
|
|
#[test]
|
|
fn jq_strategy_emits_same_day_decision() {
|
|
let data_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../data/demo");
|
|
let data = DataSet::from_csv_dir(&data_dir).expect("demo data");
|
|
let execution_date = NaiveDate::from_ymd_opt(2024, 1, 10).unwrap();
|
|
let portfolio = PortfolioState::new(1_000_000.0);
|
|
let mut cfg = JqMicroCapConfig::jq_microcap();
|
|
cfg.benchmark_signal_symbol = "000001.SZ".to_string();
|
|
cfg.benchmark_short_ma_days = 3;
|
|
cfg.benchmark_long_ma_days = 5;
|
|
cfg.stock_short_ma_days = 3;
|
|
cfg.stock_mid_ma_days = 4;
|
|
cfg.stock_long_ma_days = 5;
|
|
let mut strategy = JqMicroCapStrategy::new(cfg);
|
|
let subscriptions = BTreeSet::new();
|
|
|
|
let decision = strategy
|
|
.on_day(&StrategyContext {
|
|
execution_date,
|
|
decision_date: execution_date,
|
|
decision_index: 0,
|
|
data: &data,
|
|
portfolio: &portfolio,
|
|
open_orders: &[],
|
|
dynamic_universe: None,
|
|
subscriptions: &subscriptions,
|
|
process_events: &[],
|
|
active_process_event: None,
|
|
})
|
|
.expect("jq decision");
|
|
|
|
assert!(!decision.rebalance);
|
|
assert!(
|
|
decision
|
|
.diagnostics
|
|
.iter()
|
|
.any(|line| line.contains("jq_microcap signal="))
|
|
);
|
|
assert!(
|
|
decision
|
|
.diagnostics
|
|
.iter()
|
|
.any(|line| line.contains("selected="))
|
|
);
|
|
}
|