Add futures account model
This commit is contained in:
52
crates/fidc-core/tests/futures_account.rs
Normal file
52
crates/fidc-core/tests/futures_account.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use fidc_core::{FuturesAccountState, FuturesContractSpec, FuturesDirection};
|
||||
|
||||
#[test]
|
||||
fn futures_account_tracks_long_margin_pnl_and_settlement() {
|
||||
let spec = FuturesContractSpec::new(300.0, 0.12, 0.14);
|
||||
let mut account = FuturesAccountState::new(1_000_000.0);
|
||||
|
||||
account.open("IF2501", FuturesDirection::Long, spec, 2, 4000.0, 12.0);
|
||||
account.mark_price("IF2501", FuturesDirection::Long, 4010.0);
|
||||
|
||||
assert!((account.total_cash() - 999_988.0).abs() < 1e-6);
|
||||
assert!((account.margin() - 288_720.0).abs() < 1e-6);
|
||||
assert!((account.cash() - 711_268.0).abs() < 1e-6);
|
||||
assert!((account.position_equity() - 6_000.0).abs() < 1e-6);
|
||||
assert!((account.total_value() - 1_005_988.0).abs() < 1e-6);
|
||||
|
||||
let settlement = BTreeMap::from([("IF2501".to_string(), 4020.0)]);
|
||||
let cash_delta = account.settle(&settlement);
|
||||
|
||||
assert!((cash_delta - 12_000.0).abs() < 1e-6);
|
||||
assert!((account.total_cash() - 1_011_988.0).abs() < 1e-6);
|
||||
let position = account
|
||||
.position("IF2501", FuturesDirection::Long)
|
||||
.expect("long position");
|
||||
assert!((position.avg_price - 4020.0).abs() < 1e-6);
|
||||
assert!((position.equity()).abs() < 1e-6);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn futures_account_tracks_short_close_cash_delta() {
|
||||
let spec = FuturesContractSpec::new(10.0, 0.1, 0.2);
|
||||
let mut account = FuturesAccountState::new(100_000.0);
|
||||
|
||||
account.open("RB2501", FuturesDirection::Short, spec, 5, 3500.0, 3.0);
|
||||
account.mark_price("RB2501", FuturesDirection::Short, 3480.0);
|
||||
assert!((account.margin() - 34_800.0).abs() < 1e-6);
|
||||
assert!((account.position_equity() - 1_000.0).abs() < 1e-6);
|
||||
|
||||
let cash_delta = account
|
||||
.close("RB2501", FuturesDirection::Short, 2, 3470.0, 2.0)
|
||||
.expect("close short");
|
||||
|
||||
assert!((cash_delta - 598.0).abs() < 1e-6);
|
||||
assert!((account.total_cash() - 100_595.0).abs() < 1e-6);
|
||||
let position = account
|
||||
.position("RB2501", FuturesDirection::Short)
|
||||
.expect("remaining short position");
|
||||
assert_eq!(position.quantity, 3);
|
||||
assert!((position.equity() - 900.0).abs() < 1e-6);
|
||||
}
|
||||
Reference in New Issue
Block a user