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'] || 'BTC').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
95 96 97 98 99 100 101 102 103 |
# File 'lib/ledger_get_prices.rb', line 95 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
Returns of YahooFinance results (OpenStruct).
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 91 92 |
# 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." puts "BTC is included by default because yahoo doesn't provide a way to " + "get historical data for it." 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 |