1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . Threading . Tasks ;
4+ using VisualHFT . Commons . PluginManager ;
5+ using VisualHFT . Enums ;
6+ using VisualHFT . Commons . Model ;
7+ using VisualHFT . Commons . Interfaces ;
8+
9+ namespace MarketConnectorTemplate
10+ {
11+ /// <summary>
12+ /// Skeleton implementation of a market data connector. To build a real
13+ /// connector, derive from BasePluginDataRetriever and implement the
14+ /// connection and subscription logic using your chosen exchange client
15+ /// library. This class provides overridable methods for starting and
16+ /// stopping the plug‑in and illustrates how to publish orderbook and
17+ /// trade events into VisualHFT.
18+ /// </summary>
19+ public class TemplatePlugin : BasePluginDataRetriever
20+ {
21+ private TemplateSettings _settings ;
22+
23+ /// <inheritdoc />
24+ public override string Name { get ; set ; } = "Template Exchange Plugin" ;
25+ /// <inheritdoc />
26+ public override string Version { get ; set ; } = "0.1.0" ;
27+ /// <inheritdoc />
28+ public override string Description { get ; set ; } = "Skeleton connector for a generic exchange." ;
29+ /// <inheritdoc />
30+ public override string Author { get ; set ; } = "VisualHFT Community" ;
31+ /// <inheritdoc />
32+ public override ISetting Settings { get => _settings ; set => _settings = ( TemplateSettings ) value ; }
33+ /// <inheritdoc />
34+ public override Action CloseSettingWindow { get ; set ; }
35+
36+ public TemplatePlugin ( )
37+ {
38+ // Set the reconnection action to automatically restart the connector
39+ // when a connection drop is detected. If your exchange client
40+ // exposes reconnection hooks you may override this to use them instead.
41+ SetReconnectionAction ( InternalStartAsync ) ;
42+ }
43+
44+ /// <summary>
45+ /// Called by the plug‑in manager when the user starts this plug‑in.
46+ /// Establishes the connection to the exchange and subscribes to
47+ /// orderbook and trade feeds for the configured symbols. Always
48+ /// call base.StartAsync() before performing your own logic so that
49+ /// VisualHFT can update the provider status correctly.
50+ /// </summary>
51+ public override async Task StartAsync ( )
52+ {
53+ await base . StartAsync ( ) ;
54+
55+ // TODO: Instantiate your exchange client here using _settings. For
56+ // example, Binance.Net, Bitfinex.Net, Kraken.Net, etc. Many
57+ // libraries accept API credentials via constructor parameters.
58+
59+ try
60+ {
61+ await InternalStartAsync ( ) ;
62+ if ( Status == ePluginStatus . STOPPED_FAILED )
63+ return ;
64+
65+ // Inform VisualHFT that the provider is connected
66+ RaiseOnDataReceived ( GetProviderModel ( eSESSIONSTATUS . CONNECTED ) ) ;
67+ Status = ePluginStatus . STARTED ;
68+ }
69+ catch ( Exception ex )
70+ {
71+ // If initialization fails, propagate the error to the base class
72+ // so that reconnection logic can kick in.
73+ await HandleConnectionLost ( ex . Message , ex ) ;
74+ }
75+ }
76+
77+ /// <summary>
78+ /// Contains your actual startup logic. Do not call this directly
79+ /// outside of StartAsync(). It is used by the base class to
80+ /// implement automatic reconnection.
81+ /// </summary>
82+ private async Task InternalStartAsync ( )
83+ {
84+ // Loop over all configured symbols and subscribe. You may want
85+ // to normalise symbols here by calling GetNormalizedSymbol().
86+ foreach ( string symbol in GetAllNormalizedSymbols ( ) )
87+ {
88+ // TODO: Replace this with calls to your exchange client
89+ // For example:
90+ // await client.SubscribeToOrderBookUpdatesAsync(symbol, _settings.DepthLevels, OnOrderBookUpdate);
91+ // await client.SubscribeToTradeUpdatesAsync(symbol, OnTradeUpdate);
92+ }
93+ await Task . CompletedTask ;
94+ }
95+
96+ /// <summary>
97+ /// Called by the plug‑in manager when the user stops this plug‑in.
98+ /// Unsubscribes from all feeds and cleans up resources.
99+ /// </summary>
100+ public override async Task StopAsync ( )
101+ {
102+ Status = ePluginStatus . STOPPING ;
103+ // TODO: Unsubscribe your exchange client and dispose resources here
104+
105+ // Notify VisualHFT that the provider is disconnected and clear the
106+ // orderbook snapshot for this provider.
107+ RaiseOnDataReceived ( new List < OrderBook > ( ) ) ;
108+ RaiseOnDataReceived ( GetProviderModel ( eSESSIONSTATUS . DISCONNECTED ) ) ;
109+ await base . StopAsync ( ) ;
110+ }
111+
112+ /// <summary>
113+ /// Handler for orderbook updates from the exchange. Convert the raw
114+ /// payload into VisualHFT.Model.OrderBook and publish it via
115+ /// RaiseOnDataReceived(). Note that OrderBook has a Provider
116+ /// property which should be set to Name and a Symbol property
117+ /// containing the normalised symbol.
118+ /// </summary>
119+ /// <param name="update">Raw exchange payload.</param>
120+ private void OnOrderBookUpdate ( object update )
121+ {
122+ // TODO: Parse update into a VisualHFT.Model.OrderBook instance. At
123+ // minimum you should populate Bids, Asks, Symbol, Provider and
124+ // Timestamp. Use GetNormalizedSymbol() to map the exchange
125+ // symbol into your configured symbol list.
126+
127+ // Example stub (remove once implemented):
128+ var orderBook = new OrderBook
129+ {
130+ Provider = Name ,
131+ // Symbol = GetNormalizedSymbol(rawSymbol),
132+ // Bids = new List<OrderBookLevel> { ... },
133+ // Asks = new List<OrderBookLevel> { ... },
134+ // Timestamp = DateTime.UtcNow
135+ } ;
136+ RaiseOnDataReceived ( orderBook ) ;
137+ }
138+
139+ /// <summary>
140+ /// Handler for trade updates from the exchange. Convert the raw
141+ /// payload into VisualHFT.Model.Trade and publish via
142+ /// RaiseOnDataReceived().
143+ /// </summary>
144+ /// <param name="update">Raw trade payload.</param>
145+ private void OnTradeUpdate ( object update )
146+ {
147+ // TODO: Parse update into a VisualHFT.Model.Trade instance. A trade
148+ // must set Symbol, Price, Size, IsBuyerMaker and Timestamp.
149+
150+ // Example stub (remove once implemented):
151+ var trade = new Trade
152+ {
153+ Provider = Name ,
154+ // Symbol = GetNormalizedSymbol(rawSymbol),
155+ // Price = rawTrade.Price,
156+ // Size = rawTrade.Quantity,
157+ // IsBuyerMaker = rawTrade.IsBuyerMaker,
158+ // Timestamp = DateTime.UtcNow
159+ } ;
160+ RaiseOnDataReceived ( trade ) ;
161+ }
162+ }
163+ }
0 commit comments