Align China A-share costs with rqalpha rules
This commit is contained in:
@@ -54,15 +54,26 @@ fn snapshot(open: f64, upper_limit: f64, lower_limit: f64) -> DailyMarketSnapsho
|
||||
fn china_cost_model_applies_minimum_commission_and_stamp_tax() {
|
||||
let model = ChinaAShareCostModel::default();
|
||||
|
||||
let buy = model.calculate(OrderSide::Buy, 1_000.0);
|
||||
let buy = model.calculate(d(2023, 8, 25), OrderSide::Buy, 1_000.0);
|
||||
assert!((buy.commission - 5.0).abs() < 1e-9);
|
||||
assert_eq!(buy.stamp_tax, 0.0);
|
||||
|
||||
let sell = model.calculate(OrderSide::Sell, 100_000.0);
|
||||
let sell = model.calculate(d(2023, 8, 25), OrderSide::Sell, 100_000.0);
|
||||
assert!((sell.commission - 30.0).abs() < 1e-9);
|
||||
assert!((sell.stamp_tax - 100.0).abs() < 1e-9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn china_cost_model_switches_stamp_tax_rate_after_2023_08_28() {
|
||||
let model = ChinaAShareCostModel::default();
|
||||
|
||||
let before = model.calculate(d(2023, 8, 25), OrderSide::Sell, 100_000.0);
|
||||
let after = model.calculate(d(2023, 8, 28), OrderSide::Sell, 100_000.0);
|
||||
|
||||
assert!((before.stamp_tax - 100.0).abs() < 1e-9);
|
||||
assert!((after.stamp_tax - 50.0).abs() < 1e-9);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn china_rule_hooks_block_same_day_sell_under_t_plus_one() {
|
||||
let hooks = ChinaEquityRuleHooks;
|
||||
@@ -96,13 +107,11 @@ fn china_rule_hooks_block_buy_at_limit_up_and_sell_at_limit_down() {
|
||||
PriceField::Open,
|
||||
);
|
||||
assert!(!buy_check.allowed);
|
||||
assert!(
|
||||
buy_check
|
||||
.reason
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.contains("upper limit")
|
||||
);
|
||||
assert!(buy_check
|
||||
.reason
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.contains("upper limit"));
|
||||
|
||||
let sell_check = hooks.can_sell(
|
||||
d(2024, 1, 3),
|
||||
@@ -112,13 +121,11 @@ fn china_rule_hooks_block_buy_at_limit_up_and_sell_at_limit_down() {
|
||||
PriceField::Open,
|
||||
);
|
||||
assert!(!sell_check.allowed);
|
||||
assert!(
|
||||
sell_check
|
||||
.reason
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.contains("lower limit")
|
||||
);
|
||||
assert!(sell_check
|
||||
.reason
|
||||
.as_deref()
|
||||
.unwrap_or_default()
|
||||
.contains("lower limit"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -180,6 +187,15 @@ fn china_rule_hooks_allow_sell_when_last_price_is_above_lower_limit() {
|
||||
price_tick: 0.01,
|
||||
};
|
||||
|
||||
let sell_check = hooks.can_sell(d(2024, 4, 7), &snapshot, &candidate, &position, PriceField::Last);
|
||||
assert!(sell_check.allowed, "sell should be allowed when snapshot last is above lower limit");
|
||||
let sell_check = hooks.can_sell(
|
||||
d(2024, 4, 7),
|
||||
&snapshot,
|
||||
&candidate,
|
||||
&position,
|
||||
PriceField::Last,
|
||||
);
|
||||
assert!(
|
||||
sell_check.allowed,
|
||||
"sell should be allowed when snapshot last is above lower limit"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user