def bucketize(vbalance, accapi): price_map = accapi.build_price_map() commodity_map = accapi.get_commodity_map() base_currency = accapi.get_operating_currencies()[0] meta_prefix = 'asset_allocation_' meta_prefix_len = len(meta_prefix) # Main part: put each commodity's value into asset buckets asset_buckets = collections.defaultdict(int) for pos in vbalance.get_positions(): amount = convert.convert_position(pos, base_currency, price_map) if amount.number < 0: # print("Warning: skipping negative balance:", pos) #TODO continue if amount.currency == pos.units.currency and amount.currency != base_currency: sys.stderr.write( "Error: unable to convert {} to base currency {} (Missing price directive?)\n" .format(pos, base_currency)) sys.exit(1) commodity = pos.units.currency metas = commodity_map[commodity].meta unallocated = Decimal('100') for meta in metas: if meta.startswith(meta_prefix): bucket = meta[meta_prefix_len:] asset_buckets[bucket] += amount.number * (metas[meta] / 100) unallocated -= metas[meta] if unallocated: print( "Warning: {} asset_allocation_* metadata does not add up to 100%. Padding with 'unknown'." .format(commodity)) asset_buckets['unknown'] += amount.number * (unallocated / 100) return asset_buckets
def test_convert_position__currency_from_price(self): pos = self._pos(A("100 HOOL"), None, A("99999 USD")) self.assertEqual( A("63600.00 CAD"), convert.convert_position(pos, "CAD", self.PRICE_MAP_HIT))
def convert_position(context, pos, currency, date=None): """Coerce an amount to a particular currency.""" return convert.convert_position(pos, currency, context.price_map, date)
def test_convert_position__miss_and_success_on_implieds(self): pos = self._pos(A("100 HOOL"), Cost(D("514.00"), "USD", None, None)) self.assertEqual( A("63600.00 CAD"), convert.convert_position(pos, "CAD", self.PRICE_MAP_HIT))
def test_convert_position__miss_and_miss_both(self): pos = self._pos(A("100 HOOL"), Cost(D("514.00"), "USD", None, None)) self.assertEqual( A("100 HOOL"), convert.convert_position(pos, "CAD", self.PRICE_MAP_EMPTY))
def test_convert_position__miss_and_miss_rate_to_rate(self): pos = self._pos(A("100 HOOL"), Cost(D("514.00"), "USD", None, None)) self.assertEqual( A("100 HOOL"), convert.convert_position(pos, "JPY", self.PRICE_MAP_HIT))
def test_convert_position__success(self): pos = self._pos(A("100 HOOL"), Cost(D("514.00"), "USD", None, None)) self.assertEqual( A("53000.00 USD"), convert.convert_position(pos, "USD", self.PRICE_MAP_HIT))
def __call__(self, context): args = self.eval_args(context) pos, currency, date = args return convert.convert_position(pos, currency, context.price_map, date)