<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.spiretrading.com/index.php?action=history&amp;feed=atom&amp;title=Market_Data_Server</id>
	<title>Market Data Server - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.spiretrading.com/index.php?action=history&amp;feed=atom&amp;title=Market_Data_Server"/>
	<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Market_Data_Server&amp;action=history"/>
	<updated>2026-04-07T13:00:42Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>https://wiki.spiretrading.com/index.php?title=Market_Data_Server&amp;diff=239&amp;oldid=prev</id>
		<title>Kamal: Created page with &quot;= Market Data Server = The Market Data Server receives market data from feed clients, organizes and persists the data, and provides query and subscription services to clients....&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.spiretrading.com/index.php?title=Market_Data_Server&amp;diff=239&amp;oldid=prev"/>
		<updated>2025-12-01T22:09:49Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Market Data Server = The Market Data Server receives market data from feed clients, organizes and persists the data, and provides query and subscription services to clients....&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Market Data Server =&lt;br /&gt;
The Market Data Server receives market data from feed clients, organizes and persists the data, and provides query and subscription services to clients. It maintains real-time market data snapshots for each security, tracks security technicals (open, high, low, close, volume), and sequences all market data updates to ensure consistent ordering across the system. The server supports multiple market data types including best bid/offer quotes, book quotes, time and sales, and order imbalances.&lt;br /&gt;
&lt;br /&gt;
The Market Data Server integrates with the Service Locator for authentication and a MySQL database for historical data storage. It operates as two distinct services: a registry server for managing security metadata and subscriptions, and a feed server for receiving and distributing market data updates.&lt;br /&gt;
&lt;br /&gt;
== Configuration ==&lt;br /&gt;
The Market Data Server is configured via a YAML file that defines network interfaces for both services, database connection, and Service Locator integration. Below is the structure of the configuration file with example values:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
---&lt;br /&gt;
registry_server:&lt;br /&gt;
  # Primary network interface and port the Market Data Registry Server binds to.&lt;br /&gt;
  interface: &amp;quot;0.0.0.0:20300&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  # List of addresses the registry server is reachable at (for registration with Service Locator).&lt;br /&gt;
  addresses: [&amp;quot;198.51.100.5:20300&amp;quot;, &amp;quot;10.0.0.5:20300&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
feed_server:&lt;br /&gt;
  # Primary network interface and port the Market Data Feed Server binds to.&lt;br /&gt;
  interface: &amp;quot;0.0.0.0:20400&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  # List of addresses the feed server is reachable at (for registration with Service Locator).&lt;br /&gt;
  addresses: [&amp;quot;198.51.100.5:20400&amp;quot;, &amp;quot;10.0.0.5:20400&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
data_store:&lt;br /&gt;
  # The address of the MySQL server (host:port).&lt;br /&gt;
  address: &amp;quot;127.0.0.1:3306&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  # The username for authenticating with MySQL.&lt;br /&gt;
  username: spireadmin&lt;br /&gt;
  &lt;br /&gt;
  # The password for the MySQL user.&lt;br /&gt;
  password: 1234&lt;br /&gt;
  &lt;br /&gt;
  # The name of the database schema where data is stored.&lt;br /&gt;
  schema: spire&lt;br /&gt;
&lt;br /&gt;
# Countries for which market data is supported.&lt;br /&gt;
countries:&lt;br /&gt;
  - AU&lt;br /&gt;
  - CA&lt;br /&gt;
  - HK&lt;br /&gt;
  - JP&lt;br /&gt;
  - US&lt;br /&gt;
&lt;br /&gt;
service_locator:&lt;br /&gt;
  # The address of the Service Locator (host:port).&lt;br /&gt;
  address: &amp;quot;10.0.0.5:20000&amp;quot;&lt;br /&gt;
  &lt;br /&gt;
  # The account username used by the Market Data Server to authenticate with the Service Locator.&lt;br /&gt;
  username: market_data_service&lt;br /&gt;
  &lt;br /&gt;
  # The password for the Market Data Server's Service Locator account.&lt;br /&gt;
  password: admin_password&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Functionality ==&lt;br /&gt;
&lt;br /&gt;
=== Market Data Types ===&lt;br /&gt;
The server processes and distributes the following market data types:&lt;br /&gt;
&lt;br /&gt;
* '''BBO Quotes''' (Best Bid/Offer) - Top-of-book bid and ask prices with sizes&lt;br /&gt;
* '''Book Quotes''' - Full order book depth with multiple price levels per side&lt;br /&gt;
* '''Time and Sales''' - Executed trade prices, sizes, and timestamps&lt;br /&gt;
* '''Order Imbalances''' - Pre-opening and closing auction imbalance data&lt;br /&gt;
&lt;br /&gt;
=== Security Tracking ===&lt;br /&gt;
For each security, the server maintains:&lt;br /&gt;
&lt;br /&gt;
* Real-time market data snapshots combining BBO, book depth, and last trade&lt;br /&gt;
* Security technicals including open, high, low, close, and volume&lt;br /&gt;
* Sequence numbers ensuring consistent ordering of market data updates&lt;br /&gt;
* Source tracking to identify which feed client published each data point&lt;br /&gt;
&lt;br /&gt;
=== Data Sequencing ===&lt;br /&gt;
All market data updates are assigned monotonically increasing sequence numbers per security and data type. This ensures clients can detect gaps, maintain consistent ordering, and synchronize state reliably.&lt;br /&gt;
&lt;br /&gt;
=== Historical Data Storage ===&lt;br /&gt;
Market data is persisted to MySQL with indexed queries supporting:&lt;br /&gt;
&lt;br /&gt;
* Time range queries by security or venue&lt;br /&gt;
* Snapshot queries for initial state loading&lt;br /&gt;
* Efficient storage of high-frequency data streams&lt;br /&gt;
&lt;br /&gt;
== Utility Scripts ==&lt;br /&gt;
&lt;br /&gt;
=== add_security_info.py ===&lt;br /&gt;
A utility script to add or update security metadata in the system:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python add_security_info.py&lt;br /&gt;
  --config config.yml       # Configuration file&lt;br /&gt;
  --symbol AAPL.NASDAQ      # Ticker symbol&lt;br /&gt;
  --name &amp;quot;Apple Inc.&amp;quot;       # Display name&lt;br /&gt;
  --sector Technology       # Sector (optional)&lt;br /&gt;
  --board_lot 100          # Board lot size&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== dump_data_store.py ===&lt;br /&gt;
A backup and restore utility supporting bidirectional data transfer between MySQL and SQLite:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python dump_data_store.py&lt;br /&gt;
  --config config.yml              # Configuration file&lt;br /&gt;
  --start &amp;quot;2024-01-01 00:00:00&amp;quot;   # Start time range&lt;br /&gt;
  --end &amp;quot;2024-12-31 23:59:59&amp;quot;     # End time range&lt;br /&gt;
  --output backup.db               # Export MySQL to SQLite&lt;br /&gt;
  --cores 8                        # Number of parallel workers&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or to restore from SQLite to MySQL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python dump_data_store.py&lt;br /&gt;
  --config config.yml&lt;br /&gt;
  --start &amp;quot;2024-01-01 00:00:00&amp;quot;&lt;br /&gt;
  --end &amp;quot;2024-12-31 23:59:59&amp;quot;&lt;br /&gt;
  --input backup.db&lt;br /&gt;
  --cores 8&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The script uses multiprocessing to efficiently backup or restore large datasets across multiple securities and venues in parallel.&lt;br /&gt;
&lt;br /&gt;
== Installation &amp;amp; Setup ==&lt;br /&gt;
A &amp;lt;code&amp;gt;setup.py&amp;lt;/code&amp;gt; script is provided to generate the final &amp;lt;code&amp;gt;config.yml&amp;lt;/code&amp;gt; from the &amp;lt;code&amp;gt;config.default.yml&amp;lt;/code&amp;gt; template.&lt;br /&gt;
&lt;br /&gt;
The script supports the following arguments:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python setup.py&lt;br /&gt;
  --local 0.0.0.0           # Local interface (default: auto-detected IP)&lt;br /&gt;
  --world 198.51.100.5      # Global/public interface (optional)&lt;br /&gt;
  --address 10.0.0.5:20000  # Service Locator address (default: local_interface:20000)&lt;br /&gt;
  --password [REQUIRED]     # Service password for authentication&lt;br /&gt;
  --mysql_address 127.0.0.1:3306  # MySQL server address&lt;br /&gt;
  --mysql_username spireadmin     # MySQL username&lt;br /&gt;
  --mysql_password secretpw       # MySQL password (default: --password if omitted)&lt;br /&gt;
  --mysql_schema spire            # MySQL schema&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Operations ==&lt;br /&gt;
The Market Data Server is controlled using three operational scripts: &amp;lt;code&amp;gt;start.sh&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;stop.sh&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;check.sh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Log files are generated in the format:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
srv_YYYYMMDD_HH_MM_SS.log&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon startup, older log files are moved into the &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; directory.&lt;br /&gt;
&lt;br /&gt;
=== check.sh ===&lt;br /&gt;
The &amp;lt;code&amp;gt;check.sh&amp;lt;/code&amp;gt; script verifies whether the server is currently running by inspecting the PID recorded in &amp;lt;code&amp;gt;pid.lock&amp;lt;/code&amp;gt; and testing whether the associated process exists.&lt;br /&gt;
&lt;br /&gt;
If the server is not running, it prints:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
MarketDataServer is not running.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== start.sh ===&lt;br /&gt;
The &amp;lt;code&amp;gt;start.sh&amp;lt;/code&amp;gt; script:&lt;br /&gt;
* Exits immediately if the server is already running&lt;br /&gt;
* Creates a &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt; directory if necessary&lt;br /&gt;
* Moves any existing &amp;lt;code&amp;gt;srv_*.log&amp;lt;/code&amp;gt; files into &amp;lt;code&amp;gt;logs/&amp;lt;/code&amp;gt;&lt;br /&gt;
* Starts the &amp;lt;code&amp;gt;MarketDataServer&amp;lt;/code&amp;gt; process in the background&lt;br /&gt;
* Writes the PID to &amp;lt;code&amp;gt;pid.lock&amp;lt;/code&amp;gt;&lt;br /&gt;
* Reads network interfaces from &amp;lt;code&amp;gt;config.yml&amp;lt;/code&amp;gt; and waits until the server is listening on at least one configured address&lt;br /&gt;
&lt;br /&gt;
This ensures the server is fully initialized before the script exits.&lt;br /&gt;
&lt;br /&gt;
=== stop.sh ===&lt;br /&gt;
The &amp;lt;code&amp;gt;stop.sh&amp;lt;/code&amp;gt; script:&lt;br /&gt;
* Reads the PID from &amp;lt;code&amp;gt;pid.lock&amp;lt;/code&amp;gt;&lt;br /&gt;
* Sends &amp;lt;code&amp;gt;SIGINT&amp;lt;/code&amp;gt; to request a graceful shutdown&lt;br /&gt;
* Waits for termination using exponential backoff (up to 300 seconds)&lt;br /&gt;
* Sends &amp;lt;code&amp;gt;SIGKILL&amp;lt;/code&amp;gt; if the server fails to stop cleanly&lt;br /&gt;
* Appends a forced-termination message to the most recent log file (if applicable)&lt;br /&gt;
* Removes the &amp;lt;code&amp;gt;pid.lock&amp;lt;/code&amp;gt; file&lt;br /&gt;
&lt;br /&gt;
This guarantees consistent shutdown behavior across normal and exceptional conditions.&lt;/div&gt;</summary>
		<author><name>Kamal</name></author>
		
	</entry>
</feed>