def get_or_add_asset(trader, asset_name, precision=8): if asset_name in trader._assets: return trader._assets[asset_name] asset = Asset(trader, asset_name, precision) asset.quote = trader._account.currency if trader._watcher: if trader._watcher.has_instrument(asset_name + trader._account.currency): asset.quote = trader._account.currency elif trader._watcher.has_instrument(asset_name + trader._account.alt_currency): asset.quote = trader._account.alt_currency else: if trader.has_market(asset_name + trader._account.currency): asset.quote = trader._account.currency elif trader.has_market(asset_name + trader._account.alt_currency): asset.quote = trader._account.alt_currency for k, market in trader._markets.items(): if market.base == asset_name: asset.add_market_id(market.market_id) trader._assets[asset_name] = asset return asset
def create_asset(self, asset_name, quantity, price, quote, precision=8): asset = Asset(self, asset_name, precision) asset.set_quantity(0, quantity) asset.update_price(datetime.now(), 0, price, quote) with self._mutex: self._assets[asset_name] = asset
def __get_or_add_asset(self, asset_name, precision=8): if asset_name in self._assets: return self._assets[asset_name] asset = Asset(self, asset_name, precision) self._assets[asset_name] = asset # and find related watched markets for qs in self._quotes: if asset_name + qs in self._markets: asset.add_market_id(asset_name + qs) # find the most appriopriate quote of an asset. quote_symbol = None if asset.symbol == self._account.currency and self._watcher.has_instrument( asset.symbol + self._account.alt_currency): # probably BTCUSDT quote_symbol = self._account.alt_currency elif asset.symbol != self._account.currency and self._watcher.has_instrument( asset.symbol + self._account.currency): # any pair based on BTC quote_symbol = self._account.currency else: # others case but might not occurs often because most of the assets are expressed in BTC for qs in self._quotes: if self._watcher.has_instrument(asset.symbol + qs): quote_symbol = qs break if not quote_symbol: if not asset.quote: logger.warning("No found quote for asset %s" % asset.symbol) quote_symbol = asset.symbol asset.quote = quote_symbol return asset
def process_userdata(self): # # inset asset # with self._mutex: uai = self._pending_asset_insert self._pending_asset_insert = [] if uai: try: cursor = self._db.cursor() for ua in uai: cursor.execute(""" INSERT INTO asset(broker_id, account_id, asset_id, last_trade_id, timestamp, quantity, price, quote_symbol) VALUES(%s, %s, %s, %s, %s, %s, %s, %s) ON CONFLICT (broker_id, account_id, asset_id) DO UPDATE SET last_trade_id = EXCLUDED.last_trade_id, timestamp = EXCLUDED.timestamp, quantity = EXCLUDED.quantity, price = EXCLUDED.price, quote_symbol = EXCLUDED.quote_symbol""", (*ua,)) self._db.commit() except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_asset_insert = uai + self._pending_asset_insert except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_asset_insert = uai + self._pending_asset_insert # # select asset # with self._mutex: uas = self._pending_asset_select self._pending_asset_select = [] if uas: try: cursor = self._db.cursor() for ua in uas: cursor.execute("""SELECT asset_id, last_trade_id, timestamp, quantity, price, quote_symbol FROM asset WHERE broker_id = '%s' AND account_id = '%s'""" % (ua[2], ua[3])) rows = cursor.fetchall() assets = [] for row in rows: asset = Asset(ua[1], row[0]) # only a sync will tell which quantity is free, which one is locked asset.update_price(float(row[2]) * 0.001, row[1], float(row[4]), row[5]) asset.set_quantity(0.0, float(row[3])) assets.append(asset) # notify ua[0].notify(Signal.SIGNAL_ASSET_DATA_BULK, ua[2], assets) except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_asset_select = uas + self._pending_asset_select except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_asset_select = uas + self._pending_asset_select # # insert user_trade # with self._mutex: uti = self._pending_user_trade_insert self._pending_user_trade_insert = [] if uti: try: cursor = self._db.cursor() query = ' '.join(( "INSERT INTO user_trade(broker_id, account_id, market_id, appliance_id, trade_id, trade_type, data, operations) VALUES", ','.join(["('%s', '%s', '%s', '%s', %i, %i, '%s', '%s')" % (ut[0], ut[1], ut[2], ut[3], ut[4], ut[5], json.dumps(ut[6]).replace("'", "''"), json.dumps(ut[7]).replace("'", "''")) for ut in uti]), "ON CONFLICT (broker_id, account_id, market_id, appliance_id, trade_id) DO UPDATE SET trade_type = EXCLUDED.trade_type, data = EXCLUDED.data, operations = EXCLUDED.operations" )) cursor.execute(query) self._db.commit() except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_user_trade_insert = uti + self._pending_user_trade_insert except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_user_trade_insert = uti + self._pending_user_trade_insert # # select user_trade # with self._mutex: uts = self._pending_user_trade_select self._pending_user_trade_select = [] if uts: try: cursor = self._db.cursor() for ut in uts: cursor.execute("""SELECT market_id, trade_id, trade_type, data, operations FROM user_trade WHERE broker_id = '%s' AND account_id = '%s' AND appliance_id = '%s'""" % (ut[2], ut[3], ut[4])) rows = cursor.fetchall() user_trades = [] for row in rows: user_trades.append((row[0], row[1], row[2], json.loads(row[3]), json.loads(row[4]))) # notify ut[0].notify(Signal.SIGNAL_STRATEGY_TRADE_LIST, ut[4], user_trades) except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_user_trade_select = uts + self._pending_user_trade_select except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_user_trade_select = uts + self._pending_user_trade_select # # delete user_trade # with self._mutex: utd = self._pending_user_trade_delete self._pending_user_trade_delete = [] if utd: try: cursor = self._db.cursor() # and cleanup for ut in utd: cursor.execute("""DELETE FROM user_trade WHERE broker_id = '%s' AND account_id = '%s' AND appliance_id = '%s'""" % (ut[0], ut[1], ut[2])) self._db.commit() except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_user_trade_delete = utd + self._pending_user_trade_delete except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_user_trade_delete = utd + self._pending_user_trade_delete # # insert user_trader # with self._mutex: uti = self._pending_user_trader_insert self._pending_user_trader_insert = [] if uti: try: cursor = self._db.cursor() query = ' '.join(( "INSERT INTO user_trader(broker_id, account_id, market_id, appliance_id, activity, data, regions) VALUES", ','.join(["('%s', '%s', '%s', '%s', %i, '%s', '%s')" % (ut[0], ut[1], ut[2], ut[3], 1 if ut[4] else 0, json.dumps(ut[5]).replace("'", "''"), json.dumps(ut[6]).replace("'", "''")) for ut in uti]), "ON CONFLICT (broker_id, account_id, market_id, appliance_id) DO UPDATE SET activity = EXCLUDED.activity, data = EXCLUDED.data, regions = EXCLUDED.regions" )) cursor.execute(query) self._db.commit() except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_user_trader_insert = uti + self._pending_user_trader_insert except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_user_trader_insert = uti + self._pending_user_trader_insert # # select user_trader # with self._mutex: uts = self._pending_user_trader_select self._pending_user_trader_select = [] if uts: try: cursor = self._db.cursor() for ut in uts: cursor.execute("""SELECT market_id, activity, data, regions FROM user_trader WHERE broker_id = '%s' AND account_id = '%s' AND appliance_id = '%s'""" % (ut[2], ut[3], ut[4])) rows = cursor.fetchall() user_traders = [] for row in rows: user_traders.append((row[0], row[1] > 0, json.loads(row[2]), json.loads(row[3]))) # notify ut[0].notify(Signal.SIGNAL_STRATEGY_TRADER_LIST, ut[4], user_traders) except self.psycopg2.OperationalError as e: self.try_reconnect(e) # retry the next time with self._mutex: self._pending_user_trader_select = uts + self._pending_user_trader_select except Exception as e: self.on_error(e) # retry the next time with self._mutex: self._pending_user_trader_select = uts + self._pending_user_trader_select
def process_userdata(self): # # inset asset # self.lock() uai = self._pending_asset_insert self._pending_asset_insert = [] self.unlock() if uai: try: cursor = self._db.cursor() for ua in uai: cursor.execute( """ INSERT INTO asset(broker_id, account_id, asset_id, last_trade_id, timestamp, quantity, price, quote_symbol) VALUES(%s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE last_trade_id = %s, timestamp = %s, quantity = %s, price = %s, quote_symbol = %s""", (*ua, *ua[3:])) self._db.commit() except Exception as e: logger.error(repr(e)) # retry the next time self.lock() self._pending_asset_insert = uai + self._pending_asset_insert self.unlock() # # select asset # self.lock() uas = self._pending_asset_select self._pending_asset_select = [] self.unlock() if uas: try: cursor = self._db.cursor() for ua in uas: cursor.execute( """SELECT asset_id, last_trade_id, timestamp, quantity, price, quote_symbol FROM asset WHERE broker_id = '%s' AND account_id = '%s'""" % (ua[2], ua[3])) rows = cursor.fetchall() assets = [] for row in rows: asset = Asset(ua[1], row[0]) # only a sync will tell which quantity is free, which one is locked asset.update_price( float(row[2]) * 0.001, row[1], float(row[4]), row[5]) asset.set_quantity(0.0, float(row[3])) assets.append(asset) # notify ua[0].notify(Signal.SIGNAL_ASSET_DATA_BULK, ua[2], assets) except Exception as e: # check database for valid ohlc and volumes logger.error(repr(e)) # retry the next time self.lock() self._pending_asset_select = uas + self._pending_asset_select self.unlock() # # insert user_trade # self.lock() uti = self._pending_user_trade_insert self._pending_user_trade_insert = [] self.unlock() if uti: try: cursor = self._db.cursor() query = ' '.join(( "INSERT INTO user_trade(broker_id, account_id, market_id, appliance_id, trade_id, trade_type, data, operations) VALUES", ','.join([ "('%s', '%s', '%s', '%s', %i, %i, '%s', '%s')" % (ut[0], ut[1], ut[2], ut[3], ut[4], ut[5], json.dumps(ut[6]).replace("'", "''"), json.dumps( ut[7]).replace("'", "''")) for ut in uti ]), "ON DUPLICATE KEY UPDATE data = VALUES(data), operations = VALUES(operations)" )) cursor.execute(query) self._db.commit() except Exception as e: logger.error(repr(e)) # retry the next time self.lock() self._pending_user_trade_insert = uti + self._pending_user_trade_insert self.unlock() # # select user_trade # self.lock() uts = self._pending_user_trade_select self._pending_user_trade_select = [] self.unlock() if uts: try: cursor = self._db.cursor() for ut in uts: cursor.execute( """SELECT market_id, trade_id, trade_type, data, operations FROM user_trade WHERE broker_id = '%s' AND account_id = '%s' AND appliance_id = '%s'""" % (ut[2], ut[3], ut[4])) rows = cursor.fetchall() user_trades = [] for row in rows: user_trades.append( (row[0], row[1], row[2], json.loads(row[3]), json.loads(row[4]))) # notify ut[0].notify(Signal.SIGNAL_STRATEGY_TRADE_LIST, ut[4], user_trades) except Exception as e: # check database for valid ohlc and volumes logger.error(repr(e)) # retry the next time self.lock() self._pending_user_trade_select = uts + self._pending_user_trade_select self.unlock() # # insert user_trader # self.lock() uti = self._pending_user_trader_insert self._pending_user_trader_insert = [] self.unlock() if uti: try: cursor = self._db.cursor() query = ' '.join(( "INSERT INTO user_trader(broker_id, account_id, market_id, appliance_id, activity, data, regions) VALUES", ','.join([ "('%s', '%s', '%s', '%s', %i, '%s', '%s')" % (ut[0], ut[1], ut[2], ut[3], 1 if ut[4] else 0, json.dumps(ut[5]).replace("'", "''"), json.dumps( ut[6]).replace("'", "''")) for ut in uti ]), "ON DUPLICATE KEY UPDATE activity = VALUES(activity), data = VALUES(data), regions = VALUES(regions)" )) cursor.execute(query) self._db.commit() except Exception as e: logger.error(repr(e)) # retry the next time self.lock() self._pending_user_trader_insert = uti + self._pending_user_trader_insert self.unlock() # # select user_trader # self.lock() uts = self._pending_user_trader_select self._pending_user_trader_select = [] self.unlock() if uts: try: cursor = self._db.cursor() for ut in uts: cursor.execute( """SELECT market_id, activity, data, regions FROM user_trader WHERE broker_id = '%s' AND account_id = '%s' AND appliance_id = '%s'""" % (ut[2], ut[3], ut[4])) rows = cursor.fetchall() user_traders = [] for row in rows: user_traders.append( (row[0], row[1] > 0, json.loads(row[2]), json.loads(row[3]))) # notify ut[0].notify(Signal.SIGNAL_STRATEGY_TRADER_LIST, ut[4], user_traders) except Exception as e: # check database for valid ohlc and volumes logger.error(repr(e)) # retry the next time self.lock() self._pending_user_trade_select = uts + self._pending_user_trade_select self.unlock()