修正滑点成交后的持仓估值

This commit is contained in:
boris
2026-06-14 02:09:44 +08:00
parent 0cfb7625bf
commit 80b34280c2
3 changed files with 88 additions and 21 deletions
+34 -7
View File
@@ -66,6 +66,16 @@ impl Position {
}
pub fn buy(&mut self, date: NaiveDate, quantity: u32, price: f64) {
self.buy_with_mark_price(date, quantity, price, price);
}
pub fn buy_with_mark_price(
&mut self,
date: NaiveDate,
quantity: u32,
execution_price: f64,
mark_price: f64,
) {
if quantity == 0 {
return;
}
@@ -73,19 +83,28 @@ impl Position {
self.lots.push(PositionLot {
acquired_date: date,
quantity,
entry_price: price,
price,
entry_price: execution_price,
price: execution_price,
});
self.quantity += quantity;
self.last_price = price;
self.last_price = normalized_mark_price(mark_price, execution_price);
self.day_trade_quantity_delta += quantity as i32;
self.day_buy_quantity += quantity;
self.day_buy_value += price * quantity as f64;
self.day_buy_value += execution_price * quantity as f64;
self.recalculate_average_cost();
self.refresh_day_pnl();
}
pub fn sell(&mut self, quantity: u32, price: f64) -> Result<f64, String> {
self.sell_with_mark_price(quantity, price, price)
}
pub fn sell_with_mark_price(
&mut self,
quantity: u32,
execution_price: f64,
mark_price: f64,
) -> Result<f64, String> {
if quantity > self.quantity {
return Err(format!(
"sell quantity {} exceeds current quantity {} for {}",
@@ -102,7 +121,7 @@ impl Position {
};
let lot_sell = remaining.min(first_lot.quantity);
realized += (price - first_lot.price) * lot_sell as f64;
realized += (execution_price - first_lot.price) * lot_sell as f64;
first_lot.quantity -= lot_sell;
remaining -= lot_sell;
@@ -112,11 +131,11 @@ impl Position {
}
self.quantity -= quantity;
self.last_price = price;
self.last_price = normalized_mark_price(mark_price, execution_price);
self.realized_pnl += realized;
self.day_trade_quantity_delta -= quantity as i32;
self.day_sell_quantity += quantity;
self.day_sell_value += price * quantity as f64;
self.day_sell_value += execution_price * quantity as f64;
self.recalculate_average_cost();
self.refresh_day_pnl();
Ok(realized)
@@ -356,6 +375,14 @@ impl Position {
}
}
fn normalized_mark_price(mark_price: f64, fallback: f64) -> f64 {
if mark_price.is_finite() && mark_price > 0.0 {
mark_price
} else {
fallback
}
}
#[derive(Debug, Clone)]
pub struct PortfolioState {
initial_cash: f64,