def compose_market_data_request(self): market_data_request = quickfix44.MarketDataRequest() market_data_request.setField(quickfix.MDReqID('1')) market_data_request.setField(quickfix.SubscriptionRequestType(quickfix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) market_data_request.setField(quickfix.MarketDepth(0)) market_data_request.setField(quickfix.NoMDEntryTypes(2)) market_data_request.setField(quickfix.MDUpdateType(quickfix.MDUpdateType_INCREMENTAL_REFRESH)) group = quickfix44.MarketDataRequest().NoMDEntryTypes() group.setField(quickfix.MDEntryType(quickfix.MDEntryType_BID)) market_data_request.addGroup(group) group.setField(quickfix.MDEntryType(quickfix.MDEntryType_OFFER)) market_data_request.addGroup(group) market_data_request.setField(quickfix.NoRelatedSym(self.reference_data.get_count())) symbol = quickfix44.MarketDataRequest().NoRelatedSym() for instrument in self.reference_data.get_instruments(): symbol.setField(quickfix.SecurityExchange(instrument.exchange)) symbol.setField(quickfix.Symbol(instrument.symbol)) market_data_request.addGroup(symbol) return market_data_request
def subscribe(self): if self.marketSession is None: self.logger.info( "FIXSIM-CLIENT Market session is none, skip subscribing") return for subscription in self.subscriptions: message = self.fixVersion.MarketDataRequest() message.setField(quickfix.MDReqID(self.idGen.reqID())) message.setField( quickfix.SubscriptionRequestType( quickfix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) message.setField( quickfix.MDUpdateType(quickfix.MDUpdateType_FULL_REFRESH)) message.setField(quickfix.MarketDepth(0)) message.setField(quickfix.MDReqID(self.idGen.reqID())) relatedSym = self.fixVersion.MarketDataRequest.NoRelatedSym() relatedSym.setField(quickfix.Product(quickfix.Product_CURRENCY)) relatedSym.setField( quickfix.SecurityType( quickfix.SecurityType_FOREIGN_EXCHANGE_CONTRACT)) relatedSym.setField(quickfix.Symbol(subscription.symbol)) message.addGroup(relatedSym) group = self.fixVersion.MarketDataRequest.NoMDEntryTypes() group.setField(quickfix.MDEntryType(quickfix.MDEntryType_BID)) message.addGroup(group) group.setField(quickfix.MDEntryType(quickfix.MDEntryType_BID)) message.addGroup(group) self.sendToTarget(message, self.marketSession)
def onLogon(self, sessionID): self.sessionID = sessionID print("onLogon - sessionID: " + sessionID.toString()) currency_pairs = ['GBP/USD', 'EUR/USD'] for ccy in currency_pairs: mdr = fix.Message() mdr.getHeader().setField(fix.BeginString(fix.BeginString_FIX44)) mdr.getHeader().setField(fix.MsgType(fix.MsgType_MarketDataRequest)) current_milli_time = lambda: int(round(time.time() * 1000)) mdr.setField(fix.MDReqID(str(current_milli_time()))) # a random string mdr.setField(fix.SubscriptionRequestType(fix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) # what stater required mdr.setField(fix.MarketDepth(1)) # what stater required mdr.setField(fix.AggregatedBook(True)) mdr.setField(fix.NoMDEntryTypes(1)) # what stater required mdr.setField(fix.MDUpdateType(fix.MDUpdateType_INCREMENTAL_REFRESH)) # what stater required group = fix44.MarketDataRequest().NoMDEntryTypes() group.setField(fix.MDEntryType(fix.MDEntryType_BID)) mdr.addGroup(group) group.setField(fix.MDEntryType(fix.MDEntryType_OFFER)) mdr.addGroup(group) mdr.setField(fix.NoRelatedSym(1)) symbol = fix44.MarketDataRequest().NoRelatedSym() symbol.setField(fix.Symbol(ccy)) mdr.addGroup(symbol) fix.Session.sendToTarget(mdr, sessionID)
def createOrderBookRequest(self): orderBookRequest = fix44.MarketDataRequest() noRelatedSym = fix44.MarketDataRequest.NoRelatedSym() noRelatedSym.setField(fix.Symbol('BTC/CNY')) orderBookRequest.addGroup(noRelatedSym) orderBookRequest.setField( fix.MDReqID("123")) # Unique ID assigned to this request orderBookRequest.setField( fix.SubscriptionRequestType('1')) # 0 = Snapshot # 1 = Snapshot + Subscribe # 2 Unsubscribe orderBookRequest.setField( fix.MDUpdateType(1)) # 0 = full refresh, 1: incremental refresh orderBookRequest.setField(fix.MarketDepth(0)) # 0 = full book, group1 = fix44.MarketDataRequest.NoMDEntryTypes() group1.setField(fix.MDEntryType('0')) # bids orderBookRequest.addGroup(group1) group2 = fix44.MarketDataRequest.NoMDEntryTypes() group2.setField(fix.MDEntryType('1')) # asks orderBookRequest.addGroup(group2) return orderBookRequest
def send_mkt_data_req(self, symbol): """ :param symbol: str """ print("send_mkt_data_req: ", symbol) message = fix44.MarketDataRequest() message.setField(fix.MDReqID(self.next_id())) message.setField( fix.SubscriptionRequestType( fix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) message.setField(fix.MarketDepth(3)) message.setField(fix.MDUpdateType( fix.MDUpdateType_INCREMENTAL_REFRESH)) symbol_group = fix44.MarketDataRequest.NoRelatedSym() symbol_group.setField(fix.Symbol(symbol)) message.addGroup(symbol_group) types = fix44.MarketDataRequest.NoMDEntryTypes() types.setField(fix.MDEntryType(fix.MDEntryType_BID)) message.addGroup(types) types = fix44.MarketDataRequest.NoMDEntryTypes() types.setField(fix.MDEntryType(fix.MDEntryType_OFFER)) message.addGroup(types) fix.Session_sendToTarget(message, self.sessionID)
def main(): sessionID = fix.SessionID('FIX.4.4', SENDERCOMPID, 'PAYMIUM') params = fix.Dictionary() params.setString('ConnectionType', 'initiator') params.setString('StartTime', '00:00:00') params.setString('EndTime', '00:00:00') params.setString('HeartBtInt', '30') params.setString('CheckLatency', 'Y') params.setString('SocketConnectHost', '195.154.171.115') params.setString('SocketConnectPort', '8359') params.setString('DataDictionary', FIX44FILE) params.setString('EncryptMethod', '0') settings = fix.SessionSettings() settings.set(sessionID, params) application = MyApplication() factory = fix.FileStoreFactory("store") acceptor = fix.SocketInitiator(application, factory, settings, fix.ScreenLogFactory(DEBUG, DEBUG, DEBUG)) acceptor.start() time.sleep(2) mdr = fixMsg.MarketDataRequest() mdr.setField(fix.MDReqID("MDRQ-%d" % (time.time() * 1000000))) # We want the full book here, not just the top mdr.setField(fix.MarketDepth(1)) # We want to get a snapshot and also subscribe to the market depth updates mdr.setField( fix.SubscriptionRequestType( fix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) # We'll want only incremental refreshes when new data is available mdr.setField(fix.MDUpdateType(fix.MDUpdateType_INCREMENTAL_REFRESH)) # Specify the currency instruments = fixMsg.MarketDataRequest().NoRelatedSym() instruments.setField(fix.Symbol("EUR/XBT")) mdr.addGroup(instruments) # Specify that we'll want the bids and asks mdr.setField(fix.NoMDEntryTypes(2)) group = fixMsg.MarketDataRequest().NoMDEntryTypes() group.setField(fix.MDEntryType(fix.MDEntryType_BID)) group.setField(fix.MDEntryType(fix.MDEntryType_OFFER)) mdr.addGroup(group) fix.Session.sendToTarget(mdr, sessionID) while True: time.sleep(10) acceptor.stop()
def on_market_data_request(self, message): print('Market Data REQUEST!') message_fields = { 'md_reqID': fix.MDReqID(), 'depth': fix.MarketDepth(), 'subscription_type': fix.SubscriptionRequestType(), } message_details = {} for k, v in message_fields.items(): message_details[k] = self.get_field_value(message, v) message_details['entry_types'] = {} message_details['symbols'] = {} n_entry_types = self.get_field_value(message, fix.NoMDEntryTypes()) group = fix44.MarketDataRequest().NoMDEntryTypes() for i in range(n_entry_types): message.getGroup(i + 1, group) message_details['entry_types'][i] = self.get_field_value( group, fix.MDEntryType()) n_symbols = self.get_field_value(message, fix.NoRelatedSym()) group = fix44.MarketDataRequest().NoRelatedSym() for i in range(n_symbols): message.getGroup(i + 1, group) message_details['symbols'][i] = self.get_field_value( group, fix.Symbol()) orderID = self.gen_orderID() self.orders[orderID] = message_details # testing self.test_snaps(message_details, full=True) self.test_snaps(message_details, full=False)
def market_data_request(self, sender_comp_id, target_comp_id, symbols): md_types = [ fix.MDEntryType_BID, fix.MDEntryType_OFFER, fix.MDEntryType_TRADE ] message = fix42.MarketDataRequest() header = message.getHeader() header.setField(fix.SenderCompID(sender_comp_id)) header.setField(fix.TargetCompID(target_comp_id)) message.setField(fix.MDReqID(self._generate_id())) message.setField( fix.SubscriptionRequestType( fix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) message.setField(fix.MarketDepth(10)) group = fix42.MarketDataRequest().NoMDEntryTypes() for md_type in md_types: group.setField(fix.MDEntryType(md_type)) message.addGroup(group) group = fix42.MarketDataRequest().NoRelatedSym() for symbol in symbols: group.setField(fix.Symbol(symbol)) message.addGroup(group) try: fix.Session.sendToTarget(message) except fix.SessionNotFound: raise Exception(f"No session found {message}, exiting...")
def suscribeMD(self): print( "SUSCRIBE MD***************************************************************************" ) if len(self.tickers) == 0 or len(self.entries) == 0: return allowed_entries = ['0', '1', '2', '4', '5', '6', '7', '8', 'B', 'C'] if not all(elem in allowed_entries for elem in self.entries): return msg = fix50.MarketDataRequest() header = msg.getHeader() header.setField(fix.SenderCompID(self.usrID)) header.setField(fix.TargetCompID(self.targetCompID)) # --------------------- msg.setField(fix.MDReqID("ListaMktData")) msg.setField(fix.SubscriptionRequestType('1')) msg.setField(fix.MarketDepth(1)) msg.setField(fix.MDUpdateType(0)) msg.setField(fix.AggregatedBook(True)) # BlockMDReqGrp group = fix50.MarketDataRequest().NoMDEntryTypes() for field in self.entries: group.setField(fix.MDEntryType(str(field))) msg.addGroup(group) # Symbols norelatedsym = fix50.MarketDataRequest().NoRelatedSym() for ticker in self.tickers: norelatedsym.setField(fix.Symbol(ticker)) logfix.warning("--> Suscribe Ticker >> (%s)" % ticker) msg.addGroup(norelatedsym) fix.Session.sendToTarget(msg)
def top_n_orders(message, n): stock_id = getValue(message, 55) dict_list = give_top_n(stock_id, n) ret_message = fix44.MarketDataSnapshotFullRefresh() group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() for Dict in dict_list: group.setField(fix.MDEntryType(Dict["Type"])) group.setField(fix.MDEntryPx(Dict["Price"])) group.setField(fix.MDEntrySize(Dict["Quantity"])) group.setField(fix.OrderID(Dict["Order ID"])) ret_message.addGroup(group) ret_message.setField(55, stock_id) return ret_message
def publishMarketData(self): self.logger.info("FixServer: publishMarketData %s", self.subscriptions) for subscription in self.subscriptions: if not subscription.hasSessions(): self.logger.info( "FixServer:No session subscribed, skip publish symbol %s", subscription.symbol) continue message = self.fixVersion.MarketDataSnapshotFullRefresh() message.setField(quickfix.Symbol(subscription.symbol)) message.setField(quickfix.MDReqID(self.idGen.reqID())) group = self.fixVersion.MarketDataSnapshotFullRefresh( ).NoMDEntries() subscription.createOrderBook() for quote in subscription.orderbook: self.logger.info('FixServer:add quote to fix message %s', str(quote)) group.setField(quickfix.MDEntryType(quote.side)) group.setField(quickfix.MDEntryPx(quote.price)) group.setField(quickfix.MDEntrySize(quote.size)) group.setField(quickfix.QuoteEntryID(quote.id)) group.setField(quickfix.Currency(subscription.currency)) group.setField( quickfix.QuoteCondition( quickfix.QuoteCondition_OPEN_ACTIVE)) message.addGroup(group) for sessionID in subscription: self.sendToTarget(message, sessionID)
def market_data_request(self): request = fix44.MarketDataRequest() request.setField(fix.MDReqID(self.gen_mdReqID())) request.setField(fix.MarketDepth(0)) request.setField(fix.SubscriptionRequestType('0')) group = fix44.MarketDataRequest().NoMDEntryTypes() group.setField(fix.MDEntryType('0')) request.addGroup(group) group.setField(fix.MDEntryType('1')) request.addGroup(group) group = fix44.MarketDataRequest().NoRelatedSym() group.setField(fix.Symbol('SNAP')) request.addGroup(group) fix.Session.sendToTarget(request, self.sessionID)
def __init__(self, reference_data, market_data): self.reference_data = reference_data self.market_data = market_data self.symbol_field = quickfix.Symbol() self.security_exchange_field = quickfix.SecurityExchange() self.no_md_entries = quickfix.NoMDEntries() self.md_entry_type = quickfix.MDEntryType() self.md_entry_price = quickfix.MDEntryPx() self.md_entry_size = quickfix.MDEntrySize()
def market_data_request(self, sender_comp_id, target_comp_id, symbols): md_types = [ fix.MDEntryType_BID, fix.MDEntryType_OFFER, fix.MDEntryType_TRADE ] message = fix44.MarketDataRequest() header = message.getHeader() header.setField(fix.SenderCompID(sender_comp_id)) header.setField(fix.TargetCompID(target_comp_id)) message.setField(fix.MDReqID(self._generate_id())) message.setField( fix.SubscriptionRequestType( fix.SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES)) # message.setField( # fix.SubscriptionRequestType( # fix.SubscriptionRequestType_SNAPSHOT # ) # ) """ Valid values: 0 = Full Book 1 = Top of Book N>1 = Report best N price tiers of data """ message.setField(fix.MarketDepth(0)) """ Valid values: 0 = Full Refresh 1 = Incremental Refresh """ message.setField(fix.MDUpdateType( fix.MDUpdateType_INCREMENTAL_REFRESH)) group = fix44.MarketDataRequest().NoMDEntryTypes() for md_type in md_types: group.setField(fix.MDEntryType(md_type)) message.addGroup(group) group = fix44.MarketDataRequest().NoRelatedSym() for symbol in symbols: group.setField(fix.Symbol(symbol)) message.addGroup(group) try: fix.Session.sendToTarget(message) except fix.SessionNotFound: raise Exception(f"No session found {message}, exiting...")
def fromApp(self, message, sessionID): msg_type = message.getHeader().getField(fix.MsgType()).getString() depth = {} if msg_type == fix.MsgType_MarketDataSnapshotFullRefresh: group = fixMsg.MarketDataSnapshotFullRefresh.NoMDEntries() nb_entries = int(message.getField(fix.NoMDEntries()).getString()) for i in range(1, nb_entries + 1): message.getGroup(i, group) md_type = group.getField(fix.MDEntryType()).getString() md_price = group.getField(fix.MDEntryPx()).getString() md_amount = group.getField(fix.MDEntrySize()).getString() if not md_amount: md_amount = 0 order = {'price': float(md_price), 'amount': float(md_amount)} if md_type == fix.MDEntryType_OFFER: if 'asks' not in depth: depth['asks'] = [] depth['asks'].append(order) if md_type == fix.MDEntryType_BID: if 'bids' not in depth: depth['bids'] = [] depth['bids'].append(order) print("Received a full market data snapshot: %s" % (depth)) elif msg_type == fix.MsgType_MarketDataIncrementalRefresh: group = fixMsg.MarketDataIncrementalRefresh.NoMDEntries() nb_entries = int(message.getField(fix.NoMDEntries()).getString()) for i in range(1, nb_entries + 1): message.getGroup(i, group) md_type = group.getField(fix.MDEntryType()).getString() md_price = group.getField(fix.MDEntryPx()).getString() md_amount = group.getField(fix.MDEntrySize()).getString() if not md_amount: md_amount = 0 order = {'price': float(md_price), 'amount': float(md_amount)} if md_type == fix.MDEntryType_OFFER: if 'asks' not in depth: depth['asks'] = [] depth['asks'].append(order) if md_type == fix.MDEntryType_BID: if 'bids' not in depth: depth['bids'] = [] depth['bids'].append(order) print("Received an incremental market data update: %s" % (depth))
def handle_market_data_respond(self, message): """Handles market data respond Args: message (FIX::Message): Market data message to be handled. Returns: TODO how does the return value look like """ # Retrieve Market Data Response Type Full Refresh/Snapshot md_req_id_fix = fix.MDReqID() no_md_entries_fix = fix.NoMDEntries() symbol_fix = fix.Symbol() total_volume_traded_fix = fix.TotalVolumeTraded() md_entry_type_fix = fix.MDEntryType() md_entry_px_fix = fix.MDEntryPx() md_entry_size_fix = fix.MDEntrySize() md_entry_date_fix = fix.MDEntryDate() md_entry_time_fix = fix.MDEntryTime() md_entry_type_list = [] md_entry_px_list = [] md_entry_size_list = [] md_entry_date_list = [] md_entry_time_list = [] message.getField(md_req_id_fix) message.getField(no_md_entries_fix) message.getField(symbol_fix) message.getField(total_volume_traded_fix) groupMD = fix42.MarketDataSnapshotFullRefresh.NoMDEntries() for MDIndex in range(no_md_entries_fix.getValue()): message.getGroup(MDIndex + 1, groupMD) groupMD.getField(md_entry_type_fix) groupMD.getField(md_entry_px_fix) groupMD.getField(md_entry_size_fix) groupMD.getField(md_entry_date_fix) groupMD.getField(md_entry_time_fix) md_entry_type_list.append(md_entry_type_fix.getValue()) md_entry_px_list.append(md_entry_px_fix.getValue()) md_entry_size_list.append(md_entry_size_fix.getValue()) md_entry_date_list.append(TradingClass.FIXDate.from_fix_date_stamp_string(md_entry_date_fix.getString())) md_entry_time_list.append(TradingClass.FIXTime.from_fix_time_stamp_string(md_entry_time_fix.getString())) # Encapsulate data into market data response object market_data = TradingClass.MarketDataResponse(md_req_id_fix.getValue(), no_md_entries_fix.getValue(), symbol_fix.getValue() , md_entry_type_list, md_entry_px_list, md_entry_size_list, md_entry_date_list, md_entry_time_list, total_volume_traded_fix.getValue()) self.client_logic.process_market_data_respond(market_data) pass
def dispatch(self, book): symbol = book.symbol bids = book.bids asks = book.asks trades = book.trades message = fix44.MarketDataSnapshotFullRefresh() message.setField(fix.Symbol(symbol)) group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() if bids: for i in range(len(bids)): group.setField(fix.MDEntryType(fix.MDEntryType_BID)) group.setField(fix.MDEntryPx(float(bids[i][0]))) group.setField(fix.MDEntrySize(float(bids[i][1]))) message.addGroup(group) if asks: for i in range(len(asks)): group.setField(fix.MDEntryType(fix.MDEntryType_OFFER)) group.setField(fix.MDEntryPx(float(asks[i][0]))) group.setField(fix.MDEntrySize(float(asks[i][1]))) message.addGroup(group) if trades: for i in range(len(trades)): group.setField(fix.MDEntryType(fix.MDEntryType_TRADE)) group.setField(fix.MDEntryPx(float(trades[i][0]))) group.setField(fix.MDEntrySize(float(trades[i][1]))) message.addGroup(group) self.logger.debug(f"Clients {self.clients}") print(message.__str__().replace("\x01", "|")) if symbol in self.clients: for session in self.clients[symbol]: fix.Session.sendToTarget(message, session)
def marketDataRequest(self): # pag 63 msg = fix50.MarketDataRequest() header = msg.getHeader() # header.setField(fix.BeginString(fix.BeginString_FIXT11)) # header.setField(fix.MsgType(msgType)) header.setField(fix.SenderCompID("pjseoane232")) header.setField(fix.TargetCompID("ROFX")) # msg = self.buildMsgHeader("V") msg.setField(fix.MDReqID("ListaMktData2")) msg.setField(fix.SubscriptionRequestType('2')) msg.setField(fix.MarketDepth(1)) msg.setField(fix.MDUpdateType(0)) msg.setField(fix.AggregatedBook(True)) # msg.setField(fix.NoMDEntryTypes(2)) # ---- define Group group = fix50.MarketDataRequest().NoMDEntryTypes() group.setField(fix.MDEntryType('0')) msg.addGroup(group) # group = fix50.MarketDataRequest().NoMDEntryTypes() group.setField(fix.MDEntryType('1')) msg.addGroup(group) # group3 = fix50.MarketDataRequest().NoMDEntryTypes() # group3.setField(fix.MDEntryType('2')) # msg.addGroup(group3) # ----------------------------------------- msg.setField(fix.NoRelatedSym(1)) group = fix50.MarketDataRequest().NoRelatedSym() group.setField(fix.Symbol("RFX20Sep19")) msg.addGroup(group) fix.Session.sendToTarget(msg)
def marketDataRequest(self, ticker, subscription_type): mdr = fix.Message() mdr.getHeader().setField(fix.BeginString(fix.BeginString_FIX44)) mdr.getHeader().setField(fix.MsgType(fix.MsgType_MarketDataRequest)) group = fix44.MarketDataRequest().NoRelatedSym() group.setField(fix.Symbol(ticker)) mdr.addGroup(group) mdr.setField(fix.MDReqID('1')) mdr.setField(fix.SubscriptionRequestType(subscription_type)) mdr.setField(fix.MarketDepth(0)) mdr.setField(fix.NoMDEntryTypes(3)) group = fix44.MarketDataRequest().NoMDEntryTypes() group.setField(fix.MDEntryType(fix.MDEntryType_BID)) mdr.addGroup(group) group.setField(fix.MDEntryType(fix.MDEntryType_OFFER)) mdr.addGroup(group) group.setField(fix.MDEntryType(fix.MDEntryType_TRADE)) mdr.addGroup(group) fix.Session.sendToTarget(mdr, self.sessionID) return
def parse_MarketDataSnapshotFullRefresh(self, message, sending_time): if self.verbose: print(self._server_str + ' {MD} Full refresh!') symbol = extract_message_field_value(fix.Symbol(), message) if symbol in self.history_dict: num_entries = extract_message_field_value(fix.NoMDEntries(), message, 'int') # 268 # MarketDataSnapshotFullRefresh message contains multiple NoQuoteSets group # Groups have indexes in FIX messages starting at 1 NoMDEntries_Group = fix44.MarketDataSnapshotFullRefresh.NoMDEntries( ) # NoMDEntries_Group = fix44.MarketDataIncrementalRefresh.NoMDEntries() for i in range(num_entries): message.getGroup(i + 1, NoMDEntries_Group) bid, ask, bid_size, ask_size = None, None, None, None _type = extract_message_field_value( fix.MDEntryType(), NoMDEntries_Group, 'str') # 269 (0: bid, 1: ask) price = extract_message_field_value(fix.MDEntryPx(), NoMDEntries_Group, 'float') # 270 size = extract_message_field_value(fix.MDEntrySize(), NoMDEntries_Group, 'float') # 271 depth = extract_message_field_value(fix.QuoteEntryID(), NoMDEntries_Group, 'int') # 299 if _type == '0': bid = price bid_size = size elif _type == '1': ask = price ask_size = size if self.verbose: print( f'symbol: {symbol} | bid: {bid} | ask: {ask} | bid_size: {bid_size} | ask_size: {ask_size}' ) self.update_asset(sending_time, symbol, depth, bid, ask, bid_size, ask_size)
def onMarketDataSnapshotFullRefresh(self, message, sessionID): skip_chance = random.choice(range(1, 101)) if self.skipSnapshotChance > skip_chance: self.logger.info( "FIXSIM-CLIENT onMarketDataSnapshotFullRefresh skip making trade with random choice %d", skip_chance) return fix_symbol = quickfix.Symbol() message.getField(fix_symbol) symbol = fix_symbol.getValue() snapshot = Snapshot(symbol) group = self.fixVersion.MarketDataSnapshotFullRefresh.NoMDEntries() fix_no_entries = quickfix.NoMDEntries() message.getField(fix_no_entries) no_entries = fix_no_entries.getValue() for i in range(1, no_entries + 1): message.getGroup(i, group) price = quickfix.MDEntryPx() size = quickfix.MDEntrySize() currency = quickfix.Currency() quote_id = quickfix.QuoteEntryID() group.getField(quote_id) group.getField(currency) group.getField(price) group.getField(size) quote = Quote() quote.price = price.getValue() quote.size = size.getValue() quote.currency = currency.getValue() quote.id = quote_id.getValue() fix_entry_type = quickfix.MDEntryType() group.getField(fix_entry_type) entry_type = fix_entry_type.getValue() if entry_type == quickfix.MDEntryType_BID: snapshot.addBid(quote) elif entry_type == quickfix.MDEntryType_OFFER: snapshot.addAsk(quote) else: raise RuntimeError("Unknown entry type %s" % str(entry_type)) self.makeOrder(snapshot)
def createLiveTradesRequest(self): liveTradesRequest = fix44.MarketDataRequest() noRelatedSym = fix44.MarketDataRequest.NoRelatedSym() noRelatedSym.setField(fix.Symbol("BTC/CNY")) liveTradesRequest.addGroup(noRelatedSym) liveTradesRequest.setField(fix.MDReqID("123")) liveTradesRequest.setField(fix.SubscriptionRequestType('1')) liveTradesRequest.setField(fix.MarketDepth(0)) group = fix44.MarketDataRequest.NoMDEntryTypes() group.setField(fix.MDEntryType('2')) # trade liveTradesRequest.addGroup(group) return liveTradesRequest
def show(self, message): msgtype = fix.MsgType() message.getHeader().getField(msgtype) print(message.__str__().replace("\x01", "|")) _bids = [] _asks = [] _trades = [] if msgtype.getValue() == "W": symbol = fix.Symbol() message.getField(symbol) instrument = symbol.getValue() entry_type = fix.MDEntryType() entry_px = fix.MDEntryPx() entry_size = fix.MDEntrySize() entries = fix.NoMDEntries() message.getField(entries) group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() for i in range(entries.getValue()): message.getGroup(i + 1, group) group.getField(entry_type) group.getField(entry_px) group.getField(entry_size) if entry_type.getValue() == "0": _bids.append((entry_px.getValue(), entry_size.getValue())) elif entry_type.getValue() == "1": _asks.append((entry_px.getValue(), entry_size.getValue())) elif entry_type.getValue() == "2": _trades.append( (entry_px.getValue(), entry_size.getValue())) book = Book(instrument, _bids, _asks, _trades) print(book)
def marketDataRequest(self): self._cf.read(self._cf_path) msg = fix42.Message() for name, value in self._cf.items(self._market_section): if name == '35' or name == '115': msg.getHeader().setField(fix.StringField(int(name), value)) elif name.isdigit(): msg.setField(fix.StringField(int(name), value)) elif name == 'entrytypes': type_group = fix42.MarketDataRequest().NoMDEntryTypes() for entry in value.split(';'): type_group.setField(fix.MDEntryType(entry)) msg.addGroup(type_group) elif name == 'symbols': sym_group = fix42.MarketDataRequest().NoRelatedSym() for sym in value.split(';'): sym_group.setField(fix.Symbol(sym)) msg.addGroup(sym_group) fix.Session.sendToTarget(msg, self._session)
def send_market_data_request(self, symbol): """Sends a market data request to server Args: symbol (string): the ticker symbol of a stock Returns: """ # Create Fix Message for Market Data Request message = fix.Message(); header = message.getHeader(); header.setField(fix.MsgType(fix.MsgType_MarketDataRequest)) header.setField(fix.SendingTime()) message.setField(fix.MDReqID(str(self.client_database_handler.generate_market_data_request_id()))) message.setField(fix.SubscriptionRequestType(fix.SubscriptionRequestType_SNAPSHOT)) message.setField(fix.MarketDepth(1)) message.setField(fix.NoMDEntryTypes(10)) group_md_entry = fix42.MarketDataRequest().NoMDEntryTypes() group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_BID)) message.addGroup(group_md_entry) group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_OFFER)) message.addGroup(group_md_entry) group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_TRADE)) message.addGroup(group_md_entry) group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_OPENING_PRICE)) message.addGroup(group_md_entry) group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_CLOSING_PRICE)) message.addGroup(group_md_entry) group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_TRADING_SESSION_HIGH_PRICE)) message.addGroup(group_md_entry) group_md_entry.setField(fix.MDEntryType(fix.MDEntryType_TRADING_SESSION_LOW_PRICE)) message.addGroup(group_md_entry) group_symbol = fix42.MarketDataRequest().NoRelatedSym() group_symbol.setField(fix.Symbol(symbol)) message.addGroup(group_symbol) # Send Fix Message to Server fix.Session.sendToTarget(message, self.fix_application.sessionID) return
def fromApp(self, message, sessionID): print('::::fromApp called::::') conn = sqlite3.connect('rtmd.db') c = conn.cursor() c.execute(''' create table if not exists ask( orderId text primary key unique, price int, quantity int, company text, exchange text, time text ); ''') c.execute(''' create table if not exists bid( orderId text primary key unique, price int, quantity int, company text, exchange text, time text ); ''') class order: def __init__(self, id, price, type, qty, company, exchg, time): self.id = id self.price = price self.type = type self.qty = qty self.company = company self.exchg = exchg self.time = time group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() #orderList = [] #to store each order entry sent in an object of <class 'order'> in order to send to UI team orderID = fix.OrderID() #represents orderID MDEntryType = fix.MDEntryType() NumberOfOrders = fix.NumberOfOrders() #represents quantity MDEntryPx = fix.MDEntryPx() #represents the price MDEntrySeller = fix.MDEntrySeller() #represents company MDMkt = fix.MDMkt() #represents exchange #MDEntrytime = fix.MDEntryTime() #represents time noMDEntries = fix.NoMDEntries( ) #get the total number of groups in snapshot message.getField(noMDEntries) tag, numberOfGroups = str(noMDEntries).split('=') numberOfGroups = numberOfGroups[:-1] numberOfGroups = int(numberOfGroups) for i in range(1, numberOfGroups + 1): message.getGroup(i, group) tag, type = str(group.getField(MDEntryType)).split( '=') #storing order type in var 'type' type = type[:-1] #to ignore the last special character tag, price = str(group.getField(MDEntryPx)).split('=') price = price[:-1] tag, id = str(group.getField(orderID)).split('=') id = id[:-1] tag, qty = str(group.getField(NumberOfOrders)).split('=') qty = qty[:-1] tag, company = str(group.getField(MDEntrySeller)).split('=') company = company[:-1] tag, exchg = str(group.getField(MDMkt)).split('=') exchg = exchg[:-1] # tag, time = str(group.getField(MDEntrytime)).split('=') # time = time[:-1] time = '2020-06-12 15:02:30' orderc = order(id, price, type, qty, company, exchg, time) print(orderc.id, orderc.price, orderc.qty, orderc.company, orderc.exchg, end=' ') print(' :: will be put in table ' + str(orderc.type)) params = (orderc.id, orderc.price, orderc.qty, orderc.company, orderc.exchg, orderc.time) if (orderc.type == '0'): c.execute("insert or ignore into ask values(?, ?, ?, ?, ?, ?)", params) elif (orderc.type == '1'): c.execute("insert or ignore into bid values(?, ?, ?, ?, ?, ?)", params) print('ask table has: ') for row in c.execute("select * from ask"): print(row) print() print('bid table has: ') for row in c.execute("select * from bid"): print(row) conn.commit() conn.close() return
def onMessage(self, message, sessionID): print("OnMessage %s" % message) msgType = fix.MsgType() message.getHeader().getField(msgType) if (msgType.getValue() == "X"): print("MarketDataIncrementalRefresh %s" % message) noMDEntries = fix.NoMDEntries() message.getField(noMDEntries) if (noMDEntries.getValue() != 1): print("NoMDEntries in MarketDataIncrementalRefresh is not 1!") return group = fix44.MarketDataIncrementalRefresh.NoMDEntries() message.getGroup(1, group) entryID = fix.MDEntryID() group.getField(entryID) action = fix.MDUpdateAction() group.getField(action) actionvalue = action.getValue() # 0=New, 1=Update, 2=Delete) if (actionvalue == '2'): # delete if entryID.getValue() in securities: del securities[entryID.getValue()] return security = SECURITY() security.MDEntryID = entryID.getValue() security.MDUpdateAction = action.getValue() symbol = fix.Symbol() if (group.isSetField(symbol)): group.getField(symbol) security.Symbol = symbol.getValue() entryType = fix.MDEntryType() if (group.isSetField(entryType)): group.getField(entryType) security.MDEntryType = entryType.getValue() price = fix.MDEntryPx() if (group.isSetField(price)): group.getField(price) security.MDEntryPx = price.getValue() size = fix.MDEntrySize() if (group.isSetField(size)): group.getField(size) security.MDEntrySize = size.getValue() qty = fix.MinQty() if (group.isSetField(qty)): group.getField(qty) security.MinQty = qty.getValue() inc = MinInc() if (message.isSetField(inc)): message.getField(inc) security.MinInc = inc.getValue() br = MinBr() if (message.isSetField(br)): message.getField(br) security.MinBR = br.getValue() ytm = YTM() if (message.isSetField(ytm)): message.getField(ytm) security.YTM = ytm.getValue() ytw = YTW() if (message.isSetField(ytw)): message.getField(ytw) security.YTW = ytw.getValue() print(security) securities[entryID.getValue()] = security
def run(self): message = fix44.MarketDataSnapshotFullRefresh() group = fix44.MarketDataSnapshotFullRefresh().NoMDEntries() group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(12.32)) group.setField(fix.MDEntrySize(100)) group.setField(fix.OrderID("ORDERID")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('RIL')) group.setField(fix.MDMkt('BSE')) #group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(12.32)) group.setField(fix.MDEntrySize(100)) group.setField(fix.OrderID("ORDERID")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('RIL')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(12.34)) group.setField(fix.MDEntrySize(104)) group.setField(fix.OrderID("ORDERID2")) group.setField(fix.NumberOfOrders(9087)) group.setField(fix.MDEntrySeller('BHEL')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(12.34)) group.setField(fix.MDEntrySize(104)) group.setField(fix.OrderID("ORDERID2")) group.setField(fix.NumberOfOrders(9087)) group.setField(fix.MDEntrySeller('BHEL')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(18.92)) group.setField(fix.MDEntrySize(2000)) group.setField(fix.OrderID("ORDERID3")) group.setField(fix.NumberOfOrders(10050)) group.setField(fix.MDEntrySeller('TCS')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(200.32)) group.setField(fix.MDEntrySize(1006)) group.setField(fix.OrderID("ORDERID4")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('Credit Suisse')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('0')) group.setField(fix.MDEntryPx(1000)) group.setField(fix.MDEntrySize(100)) group.setField(fix.OrderID("ORDERID6")) group.setField(fix.NumberOfOrders(1000)) group.setField(fix.MDEntrySeller('Aramco')) group.setField(fix.MDMkt('BSE')) # group.setField(fix.MDEntryTime(20200723)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(12.67)) group.setField(fix.MDEntrySize(1045)) group.setField(fix.OrderID("ORDERID7")) group.setField(fix.NumberOfOrders(8960)) group.setField(fix.MDEntrySeller('Zomato')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(129)) group.setField(fix.MDEntrySize(10894)) group.setField(fix.OrderID("ORDERID8")) group.setField(fix.NumberOfOrders(9076)) group.setField(fix.MDEntrySeller('Gilbarco')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) group.setField(fix.MDEntryType('1')) group.setField(fix.MDEntryPx(198)) group.setField(fix.MDEntrySize(1034)) group.setField(fix.OrderID("ORDERID9")) group.setField(fix.NumberOfOrders(9087)) group.setField(fix.MDEntrySeller('Huwawei')) group.setField(fix.MDMkt('NSE')) # group.setField(fix.MDEntryTime(20200429)) message.addGroup(group) fix.Session_sendToTarget(message, self.sessionID) return
def onMessage_MarketDataSnapshotFullRefresh(self): """ onMessage - Market Data - Snapshot / Full Refresh Message Type = 'W'. The Market Data Snapshot/Full Refresh messages are sent as the response to a Market Data Request message. The message refers to only one Market Data Request. It will contain the appropiate MDReqID tag value to correlate the request with the response. Fields: - (35) MsgType = W - (262) MDReqID = (string) - Block Instrument: - (55) Symbol = (string - Ticker) - Block MDfullGrp: - (268) NoMDEntries = (Int - number of Entries) - (269) MDEntryType = 0 (Bid) / 1 (Offer) / 2 (Trade) / 4 (Opening price) / 5 (Closing Price) / 6 (Settlement Price) / 7 (Trading Session High Price) / 8 (Trading Session Low Price) / B (Trade Volume) / C (Open Interest) / x (Nominal Volume) / w (Cash Volume) - (270) MDEntryPx = (float - Conditional field when MDEntryType is 0-1-2-4-5-6-7-8-w) - (271) MDEntrySize = (int - Conditional field when MDEntryType is 0-1-2-B-C-x) - (290) MDEntryPositionNo = (int) """ data = {} ## Number of entries following (Bid, Offer, etc) noMDEntries = self.getValue(fix.NoMDEntries()) symbol = self.getValue(fix.Symbol()) ## Market ID (ROFX, BYMA) marketId = self.getValue(fix.SecurityExchange()) instrumentId = {"symbol": symbol, "marketId": marketId} data["instrumentId"] = instrumentId data["marketData"] = {"BI": [], "OF": []} group = fix50.MarketDataSnapshotFullRefresh().NoMDEntries() MDEntryType = fix.MDEntryType( ) # Identifies the type of entry (Bid, Offer, etc) MDEntryPx = fix.MDEntryPx() MDEntrySize = fix.MDEntrySize() MDEntryPositionNo = fix.MDEntryPositionNo( ) # Display position of a bid or offer, numbered from most competitive to least competitive """ table = texttable.Texttable() table.set_deco(texttable.Texttable.BORDER|texttable.Texttable.HEADER) table.header(['Ticker','Tipo','Precio','Size','Posicion']) table.set_cols_width([12,20,8,8,8]) table.set_cols_align(['c','c','c','c','c']) """ for entry in range(1, int(noMDEntries) + 1): try: md = {} price, size, position = None, None, None self.message.getGroup(entry, group) entry_type = group.getField(MDEntryType).getString() if entry_type in list('01245678w'): # campos que tienen precio price = group.getField(MDEntryPx).getString() md['price'] = float(price) if entry_type in list('012BCx'): # campos que tienen size size = group.getField(MDEntrySize).getString() md['size'] = int(size) if entry_type in list('01'): # campos que tienen orden position = group.getField(MDEntryPositionNo).getString() md['position'] = int(position) if entry_type == '0': data["marketData"]["BI"].append(md) tipo = 'BID' elif entry_type == '1': data["marketData"]["OF"].append(md) tipo = 'OFFER' elif entry_type == 'B': data["marketData"]["TV"] = md tipo = 'TRADE VOLUME' else: tipo = entry_type # table.add_row([symbol, tipo, price, size, position]) except: pass # Aca antes de devolver se puede mandar a una cola o algo return data
def onMessage(self, message, sessionID): # print("OnMessage %s" % message) msgType = fix.MsgType() message.getHeader().getField(msgType) if msgType.getValue() == "X": # print("MarketDataIncrementalRefresh %s" % message) noMDEntries = fix.NoMDEntries() message.getField(noMDEntries) if (noMDEntries.getValue() != 1): # print("NoMDEntries in MarketDataIncrementalRefresh is not 1!") return group = fix44.MarketDataIncrementalRefresh.NoMDEntries() message.getGroup(1, group) entryID = fix.MDEntryID() group.getField(entryID) action = fix.MDUpdateAction() group.getField(action) security = LAST_TRADE() security.MDEntryID = entryID.getValue() security.MDUpdateAction = action.getValue() symbol = fix.Symbol() if (group.isSetField(symbol)): group.getField(symbol) security.Symbol = symbol.getValue() entryType = fix.MDEntryType() if (group.isSetField(entryType)): group.getField(entryType) security.MDEntryType = entryType.getValue() price = fix.MDEntryPx() if (group.isSetField(price)): group.getField(price) security.MDEntryPx = price.getValue() size = fix.MDEntrySize() if (group.isSetField(size)): group.getField(size) security.MDEntrySize = size.getValue() qty = fix.MinQty() if (group.isSetField(qty)): group.getField(qty) security.MinQty = qty.getValue() fire(self.callback, "OnTradeUpdated", **{"trade": security}) if msgType.getValue() == 'W': book = BOOK() Symbol = fix.Symbol() message.getField(Symbol) book.symbol = Symbol.getValue() noMDEntries = fix.NoMDEntries() message.getField(noMDEntries) group = fix44.MarketDataSnapshotFullRefresh.NoMDEntries() MDEntryType = fix.MDEntryType() MDEntryPx = fix.MDEntryPx() MDEntrySize = fix.MDEntrySize() for i in range(1, noMDEntries.getValue()): message.getGroup(i, group) group.getField(MDEntryType) group.getField(MDEntryPx) group.getField(MDEntrySize) if MDEntryType.getValue() == '0': book.bid.append(MDEntryPx.getValue()) book.bid_size.append(MDEntrySize.getValue()) if MDEntryType.getValue() == '1': book.ask.append(MDEntryPx.getValue()) book.ask_size.append(MDEntrySize.getValue()) fire(self.callback, "OnBookUpdated", **{"book": book})