补充可配置过户费并纳入成交成本

This commit is contained in:
boris
2026-08-22 14:50:00 +08:00
parent b8776d7169
commit 375b8b2df1
8 changed files with 43 additions and 3 deletions
+20 -1
View File
@@ -9,11 +9,12 @@ use crate::risk_control::TradingConstraintConfig;
pub struct TradingCost {
pub commission: f64,
pub stamp_tax: f64,
pub transfer_fee: f64,
}
impl TradingCost {
pub fn total(self) -> f64 {
self.commission + self.stamp_tax
self.commission + self.stamp_tax + self.transfer_fee
}
}
@@ -39,6 +40,7 @@ pub struct ChinaAShareCostModel {
pub stamp_tax_rate_after_change: f64,
pub stamp_tax_change_date: NaiveDate,
pub minimum_commission: f64,
pub transfer_fee_rate: f64,
}
impl Default for ChinaAShareCostModel {
@@ -55,6 +57,7 @@ impl ChinaAShareCostModel {
stamp_tax_rate_after_change: config.stamp_tax_rate_after_change,
stamp_tax_change_date: config.stamp_tax_change_date,
minimum_commission: config.minimum_commission,
transfer_fee_rate: config.transfer_fee_rate,
}
}
@@ -80,6 +83,13 @@ impl ChinaAShareCostModel {
gross_amount * self.stamp_tax_rate_for(date)
}
pub fn transfer_fee_for(&self, gross_amount: f64) -> f64 {
if gross_amount <= 0.0 {
return 0.0;
}
gross_amount * self.transfer_fee_rate
}
pub fn commission_for_order_fill(
&self,
gross_amount: f64,
@@ -124,15 +134,18 @@ impl CostModel for ChinaAShareCostModel {
return TradingCost {
commission: 0.0,
stamp_tax: 0.0,
transfer_fee: 0.0,
};
}
let commission = self.commission_for(gross_amount);
let stamp_tax = self.stamp_tax_for(date, side, gross_amount);
let transfer_fee = self.transfer_fee_for(gross_amount);
TradingCost {
commission,
stamp_tax,
transfer_fee,
}
}
@@ -148,15 +161,18 @@ impl CostModel for ChinaAShareCostModel {
return TradingCost {
commission: 0.0,
stamp_tax: 0.0,
transfer_fee: 0.0,
};
}
let commission = self.commission_for_order_fill(gross_amount, order_id, commission_state);
let stamp_tax = self.stamp_tax_for(date, side, gross_amount);
let transfer_fee = self.transfer_fee_for(gross_amount);
TradingCost {
commission,
stamp_tax,
transfer_fee,
}
}
}
@@ -181,6 +197,7 @@ mod tests {
let config = TradingConstraintConfig {
commission_rate: 0.0003,
minimum_commission: 5.0,
transfer_fee_rate: 0.00001,
stamp_tax_rate_before_change: 0.002,
stamp_tax_rate_after_change: 0.001,
stamp_tax_change_date: NaiveDate::from_ymd_opt(2025, 1, 10).expect("valid date"),
@@ -188,6 +205,8 @@ mod tests {
};
let model = ChinaAShareCostModel::from_trading_constraints(config);
assert!((model.transfer_fee_for(10_000.0) - 0.1).abs() < 1e-12);
assert!(
(model.stamp_tax_for(
NaiveDate::from_ymd_opt(2025, 1, 9).expect("valid date"),