def do_receipt_list(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() if args.org is not None: org_obj = try_get_then_lookup( state, 'organization', ['organization:ticker', 'organization:pricing-source'], args.org) if org_obj is not None: ListWriter(state, 'receipt', args.full, args.yaml).write('PayeeId', org_obj.get('object-id')) else: raise ClientException("{} does not match an organization".format( args.org)) elif args.bond is not None: bond_obj = try_get_then_lookup(state, 'bond', ['bond:isin', 'bond:cusip'], args.bond) if bond_obj is not None: ListWriter(state, 'receipt', args.full, args.yaml).write('BondId', bond_obj.get('object-id')) else: raise ClientException("{} does not match a bond".format(args.bond)) else: ListWriter(state, 'receipt', args.full, args.yaml).write()
def do_bond_list(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() ListWriter(state, 'bond', args.full, args.yaml).write()
def do_quote_list(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() if args.org is not None: org_obj = try_get_then_lookup( state, 'organization', ['organization:ticker', 'organization:pricing-source'], args.org) if org_obj is not None: ListWriter(state, 'quote', args.full, args.yaml).write('Firm', org_obj.get('pricing-source')) else: raise ClientException("{} does not match an organization".format( args.org)) elif args.user is not None: user_obj = try_get_then_lookup( state, 'participant', ['participant:username', 'participant:key-id'], args.user) if user_obj is not None: ListWriter(state, 'quote', args.full, args.yaml).write('CreatorId', user_obj.get('object-id')) else: raise ClientException("{} does not match a user".format(args.user)) else: ListWriter(state, 'quote', args.full, args.yaml).write()
def do_holding_show(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() org_obj = try_get_then_lookup(state, 'holding', [], args.identifier) ShowWriter(org_obj, 'holding', args.identifier).write()
def do_org_list(args, config): url = config.get("DEFAULT", 'url') key_file = config.get("DEFAULT", 'key_file') client = BondClient(base_url=url, keyfile=key_file) state = client.get_all_store_objects() ListWriter(state, 'organization', args.full, args.yaml).write()
def do_bond_show(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() bond_obj = try_get_then_lookup(state, 'bond', ['bond:isin', 'bond:cusip'], args.identifier) ShowWriter(bond_obj, 'bond', args.identifier).write()
def do_settlement_show(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() object_id = vars(args).get('object-id') settlement_obj = try_get_then_lookup(state, 'settlement', ['settlement:order-id'], object_id) ShowWriter(settlement_obj, 'settlement', object_id).write()
def do_user_show(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() user_obj = try_get_then_lookup( state, 'participant', ['participant:username', 'participant:key-id'], args.identifier) ShowWriter(user_obj, 'User', args.identifier).write()
def do_org_show(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() org_obj = try_get_then_lookup( state, 'organization', ['organization:ticker', 'organization:pricing-source'], args.identifier) ShowWriter(org_obj, 'organization', args.identifier).write()
def do_holding_list(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() if args.org is not None: org_obj = try_get_then_lookup( state, 'organization', ['organization:ticker', 'organization:pricing-source'], args.org) if org_obj is None: raise ClientException("--org did not specify an organization") ListWriter(state, 'holding', args.full, args.yaml).write('OwnerId', org_obj.get('object-id')) else: ListWriter(state, 'holding', args.full, args.yaml).write()
def do_settlement_list(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() if args.creator is not None: user_obj = try_get_then_lookup( state, 'participant', ['participant:username', 'participant:key-id'], args.creator) if user_obj is not None: ListWriter(state, 'settlement', args.full, args.yaml).write('CreatorId', user_obj.get('object-id')) else: raise ClientException("{} does not match a user".format( args.creator)) else: ListWriter(state, 'settlement', args.full, args.yaml).write()
def do_order_create(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') username = config.get("DEFAULT", 'username') client = BondClient(base_url=url, keyfile=key_file) args_dict = vars(args) store = client.get_all_store_objects() limit_price = None if args_dict.get('order-type') == 'Limit': if args.limit_price is not None: limit_price = args.limit_price if args.firm_id is None: firm_id = args.firm_id try: firm_id = try_get_then_lookup(store, 'participant', ['participant:username'], username)["firm-id"] print firm_id except KeyError: pass else: firm_id = args.firm_id client.create_order(args.action, args_dict.get('order-type'), firm_id, args.quantity, args.isin, args.cusip, limit_price, object_id=args.object_id) if args.wait: client.wait_for_commit()
def do_order_show(args, config): url = config.get("DEFAULT", 'url') client = BondClient(base_url=url, keyfile=None) state = client.get_all_store_objects() order_obj = try_get_then_lookup(state, 'order', [], args.identifier) ShowWriter(order_obj, 'order', args.identifier).write() if order_obj is not None and order_obj.get('status') == 'Settled': settlement_obj = None try: settlement_obj = state.lookup('settlement:order-id', order_obj.get('object-id')) print "Settlement:" print "----------------------------------------------------" except KeyError: pass ShowWriter(settlement_obj, 'settlement', order_obj.get('object-id')).write()
def do_load(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') client = BondClient(base_url=url, keyfile=key_file) for filename in args.filename: try: with open(filename) as fd: data = yaml.load(fd) except IOError, ioe: raise ClientException("IOError: {}".format(str(ioe))) print "Loading file: {}".format(filename) with UpdateBatch(client): for i in xrange(0, len(data['Transactions'])): for j in xrange(0, len(data['Transactions'][i]["Updates"])): update = data['Transactions'][i]["Updates"][j] if "ObjectId" not in update: update["ObjectId"] = \ hashlib.sha256(dict2cbor(update)).hexdigest() print "Sending transaction {}, {}...".format(i, j) print "Update ", update client.send_bond_update(update) if args.wait: client.wait_for_commit()
def do_org_create(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') client = BondClient(base_url=url, keyfile=key_file) client.create_org(args.name, args.object_id, args.industry, args.ticker, args.pricing_src, args.auth) if args.wait: client.wait_for_commit()
def do_user_register(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') username = config.get('DEFAULT', 'username') client = BondClient(base_url=url, keyfile=key_file) client.create_participant(username, args.firm_id) if args.wait: client.wait_for_commit()
def do_settlement_create(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') client = BondClient(base_url=url, keyfile=key_file) args_dict = vars(args) client.create_settlement(args_dict.get('order-id'), args.object_id) if args.wait: client.wait_for_commit()
def do_user_update(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') key_dir = config.get("DEFAULT", 'key_dir') username = config.get("DEFAULT", 'username') args_dict = vars(args) print args_dict client = BondClient(base_url=url, keyfile=key_file) client.update_participant(args_dict.get("object-id"), username=args.username, firm_id=args.firm_id) # need to change the username in bond.cfg and the .wif filename if args.username is not None: change_wif_and_addr_filename(key_dir, username, args.username) change_config('username', args.username) if args.wait: client.wait_for_commit()
def do_holding_create(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') client = BondClient(base_url=url, keyfile=key_file) state = client.get_all_store_objects() args_dict = vars(args) org = try_get_then_lookup( state, "organization", ["organization:ticker", "organization:pricing_source"], args.owner) if args_dict.get("asset-type") == "Currency": asset_id = args_dict.get("asset-id") else: asset_id = try_get_then_lookup(state, "bond", ["bond:cusip", "bond:isin"], args_dict.get("asset-id"))["object-id"] client.create_holding(org["object-id"], args_dict.get("asset-type"), asset_id, args.amount, args.object_id) if args.wait: client.wait_for_commit()
def do_quote_create(args, config): url = config.get('DEFAULT', 'url') key_file = config.get('DEFAULT', 'key_file') client = BondClient(base_url=url, keyfile=key_file) args_dict = vars(args) try: fp = float(args_dict.get('bid-price')) bid_price = float_to_bondprice(fp) except ValueError: bid_price = args_dict.get('bid-price') try: fp = float(args_dict.get('ask-price')) ask_price = float_to_bondprice(fp) except ValueError: ask_price = args_dict.get('ask-price') client.create_quote(args.firm, args_dict.get('ask-qty'), ask_price, args_dict.get('bid-qty'), bid_price, args.isin, args.cusip, args.object_id) if args.wait: client.wait_for_commit()
def on_will_start(self): # Note that the simulator will have already let us know about # the initial list of validators. So, we can simply use the # first client to submit our initial transactions. try: # Before the simulator starts, we will do any setup of # participants, etc., if the configuration tells us to do so setup_file = self.config.get('BondWorkload', 'setup_file') # Now read in the setup file, which is to be in YAML format, # and process the transactions. with open(setup_file) as fd: data = yaml.load(fd) # Unless we know about at least one validator, we cannot load # the setup date if len(self._clients) > 0: transactions = [] organizations = [] with self._create_temporary_key_file() as key_file: client = \ BondClient( base_url=self._clients[0].bond_client.base_url, keyfile=key_file.name) LOGGER.info( 'Submit initial transactions from %s to %s', setup_file, client.base_url) for transaction in data['Transactions']: try: transactions.append( client.send_bond_txn(transaction)) # Add any organizations with a pricing source so # later we can add market maker role authorizations organizations.extend( [u for u in transaction['Updates'] if u['UpdateType'] == 'CreateOrganization' and u.get('PricingSource') is not None and u.get('ObjectId') is not None]) except (InvalidTransactionError, UniqueConstraintError) as err: LOGGER.error('Transaction failed: %s', err) LOGGER.info( 'Wait for transactions to commit on %s', client.base_url) client.wait_for_commit() # It is not enough to have waited for the client to which # bond setup transactions were issued to commit. We really # want to make sure that all of the validators have the # transactions before we begin as once things get started we # will issue new transactions to random validators. LOGGER.info( 'Wait for transactions to propagate to all validators') self._wait_for_all_to_commit(transactions) # Because we may have loaded organizations that can create # quotes (i.e., have a pricing source), we want to be sure # to catch them here as well since they may not have # already been in the system. So, run through the # transactions and look for any updates that create an # organization with a pricing source and add market maker # role authorizations by the participants. for client in self._clients: # Refresh the client state to ensure that we get the # local store in sync so that local validation of # transactions doesn't fail. for organization in organizations: try: LOGGER.info( 'Add marketmaker role authorization to ' '%s (%s) by participant {%s}', organization.get('Name'), organization.get('PricingSource'), client.id) client.bond_client.add_authorization_to_org( object_id=organization.get('ObjectId'), role='marketmaker', participant_id=client.id) # Because we succeeded, we can add the # organization to the client so it can use it # when it starts issuing orders/quotes. We will # also keep the transaction ID so we can wi client.organizations.append({ 'object-id': organization.get('ObjectId'), 'name': organization.get('Name'), 'pricing-source': organization.get('PricingSource') }) except (InvalidTransactionError, UniqueConstraintError) as err: LOGGER.error('Transaction failed: %s', err) else: LOGGER.warning( 'Cannot pre-load bond transactions as we do not have any ' 'known validators') except ConfigParser.NoSectionError: LOGGER.warning( 'Configuration does not contain BondWorkload section. ' 'Will not pre-load bond transactions before starting.') except ConfigParser.NoOptionError: LOGGER.warning( 'Configuration BondWorkload section does not contain a ' 'setup_file option. Will not pre-load bond transactions ' 'before starting.') except IOError as err: LOGGER.warning('Failed to pre-load bond transactions: %s', err) # Ensure that all clients have fresh state of the new transactions # that we submitted and that all transactions submitted to the client # are committed for client in self._clients: LOGGER.info( 'Wait for all transactions on %s to commit', client.bond_client.base_url) client.bond_client.wait_for_commit() # Fetch the state from the first client and find the list of bonds so # we can use them to issue orders state = self._clients[0].bond_client.get_all_store_objects() bond_list = [b for b in state.iteritems() if b[1]["object-type"] == 'bond'] self._bond_ids = \ [BondIdentifier(isin=b.get('isin'), cusip=b.get('cusip')) for _, b in bond_list] if len(self._bond_ids) == 0: raise \ Exception('There are no bonds to issue orders/quotes against')
def on_validator_discovered(self, url): # We need a key file for the client then create a new client and add # it to our cadre of clients to use. For each client, we are going to # get the list of organizations it knows about. For any organization # that has a pricing source (i.e., can be a market maker) that is not # one of our made up ones (i.e., starts with Z), we are going to add # an authorization to it for the newly-created participant and # role of market maker. If the client has no such organizations, we # will create one of our own. Later on we will be able to issue orders # and quotes against this(these) organization(s). It is important # that orders (buy/sell) and quotes be issued from the same client # that creates the participant. with self._create_temporary_key_file() as key_file: try: client = BondClient(base_url=url, keyfile=key_file.name) # Participant and organization names are limited to 16 # characters and a full ISO formatted date/time is too long # so generate something that can be used as a fairly random # string of 14 characters random_name = \ hashlib.md5(datetime.now().isoformat()).hexdigest() participant_name = 'P_{0:.14s}'.format(random_name) participant_id = 'intel_simparticipant_{0}'.format(random_name) LOGGER.info( 'Create participant %s with ID %s for %s', participant_name, participant_id, client.base_url) client.create_participant( username=participant_name, object_id=participant_id) # Get the list of organizations that have a pricing source # that doesn't start with Z (i.e., is one we made up). state = client.get_all_store_objects() organizations = [] org_list = [x[1] for x in state.iteritems() if x[1]["object-type"] == 'organization'] for org in org_list: pricing_source = org.get('pricing-source') if pricing_source is not None \ and not pricing_source.startswith('Z'): organizations.append(org) # If there were none, then we need to create one so that we # at least have one market maker for this client to issue # quotes/orders against. if len(organizations) == 0: marketmaker_name = 'M_{0:.14s}'.format(random_name) marketmaker_id = \ 'intel_simmarketmaker_{0}'.format(random_name) # Just in case there are market makers left lying around # from a previous run we will keep trying until we hit a # unique pricing source. Once successful, add this # organization to the list while True: try: pricing_source = \ next(self._pricing_source_generator) client.create_org( name=marketmaker_name, object_id=marketmaker_id, pricing_src=pricing_source) break except InvalidTransactionError: pass organizations.append({ 'object-id': marketmaker_id, 'name': marketmaker_name, 'pricing-source': pricing_source }) LOGGER.info( 'Create marketmaker %s with pricing source %s and ' 'ID %s for %s', marketmaker_name, pricing_source, marketmaker_id, client.base_url) # Now, we need to add a participant/market maker role # authorization to each organization for organization in organizations: LOGGER.info( 'Add marketmaker role authorization to %s (%s) by ' 'participant %s', organization.get('name'), organization.get('pricing-source'), participant_id) client.add_authorization_to_org( object_id=organization.get('object-id'), role='marketmaker', participant_id=participant_id) # Add the client to our list so that we can choose from it # when randomly issuing new transactions. with self._lock: self._clients.append( Client( organizations=organizations, bond_client=client, id=participant_id)) except (InvalidTransactionError, MessageException) as err: LOGGER.error( 'Failed to create participant and authorize ' 'organization(s): %s', err)