Align order costs and rebalance priority with rqalpha
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use chrono::NaiveDate;
|
||||
|
||||
use crate::events::OrderSide;
|
||||
@@ -18,6 +20,17 @@ impl TradingCost {
|
||||
|
||||
pub trait CostModel {
|
||||
fn calculate(&self, date: NaiveDate, side: OrderSide, gross_amount: f64) -> TradingCost;
|
||||
|
||||
fn calculate_with_order_state(
|
||||
&self,
|
||||
date: NaiveDate,
|
||||
side: OrderSide,
|
||||
gross_amount: f64,
|
||||
_order_id: Option<u64>,
|
||||
_commission_state: &mut BTreeMap<u64, f64>,
|
||||
) -> TradingCost {
|
||||
self.calculate(date, side, gross_amount)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -67,6 +80,43 @@ impl ChinaAShareCostModel {
|
||||
}
|
||||
gross_amount * self.stamp_tax_rate_for(date)
|
||||
}
|
||||
|
||||
pub fn commission_for_order_fill(
|
||||
&self,
|
||||
gross_amount: f64,
|
||||
order_id: Option<u64>,
|
||||
commission_state: &mut BTreeMap<u64, f64>,
|
||||
) -> f64 {
|
||||
if gross_amount <= 0.0 {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
let raw_commission = gross_amount * self.commission_rate;
|
||||
let Some(order_id) = order_id else {
|
||||
return raw_commission.max(self.minimum_commission);
|
||||
};
|
||||
|
||||
let remaining_minimum = commission_state
|
||||
.entry(order_id)
|
||||
.or_insert(self.minimum_commission);
|
||||
if raw_commission > *remaining_minimum {
|
||||
let charged = if (*remaining_minimum - self.minimum_commission).abs() < 1e-12 {
|
||||
raw_commission
|
||||
} else {
|
||||
raw_commission - *remaining_minimum
|
||||
};
|
||||
*remaining_minimum = 0.0;
|
||||
charged
|
||||
} else {
|
||||
let charged = if (*remaining_minimum - self.minimum_commission).abs() < 1e-12 {
|
||||
self.minimum_commission
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
*remaining_minimum -= raw_commission;
|
||||
charged
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CostModel for ChinaAShareCostModel {
|
||||
@@ -86,4 +136,28 @@ impl CostModel for ChinaAShareCostModel {
|
||||
stamp_tax,
|
||||
}
|
||||
}
|
||||
|
||||
fn calculate_with_order_state(
|
||||
&self,
|
||||
date: NaiveDate,
|
||||
side: OrderSide,
|
||||
gross_amount: f64,
|
||||
order_id: Option<u64>,
|
||||
commission_state: &mut BTreeMap<u64, f64>,
|
||||
) -> TradingCost {
|
||||
if gross_amount <= 0.0 {
|
||||
return TradingCost {
|
||||
commission: 0.0,
|
||||
stamp_tax: 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);
|
||||
|
||||
TradingCost {
|
||||
commission,
|
||||
stamp_tax,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user