Skip to content

himoacs/market-data-simulator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

market-data-simulator

market-data-simulator is a lightweight application designed to connect to an event broker via JMS (Solace PubSub+, free) and publish sample market (pricing) data (L1 quotes and trades) for securities. It can be extremely difficult to get market data for free, especially real-time market data. And when you do get it, it is usually throttled for the free tier. market-data-simulator is meant to be used as a building block for interesting financial applications such as P&L calculator, TCA application, Portfolio analysis amongst others.

So, what does it do?

market-data-simulator publishes market data for securities in JSON format. Here are two published messages for AAPL and IBM:

{
"symbol":"AAPL",
"askPrice":250.3121,
"bidSize":630,
"tradeSize":180,
"exchange":"NASDAQ",
"currency":"USD",
"tradePrice":249.9996,
"askSize":140,
"bidPrice":249.6871,
"date":"2020-03-23",
"time":"09:32:10.610764-04:00"
}

{
"symbol":"IBM",
"askPrice":101.0025,
"bidSize":720,
"tradeSize":490,
"exchange":"NYSE",
"currency":"USD",
"tradePrice":100.5,
"askSize":340,
"bidPrice":99.9975,
"date":"2020-03-23",
"time":"09:32:09.609035-04:00"
}

The data is published to a topic of this structure:

<assetClass>/marketData/v1/<country>/<exchange>/<name>

In the example above, data would be published to:

EQ/marketData/v1/US/NASDAQ/AAPL

This specific topic hierarchy is used to take full advantage of Solace PubSub+'s rich hierarchical topics which provide strong wildcard support and advance filtering logic. You can read more about that here.

Generating random data

I mostly focused on randomizing three values: askPrice, bidPrice, and tradePrice. Instead of publishing quotes data separately from trade data, I choose to combine the two for the sake of simplicity because each trade corresponds to available quotes at that given time and it is much easier to keep track of quotes and trades data if they are generated together.

The random prices generated by market-data-simulator are constrained by: bidPrice < tradePrice < askPrice. This logic makes sure that we don't encounter crossed markets where bidPrice > askPrice.

All new prices are simply slightly modified versions of the previous prices to make sure we don't get random prices that don't make sense. For example, AAPL's stock should not be worth $100 today and $500 tomorrow (because that would be crazy!).

I haven't put many constraints on sizes (askSize, bidSize, and tradeSize). If that's a requirement for your use-case, feel free to make changes.

You can find the exact logic I used to generate these random values in generatePriceAndSize method in Stock.java class.

Configurations

There are two main configurations file:

  • src/main/resources/broker.yaml
  • src/main/resources/securities.yaml

broker.yaml contains connection properties for your event broker. You need to populate the necessary fields with your specific broker properties. Those fields are: host, vpn, user, and password.

In my case, I am using free service on Solace Cloud which lets me quickly sping up a broker on AWS. Here are step-by-step instructions on how to create your own service and find connection details. This is what my sample broker.yaml file looks like:

host: <unique_host_name>:55555  
vpn: <vpn_name>  
user: <username> 
pass: <password>

securities.yaml file contains useful information about securities for which you would like to generate sample market data. Usually, in companies, you would have a separate team which stores and maintains all this data for all the securities that your company is interested in. However, in our case, we need to provide this ourselves. For now, you need to provide: name, exchange, assetClass, currency, lastTradePrice, lastAskPrice, and lastBidPrice.

exchange, assetClass and currency data is used to provide some context about the security. Which exchange does this security primarily trade on? Which asset class (EQ, FX etc) does it belong to? Which currency are the prices quoted in? Exchange information is used to link securities to exchanges and their corresponding market hours so that we only publish data when the markets are open. For example, US equities data will only be published from 09:30am to 04:00pm. In future, I would like to add support for other asset classes as well, which is why I added the assetClass property.

If you would like to add support for a new Exchange besides the ones that are currently there by default (NYSE, NASDAQ, LSE, and SGX), you would need to create a new class for each exchange (i.e. TSX.java) and invoke super Exchange.java class with the necessary information such as name, country, timezone, openTime and closeTime.

lastTradePrice, lastAskPrice, and lastBidPrice are all used to provide baseline for random prices which will be generated. You can enter whatever values you like here but to be a bit realistic, it is recommended that you use last values for this fields. The code will generate random askPrice and bidPrice and a tradePrice that falls between those two values (no crossed markets here ).

Receiving data

Purpose of market-data-simulator is to only publish market data. However, for testing purposes, I have included code for a simple subscriber in SampleConsumer.java which will subscribe to a given topic and print out any messages being published to that topic.

To set the topic, modify this line: final String TOPIC_NAME = "*/US/>";

Note: You can use Solace's powerful wildcards when specifying the topic which allows you to abstract away multiple levels and apply filtering. Here are some examples:

  • EQ/> - to subscribe to all equities
  • */*/*/*/NYSE/> - to subscribe to all NYSE securities
  • EQ/marketData/v1/US/> - to subscribe to all US equities

You can learn more about Solace's wildcards here.

Getting Started

So how do you get started with this code? Follow these simple steps:

  1. Clone the repo locally
  2. Spin up an instance of PubSub+ broker
  3. Update broker.yaml with your connection settings
  4. [Optional] Update securities.yaml with the securities you want to publish sample data for and their corresponding last (trade/ask/bid) prices.
  5. Run Main.java and watch data flow (if you have Docker installed the following is an example of building/running the sim from code stored in C:\Development\market-data-simulator - docker run -it -v C:\Development\market-data-simulator:/source --rm maven:3.6.3-openjdk-14-slim /bin/bash -c "cd /source;mvn clean;mvn compile;mvn exec:java -Dexec.mainClass=com.marketdatasimulator.Main"). Note that data will only be published during market hours.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages