94 lines
2.3 KiB
Rust
94 lines
2.3 KiB
Rust
use chrono::NaiveDate;
|
|
|
|
use crate::data::{CandidateEligibility, DailyMarketSnapshot, PriceField};
|
|
use crate::portfolio::Position;
|
|
use crate::risk_control::ChinaAShareRiskControl;
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct RuleCheck {
|
|
pub allowed: bool,
|
|
pub reason: Option<String>,
|
|
}
|
|
|
|
impl RuleCheck {
|
|
pub fn allow() -> Self {
|
|
Self {
|
|
allowed: true,
|
|
reason: None,
|
|
}
|
|
}
|
|
|
|
pub fn reject(reason: impl Into<String>) -> Self {
|
|
Self {
|
|
allowed: false,
|
|
reason: Some(reason.into()),
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait EquityRuleHooks {
|
|
fn can_buy(
|
|
&self,
|
|
execution_date: NaiveDate,
|
|
snapshot: &DailyMarketSnapshot,
|
|
candidate: &CandidateEligibility,
|
|
price_field: PriceField,
|
|
) -> RuleCheck;
|
|
|
|
fn can_sell(
|
|
&self,
|
|
execution_date: NaiveDate,
|
|
snapshot: &DailyMarketSnapshot,
|
|
candidate: &CandidateEligibility,
|
|
position: &Position,
|
|
price_field: PriceField,
|
|
) -> RuleCheck;
|
|
}
|
|
|
|
#[derive(Debug, Clone, Default)]
|
|
pub struct ChinaEquityRuleHooks;
|
|
|
|
impl EquityRuleHooks for ChinaEquityRuleHooks {
|
|
fn can_buy(
|
|
&self,
|
|
_execution_date: NaiveDate,
|
|
snapshot: &DailyMarketSnapshot,
|
|
candidate: &CandidateEligibility,
|
|
price_field: PriceField,
|
|
) -> RuleCheck {
|
|
if let Some(reason) = ChinaAShareRiskControl::buy_rejection_reason(
|
|
_execution_date,
|
|
candidate,
|
|
snapshot,
|
|
None,
|
|
ChinaAShareRiskControl::buy_check_price(snapshot, price_field),
|
|
) {
|
|
return RuleCheck::reject(reason);
|
|
}
|
|
|
|
RuleCheck::allow()
|
|
}
|
|
|
|
fn can_sell(
|
|
&self,
|
|
execution_date: NaiveDate,
|
|
snapshot: &DailyMarketSnapshot,
|
|
candidate: &CandidateEligibility,
|
|
position: &Position,
|
|
price_field: PriceField,
|
|
) -> RuleCheck {
|
|
if let Some(reason) = ChinaAShareRiskControl::sell_rejection_reason(
|
|
execution_date,
|
|
candidate,
|
|
snapshot,
|
|
None,
|
|
Some(position),
|
|
ChinaAShareRiskControl::sell_check_price(snapshot, price_field),
|
|
) {
|
|
return RuleCheck::reject(reason);
|
|
}
|
|
|
|
RuleCheck::allow()
|
|
}
|
|
}
|