def __init__(self, verbose: bool = False): """Constructor. Args: verbose (bool, optional): [description]. Defaults to False.""" Logger.verbose_console_log( verbose=arguments.verbose, message="Stocker is initializing in verbose mode", message_type=Message.MESSAGE_TYPE.STATUS) self.verbose = verbose self.ciphers: dict = initialize_lock_and_key_ciphers() self.keys: dict = load_json_resource( file_name_cipher=self.ciphers["file_name"], data_cipher=self.ciphers['data'], resource_file_name=Stocker.KEY_FILE_NAME) self.passes: dict = load_json_resource( file_name_cipher=self.ciphers["file_name"], data_cipher=self.ciphers['data'], resource_file_name=Stocker.PASS_FILE_NAME)[Stocker.USER_NAME] deposit_history: DataFrame = self.load_csv_resource( resource_file_name=Stocker.DEPOSIT_HISTORY_FILE_NAME) self.binance_account = BinanceAccount( deposit_history=deposit_history[deposit_history.Service == "binance"], transaction_history=self.load_csv_resource( resource_file_name=Stocker. BINANCE_TRANSACTION_HISTORY_FILE_NAME), api_key=self.keys['binance.us']['API Key'], api_secret=self.keys['binance.us']['Secret Key']) self.coinbase_account = CoinbaseAccount( deposit_history=deposit_history[deposit_history.Service == "coinbase"], transaction_history=self.load_csv_resource( resource_file_name=Stocker. COINBASE_TRANSACTION_HISTORY_FILE_NAME), api_key=self.keys['coinbase']['API Key'], api_secret=self.keys['coinbase']['API Secret']) self.mint = Mint(email=self.passes['mint']['email'], password=self.passes['mint']['password']) self.holdings: Holdings = Holdings.load( holding_file_name=Stocker.HOLDINGS_FILE_NAME, file_name_cipher=self.ciphers['file_name'], data_cipher=self.ciphers['data'], mint=self.mint) # Start price update thread self.price_checker_thread: PriceChecker = PriceChecker( stocker=self, verbose=self.verbose) self.price_checker_thread.start() self.holdings.initial_update.wait(timeout_ms=60000) self.generated_windows = {}
def run(self) -> None: self.running = True Logger.verbose_console_log(verbose=self.verbose, message=str(type(self)) + " is running...", message_type=Message.MESSAGE_TYPE.STATUS) while self.running: epoch_start_time = time() self.stocker.holdings.update(binance_account = self.stocker.binance_account, coinbase_account = self.stocker.coinbase_account, verbose = self.stocker.verbose) pseudo_realtime_timestep(epoch_start_time=epoch_start_time, timestep=1/self.rate)
def calculate_equity(self, holding_type: Union[str, Holdings.HOLDING_TYPE] = "all", verbose: bool = False) -> float: """[summary] Args: holding_type (Union[str, Holdings.HOLDING_TYPE], optional): [description]. Defaults to "all". Returns: float: [description]""" assert type(holding_type) == str or type( holding_type) == Holdings.HOLDING_TYPE Logger.verbose_console_log( verbose=verbose, message=str(type(self)) + " is calculating the equity of holding_type: " + str(holding_type), message_type=Message.MESSAGE_TYPE.STATUS) equity: float = 0. if type(holding_type) == str: holding_type: Holdings.HOLDING_TYPE = Holdings.HOLDING_TYPE( holding_type) if holding_type == Holdings.HOLDING_TYPE.STOCK or holding_type == Holdings.HOLDING_TYPE.ALL: equity += Holdings.calculate_holding_equity(holdings=self.stocks, verbose=verbose) if holding_type == Holdings.HOLDING_TYPE.CRYPTOCURRENCY or holding_type == Holdings.HOLDING_TYPE.ALL: equity += Holdings.calculate_holding_equity( holdings=self.cryptocoins, verbose=verbose) if holding_type == Holdings.HOLDING_TYPE.CHECKING or holding_type == Holdings.HOLDING_TYPE.ALL: equity += Holdings.calculate_holding_equity( holdings=self.checking_accounts, verbose=verbose) if (holding_type == Holdings.HOLDING_TYPE.FLOATING_USD or holding_type == Holdings.HOLDING_TYPE.ALL ) and self.floating_usd is not None: equity += Holdings.calculate_holding_equity( holdings=self.floating_usd, verbose=verbose) Logger.verbose_console_log( verbose=verbose, message=str(type(self)) + " equity of holding_type: " + str(holding_type) + " = " + "$%.2f" % equity, message_type=Message.MESSAGE_TYPE.SUCCESS) return equity
def open_window(self, window_class: Callable[[], QMainWindow]) -> None: """Opens a window class and displays it. Args: window_class (Callable[[], QMainWindow]): [description]""" Logger.verbose_console_log(verbose=self.verbose, message=str(type(self)) + " is opening window: " + str(window_class), message_type=Message.MESSAGE_TYPE.STATUS) window = window_class(stocker=self) if window_class in self.generated_windows.keys(): self.generated_windows[window_class].append(window) else: self.generated_windows[window_class] = [window] window.show()
def calculate_holding_equity(holdings: Union[ Dict[str, Holdings.Stock], Dict[str, Holdings.Cryptocoin], Dict[str, Holdings.CheckingAccount], Dict[str, float]], verbose: bool = False) -> float: """[summary] Args: holdings (Union[Dict[str, Holdings.Stock], Dict[str, Holdings.Cryptocoin], Dict[str, Holdings.CheckingAccount], Dict[str, Holdings.FloatingUSD]]): [description] verbose (bool, optional): [description]. Defaults to False. Returns: float: [description]""" total_equity: float = 0. if len(holdings.keys()) > 0: equity_type: Callable = type(holdings[list(holdings.keys())[0]]) else: return 0. for holding_name, holding in holdings.items(): if equity_type == float or equity_type == int: holding_equity = holding else: holding_equity = holding.calculate_equity() total_equity += holding_equity Logger.verbose_console_log( verbose=verbose, message=str(holding_name) + " has a " + str(equity_type) + " value of " + "$%.2f" % holding_equity, message_type=Message.MESSAGE_TYPE.STATUS) Logger.verbose_console_log( verbose=verbose, message=str(Holdings) + " has calculated a total " + str(equity_type) + " equity of " + "$%.2f" % total_equity, message_type=Message.MESSAGE_TYPE.SUCCESS) return total_equity
def update(self, binance_account: Union[BinanceAccount, None] = None, coinbase_account: Union[CoinbaseAccount, None] = None, verbose: bool = False) -> None: """[summary]""" update_time = time() self.lock.acquire() for coin_name, coin in self.cryptocoins.items(): coin.price = get_crypto_price(coin_name=coin_name, binance_account=binance_account, coinbase_account=coinbase_account) Logger.verbose_console_log( verbose=verbose, message= f"[CRYPTO] {coin_name} is currently valued at ${coin.price} per coin.", message_type=Message.MESSAGE_TYPE.STATUS) self.crypto_df = self.crypto_df.append( coin.to_series(update_time=update_time)) self.crypto_df = self.crypto_df.sort_index() for stock_symbol, stock in self.stocks.items(): stock.price = get_stock_price(symbol=stock_symbol) Logger.verbose_console_log( verbose=verbose, message= f"[STOCK] {stock.name} is currently valued at ${stock.price} per share.", message_type=Message.MESSAGE_TYPE.STATUS) self.stocks_df = self.stocks_df.append( stock.to_series(update_time=update_time)) self.stocks_df = self.stocks_df.sort_index() for account_name, checking_account in self.checking_accounts.items(): #checking_account.update() Logger.verbose_console_log( verbose=verbose, message="[CHECKING] " + account_name + " is currently valued at $" + str(checking_account.equity), message_type=Message.MESSAGE_TYPE.STATUS) self.checking_account_df = self.checking_account_df.append( checking_account.to_series(update_time=update_time)) self.checking_account_df = self.checking_account_df.sort_index() for location, usd_in_float in self.floating_usd.items(): self.floating_usd_df = self.floating_usd_df.append( Series( { "datetime": update_time, "location": location, "equity": usd_in_float }, name=time())) self.floating_usd_df = self.floating_usd_df.sort_index() self.lock.release() Logger.verbose_console_log(verbose=verbose, message=str(type(self)) + " is finished updating.", message_type=Message.MESSAGE_TYPE.SUCCESS) if not self.initial_update.is_set(): self.initial_update.set()
def stop(self) -> None: self.running = False Logger.verbose_console_log(verbose=self.verbose, message=str(type(self)) + " is stopping...", message_type=Message.MESSAGE_TYPE.STATUS)