Improve jq microcap execution semantics

This commit is contained in:
boris
2026-04-18 18:02:50 +08:00
parent 9f4165e689
commit 0e2c25e4c4
26 changed files with 5058 additions and 362 deletions

View File

@@ -1,6 +1,6 @@
use chrono::NaiveDate;
use crate::data::{CandidateEligibility, DailyMarketSnapshot};
use crate::data::{CandidateEligibility, DailyMarketSnapshot, PriceField};
use crate::portfolio::Position;
#[derive(Debug, Clone)]
@@ -31,6 +31,7 @@ pub trait EquityRuleHooks {
execution_date: NaiveDate,
snapshot: &DailyMarketSnapshot,
candidate: &CandidateEligibility,
price_field: PriceField,
) -> RuleCheck;
fn can_sell(
@@ -39,6 +40,7 @@ pub trait EquityRuleHooks {
snapshot: &DailyMarketSnapshot,
candidate: &CandidateEligibility,
position: &Position,
price_field: PriceField,
) -> RuleCheck;
}
@@ -46,12 +48,12 @@ pub trait EquityRuleHooks {
pub struct ChinaEquityRuleHooks;
impl ChinaEquityRuleHooks {
fn at_upper_limit(snapshot: &DailyMarketSnapshot) -> bool {
snapshot.open >= snapshot.upper_limit - 1e-6
fn at_upper_limit(snapshot: &DailyMarketSnapshot, price_field: PriceField) -> bool {
snapshot.is_at_upper_limit_price(snapshot.buy_price(price_field))
}
fn at_lower_limit(snapshot: &DailyMarketSnapshot) -> bool {
snapshot.open <= snapshot.lower_limit + 1e-6
fn at_lower_limit(snapshot: &DailyMarketSnapshot, price_field: PriceField) -> bool {
snapshot.is_at_lower_limit_price(snapshot.sell_price(price_field))
}
}
@@ -61,6 +63,7 @@ impl EquityRuleHooks for ChinaEquityRuleHooks {
_execution_date: NaiveDate,
snapshot: &DailyMarketSnapshot,
candidate: &CandidateEligibility,
price_field: PriceField,
) -> RuleCheck {
if snapshot.paused || candidate.is_paused {
return RuleCheck::reject("paused");
@@ -68,7 +71,7 @@ impl EquityRuleHooks for ChinaEquityRuleHooks {
if !candidate.allow_buy {
return RuleCheck::reject("buy disabled by eligibility flags");
}
if Self::at_upper_limit(snapshot) {
if Self::at_upper_limit(snapshot, price_field) {
return RuleCheck::reject("open at or above upper limit");
}
@@ -81,6 +84,7 @@ impl EquityRuleHooks for ChinaEquityRuleHooks {
snapshot: &DailyMarketSnapshot,
candidate: &CandidateEligibility,
position: &Position,
price_field: PriceField,
) -> RuleCheck {
if snapshot.paused || candidate.is_paused {
return RuleCheck::reject("paused");
@@ -88,7 +92,7 @@ impl EquityRuleHooks for ChinaEquityRuleHooks {
if !candidate.allow_sell {
return RuleCheck::reject("sell disabled by eligibility flags");
}
if Self::at_lower_limit(snapshot) {
if Self::at_lower_limit(snapshot, price_field) {
return RuleCheck::reject("open at or below lower limit");
}
if position.sellable_qty(execution_date) == 0 {