Class: RVGP::Reconcilers::Shorthand::Investment

Inherits:
Object
  • Object
show all
Defined in:
lib/rvgp/reconcilers/shorthand/investment.rb

Overview

This reconciler module will automatically allocate the proceeds (or losses) from a stock sale. This module will allocate capital gains or losses, given a symbol, amount, and price.

The module parameters we support are:

  • symbol [String] - A commodity or currency code, that represents the purchased asset

  • amount [Integer] - The amount of :symbol that was purchased, or if negative, sold.

  • price [Commodity] - A unit price, for the symbol. This field should be delimited if :total is omitted.

  • total [Commodity] - A lot price, the symbol. This represents the net purchase price, which, would be divided by the amount, in order to arrive at a unit price. This field should be delimited if :price is omitted.

  • capital_gains [Commodity] - The amount of the total, to allocate to a capital gains account. Presumably for tax reporting.

  • gains_account [String] - The account name to allocate capital gains to.

# Example Here’s how this module might be used in your reconciler: “‘ …

  • match: /Acme Stonk Exchange/ to_shorthand: Investment shorthand_params:

    symbol: VOO
    price: "$ 400.00"
    amount: "-1000"
    capital_gains: "$ -100000.00"
    gains_account: Personal:Income:AcmeExchange:VOO
    

… “‘ And here’s how that will reconcile, in your build: “‘ … 2023-06-01 Acme Stonk Exchange ACH CREDIT 123456 Yukihiro Matsumoto

Personal:Assets                   -1000 VOO @@ $ 400000.00
Personal:Income:AcmeExchange:VOO    $ 100000.00
Personal:Assets:AcmeChecking
...

“‘

Instance Method Summary collapse

Constructor Details

#initialize(rule) ⇒ Investment

Returns a new instance of Investment.

Raises:

  • (StandardError)


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
# File 'lib/rvgp/reconcilers/shorthand/investment.rb', line 52

def initialize(rule)
  @tag = rule[:tag]
  @targets = rule[:targets]
  @to = rule[:to] || 'Personal:Assets'

  if rule.key? :shorthand_params
    @symbol = rule[:shorthand_params][:symbol]
    @amount = rule[:shorthand_params][:amount]
    @gains_account = rule[:shorthand_params][:gains_account]

    %w[price total capital_gains].each do |key|
      if rule[:shorthand_params].key? key.to_sym
        instance_variable_set "@#{key}".to_sym, rule[:shorthand_params][key.to_sym].to_commodity
      end
    end
  end

  unless [symbol, amount].all?
    raise StandardError, format('Investment at line:%s missing fields', rule[:line].inspect)
  end

  @is_sell = (amount.to_f <= 0)

  # I mostly just think this doesn't make any sense... I guess if we took a
  # loss...
  raise StandardError, format('Unimplemented %s', rule.inspect) if capital_gains && !is_sell

  if (.nil? || capital_gains.nil?) && is_sell
    raise StandardError, format('Investment at line:%s missing gains_account', rule.inspect)
  end

  unless total || price
    raise StandardError, format('Investment at line:%s missing an price or total', rule[:line].inspect)
  end

  if total && price
    raise StandardError, format('Investment at line:%s specified both price and total', rule[:line].inspect)
  end
end