コード例 #1
0
    def test_aggregate_holdings_list(self):
        test_holdings = list(itertools.starmap(holdings.Holding, [
            ('Assets:Account1', D('10'), 'HOOL', D('518.73'), 'USD',
             D('5187.30'), D('5780.20'), D('578.02'), datetime.date(2014, 2, 1)),
            ('Assets:Account2', D('20'), 'HOOL', D('519.24'), 'USD',
             D('10384.80'), D('11622.00'), D('581.10'), datetime.date(2014, 2, 15)),
        ]))
        expected_holding = holdings.Holding(
            'Assets', D('30'), 'HOOL', D('519.07'), 'USD',
            D('15572.10'), D('17402.20'), D('580.0733333333333333333333333'), None)
        self.assertEqual(expected_holding, holdings.aggregate_holdings_list(test_holdings))

        # Test with zero units.
        test_holdings = list(itertools.starmap(holdings.Holding, [
            ('Assets:Acc1', D('10'), 'HOOL', D('300'), 'USD', D('3000'),
             None, None, None),
            ('Assets:Acc1', D('-10'), 'HOOL', D('400'), 'USD', D('-4000'),
             None, None, None),
        ]))
        expected_holding = holdings.Holding(
            'Assets:Acc1', D('0'), 'HOOL', None, 'USD', D('-1000'), None, None, None)
        self.assertEqual(expected_holding, holdings.aggregate_holdings_list(test_holdings))

        # Test with aggregate holdings with no cost nor price price.
        test_holdings = list(itertools.starmap(holdings.Holding, [
            ('Assets:Account1', D('10'), 'HOOL', None, 'USD',
             D('5187.30'), D('5780.20'), None, None),
            ('Assets:Account2', D('20'), 'HOOL', None, 'USD',
             D('10384.80'), D('11622.00'), None, None),
        ]))
        expected_holding = holdings.Holding(
            'Assets', D('30'), 'HOOL', D('519.07'), 'USD',
            D('15572.10'), D('17402.20'), D('580.0733333333333333333333333'), None)
        self.assertEqual(expected_holding, holdings.aggregate_holdings_list(test_holdings))
コード例 #2
0
 def test_scale_holding(self):
     test_holding = holdings.Holding(
         'Assets:US:Checking', D('100'), 'MSFT', D('54.34'), 'USD',
         D('5434.00'), D('6000.00'), D('60'), datetime.date(2012, 5, 2))
     expected_holding = holdings.Holding(
         'Assets:US:Checking', D('70.0'), 'MSFT', D('54.34'), 'USD',
         D('3803.80'), D('4200.00'), D('60'), datetime.date(2012, 5, 2))
     self.assertEqual(expected_holding, holdings.scale_holding(test_holding, D('0.7')))
コード例 #3
0
    def test_holding_to_position(self):
        test_holding = holdings.Holding(
            'Assets:US:Checking', D('100'), 'MSFT', D('54.34'), 'USD',
            D('5434.00'), D('6000.00'), D('60'), datetime.date(2012, 5, 2))
        actual_position = holdings.holding_to_position(test_holding)
        expected_position = position.from_string('100 MSFT {54.34 USD}')
        self.assertEqual(expected_position, actual_position)

        test_holding = holdings.Holding(
            'Assets:US:Checking', D('100'), 'USD', None, None,
            None, None, None, datetime.date(2012, 5, 2))
        actual_position = holdings.holding_to_position(test_holding)
        expected_position = position.from_string('100.00 USD')
        self.assertEqual(expected_position, actual_position)
コード例 #4
0
    def test_holding_to_posting(self):
        test_holding = holdings.Holding(
            'Assets:US:Checking', D('100'), 'MSFT', D('54.34'), 'USD',
            D('5434.00'), D('6000.00'), D('60'), datetime.date(2012, 5, 2))

        posting = holdings.holding_to_posting(test_holding)
        self.assertTrue(isinstance(posting, data.Posting))

        expected_position = position.from_string('100 MSFT {54.34 USD}')
        self.assertEqual(expected_position, position.Position(posting.units, posting.cost))

        expected_price = A('60.00 USD')
        self.assertEqual(expected_price, posting.price)
コード例 #5
0
def load_from_csv(fileobj):
    """Load a list of holdings from a CSV file.

    Args:
      fileobj: A file object.
    Yields:
      Instances of Holding, as read from the file.
    """
    column_spec = [
        ('Account', 'account', None),
        ('Units', 'number', D),
        ('Currency', 'currency', None),
        ('Cost Currency', 'cost_currency', None),
        ('Average Cost', 'cost_number', D),
        ('Price', 'price_number', D),
        ('Book Value', 'book_value', D),
        ('Market Value', 'market_value', D),
        ('Price Date', 'price_date', None),
    ]
    column_dict = {
        name: (attr, converter)
        for name, attr, converter in column_spec
    }
    klass = holdings.Holding

    # Create a set of default values for the namedtuple.
    defaults_dict = {attr: None for attr in klass._fields}

    # Start reading the file.
    reader = csv.reader(fileobj)

    # Check that the header is readable.
    header = next(reader)
    attr_converters = []
    for header_name in header:
        try:
            attr_converter = column_dict[header_name]
            attr_converters.append(attr_converter)
        except KeyError:
            raise IOError("Invalid file contents for holdings")

    for line in reader:
        value_dict = defaults_dict.copy()
        for (attr, converter), value in zip(attr_converters, line):
            if converter:
                value = converter(value)
            value_dict[attr] = value
        yield holdings.Holding(**value_dict)
コード例 #6
0
    def test_convert_to_currency(self, entries, _, __):
        """
        2013-01-01 price CAD 1.1 USD
        ; We don't include a price point for NOK. It's unknown.
        ; 2013-01-01 open Assets:Account2
        """
        test_holdings = list(itertools.starmap(holdings.Holding, [

            # ------------ cost currency == target currency
            # currency != target currency
            (None, D('100.00'), 'IVV', D('200'), 'USD', D('10'), D('11'), D('12'), None),
            # currency == target currency
            (None, D('100.00'), 'USD', D('200'), 'USD', D('10'), D('11'), D('12'), None),
            # currency == None
            (None, D('100.00'), None, D('200'), 'USD', D('10'), D('11'), D('12'), None),

            # ------------ cost currency == other currency
            # cost currency available in price map
            (None, D('100.00'), 'XSP', D('200'), 'CAD', D('10'), D('11'), D('12'), None),
            # cost currency not available in price map
            (None, D('100.00'), 'AGF', D('200'), 'NOK', D('10'), D('11'), D('12'), None),
            # currency == target currency, available in price map
            (None, D('100.00'), 'USD', D('200'), 'CAD', D('10'), D('11'), D('12'), None),
            # currency == target currency, not available in price map
            (None, D('100.00'), 'USD', D('200'), 'NOK', D('10'), D('11'), D('12'), None),
            # cost currency available in price map, and currency == None
            (None, D('100.00'), None, D('200'), 'CAD', D('10'), D('11'), D('12'), None),

            # ------------ cost currency == None
            # currency available in price map
            (None, D('100.00'), 'CAD', D('1.2'), None, D('10'), D('11'), D('12'), None),
            # currency available in price map, with no values (should be filled in)
            (None, D('100.00'), 'CAD', D('1.2'), None, None, None, None, None),
            # currency not available in price map
            (None, D('100.00'), 'EUR', D('1.2'), None, D('10'), D('11'), D('12'), None),
            # currency = target currency
            (None, D('100.00'), 'USD', D('1.2'), None, D('10'), D('11'), D('12'), None),

            ]))

        price_map = prices.build_price_map(entries)
        converted_holdings = holdings.convert_to_currency(price_map, 'USD', test_holdings)
        expected_holdings = list(itertools.starmap(holdings.Holding, [
            (None, D('100.00'), 'IVV', D('200'), 'USD', D('10'), D('11'), D('12'), None),
            (None, D('100.00'), 'USD', D('200'), 'USD', D('10'), D('11'), D('12'), None),
            (None, D('100.00'), None, D('200'), 'USD', D('10'), D('11'), D('12'), None),
            (None, D('100.00'), 'XSP', D('220.0'), 'USD', D('11.0'), D('12.1'), D('13.2'),
             None),
            (None, D('100.00'), 'AGF', None, None, None, None, None, None),
            (None, D('100.00'), 'USD', D('220.0'), 'USD', D('11.0'), D('12.1'), D('13.2'),
             None),
            (None, D('100.00'), 'USD', None, None, None, None, None, None),
            (None, D('100.00'), None, D('220.0'), 'USD', D('11.0'), D('12.1'), D('13.2'),
             None),
            (None, D('100.00'), 'CAD', D('1.32'), 'USD', D('11.0'), D('12.1'), D('13.2'),
             None),
            (None, D('100.00'), 'CAD', D('1.32'), 'USD', D('110.0'), D('110.0'), None,
             None),
            (None, D('100.00'), 'EUR', None, None, None, None, None, None),
            (None, D('100.00'), 'USD', D('1.2'), 'USD', D('10'), D('11'), D('12'), None),
            ]))
        self.assertEqual(expected_holdings, converted_holdings)

        # Fail elegantly if the currency itself is None.
        none_holding = holdings.Holding(None, D('100.00'), None, D('200'), None,
                                        None, None, None, None)
        with self.assertRaises(ValueError):
            converted_holdings = holdings.convert_to_currency(price_map, 'USD',
                                                              [none_holding])