def summarize_account(self): account_summary = self.ib.accountSummary(self.config["account"]["number"]) click.echo() click.secho(f"Account summary:", fg="green") click.echo() account_summary = account_summary_to_dict(account_summary) click.secho( f" Excess liquidity = {justify(account_summary['ExcessLiquidity'].value)}", fg="cyan", ) click.secho( f" Net liquidation = {justify(account_summary['NetLiquidation'].value)}", fg="cyan", ) click.secho( f" Cushion = {account_summary['Cushion'].value} ({round(float(account_summary['Cushion'].value) * 100, 1)}%)", fg="cyan", ) click.secho( f" Full maint margin = {justify(account_summary['FullMaintMarginReq'].value)}", fg="cyan", ) click.secho( f" Buying power = {justify(account_summary['BuyingPower'].value)}", fg="cyan", ) click.secho( f" Total cash value = {justify(account_summary['TotalCashValue'].value)}", fg="cyan", ) portfolio_positions = self.get_portfolio_positions() click.echo() click.secho("Portfolio positions:", fg="green") click.echo() for symbol in portfolio_positions.keys(): click.secho(f" {symbol}:", fg="cyan") for p in portfolio_positions[symbol]: if isinstance(p.contract, Stock): pnl = round(position_pnl(p) * 100, 2) click.secho( f" Stock Qty={int(p.position)} Price={round(p.marketPrice,2)} Value={round(p.marketValue,2)} AvgCost={round(p.averageCost,2)} P&L={pnl}%", fg="cyan", ) elif isinstance(p.contract, Option): pnl = round(position_pnl(p) * 100, 2) def p_or_c(p): return "Call" if p.contract.right.startswith("C") else "Put " click.secho( f" {p_or_c(p)} Qty={int(p.position)} Price={round(p.marketPrice,2)} Value={round(p.marketValue,2)} AvgCost={round(p.averageCost,2)} P&L={pnl}% Strike={p.contract.strike} Exp={p.contract.lastTradeDateOrContractMonth}", fg="cyan", ) else: click.secho(f" {p.contract}", fg="cyan") return (account_summary, portfolio_positions)
def summarize_account(self): account_summary = self.ib.accountSummary( self.config["account"]["number"]) click.echo() click.secho(f"Account summary:", fg="green") click.echo() account_summary = account_summary_to_dict(account_summary) click.secho( f" Excess liquidity = {justify(account_summary['ExcessLiquidity'].value)}", fg="cyan", ) click.secho( f" Net liquidation = {justify(account_summary['NetLiquidation'].value)}", fg="cyan", ) click.secho( f" Cushion = {account_summary['Cushion'].value} ({round(float(account_summary['Cushion'].value) * 100, 1)}%)", fg="cyan", ) click.secho( f" Full maint margin = {justify(account_summary['FullMaintMarginReq'].value)}", fg="cyan", ) click.secho( f" Buying power = {justify(account_summary['BuyingPower'].value)}", fg="cyan", ) click.secho( f" Total cash value = {justify(account_summary['TotalCashValue'].value)}", fg="cyan", ) portfolio_positions = self.get_portfolio_positions() click.echo() click.secho("Portfolio positions:", fg="green") click.echo() for symbol in portfolio_positions.keys(): click.secho(f" {symbol}:", fg="cyan") for p in portfolio_positions[symbol]: click.secho(f" {p.contract}", fg="cyan") click.secho(f" P&L {round(position_pnl(p) * 100, 1)}%", fg="cyan") return (account_summary, portfolio_positions)
def summarize_account(self): account_summary = self.ib.accountSummary( self.config["account"]["number"]) click.echo() click.secho(f"Account summary:", fg="green") click.echo() account_summary = account_summary_to_dict(account_summary) justified_values = { "ExcessLiquidity": f"{float(account_summary['ExcessLiquidity'].value):,.0f}", "NetLiquidation": f"{float(account_summary['NetLiquidation'].value):,.0f}", "FullMaintMarginReq": f"{float(account_summary['FullMaintMarginReq'].value):,.0f}", "BuyingPower": f"{float(account_summary['BuyingPower'].value):,.0f}", "TotalCashValue": f"{float(account_summary['TotalCashValue'].value):,.0f}", "Cushion": f"{float(account_summary['Cushion'].value) * 100:.1f}%", } padding = max([len(v) for v in justified_values.values()]) justified_values = { k: v.rjust(padding) for k, v in justified_values.items() } click.secho( f" Net liquidation = {justified_values['NetLiquidation']}", fg="cyan", ) click.secho( f" Excess liquidity = {justified_values['ExcessLiquidity']}", fg="cyan", ) click.secho( f" Full maint margin = {justified_values['FullMaintMarginReq']}", fg="cyan", ) click.secho( f" Buying power = {justified_values['BuyingPower']}", fg="cyan", ) click.secho( f" Total cash value = {justified_values['TotalCashValue']}", fg="cyan", ) click.secho( f" Cushion = {justified_values['Cushion']}", fg="cyan", ) portfolio_positions = self.get_portfolio_positions() click.echo() click.secho("Portfolio positions:", fg="green") click.echo() position_values = {} for symbol in portfolio_positions.keys(): for p in portfolio_positions[symbol]: position_values[p.contract.conId] = { "qty": str(int(p.position)), "mktprice": f"{p.marketPrice:,.2f}", "avgprice": f"{p.averageCost:,.2f}", "value": f"{p.marketValue:,.0f}", "cost": f"{(p.averageCost * p.position):,.0f}", "p&l": f"{(position_pnl(p) * 100):.2f}%", } if isinstance(p.contract, Option): position_values[p.contract.conId][ "avgprice"] = f"{p.averageCost/float(p.contract.multiplier):,.2f}" position_values[p.contract.conId][ "strike"] = f"{float(p.contract.strike):,.2f}" position_values[p.contract.conId]["dte"] = str( option_dte(p.contract.lastTradeDateOrContractMonth)) position_values[p.contract.conId]["exp"] = str( p.contract.lastTradeDateOrContractMonth) padding = { "qty": len("Qty"), "mktprice": len("MktPrice"), "avgprice": len("AvgPrice"), "value": len("Value"), "cost": len("Cost"), "p&l": len("P&L"), "strike": len("Strike"), "dte": len("DTE"), "exp": len("Exp"), } for _id, p in position_values.items(): for col, value in p.items(): padding[col] = max(padding[col], len(value)) # Print column headers def pcol(c): return c.rjust(padding[c.lower()]) click.secho( f" {pcol('Qty')} {pcol('MktPrice')} {pcol('AvgPrice')} {pcol('Value')} {pcol('Cost')} {pcol('P&L')} {pcol('Strike')} {pcol('DTE')} {pcol('Exp')}", fg="green", ) for symbol in portfolio_positions.keys(): click.secho(f" {symbol}:", fg="cyan") sorted_positions = sorted( portfolio_positions[symbol], key=lambda p: option_dte( p.contract.lastTradeDateOrContractMonth) if isinstance( p.contract, Option) else -1, # Keep stonks on top ) def pad(col, id): return position_values[id][col].rjust(padding[col]) for p in sorted_positions: id = p.contract.conId qty = pad("qty", id) mktPrice = pad("mktprice", id) avgPrice = pad("avgprice", id) value = pad("value", id) cost = pad("cost", id) pnl = pad("p&l", id) if isinstance(p.contract, Stock): click.secho( f" Stock {qty} {mktPrice} {avgPrice} {value} {cost} {pnl}", fg="cyan", ) elif isinstance(p.contract, Option): strike = pad("strike", id) dte = pad("dte", id) exp = pad("exp", id) def p_or_c(p): return "Call" if p.contract.right.startswith( "C") else "Put " click.secho( f" {p_or_c(p)} {qty} {mktPrice} {avgPrice} {value} {cost} {pnl} {strike} {dte} {exp}", fg="cyan", ) else: click.secho(f" {p.contract}", fg="cyan") return (account_summary, portfolio_positions)