From 19e9ccb503ed52a6e949e8d91d063d11f8f9fcff Mon Sep 17 00:00:00 2001 From: Zach Gollwitzer Date: Sun, 20 Jul 2025 09:33:00 -0400 Subject: [PATCH] Update reverse calculator flows assumptions --- .../models/balance/reverse_calculator_test.rb | 140 +++++++++++++----- 1 file changed, 105 insertions(+), 35 deletions(-) diff --git a/test/models/balance/reverse_calculator_test.rb b/test/models/balance/reverse_calculator_test.rb index 58470395..df792ed9 100644 --- a/test/models/balance/reverse_calculator_test.rb +++ b/test/models/balance/reverse_calculator_test.rb @@ -20,7 +20,9 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 0, start_cash: 0, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 0, start_cash: 0, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: { cash_adjustments: 20000, non_cash_adjustments: 0 } } ] ) @@ -55,27 +57,37 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: 0 }, # Current anchor { date: 1.day.ago, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: 0 }, { date: 2.days.ago, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: 0 }, { date: 3.days.ago, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 15000, start_cash: 15000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 15000, start_cash: 15000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: { cash_adjustments: 5000, non_cash_adjustments: 0 } }, { date: 4.days.ago, legacy_balances: { balance: 15000, cash_balance: 15000 }, - balances: { start: 15000, start_cash: 15000, start_non_cash: 0, end_cash: 15000, end_non_cash: 0, end: 15000 } + balances: { start: 15000, start_cash: 15000, start_non_cash: 0, end_cash: 15000, end_non_cash: 0, end: 15000 }, + flows: 0, + adjustments: 0 } # Opening anchor ] ) @@ -103,12 +115,16 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 10000 }, - balances: { start: 20000, start_cash: 10000, start_non_cash: 10000, end_cash: 10000, end_non_cash: 10000, end: 20000 } + balances: { start: 20000, start_cash: 10000, start_non_cash: 10000, end_cash: 10000, end_non_cash: 10000, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: 0 }, # Since $10,000 of holdings, cash has to be $10,000 to reach $20,000 total value { date: 1.day.ago, legacy_balances: { balance: 15000, cash_balance: 5000 }, - balances: { start: 15000, start_cash: 5000, start_non_cash: 10000, end_cash: 5000, end_non_cash: 10000, end: 15000 } + balances: { start: 15000, start_cash: 5000, start_non_cash: 10000, end_cash: 5000, end_non_cash: 10000, end: 15000 }, + flows: { market_flows: 0 }, + adjustments: 0 } # Since $10,000 of holdings, cash has to be $5,000 to reach $15,000 total value ] ) @@ -132,32 +148,44 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: 0 }, # Current balance { date: 1.day.ago, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: 0, + adjustments: 0 }, # No change { date: 2.days.ago, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20100, start_cash: 20100, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20100, start_cash: 20100, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: { cash_inflows: 0, cash_outflows: 100 }, + adjustments: 0 }, # After expense (+100) { date: 3.days.ago, legacy_balances: { balance: 20100, cash_balance: 20100 }, - balances: { start: 20100, start_cash: 20100, start_non_cash: 0, end_cash: 20100, end_non_cash: 0, end: 20100 } + balances: { start: 20100, start_cash: 20100, start_non_cash: 0, end_cash: 20100, end_non_cash: 0, end: 20100 }, + flows: 0, + adjustments: 0 }, # Before expense { date: 4.days.ago, legacy_balances: { balance: 20100, cash_balance: 20100 }, - balances: { start: 19600, start_cash: 19600, start_non_cash: 0, end_cash: 20100, end_non_cash: 0, end: 20100 } + balances: { start: 19600, start_cash: 19600, start_non_cash: 0, end_cash: 20100, end_non_cash: 0, end: 20100 }, + flows: { cash_inflows: 500, cash_outflows: 0 }, + adjustments: 0 }, # After income (-500) { date: 5.days.ago, legacy_balances: { balance: 19600, cash_balance: 19600 }, - balances: { start: 19600, start_cash: 19600, start_non_cash: 0, end_cash: 19600, end_non_cash: 0, end: 19600 } + balances: { start: 19600, start_cash: 19600, start_non_cash: 0, end_cash: 19600, end_non_cash: 0, end: 19600 }, + flows: 0, + adjustments: { cash_adjustments: 19600, non_cash_adjustments: 0 } } # After income (-500) ] ) @@ -182,32 +210,44 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 2000, cash_balance: 2000 }, - balances: { start: 2000, start_cash: 2000, start_non_cash: 0, end_cash: 2000, end_non_cash: 0, end: 2000 } + balances: { start: 2000, start_cash: 2000, start_non_cash: 0, end_cash: 2000, end_non_cash: 0, end: 2000 }, + flows: 0, + adjustments: 0 }, # Current balance { date: 1.day.ago, legacy_balances: { balance: 2000, cash_balance: 2000 }, - balances: { start: 2000, start_cash: 2000, start_non_cash: 0, end_cash: 2000, end_non_cash: 0, end: 2000 } + balances: { start: 2000, start_cash: 2000, start_non_cash: 0, end_cash: 2000, end_non_cash: 0, end: 2000 }, + flows: 0, + adjustments: 0 }, # No change { date: 2.days.ago, legacy_balances: { balance: 2000, cash_balance: 2000 }, - balances: { start: 1900, start_cash: 1900, start_non_cash: 0, end_cash: 2000, end_non_cash: 0, end: 2000 } + balances: { start: 1900, start_cash: 1900, start_non_cash: 0, end_cash: 2000, end_non_cash: 0, end: 2000 }, + flows: { cash_inflows: 0, cash_outflows: 100 }, + adjustments: 0 }, # After expense (+100) { date: 3.days.ago, legacy_balances: { balance: 1900, cash_balance: 1900 }, - balances: { start: 1900, start_cash: 1900, start_non_cash: 0, end_cash: 1900, end_non_cash: 0, end: 1900 } + balances: { start: 1900, start_cash: 1900, start_non_cash: 0, end_cash: 1900, end_non_cash: 0, end: 1900 }, + flows: 0, + adjustments: 0 }, # Before expense { date: 4.days.ago, legacy_balances: { balance: 1900, cash_balance: 1900 }, - balances: { start: 2400, start_cash: 2400, start_non_cash: 0, end_cash: 1900, end_non_cash: 0, end: 1900 } + balances: { start: 2400, start_cash: 2400, start_non_cash: 0, end_cash: 1900, end_non_cash: 0, end: 1900 }, + flows: { cash_inflows: 0, cash_outflows: 500 }, + adjustments: 0 }, # After CC payment (-500) { date: 5.days.ago, legacy_balances: { balance: 2400, cash_balance: 2400 }, - balances: { start: 2400, start_cash: 2400, start_non_cash: 0, end_cash: 2400, end_non_cash: 0, end: 2400 } + balances: { start: 2400, start_cash: 2400, start_non_cash: 0, end_cash: 2400, end_non_cash: 0, end: 2400 }, + flows: 0, + adjustments: { cash_adjustments: 2400, non_cash_adjustments: 0 } } ] ) @@ -234,17 +274,23 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 198000, cash_balance: 0 }, - balances: { start: 198000, start_cash: 0, start_non_cash: 198000, end_cash: 0, end_non_cash: 198000, end: 198000 } + balances: { start: 198000, start_cash: 0, start_non_cash: 198000, end_cash: 0, end_non_cash: 198000, end: 198000 }, + flows: 0, + adjustments: 0 }, { date: 1.day.ago, legacy_balances: { balance: 198000, cash_balance: 0 }, - balances: { start: 200000, start_cash: 0, start_non_cash: 200000, end_cash: 0, end_non_cash: 198000, end: 198000 } + balances: { start: 200000, start_cash: 0, start_non_cash: 200000, end_cash: 0, end_non_cash: 198000, end: 198000 }, + flows: { non_cash_inflows: 2000, non_cash_outflows: 0, cash_inflows: 0, cash_outflows: 0 }, + adjustments: 0 }, { date: 2.days.ago, legacy_balances: { balance: 200000, cash_balance: 0 }, - balances: { start: 200000, start_cash: 0, start_non_cash: 200000, end_cash: 0, end_non_cash: 200000, end: 200000 } + balances: { start: 200000, start_cash: 0, start_non_cash: 200000, end_cash: 0, end_non_cash: 200000, end: 200000 }, + flows: 0, + adjustments: { cash_adjustments: 0, non_cash_adjustments: 200000 } } ] ) @@ -270,17 +316,23 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 1000, cash_balance: 0 }, - balances: { start: 1000, start_cash: 0, start_non_cash: 1000, end_cash: 0, end_non_cash: 1000, end: 1000 } + balances: { start: 1000, start_cash: 0, start_non_cash: 1000, end_cash: 0, end_non_cash: 1000, end: 1000 }, + flows: 0, + adjustments: 0 }, { date: 1.day.ago, legacy_balances: { balance: 1000, cash_balance: 0 }, - balances: { start: 1000, start_cash: 0, start_non_cash: 1000, end_cash: 0, end_non_cash: 1000, end: 1000 } + balances: { start: 1000, start_cash: 0, start_non_cash: 1000, end_cash: 0, end_non_cash: 1000, end: 1000 }, + flows: 0, + adjustments: 0 }, { date: 2.days.ago, legacy_balances: { balance: 1000, cash_balance: 0 }, - balances: { start: 1000, start_cash: 0, start_non_cash: 1000, end_cash: 0, end_non_cash: 1000, end: 1000 } + balances: { start: 1000, start_cash: 0, start_non_cash: 1000, end_cash: 0, end_non_cash: 1000, end: 1000 }, + flows: 0, + adjustments: { cash_adjustments: 0, non_cash_adjustments: 1000 } } ] ) @@ -314,17 +366,23 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 19000 }, - balances: { start: 20000, start_cash: 19000, start_non_cash: 1000, end_cash: 19000, end_non_cash: 1000, end: 20000 } + balances: { start: 20000, start_cash: 19000, start_non_cash: 1000, end_cash: 19000, end_non_cash: 1000, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: 0 }, # Current: $19k cash + $1k holdings (anchor) { date: 1.day.ago.to_date, legacy_balances: { balance: 20000, cash_balance: 19000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 19000, end_non_cash: 1000, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 19000, end_non_cash: 1000, end: 20000 }, + flows: { cash_inflows: 0, cash_outflows: 1000, non_cash_inflows: 1000, non_cash_outflows: 0, net_market_flows: 0 }, + adjustments: 0 }, # After trade: $19k cash + $1k holdings { date: 2.days.ago.to_date, legacy_balances: { balance: 20000, cash_balance: 20000 }, - balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 } + balances: { start: 20000, start_cash: 20000, start_non_cash: 0, end_cash: 20000, end_non_cash: 0, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: { cash_adjustments: 20000, non_cash_adjustments: 0 } } # At first, account is 100% cash, no holdings (no trades) ] ) @@ -360,17 +418,23 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 19000 }, - balances: { start: 20000, start_cash: 19000, start_non_cash: 1000, end_cash: 19000, end_non_cash: 1000, end: 20000 } + balances: { start: 20000, start_cash: 19000, start_non_cash: 1000, end_cash: 19000, end_non_cash: 1000, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: 0 }, # Current: $19k cash + $1k holdings ($500 MSFT, $500 AAPL) { date: 1.day.ago.to_date, legacy_balances: { balance: 20000, cash_balance: 19000 }, - balances: { start: 20000, start_cash: 19500, start_non_cash: 500, end_cash: 19000, end_non_cash: 1000, end: 20000 } + balances: { start: 20000, start_cash: 19500, start_non_cash: 500, end_cash: 19000, end_non_cash: 1000, end: 20000 }, + flows: { cash_inflows: 0, cash_outflows: 500, non_cash_inflows: 500, non_cash_outflows: 0, net_market_flows: 0 }, + adjustments: 0 }, # After AAPL trade: $19k cash + $1k holdings { date: 2.days.ago.to_date, legacy_balances: { balance: 20000, cash_balance: 19500 }, - balances: { start: 20000, start_cash: 19500, start_non_cash: 500, end_cash: 19500, end_non_cash: 500, end: 20000 } + balances: { start: 20000, start_cash: 19500, start_non_cash: 500, end_cash: 19500, end_non_cash: 500, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: { cash_adjustments: 19500, non_cash_adjustments: 500 } } # Before AAPL trade: $19.5k cash + $500 MSFT ] ) @@ -401,17 +465,23 @@ class Balance::ReverseCalculatorTest < ActiveSupport::TestCase { date: Date.current, legacy_balances: { balance: 20000, cash_balance: 18000 }, - balances: { start: 20000, start_cash: 18000, start_non_cash: 2000, end_cash: 18000, end_non_cash: 2000, end: 20000 } + balances: { start: 20000, start_cash: 18000, start_non_cash: 2000, end_cash: 18000, end_non_cash: 2000, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: 0 }, { date: 1.day.ago, legacy_balances: { balance: 20000, cash_balance: 18000 }, - balances: { start: 20000, start_cash: 18000, start_non_cash: 2000, end_cash: 18000, end_non_cash: 2000, end: 20000 } + balances: { start: 20000, start_cash: 18000, start_non_cash: 2000, end_cash: 18000, end_non_cash: 2000, end: 20000 }, + flows: { market_flows: 0 }, + adjustments: { cash_adjustments: 3000, non_cash_adjustments: 2000 } }, { date: 2.days.ago, legacy_balances: { balance: 15000, cash_balance: 15000 }, - balances: { start: 15000, start_cash: 15000, start_non_cash: 0, end_cash: 15000, end_non_cash: 0, end: 15000 } + balances: { start: 15000, start_cash: 15000, start_non_cash: 0, end_cash: 15000, end_non_cash: 0, end: 15000 }, + flows: { market_flows: 0 }, + adjustments: 0 } # Opening anchor sets absolute balance ] )