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)
Esempio n. 2
0
def printPositions(accounts: AccountAggregator, args: Namespace) -> None:
    values: Dict[Position, Cash] = {}
    if args.live_value:
        dataProvider = marketDataProvider(accounts)
        if dataProvider:
            values = analysis.liveValuesForPositions(
                accounts.positions(),
                dataProvider=dataProvider,
                progressBar=Bar("Loading market data for positions"),
            )
        else:
            logging.error(
                "Live data connection required to fetch market values")

    for p in sorted(accounts.positions(), key=lambda p: p.instrument):
        print(p)

        if p in values:
            print(f"\tMarket value: {values[p]}")
        elif args.live_value:
            logging.warning(f"Could not fetch market value for {p.instrument}")

        print(f"\tCost basis: {p.costBasis}")

        if args.realized_basis and isinstance(p.instrument, Stock):
            realizedBasis = analysis.realizedBasisForSymbol(
                p.instrument.symbol, activity=accounts.activity())
            print(f"\tRealized basis: {realizedBasis}")
Esempio n. 3
0
def printActivity(accounts: AccountAggregator, args: Namespace) -> None:
    if args.output_csv:
        df = converter.dataframeForModelObjects(list(
            accounts.activity())).sort_values(by=["Date"])
        df.to_csv(args.output_csv, index=False)
        print(f"Activity saved to: {args.output_csv}")
    else:
        for t in sorted(accounts.activity(),
                        key=lambda t: t.date,
                        reverse=True):
            print(t)
Esempio n. 4
0
def main() -> None:
    args = parser.parse_args()
    if args.verbose:
        logging.basicConfig(level=logging.INFO)

    config = loadConfig(
        chain(Configuration.defaultSearchPaths,
              args.config if args.config else []))

    if not args.command:
        parser.print_usage()
        quit(1)

    mergedSettings: Dict[Settings, str] = dict(
        chain(
            readFidelitySettings(config, args).items() if fidelity else [],
            readSchwabSettings(config, args).items() if schwab else [],
            readVanguardSettings(config, args).items() if vanguard else [],
            readIBSettings(config, args).items() if ibkr else [],
        ))

    accounts = AccountAggregator.fromSettings(mergedSettings,
                                              lenient=args.lenient)
    commands[args.command](accounts, args)
Esempio n. 5
0
def symbolTimeline(accounts: AccountAggregator, args: Namespace) -> None:
    for entry in reversed(
            list(analysis.timelineForSymbol(args.symbol,
                                            accounts.activity()))):
        print(entry)
Esempio n. 6
0
def printBalances(accounts: AccountAggregator, args: Namespace) -> None:
    print(accounts.balance())
 def testDiscoversRecursiveDescendants(self) -> None:
     aggregator = AccountAggregator.fromSettings({}, lenient=False)
     accountClasses = [type(acct) for acct in aggregator.accounts]
     self.assertIn(StubRecursiveAccount, accountClasses)
     self.assertNotIn(RecursiveAccountData, accountClasses)