Improved performance of get_mvmts_in_ar(). Also changed the name. Also corrected the logic. Also double-checked its logic was appropriate in all the places it is called. Also documented it.

This commit is contained in:
scoobybejesus 2019-09-24 22:31:18 -04:00
parent 6f71d3a789
commit 941f51bcb7
4 changed files with 55 additions and 25 deletions

View File

@ -594,6 +594,20 @@ pub(crate) fn create_lots_and_movements(
Ok(txns_map) Ok(txns_map)
} }
/// Chooses the outgoing `ActionRecord`. Gets a `Vec` of its `Movement`s. Chooses its
/// first/earliest `Movement`. Gets that `Movement`'s `ActionRecord`. Gets that
/// `ActionRecord`'s `Account`. Gets the first `Lot` from that `Account`'s
/// `list_of_lots`. Get the `Movement`s from that `Lot`. Takes the first `Movement`
/// and gets that `Movement`'s `Transaction`. Gets base and quote keys from that.println!
///
/// The rationale for this was to be able to determine whether this should be classifiable
/// as a Long or a Short. As it turns out, the two are basically indistinguishable and/or
/// interchangeable, so this `fn` should be simplified.
///
/// Just kidding. You weren't paying attention, were you? This is a dual `ActionRecord`
/// `Flow` `Transaction`, meaning this is most likely recording a margin profit or a
/// margin loss. The `fn` was designed this was to definitely work for a margin profit,
/// but it might could use reworking to be generalized for margin profit or loss.
fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx( fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx(
txn_num: u32, txn_num: u32,
ar_map: &HashMap<u32, ActionRecord>, ar_map: &HashMap<u32, ActionRecord>,
@ -606,7 +620,7 @@ fn get_base_and_quote_acct_for_dual_actionrecord_flow_tx(
let og_flow_ar = ar_map.get(txn.action_record_idx_vec.first().unwrap()).unwrap(); let og_flow_ar = ar_map.get(txn.action_record_idx_vec.first().unwrap()).unwrap();
// println!("Acct: {}, Amount: {}, Tx: {}, ar: {}", // println!("Acct: {}, Amount: {}, Tx: {}, ar: {}",
// outgoing_flow_ar.account_key, outgoing_flow_ar.amount, outgoing_flow_ar.tx_key, outgoing_flow_ar.self_ar_key); // outgoing_flow_ar.account_key, outgoing_flow_ar.amount, outgoing_flow_ar.tx_key, outgoing_flow_ar.self_ar_key);
let og_ar_mvmts_list = &og_flow_ar.get_mvmts_in_ar(acct_map, txns_map); // TODO: ... in margin profit, this just takes a list of one mvmt let og_ar_mvmts_list = &og_flow_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map); // TODO: ... in margin profit, this just takes a list of one mvmt
let og_ar_list_first_mvmt = &og_ar_mvmts_list.first().unwrap(); // TODO: then this takes the one mvmt let og_ar_list_first_mvmt = &og_ar_mvmts_list.first().unwrap(); // TODO: then this takes the one mvmt
let og_ar_list_first_mvmt_ar = ar_map.get(&og_ar_list_first_mvmt.action_record_key).unwrap(); let og_ar_list_first_mvmt_ar = ar_map.get(&og_ar_list_first_mvmt.action_record_key).unwrap();
let og_ar_list_first_mvmt_ar_acct = acct_map.get(&og_ar_list_first_mvmt_ar.account_key).unwrap(); let og_ar_list_first_mvmt_ar_acct = acct_map.get(&og_ar_list_first_mvmt_ar.account_key).unwrap();
@ -828,12 +842,12 @@ fn process_multiple_incoming_lots_and_mvmts(
let mut all_but_last_incoming_mvmt_amt = d128!(0.0); let mut all_but_last_incoming_mvmt_amt = d128!(0.0);
let mut all_but_last_incoming_mvmt_ratio = d128!(0.0); let mut all_but_last_incoming_mvmt_ratio = d128!(0.0);
// println!("Txn date: {}. Outgoing mvmts: {}, Outgoing amount: {}", txn.date, outgoing_ar.movements.borrow().len(), outgoing_ar.amount); // println!("Txn date: {}. Outgoing mvmts: {}, Outgoing amount: {}", txn.date, outgoing_ar.movements.borrow().len(), outgoing_ar.amount);
let list_of_mvmts_of_outgoing_ar = outgoing_ar.get_mvmts_in_ar(acct_map, txns_map); let list_of_mvmts_of_outgoing_ar = outgoing_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
let final_mvmt = list_of_mvmts_of_outgoing_ar.last().unwrap(); let final_mvmt = list_of_mvmts_of_outgoing_ar.last().unwrap();
// First iteration, for all but final movement // First iteration, for all but final movement
for outgoing_mvmt in list_of_mvmts_of_outgoing_ar for outgoing_mvmt in list_of_mvmts_of_outgoing_ar
.iter() .iter()
.take(outgoing_ar.get_mvmts_in_ar(acct_map, txns_map).len() - 1) { .take(outgoing_ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map).len() - 1) {
let ratio_of_outgoing_mvmt_to_total_ar = outgoing_mvmt.amount / outgoing_ar.amount; // Negative divided by negative is positive let ratio_of_outgoing_mvmt_to_total_ar = outgoing_mvmt.amount / outgoing_ar.amount; // Negative divided by negative is positive
// println!("Ratio of outgoing amt to total actionrecord amt: {:.8}", ratio_of_outgoing_to_total_ar); // println!("Ratio of outgoing amt to total actionrecord amt: {:.8}", ratio_of_outgoing_to_total_ar);
let tentative_incoming_amt = ratio_of_outgoing_mvmt_to_total_ar * incoming_ar.amount; let tentative_incoming_amt = ratio_of_outgoing_mvmt_to_total_ar * incoming_ar.amount;

View File

@ -32,7 +32,7 @@ pub(crate) fn add_cost_basis_to_movements(
let ar = ars.get(ar_num).unwrap(); let ar = ars.get(ar_num).unwrap();
let acct = acct_map.get(&ar.account_key).unwrap(); let acct = acct_map.get(&ar.account_key).unwrap();
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap(); let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
let movements = ar.get_mvmts_in_ar(acct_map, txns_map); let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
for mvmt in movements.iter() { for mvmt in movements.iter() {
@ -168,7 +168,7 @@ pub(crate) fn add_cost_basis_to_movements(
assert_eq!(other_ar_borrowed.direction(), Polarity::Outgoing); assert_eq!(other_ar_borrowed.direction(), Polarity::Outgoing);
let mut basis = d128!(0); let mut basis = d128!(0);
let movements = other_ar_borrowed.get_mvmts_in_ar(acct_map, txns_map); let movements = other_ar_borrowed.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
for mvmt in movements.iter() { for mvmt in movements.iter() {
basis += mvmt.cost_basis.get(); basis += mvmt.cost_basis.get();
@ -197,7 +197,7 @@ pub(crate) fn add_proceeds_to_movements(
for ar_num in txn.action_record_idx_vec.iter() { for ar_num in txn.action_record_idx_vec.iter() {
let ar = ars.get(ar_num).unwrap(); let ar = ars.get(ar_num).unwrap();
let movements = ar.get_mvmts_in_ar(acct_map, txns_map); let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
for mvmt in movements.iter() { for mvmt in movements.iter() {
@ -289,7 +289,7 @@ fn update_current_txn_for_prior_likekind_treatment(
let ar = ars.get(ar_num).unwrap(); let ar = ars.get(ar_num).unwrap();
let acct = acct_map.get(&ar.account_key).unwrap(); let acct = acct_map.get(&ar.account_key).unwrap();
let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap(); let raw_acct = raw_acct_map.get(&acct.raw_key).unwrap();
let movements = ar.get_mvmts_in_ar(acct_map, txns_map); let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
for mvmt in movements.iter() { for mvmt in movements.iter() {
@ -386,7 +386,7 @@ fn perform_likekind_treatment_on_txn(
for ar_num in txn.action_record_idx_vec.iter() { for ar_num in txn.action_record_idx_vec.iter() {
let ar = ars.get(ar_num).unwrap(); let ar = ars.get(ar_num).unwrap();
let movements = ar.get_mvmts_in_ar(acct_map, txns_map); let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
for mvmt in movements.iter() { for mvmt in movements.iter() {
@ -431,7 +431,7 @@ fn perform_likekind_treatment_on_txn(
for ar_num in txn.action_record_idx_vec.iter() { for ar_num in txn.action_record_idx_vec.iter() {
let ar = ars.get(ar_num).unwrap(); let ar = ars.get(ar_num).unwrap();
let movements = ar.get_mvmts_in_ar(acct_map, txns_map); let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
let polarity = ar.direction(); let polarity = ar.direction();

View File

@ -67,7 +67,7 @@ fn compare_movements_across_implementations(
+ " with amount: " + " with amount: "
+ &ar.amount.to_string() + &"\n".to_string() + &ar.amount.to_string() + &"\n".to_string()
); );
let mvmts = ar.get_mvmts_in_ar(&account_map, &transactions_map); let mvmts = ar.get_mvmts_in_ar_in_date_order(&account_map, &transactions_map);
let mut amts = d128!(0); let mut amts = d128!(0);
for mvmt in mvmts { for mvmt in mvmts {
amts += mvmt.amount; amts += mvmt.amount;
@ -156,7 +156,7 @@ pub fn test_action_records_amts_vs_mvmt_amts(
for ar_num in &txn.action_record_idx_vec { for ar_num in &txn.action_record_idx_vec {
let ar = action_records_map.get(&(ar_num)).unwrap(); let ar = action_records_map.get(&(ar_num)).unwrap();
let mvmts = ar.get_mvmts_in_ar(&account_map, &transactions_map); let mvmts = ar.get_mvmts_in_ar_in_date_order(&account_map, &transactions_map);
for mvmt in mvmts { for mvmt in mvmts {
mvmt_amt_ar += mvmt.amount mvmt_amt_ar += mvmt.amount
} }

View File

@ -164,7 +164,7 @@ impl Transaction {
if !raw_acct.is_home_currency(user_home_currency) & !raw_acct.is_margin { if !raw_acct.is_home_currency(user_home_currency) & !raw_acct.is_margin {
let movements = ar.get_mvmts_in_ar(acct_map, txns_map); let movements = ar.get_mvmts_in_ar_in_date_order(acct_map, txns_map);
match self.transaction_type(ars, raw_acct_map, acct_map)? { match self.transaction_type(ars, raw_acct_map, acct_map)? {
TxType::Exchange => { TxType::Exchange => {
@ -292,31 +292,47 @@ impl ActionRecord {
// raw_acct.ticker.contains('_') // raw_acct.ticker.contains('_')
// } // }
pub fn get_mvmts_in_ar( /// Iterates through every `Lot` in the `list_of_lots` of the `ActionRecord`'s `Account`
/// until it finds all the `Movements` - cloning each along the way - and then returns
/// a `Vec` of `Rc<Movements>`.
///
/// Note that a `Lot`'s `date`, and generally its `basis_date` too, will increase
/// chronologically along with the `Lot`'s `lot_num` which is just it's `index` in the
/// `list_of_lots` plus `1`. Exceptions will occur, because `Lot`s are permanently
/// ordered by their creation date (`date`), so later `Lot`s may have earlier `basis_date`s
/// by virtue of them being the result of a `ToSelf` type `Transaction` that transferred
/// old "coins."
pub fn get_mvmts_in_ar_in_date_order(
&self, &self,
acct_map: &HashMap<u16, Account>, acct_map: &HashMap<u16, Account>,
txns_map: &HashMap<u32, Transaction>, txns_map: &HashMap<u32, Transaction>,
) -> Vec<Rc<Movement>> { ) -> Vec<Rc<Movement>> {
// let polarity = Self::direction(self);
let txn = txns_map.get(&self.tx_key).unwrap(); let txn = txns_map.get(&self.tx_key).unwrap();
let mut movements_in_ar = [].to_vec(); let mut movements_in_ar = [].to_vec();
let acct = acct_map.get(&self.account_key).unwrap(); let acct = acct_map.get(&self.account_key).unwrap();
let target = self.amount;
let mut measure = d128!(0);
for lot in acct.list_of_lots.borrow().iter() { for lot in acct.list_of_lots.borrow().iter() {
for mvmt in lot.movements.borrow().iter() { for mvmt in lot.movements.borrow().iter() {
if (mvmt.date) <= txn.date { if (mvmt.date) <= txn.date {
if mvmt.action_record_key == self.self_ar_key { if mvmt.action_record_key == self.self_ar_key {
// if polarity == Polarity::Incoming{
// movements_in_ar.push(mvmt.clone()) measure += mvmt.amount;
// } else {
movements_in_ar.insert(0, mvmt.clone()) movements_in_ar.push(mvmt.clone());
// }
// ^^ leaving that ugliness for this commit on purpose if measure == target { return movements_in_ar }
} }
} }
} }
} }
println!("ERROR: This should never print.");
movements_in_ar movements_in_ar
} }
} }
@ -331,11 +347,11 @@ pub enum TxType {
impl fmt::Display for TxType { impl fmt::Display for TxType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
TxType::Exchange => write!(f, "Exchange"), TxType::Exchange => write!(f, "Exchange"),
TxType::ToSelf => write!(f, "ToSelf"), TxType::ToSelf => write!(f, "ToSelf"),
TxType::Flow => write!(f, "Flow"), TxType::Flow => write!(f, "Flow"),
} }
} }
} }