From c8d670a485be6b4edb15412d1aac769e7bd70d80 Mon Sep 17 00:00:00 2001 From: Ariel Silahian Date: Mon, 10 Aug 2026 10:36:29 -0400 Subject: [PATCH] docs: brand public README and correct architecture docs --- README.md | 106 ++++++++-------- assets/brand/visualhft-wordmark-dark.png | Bin 0 -> 8187 bytes assets/brand/visualhft-wordmark-light.png | Bin 0 -> 8379 bytes docs/architecture.md | 80 +++++++++---- docs/extending/README.md | 8 -- docs/system-architecture.html | 140 ++++++---------------- 6 files changed, 141 insertions(+), 193 deletions(-) create mode 100644 assets/brand/visualhft-wordmark-dark.png create mode 100644 assets/brand/visualhft-wordmark-light.png diff --git a/README.md b/README.md index c62c4e05..fe9e3ef5 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,46 @@ -# VisualHFT - -An open-source desktop application for real-time market microstructure analysis. - -[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-0D7C66?style=flat-square)](LICENSE.txt) -[![.NET 10](https://img.shields.io/badge/.NET-10-512BD4?style=flat-square)](https://dotnet.microsoft.com/download/dotnet/10.0) -![Windows](https://img.shields.io/badge/platform-Windows-0078D4?style=flat-square) -[![Discord](https://img.shields.io/badge/community-Discord-5865F2?style=flat-square&logo=discord&logoColor=white)](https://visualhft.com/discord) -[![GitHub Discussions](https://img.shields.io/badge/community-GitHub%20Discussions-24292F?style=flat-square&logo=github)](https://github.com/visualHFT/VisualHFT/discussions) +

+ + + + VisualHFT + +

+ +

+ An open-source desktop application for real-time market microstructure analysis. +

+ +

+ Website · + Documentation · + Discord · + Discussions +

+ +

+ License: Apache-2.0 + .NET 10 + Platform: Windows + Community: Discord +

![VisualHFT dashboard showing real-time Level 2 order book, liquidity, and market microstructure analytics](docImages/visualhft-hero-L2.gif) -[Quickstart](#quickstart) · [Write a plugin](#write-a-plugin) · [Architecture](docs/architecture.md) · [Changelog](CHANGELOG.md) · [Contributing](CONTRIBUTING.md) - -## What it is - -VisualHFT shows live order books and trades from supported venues in one desktop application. It gives traders, quants, and researchers a direct view of depth, liquidity, order flow, and market resilience while the market is moving. +

+ Quickstart · + Architecture · + Extend · + Changelog · + Contributing +

-## What you can see +## What it does -| Order book | Studies | Extensions | -| --- | --- | --- | -| Follow depth, trades, spreads, and venue conditions in one view. | Watch VPIN, LOB Imbalance, Market Resilience, and Order-to-Trade Ratio as conditions change. | Add a market connector or study for the data and measures you need. | +VisualHFT brings live order books and trades from supported venues into one desktop view. It helps traders, quants, and researchers examine depth, liquidity, order flow, and market resilience while conditions are changing. -![Full depth order-book view updating with live bid, ask, trade, and study data](docImages/LOB_fulldepth.gif) +| Live order book | Built-in study | +| --- | --- | +| ![Full depth order-book view updating with live bid, ask, trade, and study data](docImages/LOB_fulldepth.gif) | ![LOB Imbalance study visualising changes in order-book pressure](docImages/LOB_imbalances_2.gif) | ## Quickstart @@ -41,60 +59,34 @@ Open `VisualHFT/VisualHFT.sln` in Visual Studio and build the solution. Set `Vis Need help with setup? See [Troubleshooting](docs/troubleshooting.md) or ask in [Discord](https://visualhft.com/discord). -## Supported venues and studies +## Included in this repository -| Type | Included examples | +| Area | Included examples | | --- | --- | | Market data connectors | Binance, Bitfinex, Bitstamp, Coinbase, Gemini, Kraken, KuCoin, and a generic WebSocket connector | | Built-in studies | VPIN, LOB Imbalance, Market Resilience, and Order-to-Trade Ratio | +| Extensibility | Templates for additional market connectors and market-microstructure studies | -## What it does - -- Normalises live Level 2 order book and trade updates from supported connectors. -- Displays depth, trades, spreads, liquidity changes, and study outputs in one desktop view. -- Computes market microstructure metrics through included study plugins. -- Runs trigger conditions and sends alerts to the UI or REST endpoints. -- Supports additional connectors and studies without changes to the core application. +Connectors normalise live Level 2 order-book and trade updates for the dashboard and study plugins. Study outputs can also drive trigger conditions that send alerts to the user interface or configured REST endpoints. -## Screenshots +## Extend VisualHFT -
-Open the current dashboard views - -| Depth | Limit order book | -| --- | --- | -| ![Depth view](docImages/Aspose.Words.5b849bdf-d96d-4013-ad76-8c3daba3aead.004.png) | ![Limit order book view](docImages/Aspose.Words.5b849bdf-d96d-4013-ad76-8c3daba3aead.007.png) | - -
- -## How it works - -Connectors publish normalised market data to VisualHFT. The dashboard and study plugins read that data and update the live view. See the [architecture overview](docs/architecture.md) for the component map and data flow. - -## Write a plugin - -VisualHFT has two extension templates: +VisualHFT has templates and guides for two extension points: - [Market connector template](SDK-MarketConnectorTemplate/) for a new market-data source. - [Study template](SDK-StudyTemplate/) for a custom market-microstructure calculation. -Use the matching template and guide. Plugin authors should also review `RequiredLicenseLevel` before distributing a plugin. - -## Roadmap +Read the [architecture overview](docs/architecture.md) before extending the application. Use the matching template and guide before distributing a plugin. -See the [project roadmap](https://visualhft.com/#roadmap) for planned work. This README describes only functionality included in the public repository today. +## Community and updates -## Changelog +Ask questions in [Discord](https://visualhft.com/discord) or [GitHub Discussions](https://github.com/visualHFT/VisualHFT/discussions). Report bugs and feature requests through [GitHub Issues](https://github.com/visualHFT/VisualHFT/issues). -See [CHANGELOG.md](CHANGELOG.md) for changes by date. +Follow [VisualHFT Connect](https://visualhft.com/connect), [LinkedIn](https://www.linkedin.com/company/visualhft/), [X](https://x.com/visualHFT), and [Substack](https://visualhft.substack.com) for research and project updates. See [CONTRIBUTING.md](CONTRIBUTING.md) to contribute code or documentation. -## Community and contributing +## Roadmap and changes -- **Questions and live discussion:** [VisualHFT Discord](https://visualhft.com/discord) -- **Ideas and project discussion:** [GitHub Discussions](https://github.com/visualHFT/VisualHFT/discussions) -- **Bugs and feature requests:** [GitHub Issues](https://github.com/visualHFT/VisualHFT/issues) -- **Research and updates:** [VisualHFT Connect](https://visualhft.com/connect) -- **Code and documentation contributions:** [CONTRIBUTING.md](CONTRIBUTING.md) +See the [project roadmap](https://visualhft.com/#roadmap) for planned work and [CHANGELOG.md](CHANGELOG.md) for dated changes. This README describes functionality included in the public repository today. ## License diff --git a/assets/brand/visualhft-wordmark-dark.png b/assets/brand/visualhft-wordmark-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..31d6577451aa33329cc5c2401e5476eaf808f847 GIT binary patch literal 8187 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 z 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 literal 0 HcmV?d00001 diff --git a/assets/brand/visualhft-wordmark-light.png b/assets/brand/visualhft-wordmark-light.png new file mode 100644 index 0000000000000000000000000000000000000000..8529063722a2828b3006f8be052296c4ee19873b GIT binary patch literal 8379 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 S{03I>AtgC=*{bIj;r|D|zQ$Mp literal 0 HcmV?d00001 diff --git a/docs/architecture.md b/docs/architecture.md index e2192d35..c55f626b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,43 +1,73 @@ # Architecture overview -VisualHFT is a Windows desktop application built around a shared market-data layer and independently loadable plugins. - -```text -Market connector plugins - ↓ -Normalised OrderBook and Trade models - ↓ -Shared helper services - ↓ -Dashboard and study plugins - ↓ -Charts, metrics, triggers, and alerts +VisualHFT is a Windows desktop application that turns live venue data into a shared market-data view, analytical studies, and configurable trigger actions. This page describes the open-source repository as it runs today. + +## System at a glance + +```mermaid +flowchart LR + A[Venue feed] --> B[Connector plugin] + B --> C[Normalised market models] + C --> D[Shared helpers] + D --> E[Dashboard view models] + D --> F[Study plugins] + F --> G[BaseStudyModel results] + G --> H[Charts and tiles] + G --> I[Trigger engine] + I --> J[Configured UI or REST actions] ``` -## Main components +## Components and dependency boundaries ### Desktop host -The `VisualHFT` project is the WPF desktop host. It owns the dashboard, plugin-management views, trigger configuration, and application startup. +The `VisualHFT` project is the WPF application. It starts the application, loads and starts plugins, hosts the dashboard, and owns trigger configuration and the trigger engine. -### Shared core +### Shared libraries -`VisualHFT.Commons` contains shared models, helpers, plugin base classes, and contracts. `VisualHFT.Commons.WPF` contains reusable WPF-specific behavior. +`VisualHFT.Commons` contains the shared market models, helper publishers, plugin contracts, and plugin base classes. It does not depend on WPF. -### Market connector plugins +`VisualHFT.Commons.WPF` contains reusable WPF support and depends on `VisualHFT.Commons`. The desktop host can use both libraries. -Connectors derive from `BasePluginDataRetriever`. They connect to a venue, map its symbols into the configured normalised form, and publish `OrderBook` and `Trade` updates with `RaiseOnDataReceived(...)`. +### Plugins -### Study plugins +Connector and study assemblies use the shared contracts. A connector derives from `BasePluginDataRetriever`. A study derives from `BasePluginStudy`. Built-in plugins are included as project references by the host so their assemblies are copied beside the application for runtime discovery. -Studies derive from `BasePluginStudy`. They subscribe to shared market data, perform their calculation away from the incoming data callback, and publish `BaseStudyModel` values with `AddCalculation(...)`. +## Market-data path -## Plugin discovery +A connector receives a venue-specific feed, maps it into VisualHFT's normalised models, and publishes updates through `RaiseOnDataReceived(...)`. Order books, trades, providers, and symbols are delivered by the corresponding shared helper. -At startup, `PluginManager.LoadPlugins()` scans the directory that contains `VisualHFT.exe` for DLLs. It loads non-abstract types that implement `IPlugin` and that meet their declared `RequiredLicenseLevel`. There is no separate plugin folder. +Dashboard view models and study plugins subscribe to the same helpers. The helper callbacks are synchronous. A subscriber must finish quickly and must not retain the mutable `OrderBook` it receives. -For a new connector or study, start with the [extension templates](extending/README.md). +## Study results and triggers -## Interactive reference +Studies decide how to process their input. A short calculation can run in a helper callback. A study that needs to keep an order-book state or do longer work can take an `OrderBookSnapshot`, queue that work, and dispose the snapshot when it is finished. -The existing [interactive architecture map](system-architecture.html) provides a visual companion to this overview. +`BasePluginStudy.AddCalculation(...)` sends a `BaseStudyModel` through the study's aggregation and result path, then raises `OnCalculated`. The plugin manager registers single-study results with the trigger engine. The dashboard consumes the same study output for live tiles and charts. + +This is deliberately not a claim that every study uses a queue or snapshot. For example, the VPIN study processes its configured trade and order-book callbacks directly, while the Market Resilience study snapshots order books before queued processing. + +## Plugin discovery and lifecycle + +At startup, `PluginManager.LoadPlugins()` scans the directory containing `VisualHFT.exe` for DLLs. It creates non-abstract exported types that implement `IPlugin`, then starts the applicable connector, study, or multi-study lifecycle. + +For a source build, add an extension project as a `ProjectReference` to `VisualHFT.csproj`. Its output must be copied next to the application executable for the runtime loader to discover it. Discovery loads assemblies in the application process. It is not a process-isolation boundary. + +## Extending VisualHFT + +Start from the public templates: + +- [Market connector template](../SDK-MarketConnectorTemplate/MarketConnectorSDK_Guidelines.md) +- [Study template](../SDK-StudyTemplate/StudySDK_Guidelines.md) +- [Extension guide](extending/README.md) + +## Source map + +- [Application startup](../App.xaml.cs) +- [Plugin discovery and lifecycle](../PluginManager/PluginManager.cs) +- [Connector publish contract](../VisualHFT.Commons/PluginManager/BasePluginDataRetriever.cs) +- [Study result contract](../VisualHFT.Commons/PluginManager/BasePluginStudy.cs) +- [Order-book callback helper](../VisualHFT.Commons/Helpers/HelperOrderBook.cs) +- [Disposable order-book snapshot](../VisualHFT.Commons/Model/OrderBookSnapshot.cs) + +For a visual companion, see the [interactive architecture map](system-architecture.html). diff --git a/docs/extending/README.md b/docs/extending/README.md index 38ea5559..8b294cf6 100644 --- a/docs/extending/README.md +++ b/docs/extending/README.md @@ -13,12 +13,4 @@ Both templates compile against the current shared plugin APIs. Follow the linked VisualHFT discovers plugin DLLs in the directory that contains `VisualHFT.exe`. For a source build, add the extension project as a `ProjectReference` in `VisualHFT.csproj`, then rebuild the solution. No manual registration is required. -## License level - -`IPlugin.RequiredLicenseLevel` is checked when VisualHFT loads a plugin. The public base classes default to `eLicenseLevel.COMMUNITY`. Keep that default, or explicitly return it, for a plugin intended for this public repository. - -```csharp -public override eLicenseLevel RequiredLicenseLevel => eLicenseLevel.COMMUNITY; -``` - See the [architecture overview](../architecture.md) for the data flow and plugin boundary. diff --git a/docs/system-architecture.html b/docs/system-architecture.html index 727c1396..896aded8 100644 --- a/docs/system-architecture.html +++ b/docs/system-architecture.html @@ -5,7 +5,6 @@ VisualHFT: Interactive Architectural Blueprint - @@ -51,28 +50,28 @@

VisualHFT: The Architecture (
-

System Architecture: The Three Tiers

+

System Architecture

-

1. Presentation Layer (WPF)

-

The user-facing GUI, built with a strict MVVM pattern. Views (`.xaml`) are decoupled from logic (`ViewModels`), with data binding automated by Fody for clean, maintainable code.

+

1. Desktop host

+

The WPF application starts VisualHFT, hosts the dashboard, loads plugins, and owns the trigger-engine configuration.

-

2. Core Services Engine

-

The central nervous system. Manages the plugin lifecycle (`PluginManager`) and orchestrates data flow via a high-speed, in-memory Pub/Sub data bus (`Helper` classes).

+

2. Shared libraries

+

VisualHFT.Commons owns shared models, helpers, and plugin contracts. VisualHFT.Commons.WPF adds reusable WPF support on top of Commons.

-

3. Plugin Ecosystem

-

Dynamically loaded DLLs that extend functionality. `Data Retrievers` connect to external sources, while `Studies` perform complex, real-time analytics.

+

3. Plugin assemblies

+

Connector plugins ingest venue data. Study plugins calculate live analytics. Both use the shared contracts and are discovered beside the application executable.

-

Real-Time Data Flow: The Pub/Sub Bus

+

Market Data and Results

-

Data flows unidirectionally from producers to consumers via a decoupled, event-driven bus implemented with singleton `Helper` classes. This ensures modularity and real-time responsiveness.

+

Connectors publish normalised order books, trades, providers, and symbols through their matching shared helpers. Dashboard view models and studies subscribe to those helpers. Studies emit BaseStudyModel results for live views and trigger evaluation.

🔌

@@ -82,14 +81,14 @@

Real-Time Data F

🚌

-

Data Bus

-

`Helper` Class

+

Shared Helpers

+

OrderBook, Trade, Provider, Symbol

📈

Consumers

-

UI & Study Plugins

+

Dashboard and study plugins

@@ -101,24 +100,24 @@

Core Engine: Hig
-

Concurrency: decoupled processing

-

Connectors publish normalized market data through shared helper services. Studies use their own processing queues and snapshots so calculations do not block incoming market-data callbacks.

+

Callback ownership

+

Order-book and trade helpers invoke subscribers synchronously. A subscriber must return quickly and must not retain the mutable OrderBook from the callback.

-

Memory Management: Custom Object Pools

-

To minimize Garbage Collector (GC) pressure and prevent unpredictable latency spikes, the platform implements custom object pools. Frequently used objects like `Trade` and `OrderBookUpdate` are recycled instead of being newly allocated, dramatically reducing memory churn.

+

Snapshot when work outlives the callback

+

A consumer that needs an independent book state can create an OrderBookSnapshot. It rents storage for copied book items and must be disposed after use.

Optimized LOB Data Structure

-

Order books are updated in place as market data arrives. Plugins that need to process data away from the incoming callback use an independent snapshot.

+

Order books are updated in place as market data arrives. Queues and snapshots are opt-in consumer choices, not a universal study implementation.

-

1. Incoming update: an `OrderBook` is updated by its connector.

+

1. Incoming update: a connector updates a normalised OrderBook.

// connector code owns the venue-specific delta logic

-

2. Shared view: helper services publish the updated book.

-

// dashboard and studies subscribe to the same normalized data

-

3. Study work: a study takes a disposable `OrderBookSnapshot`.

-

// calculations run outside the data-feed callback

+

2. Shared view: HelperOrderBook calls dashboard and study subscribers.

+

// callback work must remain short

+

3. Longer work: a consumer creates and later disposes an OrderBookSnapshot.

+

// snapshot and queue use are per-consumer decisions

@@ -128,15 +127,15 @@

Optimized LOB Data Structure

The Plugin Ecosystem: A Framework for Extensibility

-

The `PluginManager` orchestrates the ecosystem. At startup, it scans the directory containing `VisualHFT.exe`, uses reflection to find non-abstract types implementing `IPlugin`, and manages their lifecycle (`StartAsync`, `StopAsync`).

+

At startup, PluginManager scans the directory containing VisualHFT.exe, finds non-abstract exported types implementing IPlugin, and starts the applicable connector, study, or multi-study lifecycle.

Data Retriever Plugin

-

Connects to a data source (e.g., FIX, WebSocket), parses the native format, and publishes standardized `Model` objects to the data bus.

+

Connects to a venue, maps its native messages into normalised market models, and publishes those models through the matching shared helpers.

Study Plugin

-

Subscribes to data from the bus, performs calculations (e.g., VPIN, Imbalance) in a separate thread, and publishes results back to the bus.

+

Subscribes to shared data, calculates its metric, and sends BaseStudyModel output through AddCalculation(...) and OnCalculated.

@@ -146,26 +145,26 @@

Study Plugin

Anatomy of a Study: VPIN Implementation

-

A `VPINStudy` plugin demonstrates the platform's analytical power. It's a stateful, event-driven component that processes raw trades into a sophisticated microstructure indicator.

+

A VPINStudy plugin demonstrates the platform's analytical power. It is a stateful, event-driven component that processes raw trades into a microstructure indicator.

-
1

Subscribe to `OnTrade` event from `HelperTrade` data bus.

+
1

Subscribe to configured trade and order-book updates from HelperTrade and HelperOrderBook.

-
2

Classify incoming trade as Buy/Sell (e.g., using Tick Rule).

+
2

Classify a trade against the latest order-book midpoint, with the provider's buy or sell flag as fallback.

3

Add classified volume to the current Volume Bucket.

-
4

If bucket is full: calculate imbalance, add to rolling window (queue).

+
4

When a bucket is full, calculate its imbalance and add it to the fixed-size rolling window.

5

Calculate new VPIN value from the rolling window.

-
6

Publish VPIN value to the data bus for UI consumption.

+
6

Emit the new VPIN value with AddCalculation(...), which raises OnCalculated for live views and triggers.

-

Technology Stack & Key Dependencies

+

Technology Stack and Runtime Boundaries

Core Stack

@@ -178,11 +177,12 @@

Core Stack

-

Dependency Licensing

-

Key dependencies have licensing terms with significant implications for enterprise adoption.

-
- -
+

Runtime boundaries

+
    +
  • Commons: Shared models, helpers, and contracts with no WPF dependency.
  • +
  • Commons.WPF: Reusable WPF support that depends on Commons.
  • +
  • Plugins: Assemblies loaded into the desktop application's process from beside the executable.
  • +
@@ -224,72 +224,6 @@

Dependency Licensing

}); }); - // --- Chart.js Logic --- - const palette = { - blue: '#4f46e5', - pink: '#ec4899', - green: '#10b981', - yellow: '#f59e0b', - red: '#ef4444', - purple: '#8b5cf6', - }; - - const wrapLabel = (label) => { - const maxLength = 16; - if (label.length <= maxLength) return label; - const words = label.split(' '); - const lines = []; - let currentLine = ''; - words.forEach(word => { - if ((currentLine + word).length > maxLength) { - lines.push(currentLine.trim()); - currentLine = ''; - } - currentLine += word + ' '; - }); - lines.push(currentLine.trim()); - return lines.filter(line => line.length > 0); - }; - - const chartLabels = [ - 'Prism.Core (Dual License: Community/Commercial)', - 'OxyPlot.Wpf (MIT)', - 'Fody (MIT)', - 'log4net (Apache 2.0)' - ].map(wrapLabel); - - const chartData = [40, 25, 15, 20]; - const ctx = document.getElementById('dependenciesChart').getContext('2d'); - - new Chart(ctx, { - type: 'doughnut', - data: { - labels: chartLabels, - datasets: [{ - label: 'Dependency License', - data: chartData, - backgroundColor: [palette.red, palette.blue, palette.purple, palette.yellow], - borderColor: '#ffffff', - borderWidth: 3 - }] - }, - options: { - responsive: true, - maintainAspectRatio: false, - plugins: { - legend: { position: 'bottom', labels: { font: { size: 10 }, boxWidth: 15, padding: 15 } }, - tooltip: { - callbacks: { - title: (tooltipItems) => { - const item = tooltipItems[0]; - let label = item.chart.data.labels[item.dataIndex]; - return Array.isArray(label) ? label.join(' ') : label; - } - } - } - } - } - }); });