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
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)), ) } )
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)), ) })
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={})
def balance(self) -> AccountBalance: if not self.client: return AccountBalance(cash={}) return _downloadBalance(self.client, self._lenient)