chore: 更新 fidc-backtest-engine - 2026-05-22
This commit is contained in:
@@ -17,6 +17,7 @@ use crate::events::{FillEvent, OrderEvent, OrderSide, OrderStatus, ProcessEvent}
|
||||
use crate::futures::{FuturesAccountState, FuturesOrderIntent};
|
||||
use crate::instrument::Instrument;
|
||||
use crate::portfolio::PortfolioState;
|
||||
use crate::risk_control::ChinaAShareRiskControl;
|
||||
use crate::scheduler::ScheduleRule;
|
||||
use crate::universe::{DynamicMarketCapBandSelector, SelectionContext, UniverseSelector};
|
||||
|
||||
@@ -2330,18 +2331,6 @@ impl OmniMicroCapStrategy {
|
||||
true
|
||||
}
|
||||
|
||||
fn special_name(&self, ctx: &StrategyContext<'_>, symbol: &str) -> bool {
|
||||
let instrument_name = ctx
|
||||
.data
|
||||
.instruments()
|
||||
.get(symbol)
|
||||
.map(|instrument| instrument.name.as_str())
|
||||
.unwrap_or("");
|
||||
instrument_name.contains("ST")
|
||||
|| instrument_name.contains('*')
|
||||
|| instrument_name.contains('退')
|
||||
}
|
||||
|
||||
fn can_sell_position(&self, ctx: &StrategyContext<'_>, date: NaiveDate, symbol: &str) -> bool {
|
||||
let Some(position) = ctx.portfolio.position(symbol) else {
|
||||
return false;
|
||||
@@ -2355,11 +2344,15 @@ impl OmniMicroCapStrategy {
|
||||
let Ok(candidate) = ctx.data.require_candidate(date, symbol) else {
|
||||
return false;
|
||||
};
|
||||
let lower_limit_check_price = market.price(PriceField::Last);
|
||||
!(market.paused
|
||||
|| candidate.is_paused
|
||||
|| !candidate.allow_sell
|
||||
|| market.is_at_lower_limit_price(lower_limit_check_price))
|
||||
ChinaAShareRiskControl::sell_rejection_reason(
|
||||
date,
|
||||
candidate,
|
||||
market,
|
||||
ctx.data.instrument(symbol),
|
||||
Some(position),
|
||||
ChinaAShareRiskControl::sell_check_price(market, PriceField::Last),
|
||||
)
|
||||
.is_none()
|
||||
}
|
||||
|
||||
fn buy_rejection_reason(
|
||||
@@ -2371,25 +2364,14 @@ impl OmniMicroCapStrategy {
|
||||
let market = ctx.data.require_market(date, symbol)?;
|
||||
let candidate = ctx.data.require_candidate(date, symbol)?;
|
||||
|
||||
if market.paused || candidate.is_paused {
|
||||
return Ok(Some("paused".to_string()));
|
||||
}
|
||||
if candidate.is_st || self.special_name(ctx, symbol) {
|
||||
return Ok(Some("st_or_special_name".to_string()));
|
||||
}
|
||||
if candidate.is_kcb {
|
||||
return Ok(Some("kcb".to_string()));
|
||||
}
|
||||
if !candidate.allow_buy {
|
||||
return Ok(Some("buy_disabled".to_string()));
|
||||
}
|
||||
if market.is_at_upper_limit_price(market.day_open)
|
||||
|| market.is_at_upper_limit_price(market.buy_price(PriceField::Last))
|
||||
{
|
||||
return Ok(Some("upper_limit".to_string()));
|
||||
}
|
||||
if market.day_open <= 1.0 {
|
||||
return Ok(Some("one_yuan".to_string()));
|
||||
if let Some(reason) = ChinaAShareRiskControl::buy_rejection_reason(
|
||||
date,
|
||||
candidate,
|
||||
market,
|
||||
ctx.data.instrument(symbol),
|
||||
ChinaAShareRiskControl::buy_check_price(market, PriceField::Last),
|
||||
) {
|
||||
return Ok(Some(reason.to_string()));
|
||||
}
|
||||
if !self.truth_selection_contains(date, symbol)
|
||||
&& !self.stock_passes_ma_filter(ctx, date, symbol)
|
||||
|
||||
Reference in New Issue
Block a user