The MarketData solution is a distributed system for simulating, generating, and visualizing real-time market price data. It demonstrates modern .NET development practices including gRPC streaming, background services, WPF data visualization, and hot-reloadable configuration.
My motivations were to show off my skills in API design and WPF in a fintech system. It is purely a hobby project.
I first wanted to create a small application that could stream market data, and another application that could "book" (fake) trades based on that data. After soon realizing that market data would come at some expense I decided to start simulating that data. I implemented some basic models. Going forward, there is a lot that can be done to get this into a scalable tool with plugins. Key areas of growth on server-side includes adding new simulation models, splitting behemouth PriceGenerator service into distributed Generate Price -> Enrich (e.g. static data) -> post to API consumers & update database. Other future featues include moving to a more sophisticated RDBMS and eventually being able to trade on the data in a separate app.
This repository is open to contributors - please get in touch via the GitHub Issues tab or email marketdata.oss.szigh@gmail.com !
Jonas
| Component | Technology |
|---|---|
| Backend Framework | ASP.NET Core 10.0 |
| Client Framework | WPF (.NET 10 Windows) |
| RPC Framework | gRPC |
| Database | SQLite with Entity Framework Core |
| ORM | Entity Framework Core 10.0 |
| Logging | Serilog with Seq |
| Charting | FancyCandles 2.7.1 |
| API Documentation | OpenAPI with Scalar |
| Background Processing | IHostedService |
| Dependency Injection | Microsoft.Extensions.DependencyInjection |
* To be implemented
Type: ASP.NET Core Web API with gRPC
Framework: .NET 10
Key Technologies: Entity Framework Core, gRPC, SQLite
Purpose:
The core backend service that generates and streams real-time market data to clients.
Key Components:
- Background Service:
MarketDataGeneratorServicecontinuously generates price updates - gRPC Services:
MarketDataService- Streams real-time price updates to subscribersModelConfigurationGrpcService- Manages price simulation model configurations
- REST API: Controllers for instruments and prices (via OpenAPI/Scalar)
- Database: SQLite for persisting instruments, prices, and model configurations
- Model Management:
IInstrumentModelManagerfor configuration management via EF Core, including model parameters and instrument data (tick interval, active model) and adding new instruments
Key Features:
- Real-time price generation using multiple simulation models
- Hot reload of model configurations without service restart
- Per-instrument configurable tick intervals
- Streaming via gRPC for efficient real-time updates
- Persistent storage of price history
Dependencies:
MarketData.PriceSimulator- Price simulation algorithms
Type: WPF Desktop Application
Framework: .NET 10 Windows
Key Technologies: WPF MVVM, gRPC Client, FancyCandles (chart control)
Purpose:
Rich desktop client for visualizing market data with real-time candlestick charts and model configuration.
Key Components:
- ViewModels: MVVM pattern with
MainWindowViewModel,InstrumentViewModel(per tab/instrument, includes ticking prices and candle chart),ModelConfigViewModel(for editing model parameters) - Views: Multi-tab interface with candlestick charts and model configuration panels
- gRPC Client: Uses MarketData.Client.Grpc for Grpc services for price streaming and model configuration
- Chart Integration: FancyCandles library for professional candlestick visualization
- Model Configuration UI: Dynamic forms for editing simulation parameters
Key Features:
- Real-time candlestick charts with configurable timeframes
- Multi-instrument tabs
- Live model configuration editing with hot reload
- Visual representation of price simulation behavior
- Async initialization
Dependencies:
MarketData.Wpf.Shared- Shared WPF utilities (RelayCommand, ViewModelBase, behaviours, converters)MarketData.Client.Grpc- Shared gRPC services and configuration
Type: Class Library
Framework: .NET 10
Purpose:
Core price simulation engine with multiple mathematical models for generating realistic market data.
Price Simulation Models:
- RandomMultiplicativeProcess - Percentage-based random walk
- MeanRevertingProcess - Ornstein-Uhlenbeck mean reversion
- RandomAdditiveWalk - Configurable step-based walk with custom patterns
- Flat - Static pricing (for testing)
Key Interface:
public interface IPriceSimulator
{
Task<double> GenerateNextPrice(double price);
}Features:
- Each model implements
IPriceSimulatorfor polymorphic usage - Configurable parameters per model
- Stateless design (receives current price, returns next price)
- Used by both server and
FastSimulateproject
Type: Class Library
Framework: .NET 10 Windows
Purpose:
Shared WPF infrastructure components.
Contents:
ViewModelBase- Base class for MVVM view models with INotifyPropertyChangedRelayCommand- ICommand implementation for MVVM- Common WPF utilities
Type: Class Library
Framework: .NET 10
Purpose:
Shared configuration and service classes for gRPC clients.
Contents:
- Services:
IPriceService(for price streaming, historical prices),IModelConfigService(for model configuration management) GrpcConnectionInitialization- optional helper for initializing gRPC channel and clients which can help kick start the connection before attempting service calls.GrpcSettings- Configuration model for server URL binding
Dependencies:
- proto files from
MarketDataproject for gRPC service definitions
Type: Quick Testing Console App
Framework: .NET 10
Purpose:
Standalone console application for rapidly testing and visualizing price simulator behavior without the full server infrastructure.
Use Case:
Quick iteration and tuning of simulator parameters during development.
No future enhancements planned, soon to be deprecated and replaced with a more feature-rich console client in another repository
Type: Console Application
Framework: .NET 10
Purpose:
Lightweight console client for subscribing to market data streams. Useful for testing and demonstrations.
Key Features:
- Simple command-line interface
- Subscribe to multiple instruments
- Real-time console output of price updates
Dependencies:
MarketData.Client.Grpc- Shared gRPC services and configuration
[Timer Tick]
→ [MarketDataGeneratorService]
→ [IPriceSimulator.GenerateNextPrice()]
→ [New Price]
→ [SQLite DB]
→ [gRPC Broadcast]
→ [MarketData.Client.Grpc]
→ [Connected Clients]
[Client UI Change]
→ [gRPC ModelConfiguration.UpdateConfig()]
→ [InstrumentModelManager]
→ [Validate & Update DB]
→ [Raise ConfigurationChanged Event]
→ [MarketDataGeneratorService.HotReload()]
→ [New Simulator Instance]
[Client Connect]
→ [SubscribeToPrices(instruments)]
→ [Server Stream Setup]
→ [MarketDataGeneratorService.RegisterSubscriber]
→ [Continuous Price Updates via gRPC Stream]
All projects use constructor injection for loose coupling and testability.
IPriceSimulator allows swapping different price simulation algorithms at runtime.
PriceSimulatorFactorycreates appropriate simulators based on configurationInstrumentViewModelFactorycreates view models with proper dependencies
IInstrumentModelManager.ConfigurationChangedevent for hot reload- gRPC streaming for real-time price updates
WPF client strictly follows MVVM for separation of concerns and testability.
Entity Framework DbContext abstracts data access.
gRPC services are implemented in MarketData.Client.Grpc and client applications (e.g. WPF client) can consume these services for real-time price updates and model configuration management.
I will soon be implementing a console app that shows a minimal consumption of the gRPC services, but for now the WPF client is the main consumer. The long term goal is to have MarketData.Client.Grpc packaged and then you just need to configure the url, access token and register the services (IPriceService, IModelConfigService).
Proto: marketdata.proto
service MarketDataService {
rpc SubscribeToPrices (SubscribeRequest) returns (stream PriceUpdate);
rpc GetHistoricalData (HistoricalDataRequest) returns (HistoricalDataResponse);
}Purpose: Real-time price streaming and historical data retrieval
Proto: modelconfiguration.proto
service ModelConfigurationService {
rpc GetAllInstruments(GetAllInstrumentsRequest) returns (GetAllInstrumentsResponse);
rpc TryAddInstrument(TryAddInstrumentRequest) returns (TryAddInstrumentResponse);
rpc TryRemoveInstrument(TryRemoveInstrumentRequest) returns (TryRemoveInstrumentResponse);
rpc GetSupportedModels(GetSupportedModelsRequest) returns (SupportedModelsResponse);
rpc GetConfigurations(GetConfigurationsRequest) returns (ConfigurationsResponse);
rpc UpdateTickInterval(UpdateTickIntervalRequest) returns (UpdateConfigResponse);
rpc SwitchModel(SwitchModelRequest) returns (SwitchModelResponse);
rpc UpdateRandomMultiplicativeConfig(UpdateRandomMultiplicativeRequest) returns (UpdateConfigResponse);
rpc UpdateMeanRevertingConfig(UpdateMeanRevertingRequest) returns (UpdateConfigResponse);
rpc UpdateRandomAdditiveWalkConfig(UpdateRandomAdditiveWalkRequest) returns (UpdateConfigResponse);
}Purpose: Remote configuration management for price simulation models
Features:
- Get existing instruments and their configurations, add/remove instruments
- Switch active model per instrument
- Update model-specific parameters
- Update tick intervals
- Get existing instruments and add new instruments (including seeding database with initial price)
- Hot reload without reconnection
- Instruments - Market instruments (stocks, indices, etc.)
- Prices - Time-series price data
- RandomMultiplicativeConfig - Configuration for multiplicative random walk
- MeanRevertingConfig - Configuration for mean-reverting process
- FlatConfig - Configuration for flat pricing
- RandomAdditiveWalkConfig - Configuration for additive walk with steps
- Each
Instrumenthas one configuration per model type (one-to-one) Instrument.ModelTypedetermines active model- All configurations cascade delete with instrument
File: MarketData/appsettings.json
- Database connection string
MarketDataGeneratorOptions- Generator settings (including settings to throttle database/grpc publish if needed).- Kestrel endpoints for HTTP/HTTPS/gRPC
File: MarketData.Wpf.Client/appsettings.json / MarketData.Client/appsettings.json
GrpcSettings.ServerUrl- Server endpoint (default:https://localhost:7264)
-
Start the Server:
(from the root of the git repo)
dotnet run --project MarketData
Server runs on
https://localhost:7264(default)Optionally add
--seed-datato seed database with a sample instrument and model config (e.g. for first-time setup)dotnet run --project MarketData --seed-data
To test REST API, I have included Scalar for OpenAPI documentation and testing. This is hosted at
https://localhost:7264/scalar/v1by default. -
Start WPF Client:
dotnet run --project MarketData.Wpf.Client
- Logs are automatically logged to file, and additionally Seq (if it is running - see below secition on logging to see how to set up a Seq service in Docker)
- If running in WSL you may need to install the SDK, below is an example for Ubuntu
# Add Microsoft package repository wget https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb -O packages-microsoft-prod.deb sudo dpkg -i packages-microsoft-prod.deb rm packages-microsoft-prod.deb # Update and install sudo apt update sudo apt install -y dotnet-sdk-10.0 # Verify dotnet --version
cd MarketData
dotnet ef migrations add <MigrationName>
dotnet ef database updateNote: Migrations are automatically applied in development environment. In production this should be done in deployment.
- Create new class implementing
IPriceSimulatorinMarketData.PriceSimulator - Add configuration model to
MarketData/Models/ - Update
MarketDataContextwith new DbSet and relationship - Update
PriceSimulatorFactoryto handle new model - Add gRPC configuration methods to
ModelConfigurationGrpcService - Create WPF view for configuration in
MarketData.Wpf.Client/Views/ModelConfigs/
- Call
TryAddInstrumentwith new instrument name, tick interval and initial price, and optionally initial model type - Server creates new instrument, seeds initial price.
- If no configuration provided, defaults to
Flat(consthardcoded inInstrumentModelManager); otherwise, uses default parameters for the specified model type. - Event is raised, background service hot reloads, new price stream starts immediately.
- Insert into
Instrumentstable - Create initial price record
- Set desired
ModelTypeand create corresponding configuration - Set tick interval
- Restart server
- gRPC Streaming: Efficient binary protocol with HTTP/2 multiplexing
- Background Service: Asynchronous price generation prevents blocking
- Concurrent Dictionaries: Thread-safe price simulator management
- Entity Framework: AsNoTracking for read-only queries
- WPF Async: Proper async/await patterns prevent UI freezing
- Hot Reload: Individual instrument updates without full restart
- Server runs on HTTPS by default
- gRPC uses HTTP/2 with TLS
- No authentication currently implemented (suitable for local development)
See LOGGING.md
See TESTING.md
- Authentication and authorization
- Performance metrics and monitoring*
- Docker containerization
- Cloud deployment (Azure, AWS)
- Trade execution simulation
- Multi-user support with isolated workspaces
- More sophisticated simulation models (volatility clustering, jump processes)
* Part implemented with Serilog and Seq, OpenTelemetry is WIP: https://github.com/szigh/MarketData/tree/13-add-opentelemetry-for-metrics-and-monitoring
MarketData.Wpf.Client
├── MarketData.Wpf.Shared
├── MarketData.Client.Shared
└── (Proto files from MarketData)
MarketData.Client
├── MarketData.Client.Shared
└── (Proto files from MarketData)
MarketData
└── MarketData.PriceSimulator
FastSimulate
└── MarketData.PriceSimulator
MarketData.Wpf.Shared
└── (No dependencies)
MarketData.Client.Shared
└── (No dependencies)
MarketData.PriceSimulator
└── (No dependencies)
# Test Projects
MarketData.Tests
├── MarketData (project reference)
├── MarketData.PriceSimulator (project reference)
└── Testing Libraries (xUnit, Moq, EF InMemory, ASP.NET Testing)
MarketData.PriceSimulator.Tests
├── MarketData.PriceSimulator (project reference)
└── Testing Libraries (xUnit)
Resources:
Created: 2026
License: MIT
Type: Hobby Project / Portfolio Demonstration
Contact: marketdata.oss.szigh@gmail.com





