44#include < format>
55#include < iostream>
66#include < iomanip>
7- #include < map>
8- #include < ranges>
97#include < stdexcept>
108#include < string>
11- #include < tuple>
129#include < utility>
1310#include < vector>
1411#include " Auth.h"
@@ -95,161 +92,35 @@ void FixApp::toApp(FIX::Message& msg, const FIX::SessionID& sessionId) noexcept(
9592 const FIX ::Header& header = msg.getHeader ();
9693 FIX ::MsgType msgType;
9794 header.getField (msgType);
98- std::cout << std::format (" toApp, session Id [{}], type [{}], message [{}]" ,
99- sessionId.toString (), msgType.getString (), replaceSoh (msg.toString ())) << std::endl;
95+ // std::cout << std::format("toApp, session Id [{}], type [{}], message [{}]",
96+ // sessionId.toString(), msgType.getString(), replaceSoh(msg.toString())) << std::endl;
10097};
10198void FixApp::fromAdmin (const FIX ::Message& msg, const FIX ::SessionID& sessionId) noexcept (false ) {
10299 const FIX ::Header& header = msg.getHeader ();
103100 FIX ::MsgType msgType;
104101 header.getField (msgType);
105- std::cout << std::format (" fromAdmin, session Id [{}], type [{}], message [{}]" ,
106- sessionId.toString (), msgType.getString (), replaceSoh (msg.toString ())) << std::endl;
102+ // std::cout << std::format("fromAdmin, session Id [{}], type [{}], message [{}]",
103+ // sessionId.toString(), msgType.getString(), replaceSoh(msg.toString())) << std::endl;
107104};
108105void FixApp::fromApp (const FIX ::Message& msg, const FIX ::SessionID& sessionId) noexcept (false ) {
109106 FIX::MessageCracker::crack (msg, sessionId);
110107 // std::cout << std::format("fromApp, session Id [{}], message [{}]",
111108 // sessionId.toString(), replaceSoh(msg.toString())) << std::endl;
112109}
113110
114-
115- void FixApp::printBook () {
116- // Column headers
117- std::cout << std::left
118- << std::setw (10 ) << " BID_SZ"
119- << std::setw (10 ) << " BID"
120- << std::setw (10 ) << " ASK"
121- << std::setw (10 ) << " ASK_SZ"
122- << " \n " ;
123- // Divider
124- std::cout << std::string (40 , ' -' ) << " \n " ;
125-
126- // print top 10x
127- auto data = std::vector<std::tuple<double , double , double , double >>(10 , std::make_tuple (0 , 0 , 0 , 0 ));
128-
129- // bids
130- int i = 0 ;
131- for (auto && [px, sz] : std::views::reverse (bidMap_)) {
132- std::get<0 >(data[i]) = sz;
133- std::get<1 >(data[i]) = px;
134- i++;
135- if (i > 9 )
136- break ;
137- }
138-
139- // offers
140- i = 0 ;
141- for (const auto & [px, sz] : offerMap_) {
142- std::get<2 >(data[i]) = px;
143- std::get<3 >(data[i]) = sz;
144- i++;
145- if (i > 9 )
146- break ;
147- }
148-
149- for (auto item: data) {
150- std::cout << std::left
151- << std::setw (10 ) << std::get<0 >(item)
152- << std::setw (10 ) << std::get<1 >(item)
153- << std::setw (10 ) << std::get<2 >(item)
154- << std::setw (10 ) << std::get<3 >(item)
155- << " \n " ;
156- }
157-
158- std::cout << std::flush;
159- }
160111void FixApp::onMessage (const FIX44 ::MarketDataSnapshotFullRefresh& m, const FIX ::SessionID& sessionID) {
161- FIX ::Symbol symbol;
162- m.get (symbol);
163- std::cout << std::format (" MD snapshot message, symbol [{}]" , symbol.getString ()) << std::endl;
164- std::string symbolValue = symbol.getValue ();
165- if (symbolValue != " BTCUSDT" ) {
166- std::cout << std::format (" wrong symbol, skipping snapshot. value [{}]" , symbolValue) << std::endl;
167- return ;
168- }
169- bidMap_.clear ();
170- offerMap_.clear ();
171- FIX ::NoMDEntries noMDEntries;
172- m.get (noMDEntries);
173- int numEntries = noMDEntries.getValue ();
174- for (int i = 1 ; i <= numEntries; i++) {
175- FIX44 ::MarketDataSnapshotFullRefresh::NoMDEntries group;
176- m.getGroup (i, group);
177- FIX ::MDEntryType entryType;
178- FIX ::MDEntryPx px;
179- FIX ::MDEntrySize sz;
180- group.get (entryType);
181- group.get (px);
182- group.get (sz);
183-
184- if (entryType == FIX ::MDEntryType_BID) {
185- bidMap_[px.getValue ()] = sz.getValue ();
186- } else if (entryType == FIX ::MDEntryType_OFFER) {
187- offerMap_[px.getValue ()] = sz.getValue ();
188- } else {
189- std::cout << std::format (" unknown bid/offer type [{}]" , entryType.getString ()) << std::endl;
190- }
191- }
192-
193- printBook ();
112+ auto msgPtr = std::make_shared<FIX44 ::MarketDataSnapshotFullRefresh>(m);
113+ queue.enqueue (msgPtr);
194114}
195- void FixApp::onMessage (const FIX44 ::MarketDataIncrementalRefresh& message, const FIX ::SessionID& sessionID) {
196- FIX ::NoMDEntries noMDEntries;
197- message.get (noMDEntries);
198- int numEntries = noMDEntries.getValue ();
199- for (int i = 1 ; i <= numEntries; i++) {
200- FIX44 ::MarketDataIncrementalRefresh::NoMDEntries group;
201- message.getGroup (i, group);
202-
203- FIX ::Symbol symbol;
204- if (group.isSetField (FIX ::FIELD ::Symbol)) {
205- group.get (symbol);
206- }
207- // std::string symbolValue = symbol.getValue();
208- // if (symbolValue != "BTCUSDT") {
209- // std::cout << std::format("wrong symbol, skipping increment. value [{}]", symbolValue) << std::endl;
210- // continue;
211- // }
212-
213- FIX ::MDUpdateAction action;
214- FIX ::MDEntryType entryType;
215- FIX ::MDEntryPx px;
216- group.get (action);
217- group.get (entryType);
218- group.get (px);
219-
220- if (entryType != FIX ::MDEntryType_BID && entryType != FIX ::MDEntryType_OFFER) {
221- std::cout << std::format (" unknown entry type, skipping. value [{}]" , entryType.getString ()) << std::endl;
222- continue ;
223- }
224-
225- if (action.getValue () == FIX ::MDUpdateAction_NEW || action.getValue () == FIX ::MDUpdateAction_CHANGE) {
226- if (group.isSetField (FIX ::FIELD ::MDEntrySize)) {
227- FIX ::MDEntrySize sz;
228- group.get (sz);
229- if (entryType == FIX ::MDEntryType_BID) {
230- bidMap_[px.getValue ()] = sz.getValue ();
231- } else if (entryType == FIX ::MDEntryType_OFFER) {
232- offerMap_[px.getValue ()] = sz.getValue ();
233- }
234- }
235- } else if (action.getValue () == FIX ::MDUpdateAction_DELETE) {
236- if (entryType == FIX ::MDEntryType_BID) {
237- bidMap_.erase (px.getValue ());
238- } else if (entryType == FIX ::MDEntryType_OFFER) {
239- offerMap_.erase (px.getValue ());
240- }
241- } else {
242- std::cout << std::format (" unknown action. value [{}]" , action.getValue ()) << std::endl;
243- }
244- }
245-
246- printBook ();
115+ void FixApp::onMessage (const FIX44 ::MarketDataIncrementalRefresh& m, const FIX ::SessionID& sessionID) {
116+ auto msgPtr = std::make_shared<FIX44 ::MarketDataIncrementalRefresh>(m);
117+ queue.enqueue (msgPtr);
247118}
248119
249120
250121// PUBLIC
251122
252- FixApp::FixApp (std::string apiKey, std::string privatePemPath) : bidMap_{}, offerMap_{} {
123+ FixApp::FixApp (std::string apiKey, std::string privatePemPath) {
253124 apiKey_ = std::move (apiKey);
254125 privatePemPath_ = std::move (privatePemPath);
255126
@@ -271,7 +142,7 @@ void FixApp::subscribeToDepth(const FIX::SessionID& sessionId) {
271142 FIX ::SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES));
272143
273144 // Set market depth
274- marketDataRequest.set (FIX::MarketDepth (5 )); // 1 = Top of book
145+ marketDataRequest.set (FIX::MarketDepth (15 )); // 1 = Top of book
275146
276147 // Create NoMDEntryTypes group for requesting BID and OFFER
277148 FIX44 ::MarketDataRequest::NoMDEntryTypes entryTypeGroup;
0 commit comments