Skip to content

Instantly share code, notes, and snippets.

@BlakeMesdag
Created April 27, 2020 22:42
Show Gist options
  • Save BlakeMesdag/f52cc784721972429a8d224c630080c6 to your computer and use it in GitHub Desktop.
Save BlakeMesdag/f52cc784721972429a8d224c630080c6 to your computer and use it in GitHub Desktop.
USD ACB Calculator for CAD
require 'csv'
require 'bigdecimal'
require 'byebug'
class Transaction
attr_reader :date, :description, :debit_amount, :credit_amount, :balance
attr_accessor :exchange_rate
def initialize(date, description, debit_amount, credit_amount, exchange_rate, date_format:"%m/%d/%Y")
@date = Date.strptime(date, date_format)
@description = description.strip
@debit_amount = BigDecimal(debit_amount || "0")
@credit_amount = BigDecimal(credit_amount || "0")
if exchange_rate
@exchange_rate = BigDecimal(exchange_rate || "1")
end
end
def debit_amount_cad
debit_amount * exchange_rate
end
def credit_amount_cad
credit_amount * exchange_rate
end
end
exchange_rates = CSV.read("exchange-rates.csv").to_h
transactions = []
current_balance_cad = BigDecimal(0)
current_balance_usd = BigDecimal(0)
current_acb = BigDecimal(0)
total_credits_usd = BigDecimal(0)
total_credits_cad = BigDecimal(0)
total_debits_usd = BigDecimal(0)
total_debits_cad = BigDecimal(0)
capital_gains = Hash.new do |h, k|
h[k] = BigDecimal(0)
end
CSV.foreach("usd-transactions.csv") do |row|
transaction = Transaction.new(*row)
current_exchange_rate = exchange_rates[transaction.date.to_s]
if BigDecimal(current_exchange_rate) <= 1
debugger
end
transaction.exchange_rate = BigDecimal(current_exchange_rate)
if transaction.credit_amount > 0
current_balance_usd += transaction.credit_amount
current_balance_cad += transaction.credit_amount_cad
current_acb = current_balance_cad / current_balance_usd
total_credits_usd += transaction.credit_amount
total_credits_cad += transaction.credit_amount_cad
else
current_balance_cad -= transaction.debit_amount * current_acb
current_balance_usd -= transaction.debit_amount
transaction_gain_amount = transaction.debit_amount * (transaction.exchange_rate - current_acb)
capital_gains[transaction.date.year] += transaction_gain_amount
total_debits_usd += transaction.debit_amount
total_debits_cad += transaction.debit_amount_cad
puts "Transaction Debit Amount: #{transaction.debit_amount.to_f}"
puts "Transaction Gain: #{transaction_gain_amount.to_f}"
end
puts "Transaction Date: #{transaction.date}"
puts "Transaction Exchange Rate: #{transaction.exchange_rate.to_f}"
puts "Current ACB: #{current_acb.to_f}"
puts "Current Balance CAD: #{current_balance_cad.to_f}"
puts "Current Balance USD: #{current_balance_usd.to_f}"
puts "Current Capital Gains: #{capital_gains.map { |y,v| "#{y}: #{v.to_f}"}}"
puts ""
transactions << transaction
end
if ENV['DEBUG'] != ""
debugger
end
puts "Total transactions: #{transactions.size}"
puts ""
puts "Total debits USD: #{total_debits_usd.to_f}"
puts "Total credits USD: #{total_credits_usd.to_f}"
puts ""
puts "Total debits CAD: #{total_debits_cad.to_f}"
puts "Total credits CAD: #{total_credits_cad.to_f}"
puts ""
puts "Final balance: #{transactions.last.balance.to_f}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment