Class: LedgerGetPrices::GetPrices
- Inherits:
-
Object
- Object
- LedgerGetPrices::GetPrices
- Defined in:
- lib/ledger_get_prices.rb
Overview
Synopsis
Tool that uses Yahoo finance to intelligently generate a ledger price database based on your current ledger commodities and time period.
Ensure that you have set the LEDGER and LEDGER_PRICE_DB environment variables before proceeding. Alternatively, you can make the same addition to your .ledgerrc, so long as running ledger vanilla knows where to get the journal and pricedb.
Options
LEDGER_BASE_CURRENCY: Defaults to USD, change this to your reporting currency. LEDGER_PRICE_DATE_FORMAT: The date format of the outputted pricedb. Defaults to %Y/%m/%d.
Constant Summary collapse
- BASE_CURRENCY =
Yahoo finance works best in USD, if the base currency is different we will also store the USD price of that currency to allow for conversion.
ENV['LEDGER_BASE_CURRENCY'] || "USD"
- PRICE_DB_PATH =
PRICE_HIST is <v3
ENV['LEDGER_PRICE_DB'] || ENV['PRICE_HIST']
- DATE_FORMAT =
ENV['LEDGER_PRICE_DATE_FORMAT'] || "%Y/%m/%d"
- PRICE_FORMAT =
"P %{date} %{time} %{symbol} %{price}"- COMMODITY_BLACKLIST =
(ENV['LEDGER_PRICE_COMMODITY_BLACKLIST'] || '').split(" ")
Class Method Summary collapse
-
.existing_prices ⇒ Array
We work with the database as an array of price definitions.
-
.new_prices ⇒ Array
This method builds a new price database intelligently.
- .price_string_from_result(data, symbol: nil) ⇒ String
-
.prices_for_symbol(symbol, start_date: start_date, end_date: end_date) ⇒ Array
Of YahooFinance results (OpenStruct).
-
.run! ⇒ Object
With a bang because it does a file write.
Class Method Details
.existing_prices ⇒ Array
We work with the database as an array of price definitions
44 45 46 47 48 |
# File 'lib/ledger_get_prices.rb', line 44 def existing_prices @existing_prices ||= File.read(PRICE_DB_PATH) .split("\n") .reject { |x| (/^P.*$/ =~ x) != 0 } end |
.new_prices ⇒ Array
This method builds a new price database intelligently.
53 54 55 56 57 58 59 |
# File 'lib/ledger_get_prices.rb', line 53 def new_prices commodities.reduce(existing_prices) do |db, c| # `|` is a shortcut for merge db | prices_for_symbol(c, start_date: start_date, end_date: end_date) .map { |x| price_string_from_result(x, symbol: c) } end end |
.price_string_from_result(data, symbol: nil) ⇒ String
93 94 95 96 97 98 99 100 101 |
# File 'lib/ledger_get_prices.rb', line 93 def price_string_from_result(data, symbol: nil) raise "Must pass symbol" if symbol.nil? PRICE_FORMAT % { date: Date.strptime(data.trade_date, '%Y-%m-%d').strftime(DATE_FORMAT), time: '23:59:59', symbol: (BASE_CURRENCY == 'USD' ? '$' : 'USD'), price: (BASE_CURRENCY == symbol ? '$' : symbol)+ data.close } end |
.prices_for_symbol(symbol, start_date: start_date, end_date: end_date) ⇒ Array
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/ledger_get_prices.rb', line 62 def prices_for_symbol(symbol, start_date: start_date, end_date: end_date) # -> Array puts "Getting historical quotes for: #{symbol}" if COMMODITY_BLACKLIST.include?(symbol) puts "Skipping #{symbol}: blacklisted." puts "Use `LEDGER_PRICE_COMMODITY_BLACKLIST` to configure the blacklist." return [] end result = nil quote_strings = possible_quote_strings(commodity: symbol) err = nil while quote_strings.length > 0 && result.nil? begin result = YahooFinance::Client.new.historical_quotes( quote_strings.shift, start_date: start_date, end_date: end_date, period: :daily) rescue OpenURI::HTTPError => e err = e end end if result.nil? puts "Could not get quotes from Yahoo for: #{symbol}" puts "It may be worthwhile getting prices for this manually." [] else result end end |
.run! ⇒ Object
With a bang because it does a file write.
38 39 40 |
# File 'lib/ledger_get_prices.rb', line 38 def run! File.write(PRICE_DB_PATH, new_prices.join("\n")) end |