def cancel(self, ver, user, symbol): amount = -1 try: curr = self.timers[ver][user] try: event = curr[symbol] try: if event[0] is not None: if event[0].is_alive(): # Kill QuoteThread if running event[0].join() else: event[1] = 0 event[0] = None amount = event[1] elif event[1] > 0: amount = event[1] event[1] = 0 self.timers[ver][user].pop(symbol) except Exception as e: AuditLogBuilder("ERROR", "event_server", AuditCommandType.errorEvent).build({ "Command": "CANCEL_SET_BUY", "errorMessage": str(e) }).send() except KeyError: pass # TR-added # curr[symbol] = [None, 0, 0] # TR-This line makes no sense, why add an empty trigger? except KeyError: pass # TR-added # self.timers[ver][user] = {symbol: [None, 0, 0]} # TR-This line also makes no sense to execute return amount
def quote(self, data): AuditLogBuilder("QUOTE", self._server_name, AuditCommandType.userCommand).build(data).send() quote_data = self.cache.quote(data["StockSymbol"], data["userid"]) data["Quote"] = quote_data[0] data["quoteServerTime"] = quote_data[3] data["cryptokey"] = quote_data[4] return True
def cancel_set_sell(self, data): AuditLogBuilder("CANCEL_SET_SELL", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] symbol = data["StockSymbol"] self.events.cancel("sel", user, symbol) return succeeded
def set_sell_trigger(self, data): AuditLogBuilder("SET_SELL_TRIGGER", self._server_name, AuditCommandType.userCommand).build(data).send() user = data["userid"] symbol = data["StockSymbol"] price = float(data["amount"]) # Sell shares at this price or higher result = self.events.trigger("sel", user, symbol, price) return result
def set_buy_trigger(self, data): AuditLogBuilder("SET_BUY_TRIGGER", self._server_name, AuditCommandType.userCommand).build(data).send() user = data["userid"] symbol = data["StockSymbol"] price = float(data["amount"]) result = self.events.trigger("buy", user, symbol, price) return result
def set_sell_amount(self, data): AuditLogBuilder("SET_SELL_AMOUNT", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] symbol = data["StockSymbol"] amount = int(float(data["amount"])) if self.events.register("sel", user, symbol, amount): succeeded = True return succeeded
def cancel_sell(self, data): AuditLogBuilder("CANCEL_SELL", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] try: self.cli_data.pop(user, "sell") succeeded = True except Exception as e: print(f"\033[1;33mTrans-Server.cancel_sell:{e}\033[0;0m") pass return succeeded
def sell(self, data): AuditLogBuilder("SELL", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] dollar_amt_to_sell = float(data["amount"]) symbol = data["StockSymbol"] stocks_on_hand = int(self.cli_data.get_stock_held(user, symbol)) if stocks_on_hand > 0: self.cli_data.push(user, data["StockSymbol"], dollar_amt_to_sell, "sell") succeeded = True return succeeded
def buy(self, data): AuditLogBuilder("BUY", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] amount = Currency(data["amount"]) user_funds = self.cli_data.check_money(user) if ((user_funds - amount) > 0): self.cli_data.push(user, data["StockSymbol"], float(amount), "buy") succeeded = True return succeeded
def new_quote(self, symbol, user): if (self.quote_server): self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.conn.connect( (self.quote_server_host, self.quote_server_port)) self.conn.sendall(str.encode(symbol + ", " + user + "\n")) print( "\033[1;33m->quote_server 'quote request' sent\n->waiting for response...\033[0;0m" ) data = self.conn.recv(BUFFER_SIZE).decode().split(",") self.conn.close() except Exception as e: print(f"\033[1;31m{e}\033[0;0m") else: # time.sleep(2) data = ["20.87", symbol, user, time.time(), "QWERTYUIOP"] qtm = time.time() amount = Currency(data[0]) data[0] = amount cryptokey = data[4] requests.post( f"{self.quote_cache_server_url}/{QuoteCacheUrls.CACHE_QUOTE}", json={ "stock_symbol": symbol, "dollars": amount.dollars, "cents": amount.cents, "quote_time": qtm, "cryptokey": cryptokey }) AuditLogBuilder("QUOTE", self._server_name, AuditCommandType.quoteServer).build({ "Quote": data[0], "StockSymbol": data[1], "userid": data[2], "quoteServerTime": data[3], "cryptokey": data[4] }).send() return data
def display_summary(self, data): user = data["userid"] acc = self.cli_data.get_user(user) tri = self.events.state(user) buy_triggers_keys = tri["buy"].keys() sell_triggers_keys = tri["sel"].keys() tri_copy = {"buy": {}, "sel": {}} for stock_sym in buy_triggers_keys: tri_copy["buy"][stock_sym] = str(tri["buy"][stock_sym]) for stock_sym in sell_triggers_keys: tri_copy["sel"][stock_sym] = str(tri["sel"][stock_sym]) AuditLogBuilder("DISPLAY_SUMMARY", self._server_name, AuditCommandType.userCommand).build(data).send() return {"Account": acc, "Triggers": tri_copy}
def commit_sell(self, data): AuditLogBuilder("COMMIT_SELL", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] cli_data = self.cli_data try: sell_data = cli_data.pop(user, "sell") if (len(sell_data) != 0): raise Exception("pop() performed on empty sell stack") symbol = sell_data["stock_symbol"] shares_on_hand = cli_data.get_stock_held(user, symbol) price = self.cache.quote(symbol, user)[0] shares_to_sell = int(int(sell_data["dollars"]) / price.dollars) if shares_to_sell <= shares_on_hand: status = cli_data.commit_sell(user, symbol, price, shares_to_sell)["status"] succeeded = status == "SUCCESS" except Exception as e: print(f"\033[1;33mTrans-Server.commit_sell:{e}\033[0;0m") pass self.cli_data = cli_data return succeeded
def commit_buy(self, data): AuditLogBuilder("COMMIT_BUY", self._server_name, AuditCommandType.userCommand).build(data).send() succeeded = False user = data["userid"] cli_data = self.cli_data try: buy_data = cli_data.pop(user, "buy") if (len(buy_data) != 0): raise Exception("pop() performed on empty buy stack") stock_symbol = buy_data["stock_symbol"] price = self.cache.quote(stock_symbol, user)[0] buy_amount = Currency(buy_data["dollars"]) + Currency( buy_data["cents"]) status = cli_data.commit_buy(user, stock_symbol, price, buy_amount)["status"] succeeded = status == "SUCCESS" except Exception as e: print(f"\033[1;33mTrans-Server.commit_buy:{e}\033[0;0m") pass self.cli_data = cli_data return succeeded
def add(self, data): user = data["userid"] AuditLogBuilder("ADD", self._server_name, AuditCommandType.userCommand).build(data).send() amount = data["amount"] return self.cli_data.add_money(user, amount)
def transaction(self, conn): # TODO: We should consider creating a queue for the incoming commands. incoming_data = conn.recv(BUFFER_SIZE).decode() if incoming_data == "": return False # DEBUG # print(f"{incoming_data}") try: try: data_payload_list = [json.loads(incoming_data)] except ValueError as v: data_payload_list = [] split_data = incoming_data.split("}{") for partial_json_str in split_data: json_str = partial_json_str if (partial_json_str[0] != "{"): json_str = "{" + json_str if (partial_json_str[len(partial_json_str) - 1] != "}"): json_str = json_str + "}" json_data = json.loads(json_str) data_payload_list.append(json_data) for data in data_payload_list: print(f"\033[1;32mTrans-Server:{data}\033[0;0m") if (type(data) == str): data = json.loads(data) if (not self.check_session(data)): conn.send( str.encode( f"FAILED! user is not authenticated for the request | {data}" )) return False command = data["Command"] if command == "LOGIN": resp = self.authenticate(data) data["Succeeded"] = resp["status"] == "SUCCESS" data["session"] = resp["session"] elif command == "ADD": data["Succeeded"] = self.add(data) elif command == "QUOTE": data["Succeeded"] = self.quote(data) elif command == "BUY": data["Succeeded"] = self.buy(data) elif command == "COMMIT_BUY": data["Succeeded"] = self.commit_buy(data) elif command == "CANCEL_BUY": data["Succeeded"] = self.cancel_buy(data) elif command == "SELL": data["Succeeded"] = self.sell(data) elif command == "COMMIT_SELL": data["Succeeded"] = self.commit_sell(data) elif command == "CANCEL_SELL": data["Succeeded"] = self.cancel_sell(data) elif command == "SET_BUY_AMOUNT": data["Succeeded"] = self.set_buy_amount(data) elif command == "CANCEL_SET_BUY": data["Succeeded"] = self.cancel_set_buy(data) elif command == "SET_BUY_TRIGGER": data["Succeeded"] = self.set_buy_trigger(data) elif command == "SET_SELL_AMOUNT": data["Succeeded"] = self.set_sell_amount(data) elif command == "CANCEL_SET_SELL": data["Succeeded"] = self.cancel_set_sell(data) elif command == "SET_SELL_TRIGGER": data["Succeeded"] = self.set_sell_trigger(data) elif command == "DISPLAY_SUMMARY": data["Data"] = self.display_summary(data) # Echo back JSON with new attributes conn.send(str.encode(json.dumps(data, cls=Currency))) except Exception as e: print(f"\033[1;31mTrans-Server.transaction:{e}\033[0;0m") raise e # TODO: this raise function means nothing below it is accessible, needs reworking print(f"\033[1;31mTrans-Server.transaction:{e}\033[0;0m") AuditLogBuilder("ERROR", self._server_name, AuditCommandType.errorEvent).build({ "errorMessage": str(e) }).send() conn.send(str.encode(f"FAILED! | {data}")) return False return True