修复回报上下文与盘前意图并在提交前采用最新完整目标
This commit is contained in:
@@ -675,3 +675,104 @@ fn a_clock_slice_does_not_turn_window_twap_into_an_unlimited_instant_order() {
|
||||
assert_eq!(last.order_events.last().unwrap().filled_quantity, 200);
|
||||
assert!(broker.open_order_views().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_matching_controls_amend_or_cancel_without_filling_a_crossing_quote() {
|
||||
let data = data(&[(0, 10., 4_000), (2, 9.4, 4_000)]);
|
||||
let broker = broker();
|
||||
let mut account = PortfolioState::new(20_000.);
|
||||
step(
|
||||
&broker,
|
||||
&mut account,
|
||||
&data,
|
||||
0,
|
||||
&StrategyDecision {
|
||||
order_intents: vec![
|
||||
OrderIntent::LimitShares {
|
||||
symbol: "000001.SZ".into(),
|
||||
quantity: 100,
|
||||
limit_price: 9.5,
|
||||
reason: "resting".into(),
|
||||
}
|
||||
.with_time_in_force(OrderTimeInForce::Gtc),
|
||||
],
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
assert_eq!(broker.open_order_views().len(), 1);
|
||||
let modify = broker
|
||||
.execute_controls_without_matching(
|
||||
limit_test_snapshot().date,
|
||||
limit_test_snapshot().date,
|
||||
&mut account,
|
||||
&data,
|
||||
&StrategyDecision {
|
||||
order_intents: vec![OrderIntent::ModifyOrder {
|
||||
order_id: 1,
|
||||
new_total_quantity: Some(200),
|
||||
new_limit_price: Some(9.3),
|
||||
reason: "pre-open-amend".into(),
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
Some(time(2)),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(modify.fill_events.is_empty());
|
||||
assert_eq!(broker.open_order_views()[0].limit_price, 9.3);
|
||||
assert_eq!(broker.open_order_views()[0].requested_quantity, 200);
|
||||
let cancel = broker
|
||||
.execute_controls_without_matching(
|
||||
limit_test_snapshot().date,
|
||||
limit_test_snapshot().date,
|
||||
&mut account,
|
||||
&data,
|
||||
&StrategyDecision {
|
||||
order_intents: vec![OrderIntent::CancelAll {
|
||||
reason: "pre-open-cancel".into(),
|
||||
}],
|
||||
..Default::default()
|
||||
},
|
||||
Some(time(2)),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(cancel.fill_events.is_empty());
|
||||
assert_eq!(
|
||||
cancel.order_events.last().unwrap().status,
|
||||
OrderStatus::Canceled
|
||||
);
|
||||
assert_eq!(account.cash(), 20_000.);
|
||||
assert!(broker.open_order_views().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn control_only_phase_cannot_be_used_to_submit_an_order_or_leave_matching_disabled() {
|
||||
let data = data(&[(0, 10., 4_000)]);
|
||||
let broker = broker();
|
||||
let mut account = PortfolioState::new(20_000.);
|
||||
let submit = StrategyDecision {
|
||||
order_intents: vec![OrderIntent::Shares {
|
||||
symbol: "000001.SZ".into(),
|
||||
quantity: 100,
|
||||
reason: "normal-order".into(),
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
assert!(
|
||||
broker
|
||||
.execute_controls_without_matching(
|
||||
limit_test_snapshot().date,
|
||||
limit_test_snapshot().date,
|
||||
&mut account,
|
||||
&data,
|
||||
&submit,
|
||||
Some(time(0))
|
||||
)
|
||||
.is_err()
|
||||
);
|
||||
assert_eq!(account.cash(), 20_000.);
|
||||
assert_eq!(
|
||||
step(&broker, &mut account, &data, 0, &submit).fill_events[0].quantity,
|
||||
100
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user