def test_find_balance_currencies(self): currencies = find_prices.find_balance_currencies(self.entries, None) self.assertEqual( {('QQQ', 'USD'), ('GBP', 'USD'), ('GBP', 'CAD'), ('USD', 'CAD')}, currencies) currencies = find_prices.find_balance_currencies( self.entries, datetime.date(2015, 12, 1)) self.assertEqual( {('XSP', 'CAD'), ('QQQ', 'USD'), ('GBP', 'USD'), ('GBP', 'CAD'), ('USD', 'CAD')}, currencies) currencies = find_prices.find_balance_currencies( self.entries, datetime.date(2015, 11, 1)) self.assertEqual( {('QQQ', 'USD'), ('GBP', 'USD'), ('GBP', 'CAD'), ('USD', 'CAD')}, currencies) currencies = find_prices.find_balance_currencies( self.entries, datetime.date(2015, 2, 1)) self.assertEqual(set(), currencies)
def get_price_jobs_at_date(entries: data.Entries, date: Optional[datetime.date] = None, inactive: bool = False, undeclared_source: Optional[str] = None): """Get a list of prices to fetch from a stream of entries. The active holdings held on the given date are included. Args: entries: A list of beancount entries, the name of a file to process. date: A datetime.date instance. inactive: Include currencies with no balance at the given date. The default is to only include those currencies which have a non-zero balance. undeclared_source: A string, the name of the default source module to use to pull prices for commodities without a price source metadata on their Commodity directive declaration. Returns: A list of DatedPrice instances. """ # Find the list of declared currencies, and from it build a mapping for # tickers for each (base, quote) pair. This is the only place tickers # appear. declared_triples = find_currencies_declared(entries, date) currency_map = {(base, quote): psources for base, quote, psources in declared_triples} # Compute the initial list of currencies to consider. if undeclared_source: # Use the full set of possible currencies. cur_at_cost = find_prices.find_currencies_at_cost(entries) cur_converted = find_prices.find_currencies_converted(entries, date) cur_priced = find_prices.find_currencies_priced(entries, date) currencies = cur_at_cost | cur_converted | cur_priced log_currency_list("Currency held at cost", cur_at_cost) log_currency_list("Currency converted", cur_converted) log_currency_list("Currency priced", cur_priced) default_source = import_source(undeclared_source) else: # Use the currencies from the Commodity directives. currencies = set(currency_map.keys()) default_source = None log_currency_list("Currencies in primary list", currencies) # By default, restrict to only the currencies with non-zero balances at the # given date. if not inactive: balance_currencies = find_prices.find_balance_currencies(entries, date) log_currency_list("Currencies held in assets", balance_currencies) currencies = currencies & balance_currencies log_currency_list("Currencies to fetch", currencies) # Build up the list of jobs to fetch prices for. jobs = [] for base_quote in currencies: psources = currency_map.get(base_quote, None) base, quote = base_quote # If there are no sources, create a default one. if not psources: psources = [PriceSource(default_source, base, False)] jobs.append(DatedPrice(base, quote, date, psources)) return sorted(jobs)