use crate::account::UserFees;
use crate::account::holdings::outcomes::Fill;
use crate::trade::Side;
use crate::utils::{Dec, Round};
#[must_use]
pub fn multiplier(scale: Dec) -> Option<Dec> {
scale.checked_add(scale.max(Dec::ONE))
}
#[must_use]
pub fn deployer_share(fee: Dec, scale: Dec) -> Option<Dec> {
fee.checked_mul(scale)?.checked_div(multiplier(scale)?, 8, Round::Down)
}
#[must_use]
pub fn rate(fees: &UserFees, crossed: bool, scale: Dec) -> Option<Dec> {
let base = if crossed { fees.user_spot_cross_rate } else { fees.user_spot_add_rate };
let kept = Dec::ONE.checked_sub(fees.active_referral_discount)?;
base.checked_mul(multiplier(scale)?)?.checked_mul(kept)
}
#[must_use]
pub fn billed(fees: &UserFees, side: Side, crossed: bool, scale: Dec, notional: Dec) -> Option<Dec> {
match side {
Side::Buy => Some(Dec::ZERO),
Side::Sell => rate(fees, crossed, scale)?.checked_mul(notional),
}
}
#[must_use]
pub fn billed_for(fees: &UserFees, fill: &Fill, scale: Dec) -> Option<Dec> {
billed(fees, fill.side, fill.crossed, scale, fill.notional())
}
#[cfg(test)]
#[path = "tests/fee.rs"]
mod tests;