1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
use std::collections::BTreeMap; use crate::core::GenericResult; use crate::types::{Decimal, TradeType}; use crate::util::RoundingMethod; use super::{ CommissionSpec, TradeCommissionSpec, TransactionCommissionSpec, CumulativeCommissionSpec, CumulativeFeeSpec }; pub struct CommissionSpecBuilder(CommissionSpec); impl CommissionSpecBuilder { pub fn new(currency: &'static str) -> CommissionSpecBuilder { CommissionSpecBuilder(CommissionSpec { currency, rounding_method: RoundingMethod::Round, trade: Default::default(), cumulative: Default::default(), }) } pub fn rounding_method(mut self, method: RoundingMethod) -> CommissionSpecBuilder { self.0.rounding_method = method; self } pub fn trade(mut self, spec: TradeCommissionSpec) -> CommissionSpecBuilder { self.0.trade = spec; self } pub fn cumulative(mut self, spec: CumulativeCommissionSpec) -> CommissionSpecBuilder { self.0.cumulative = spec; self } pub fn build(self) -> CommissionSpec { self.0 } } #[derive(Default)] pub struct TradeCommissionSpecBuilder(TradeCommissionSpec); impl TradeCommissionSpecBuilder { pub fn new() -> TradeCommissionSpecBuilder { TradeCommissionSpecBuilder::default() } pub fn commission(mut self, spec: TransactionCommissionSpec) -> TradeCommissionSpecBuilder { self.0.commission = spec; self } pub fn transaction_fee(mut self, trade_type: TradeType, spec: TransactionCommissionSpec) -> TradeCommissionSpecBuilder { self.0.transaction_fees.push((trade_type, spec)); self } pub fn build(self) -> TradeCommissionSpec { self.0 } } #[derive(Default)] pub struct TransactionCommissionSpecBuilder(TransactionCommissionSpec); impl TransactionCommissionSpecBuilder { pub fn new() -> TransactionCommissionSpecBuilder { TransactionCommissionSpecBuilder::default() } pub fn minimum(mut self, minimum: Decimal) -> TransactionCommissionSpecBuilder { self.0.minimum = Some(minimum); self } pub fn per_share(mut self, per_share: Decimal) -> TransactionCommissionSpecBuilder { self.0.per_share = Some(per_share); self } pub fn percent(mut self, percent: Decimal) -> TransactionCommissionSpecBuilder { self.0.percent = Some(percent); self } pub fn maximum_percent(mut self, maximum_percent: Decimal) -> TransactionCommissionSpecBuilder { self.0.maximum_percent = Some(maximum_percent); self } pub fn build(self) -> GenericResult<TransactionCommissionSpec> { match (self.0.per_share, self.0.percent) { (Some(_), None) | (None, Some(_)) => (), _ => return Err!("Invalid commission specification"), }; Ok(self.0) } } #[derive(Default)] pub struct CumulativeCommissionSpecBuilder(CumulativeCommissionSpec); impl CumulativeCommissionSpecBuilder { pub fn new() -> CumulativeCommissionSpecBuilder { CumulativeCommissionSpecBuilder::default() } pub fn tiers(mut self, tiers: BTreeMap<Decimal, Decimal>) -> GenericResult<CumulativeCommissionSpecBuilder> { if tiers.is_empty() || tiers.get(&dec!(0)).is_none() { return Err!(concat!( "Invalid tiered commission specification: ", "There is no tier with zero starting volume", )); } self.0.tiers.replace(tiers); Ok(self) } pub fn minimum_daily(mut self, minimum: Decimal) -> CumulativeCommissionSpecBuilder { self.0.minimum_daily.replace(minimum); self } pub fn minimum_monthly(mut self, minimum: Decimal) -> CumulativeCommissionSpecBuilder { self.0.minimum_monthly.replace(minimum); self } pub fn percent_fee(mut self, percent: Decimal) -> CumulativeCommissionSpecBuilder { self.0.fees.push(CumulativeFeeSpec { percent: percent, }); self } pub fn monthly_depositary(mut self, amount: Decimal) -> CumulativeCommissionSpecBuilder { self.0.monthly_depositary.replace(amount); self } pub fn build(self) -> CumulativeCommissionSpec { self.0 } }