Price updates

The role of the initiator is to start a connection with the acceptor. When the connection is established, the initiator will subscribe to the acceptor and request price updates. The first function we will review is the function to subscribe. This function will be called once the connection is established.

The subscribe function will be called after fixed intervals. When this function is called, we need to check whether there is an active session. It will build the market data request by iterating through the list of symbols. Let's have a look at the following code block:

8=FIX.4.4|9=78|35=V|146=1|55=USD/RUB|460=4|167=FOR|262=2|263=1|264=0|265=0|267=2|269=0|269=0|10=222|

As we can see, the message will have a message type of 35=V. The tags and their corresponding fields and values have been listed in the following table:

Tag

Field

Value

8

BeginString

FIX.4.4

9

BodyLength

78

35

MsgType

V

146

NoRelatedSym

1

55

Symbol

USD/RUB

460

Product

4

167

SecurityType

FOR

262

MDReqID

2

263

SubscriptionRequestType

1

264

MarketDepth

0

265

MDUpdateType

0

267

NoMDEntryTypes

2

269

MDEntryType

0

269

MDEntryType

1

10

CheckSum

222

 

We can see the following in the preceding table:

  • For each symbol (the ticker you would like to trade), this function will create a new market data request message.
  • Each market data request must have a unique identifier (Market Data Request ID, that is, MDReqID) that's associated with a given symbol. In the following example, we use USD/RUB:
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_OFFER))
message.addGroup(group)

self.sendToTarget(message, self.marketSession)

We can see the following in the preceding code:

  • Once we subscribe to all the desired symbols (in this example, currency pairs), the acceptor will start sending market updates.
  • The onMarketDataSnapshotFullRefresh function will receive the full snapshot of every price update coming into the system.

The type of message that's received by the price update gateway is as follows:

8=FIX.4.4|9=429|35=W|34=1781|49=FIXSIM-SERVER-MKD|52=20190909-19:31:48.011|56=FIXSIM-CLIENT-MKD|55=EUR/USD|262=74|268=4|269=0|270=6.512|15=EUR|271=2000|276=A|299=a23de46d-6309-4783-a880-80d6a02c6140|269=0|270=5.1|15=EUR|271=5000|276=A|299=1f551637-20e5-4d8b-85d9-1870fd49e7e7|269=1|270=6.512|15=EUR|271=2000|276=A|299=445cb24b-8f94-47dc-9132-75f4c09ba216|269=1|270=9.49999999999999|15=EUR|271=5000|276=A|299=3ba6f03c-131d-4227-b4fb-bd377249f50f|10=001|

This function is a callback. It is called when a Full Snapshot message is received and parsed. The message parameter will contain the message. Let's have a look at the code:

def onMarketDataSnapshotFullRefresh(self, message, sessionID):

fix_symbol = quickfix.Symbol()
message.getField(fix_symbol)
symbol = fix_symbol.getValue()

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()

As we can see, we can access the field by using the getField method.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.218.209.8