def testDataAddsUp(self, accounts: List[AccountData]) -> None:
        aggregator = AccountAggregator(accounts, lenient=False)
        instruments = set((p.instrument for p in aggregator.positions()))

        balance = AccountBalance(cash={})
        for account in accounts:
            balance += account.balance()

            for p in account.positions():
                self.assertIn(
                    p.instrument,
                    instruments,
                    msg=
                    f"Expected {p} from {account} to show up in aggregated data",
                )

            for a in account.activity():
                self.assertIn(
                    a,
                    aggregator.activity(),
                    msg=
                    f"Expected {a} from {account} to show up in aggregated data",
                )

        self.assertEqual(aggregator.balance(), balance)
    def balance(self) -> AccountBalance:
        if not self._positionsPath:
            return AccountBalance(cash={})

        if not self._balance:
            self._balance = _parseBalance(self._positionsPath, lenient=self._lenient)

        return self._balance
示例#3
0
    def test_zeroEntriesIgnoredForEquality(
        self, t: Tuple[Currency, AccountBalance]
    ) -> None:
        zeroCurrency, balance = t

        cashWithZero = balance.cash.copy()
        cashWithZero[zeroCurrency] = Cash(currency=zeroCurrency, quantity=Decimal(0))
        balanceWithZero = AccountBalance(cash=cashWithZero)

        self.assertEqual(
            balance,
            balanceWithZero,
            f"Expected <{balance}> to equal <{balanceWithZero}>",
        )
def _downloadBalance(ib: IB.IB, lenient: bool) -> AccountBalance:
    accountValues = (val for val in ib.accountSummary()
                     if val.account == "All" and val.tag == "TotalCashBalance"
                     and val.currency != "BASE")

    cashByCurrency: Dict[Currency, Cash] = {}

    for cash in parsetools.lenientParse(accountValues,
                                        transform=_extractCash,
                                        lenient=lenient):
        cashByCurrency[cash.currency] = (cashByCurrency.get(
            cash.currency, Cash(currency=cash.currency, quantity=Decimal(0))) +
                                         cash)

    return AccountBalance(cash=cashByCurrency)
def _parseBalance(path: Path, lenient: bool = False) -> AccountBalance:
    with open(path, newline="") as csvfile:
        reader = csv.reader(csvfile)

        interestingKeys = {"Futures Cash", "Cash & Money Market"}

        keysAndCash = parsetools.lenientParse(
            _schwabPositionsFromRows(reader), transform=_parseCashValue, lenient=lenient
        )

        return AccountBalance(
            cash={
                Currency.USD: reduce(
                    operator.add,
                    (cash for key, cash in keysAndCash if key in interestingKeys),
                    Cash(currency=Currency.USD, quantity=Decimal(0)),
                )
            }
        )
示例#6
0
def _parseBalance(path: Path, lenient: bool = False) -> AccountBalance:
    with open(path, newline="") as csvfile:
        reader = csv.reader(csvfile)

        fieldLen = len(_FidelityPosition._fields)
        positions = (_FidelityPosition._make(r[0:fieldLen]) for r in reader
                     if len(r) >= fieldLen)

        return AccountBalance(
            cash={
                Currency.USD:
                reduce(
                    operator.add,
                    parsetools.lenientParse(
                        (p for p in positions if p.symbol == "CASH"),
                        transform=_parseCash,
                        lenient=lenient,
                    ),
                    Cash(currency=Currency.USD, quantity=Decimal(0)),
                )
            })
示例#7
0
 def balance(self) -> AccountBalance:
     return reduce(
         operator.add,
         (account.balance() for account in self._accounts),
         AccountBalance(cash={}),
     )
 def balance(self) -> AccountBalance:
     # Vanguard puts all cash into money market funds, which will show up to
     # us as Positions, not uninvested cash.
     return AccountBalance(cash={})
 def balance(self) -> AccountBalance:
     return AccountBalance(cash={})
示例#10
0
    def balance(self) -> AccountBalance:
        if not self.client:
            return AccountBalance(cash={})

        return _downloadBalance(self.client, self._lenient)