OnixS C++ Eurex T7 Market and Reference Data (EMDI, MDI, RDI, EOBI) Handlers 20.0.1
Users' manual and API documentation
Loading...
Searching...
No Matches
Benchmark Sample

This sample demonstrates how to measure the handler latency.

Source code

1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement(the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#include <iostream>
20
26
27#include "RdiListener.h"
28#include "EmdiListener.h"
29#include "EobiListener.h"
30
31#include "../Common/Signal.h"
32#include "../Common/Options.h"
33#include "../Common/Settings.h"
34#include "../Common/Utils.h"
35
36using namespace OnixS::Eurex::MarketData;
37using namespace OnixS::Eurex::MarketData::EOBI;
38
39template <typename Configuration> void process(const EmdiDescriptors& descriptors, FeedEngine& feedEngine, const Configuration& cfg);
40template <typename Configuration> void process(const EobiDescriptors& descriptors, FeedEngine& feedEngine, const Configuration& cfg);
41
42
44int main(int argc, char* argv[])
45{
46 // `--help` to show options.
47 const Samples::AppConfiguration<
48 Samples::NetworkInterfaceConfiguration
49 , Samples::EnvironmentConfiguration
50 , Samples::LogDirectoryConfiguration
51 , Samples::AffinityConfiguration
52 , Samples::MarketSegmentConfiguration
53 , Samples::ProductConfiguration
54 , Samples::PacketCountConfiguration
55 > cfg{"Benchmark", argc, argv};
56
57 try
58 {
59 Samples::SignalHelper::manageSignals();
60
61 ThisThread::affinity(cfg.cpu());
62 SocketFeedEngine feedEngine(0);
63
64 auto rdiSettings = Samples::makeSettings<RdiHandlerSettings>(cfg);
65 fillEnvironment(rdiSettings, cfg);
66
67 RdiListener rdiListener;
68 RdiHandler rdiHandler(rdiSettings);
69 rdiHandler.bindFeedEngine(feedEngine);
70
71 rdiHandler.registerErrorListener(&rdiListener);
72 rdiHandler.registerWarningListener(&rdiListener);
73 rdiHandler.registerReferenceDataListener(&rdiListener);
74
75 std::clog << "Will start the RDI Handler ..." << std::endl;
76 std::clog << "Please press Ctrl+C key to stop..." << std::endl;
77
78 rdiHandler.start();
79
80 while(!rdiListener.referenceDataReceived() && !Samples::SignalHelper::interruptDetected())
81 process(feedEngine);
82
83 std::clog << "Will stop the RDI Handler ..." << std::endl;
84 rdiHandler.stop();
85
86 while(process(feedEngine));
87
88 if(Samples::SignalHelper::interruptDetected())
89 return 0;
90
91 const MarketSegments mktSeg {cfg.marketSegment()};
92
93 switch (cfg.product())
94 {
95 case Samples::Product::Emdi:
96 process(rdiHandler.findEmdiDescriptors(mktSeg), feedEngine, cfg);
97 break;
98
99 case Samples::Product::Eobi:
100 process(rdiHandler.findEobiDescriptors(mktSeg), feedEngine, cfg);
101 break;
102 }
103 }
104 catch(const std::exception& ex)
105 {
106 std::cerr << "EXCEPTION: " << ex.what() << std::endl;
107 }
108
109 return 0;
110}
111
112template <typename Settings, typename Configuration, typename Descriptor>
113Settings makeBmSettings(const Configuration& cfg, const Descriptor& descriptor)
114{
115 auto settings = Samples::makeSettings<Settings>(cfg);
116
117 settings.buildInternalOrderBooks = false;
118 settings.logLevel = LogLevel::Fatal;
119 settings.logSettings = LogSettings::TraceToFile;
120 settings.interfaceDescriptor.incrementalFeed = descriptor.incrementalFeed;
121 settings.interfaceDescriptor.snapshotFeed = descriptor.snapshotFeed;
122
123 return settings;
124}
125
126template <typename Configuration>
127void process(const EmdiDescriptors& descriptors, FeedEngine& feedEngine, const Configuration& cfg)
128{
129 if(descriptors.empty())
130 throw std::runtime_error("No products found.");
131
132 const auto& descriptor = descriptors[0];
133
134 EmdiListener listener{cfg.packetsCount()};
135
136 const auto settings = makeBmSettings<EmdiHandlerSettings>(cfg, descriptor);
137 auto handler = Samples::makeUnique<EmdiHandler>(settings);
138
139 handler->bindFeedEngine(feedEngine);
140
141 handler->setPartitionIdFilters(descriptor.partitionIdFilters);
142 handler->setMarketSegmentIdFilters(descriptor.marketSegmentIdFilters);
143
144 listener.subscribe(*handler);
145
146 handler->start();
147
148 while(!Samples::SignalHelper::interruptDetected() || listener.done())
149 process(feedEngine);
150
151 handler->stop();
152
153 process(feedEngine);
154
155 listener.saveLatencies("emdi-results.csv");
156 listener.processLatencies();
157}
158
159template <typename Configuration>
160void process(const EobiDescriptors& descriptors, FeedEngine& feedEngine, const Configuration& cfg)
161{
162 if(descriptors.empty())
163 throw std::runtime_error("No products found.");
164
165 const auto& descriptor = descriptors[0];
166
167 EobiListener listener{cfg.packetsCount()};
168
169 const auto settings = makeBmSettings<EobiHandlerSettings>(cfg, descriptor);
170 auto handler = Samples::makeUnique<EobiHandler>(settings);
171
172 handler->bindFeedEngine(feedEngine);
173
174 handler->setPartitionIdFilters(descriptor.partitionIdFilters);
175 handler->setMarketSegmentIdFilters(descriptor.marketSegmentIdFilters);
176
177 listener.subscribe(*handler);
178
179 handler->start();
180
181 while(!Samples::SignalHelper::interruptDetected() || listener.done())
182 process(feedEngine);
183
184 handler->stop();
185
186 process(feedEngine);
187
188 listener.saveLatencies("eobi-results.csv");
189 listener.processLatencies();
190}
The Feed Engine machinery.
Definition FeedEngine.h:104
Eurex Reference Data Interface Handler.
Definition RdiHandler.h:44
The given class implements feed engine concept using pool of working threads and standard socket API.
Definition FeedEngine.h:139
static void affinity(const ThreadAffinity &)
Sets the processor affinity mask for the current thread.
EobiDescriptor::Collection EobiDescriptors
EmdiDescriptor::Collection EmdiDescriptors
IInterfaceDescriptorProvider::MarketSegments MarketSegments
bool process(FeedEngine &engine)
Definition FeedEngine.h:132
@ Fatal
Fatal error, cannot continue.
Definition LogSettings.h:37
@ TraceToFile
Trace to the log file.
Definition LogSettings.h:55
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#pragma once
20
25
26
27class RdiListener final
31{
32public:
34 RdiListener();
35
37 ~RdiListener() override;
38
40 void onError(OnixS::Eurex::MarketData::ErrorCode::Enum code, const std::string& description) override;
41
43 void onWarning(const std::string& description) override;
44
46 void onSnapshotCycleStart() override;
47
49 void onProduct(const OnixS::Eurex::MarketData::ProductSnapshot& productSnapshot, const OnixS::Eurex::MarketData::DataSource& dataSource) override;
50
53
56
59
62
65
67 void onSnapshotCycleEnd() override;
68
70 bool referenceDataReceived() const;
71
72private:
74 bool referenceDataReady_;
75};
virtual void onError(ErrorCode::Enum code, const std::string &description)=0
virtual void onTradeAtReferencePriceStatus(const TradeAtReferencePriceStatus &status, const DataSource &dataSource)=0
Is called when TradeAtReferencePriceStatus message is received.
virtual void onSnapshotCycleStart()=0
Is called when reference data snapshot cycle is started.
virtual void onVarianceFuturesStatus(const VarianceFuturesStatus &status, const DataSource &dataSource)=0
Is called when variance futures status is received.
virtual void onSnapshotCycleEnd()=0
Is called when reference data snapshot cycle is ended.
virtual void onInstrumentIncremental(const InstrumentIncremental &incremental, const DataSource &dataSource)=0
Is called when instrument incremental update is received.
virtual void onProduct(const ProductSnapshot &snapshot, const DataSource &dataSource)=0
Is called when product snapshot is received.
virtual void onTotalReturnFuturesStatus(const TotalReturnFuturesStatus &status, const DataSource &dataSource)=0
Is called when total return futures status message is received.
virtual void onInstrument(const InstrumentSnapshot &snapshot, const DataSource &dataSource)=0
Is called when instrument snapshot is received.
virtual void onWarning(const std::string &reason)=0
Is called when the Warning condition is detected.
Enum
Known (selected) error codes.
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#include <iostream>
20#include <sstream>
21
22#include "RdiListener.h"
23
24
25using namespace OnixS::Eurex::MarketData;
26
27/*
28 RdiListener
29*/
30
31RdiListener::RdiListener()
32 : referenceDataReady_(false)
33{
34}
35
36RdiListener::~RdiListener() = default;
37
38void RdiListener::onError(ErrorCode::Enum code, const std::string& description)
39{
40 std::clog << "Error occurred, errorCode = " << enumToString(code) << ". Description: '" << description << "'" << std::endl;
41}
42
43void RdiListener::onWarning(const std::string& description)
44{
45 std::stringstream ss;
46 std::clog << "Warning occurred. Description: '" << description << "'" << std::endl;
47}
48
49void RdiListener::onSnapshotCycleStart()
50{
51}
52
53void RdiListener::onProduct(const ProductSnapshot&, const DataSource&)
54{
55}
56
57void RdiListener::onInstrument(const InstrumentSnapshot&, const DataSource&)
58{
59}
60
61void RdiListener::onInstrumentIncremental(const InstrumentIncremental&, const DataSource&)
62{
63}
64
65void RdiListener::onVarianceFuturesStatus(const VarianceFuturesStatus&, const DataSource&)
66{
67}
68
69void RdiListener::onTotalReturnFuturesStatus(const TotalReturnFuturesStatus&, const DataSource&)
70{
71}
72
73void RdiListener::onTradeAtReferencePriceStatus(const TradeAtReferencePriceStatus&, const DataSource&)
74{
75}
76
77void RdiListener::onSnapshotCycleEnd()
78{
79 referenceDataReady_ = true;
80}
81
82bool RdiListener::referenceDataReceived() const
83{
84 return referenceDataReady_;
85}
std::string enumToString(HandlerState::Enum)
Returns string representation of HandlerState value.
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#pragma once
20
34
35#include "ListenerBase.h"
36
37class EmdiListener
38 : public ListenerBase
50{
51public:
53 explicit EmdiListener(size_t count);
54
56 ~EmdiListener() override;
57
59 void subscribe(OnixS::Eurex::MarketData::EmdiHandler& handler);
60
62 void onError(OnixS::Eurex::MarketData::ErrorCode::Enum code, const std::string& description) override;
63
65 void onWarning(const std::string& description) override;
66
69
72
74 void onDepthReset(OnixS::Eurex::MarketData::MarketSegmentId marketSegmentId) override;
75
78
81
84
87
90
93
96
99
102};
virtual void onComplexInstrumentUpdate(const ComplexInstrumentUpdate &update, const DataSource &dataSource)=0
Is called when complex instrument update is received.
virtual void onCrossRequest(const CrossRequest &request, const DataSource &dataSource)=0
Is called when cross request is received.
virtual void onDepthReset(MarketSegmentId marketSegmentId)=0
Is called when all the books are reset for a given market segment.
virtual void onDepthOutOfDate(MarketSegmentId marketSegmentId)=0
virtual void onDepthSnapshot(const DepthSnapshot &snapshot, const DataSource &dataSource)=0
Is called when depth snapshot is received.
virtual void onDepthIncremental(const DepthIncremental &incremental, const DataSource &dataSource)=0
Is called when depth incremental is received.
Eurex Enhanced Market Data Interface Handler.
Definition EmdiHandler.h:60
virtual void onFlexibleInstrumentUpdate(const FlexibleInstrumentUpdate &update, const DataSource &dataSource)=0
Is called when mass instrument state change is received.
virtual void onInstrumentStateChange(const InstrumentStateChange &change, const DataSource &dataSource)=0
Is called when instrument state change is received.
virtual void onMassInstrumentStateChange(const MassInstrumentStateChange &change, const DataSource &dataSource)=0
Is called when mass instrument state change is received.
virtual void onProductStateChange(const ProductStateChange &change, const DataSource &dataSource)=0
Is called when product state change is received.
virtual void onQuoteRequest(const QuoteRequest &request, const DataSource &dataSource)=0
Is called when quote request is received.
virtual void onTopOfBookImplied(const TopOfBookImplied &msg, const DataSource &dataSource)=0
Is called when Top Of Book Implied message is received.
UInt32 MarketSegmentId
Alias for Market Segment ID type.
Definition Defines.h:40
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#include <map>
20#include <climits>
21#include <iostream>
22#include <sstream>
23
24#include "EmdiListener.h"
25
26
27using namespace OnixS::Eurex::MarketData;
28
29/*
30 EmdiListener
31*/
32
33EmdiListener::EmdiListener(size_t count)
34 : ListenerBase(count)
35{
36}
37
38EmdiListener::~EmdiListener() = default;
39
40void EmdiListener::subscribe(OnixS::Eurex::MarketData::EmdiHandler& handler)
41{
42 handler.registerErrorListener(this);
43 handler.registerWarningListener(this);
44 handler.registerDepthListener(this);
49 handler.registerQuoteRequestListener(this);
50 handler.registerCrossRequestListener(this);
53}
54
55void EmdiListener::onError(ErrorCode::Enum code, const std::string& description)
56{
57 std::clog << "Error occurred, errorCode = " << enumToString(code) << ". Description: '" << description << "'" << std::endl;
58}
59
60void EmdiListener::onWarning(const std::string& description)
61{
62 std::clog << "Warning occurred. Description: '" << description << "'" << std::endl;
63}
64
65void EmdiListener::onDepthSnapshot(const DepthSnapshot&, const DataSource&)
66{
67}
68
69void EmdiListener::onDepthIncremental(const DepthIncremental&, const DataSource& dataSource)
70{
71 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
72 addLatency(dataSource.packetReceptionTime);
73}
74
75void EmdiListener::onDepthReset(MarketSegmentId)
76{
77}
78
79void EmdiListener::onDepthOutOfDate(MarketSegmentId)
80{
81}
82
83void EmdiListener::onTopOfBookImplied(const TopOfBookImplied&, const DataSource& dataSource)
84{
85 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
86 addLatency(dataSource.packetReceptionTime);
87}
88
89void EmdiListener::onProductStateChange(const ProductStateChange&, const DataSource& dataSource)
90{
91 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
92 addLatency(dataSource.packetReceptionTime);
93}
94
95void EmdiListener::onMassInstrumentStateChange(const MassInstrumentStateChange&, const DataSource& dataSource)
96{
97 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
98 addLatency(dataSource.packetReceptionTime);
99}
100
101void EmdiListener::onInstrumentStateChange(const InstrumentStateChange&, const DataSource& dataSource)
102{
103 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
104 addLatency(dataSource.packetReceptionTime);
105}
106
107void EmdiListener::onQuoteRequest(const QuoteRequest&, const DataSource& dataSource)
108{
109 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached )
110 addLatency(dataSource.packetReceptionTime);
111}
112
113void EmdiListener::onCrossRequest(const CrossRequest&, const DataSource& dataSource)
114{
115 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached )
116 addLatency(dataSource.packetReceptionTime);
117}
118
119void EmdiListener::onComplexInstrumentUpdate(const ComplexInstrumentUpdate&, const DataSource& dataSource)
120{
121 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
122 addLatency(dataSource.packetReceptionTime);
123}
124
125void EmdiListener::onFlexibleInstrumentUpdate(const FlexibleInstrumentUpdate&, const DataSource& dataSource)
126{
127 if(dataSource.packetMessageSeqNum == 2 && !dataSource.cached)
128 addLatency(dataSource.packetReceptionTime);
129}
EmdiHandler & registerWarningListener(WarningListener *listener)
EmdiHandler & registerErrorListener(ErrorListener *listener)
EmdiHandler & registerCrossRequestListener(CrossRequestListener *listener)
EmdiHandler & registerMassInstrumentStateChangeListener(MassInstrumentStateChangeListener *listener)
EmdiHandler & registerTopOfBookImpliedListener(TopOfBookImpliedListener *listener)
EmdiHandler & registerQuoteRequestListener(QuoteRequestListener *listener)
EmdiHandler & registerComplexInstrumentUpdateListener(ComplexInstrumentUpdateListener *listener)
EmdiHandler & registerInstrumentStateChangeListener(InstrumentStateChangeListener *listener)
EmdiHandler & registerFlexibleInstrumentUpdateListener(FlexibleInstrumentUpdateListener *listener)
EmdiHandler & registerProductStateChangeListener(ProductStateChangeListener *listener)
EmdiHandler & registerDepthListener(DepthListener *listener)
SequenceNumber packetMessageSeqNum
Packet message number.
Definition Defines.h:109
Timestamp packetReceptionTime
Time when the packet was received by Handler from UDP, in system ticks,.
Definition Defines.h:99
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#pragma once
20
32
33#include "ListenerBase.h"
34
35
36class EobiListener final
37 : public ListenerBase
44{
45public:
47 explicit EobiListener(size_t count);
48
50 ~EobiListener() override;
51
53 void subscribe(OnixS::Eurex::MarketData::EOBI::EobiHandler& handler);
54
56 void onError(OnixS::Eurex::MarketData::ErrorCode::Enum code, const std::string& description) override;
57
59 void onWarning(const std::string& description) override;
60
61 void onOrderAdd(const OnixS::Eurex::MarketData::EOBI::OrderAdd& orderAdd) override;
62
63 void onOrderModify(const OnixS::Eurex::MarketData::EOBI::OrderModify& orderModify) override;
64
66
67 void onOrderDelete(const OnixS::Eurex::MarketData::EOBI::OrderDelete& orderDelete) override;
68
69 void onOrderMassDelete(const OnixS::Eurex::MarketData::EOBI::OrderMassDelete& orderMassDelete) override;
70
72
73 void onFullOrderExecution(const OnixS::Eurex::MarketData::EOBI::FullOrderExecution& fullOrderExecution) override;
74
75 void onAuctionBestBidOffer(const OnixS::Eurex::MarketData::EOBI::AuctionBestBidOffer& auctionBestBidOffer) override;
76
78
79 void onTopOfBook(const OnixS::Eurex::MarketData::EOBI::TopOfBook& topOfBook) override;
80
81 void onExecutionSummary(const OnixS::Eurex::MarketData::EOBI::ExecutionSummary& executionSummary) override;
82
83 void onQuoteRequest(const OnixS::Eurex::MarketData::EOBI::QuoteRequest& quoteRequest) override;
84
85 void onCrossRequest(const OnixS::Eurex::MarketData::EOBI::CrossRequest& crossRequest) override;
86
87 void onTradeReport(const OnixS::Eurex::MarketData::EOBI::TradeReport& tradeReport) override;
88
89 void onTradeReversal(const OnixS::Eurex::MarketData::EOBI::TradeReversal& tradeReversal) override;
90
91 void onProductStateChange(const OnixS::Eurex::MarketData::EOBI::ProductStateChange& productStateChange) override;
92
94
96
98
100
102
104};
Eurex Enhanced Order Book Interface Handler.
Definition EobiHandler.h:55
virtual void onOrderModify(const OrderModify &orderModify)=0
virtual void onFullOrderExecution(const FullOrderExecution &fullOrderExecution)=0
virtual void onAuctionBestBidOffer(const AuctionBestBidOffer &auctionBestBidOffer)=0
virtual void onOrderDelete(const OrderDelete &orderDelete)=0
virtual void onTopOfBook(const TopOfBook &topOfBook)=0
virtual void onOrderAdd(const OrderAdd &orderAdd)=0
virtual void onPartialOrderExecution(const PartialOrderExecution &partialOrderExecution)=0
virtual void onOrderModifySamePriority(const OrderModifySamePriority &orderModifySamePriority)=0
virtual void onOrderMassDelete(const OrderMassDelete &orderMassDelete)=0
virtual void onAuctionClearingPrice(const AuctionClearingPrice &auctionClearingPrice)=0
virtual void onAddComplexInstrument(const AddComplexInstrument &addComplexInstrument)=0
virtual void onAddScaledSimpleInstrument(const AddScaledSimpleInstrument &addFlexibleInstrument)=0
virtual void onAddFlexibleInstrument(const AddFlexibleInstrument &addFlexibleInstrument)=0
virtual void onProductStateChange(const ProductStateChange &productStateChange)=0
virtual void onInstrumentStateChange(const InstrumentStateChange &instrumentStateChange)=0
virtual void onMassInstrumentStateChange(const MassInstrumentStateChange &instrumentStateChange)=0
virtual void onTradeReport(const TradeReport &tradeReport)=0
virtual void onTESTradeReport(const TESTradeReport &tradeReport)=0
virtual void onCrossRequest(const CrossRequest &crossRequest)=0
virtual void onTradeReversal(const TradeReversal &tradeReversal)=0
virtual void onQuoteRequest(const QuoteRequest &quoteRequest)=0
virtual void onExecutionSummary(const ExecutionSummary &executionSummary)=0
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#include <map>
20#include <iostream>
21#include <sstream>
22
24
25#include "EobiListener.h"
26
27using namespace OnixS::Eurex::MarketData;
28using namespace OnixS::Eurex::MarketData::EOBI;
29
30/*
31 EobiListener
32*/
33
34EobiListener::EobiListener(size_t count)
35 : ListenerBase(count)
36{
37}
38
39EobiListener::~EobiListener() = default;
40
41void EobiListener::subscribe(OnixS::Eurex::MarketData::EOBI::EobiHandler& handler)
42{
43 handler.registerErrorListener(this);
44 handler.registerWarningListener(this);
45 handler.registerOrderDataListener(this);
46 handler.registerTradeDataListener(this);
47 handler.registerStateChangeListener(this);
49}
50
51void EobiListener::onError(ErrorCode::Enum code, const std::string& description)
52{
53 std::clog << "Error occurred, errorCode = " << enumToString(code) << ". Description: '" << description << "'" << std::endl;
54}
55
56void EobiListener::onWarning(const std::string& description)
57{
58 std::clog << "Warning occurred. Description: '" << description << "'" << std::endl;
59}
60
61void EobiListener::onOrderAdd(const OrderAdd& orderAdd)
62{
63 const DataSource& dataSource = orderAdd.dataSource();
64 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
65 addLatency(dataSource.packetReceptionTime);
66}
67
68void EobiListener::onOrderModify(const OrderModify& orderModify)
69{
70 const DataSource& dataSource = orderModify.dataSource();
71 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
72 addLatency(dataSource.packetReceptionTime);
73}
74
75void EobiListener::onOrderModifySamePriority(const OrderModifySamePriority& orderModify)
76{
77 const DataSource& dataSource = orderModify.dataSource();
78 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
79 addLatency(dataSource.packetReceptionTime);
80}
81
82void EobiListener::onOrderDelete(const OrderDelete& orderDelete)
83{
84 const DataSource& dataSource = orderDelete.dataSource();
85 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
86 addLatency(dataSource.packetReceptionTime);
87}
88
89void EobiListener::onOrderMassDelete(const OrderMassDelete& orderMassDelete)
90{
91 const DataSource& dataSource = orderMassDelete.dataSource();
92 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
93 addLatency(dataSource.packetReceptionTime);
94}
95
96void EobiListener::onPartialOrderExecution(const PartialOrderExecution& partialOrderExecution)
97{
98 const DataSource& dataSource = partialOrderExecution.dataSource();
99 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
100 addLatency(dataSource.packetReceptionTime);
101}
102
103void EobiListener::onFullOrderExecution(const FullOrderExecution& fullOrderExecution)
104{
105 const DataSource& dataSource = fullOrderExecution.dataSource();
106 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
107 addLatency(dataSource.packetReceptionTime);
108}
109
110void EobiListener::onAuctionBestBidOffer(const AuctionBestBidOffer& auctionBestBidOffer)
111{
112 const DataSource& dataSource = auctionBestBidOffer.dataSource();
113 if(dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
114 addLatency (dataSource.packetReceptionTime);
115}
116
117void EobiListener::onAuctionClearingPrice(const AuctionClearingPrice& auctionClearingPrice)
118{
119 const DataSource& dataSource = auctionClearingPrice.dataSource();
120 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
121 addLatency (dataSource.packetReceptionTime);
122}
123
124void EobiListener::onTopOfBook(const TopOfBook& topOfBook)
125{
126 const DataSource& dataSource = topOfBook.dataSource();
127 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
128 addLatency (dataSource.packetReceptionTime);
129}
130
131void EobiListener::onExecutionSummary(const ExecutionSummary& executionSummary)
132{
133 const DataSource& dataSource = executionSummary.dataSource();
134 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
135 addLatency (dataSource.packetReceptionTime);
136}
137
138void EobiListener::onQuoteRequest(const EOBI::QuoteRequest& quoteRequest)
139{
140 const DataSource& dataSource = quoteRequest.dataSource();
141 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
142 addLatency (dataSource.packetReceptionTime);
143}
144
145void EobiListener::onCrossRequest(const EOBI::CrossRequest& crossRequest)
146{
147 const DataSource& dataSource = crossRequest.dataSource();
148 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
149 addLatency (dataSource.packetReceptionTime);
150}
151
152void EobiListener::onTradeReport(const TradeReport& tradeReport)
153{
154 const DataSource& dataSource = tradeReport.dataSource();
155 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
156 addLatency (dataSource.packetReceptionTime);
157}
158
159void EobiListener::onTradeReversal(const TradeReversal& tradeReversal)
160{
161 const DataSource& dataSource = tradeReversal.dataSource();
162 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
163 addLatency (dataSource.packetReceptionTime);
164}
165
166void EobiListener::onProductStateChange(const EOBI::ProductStateChange& productStateChange)
167{
168 const DataSource& dataSource = productStateChange.dataSource();
169 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
170 addLatency (dataSource.packetReceptionTime);
171}
172
173void EobiListener::onInstrumentStateChange(const EOBI::InstrumentStateChange& instrumentStateChange)
174{
175 const DataSource& dataSource = instrumentStateChange.dataSource();
176 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
177 addLatency (dataSource.packetReceptionTime);
178}
179
180void EobiListener::onMassInstrumentStateChange(
182{
183 const DataSource& dataSource = instrumentStateChange.dataSource();
184 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
185 addLatency (dataSource.packetReceptionTime);
186}
187
188void EobiListener::onAddComplexInstrument(const AddComplexInstrument& addComplexInstrument)
189{
190 const DataSource& dataSource = addComplexInstrument.dataSource();
191 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
192 addLatency (dataSource.packetReceptionTime);
193}
194
195void EobiListener::onAddFlexibleInstrument (const OnixS::Eurex::MarketData::EOBI::AddFlexibleInstrument& addFlexibleInstrument)
196{
197 const DataSource& dataSource = addFlexibleInstrument.dataSource();
198 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
199 addLatency (dataSource.packetReceptionTime);
200}
201
202void EobiListener::onTESTradeReport(const OnixS::Eurex::MarketData::EOBI::TESTradeReport& tradeReport)
203{
204 const DataSource& dataSource = tradeReport.dataSource();
205 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
206 addLatency (dataSource.packetReceptionTime);
207}
208
209void EobiListener::onAddScaledSimpleInstrument (const OnixS::Eurex::MarketData::EOBI::AddScaledSimpleInstrument& addFlexibleInstrument)
210{
211 const DataSource& dataSource = addFlexibleInstrument.dataSource();
212 if (dataSource.packetMessageSeqNum == 1 && dataSource.completionIndicator && !dataSource.cached)
213 addLatency (dataSource.packetReceptionTime);
214}
EobiHandler & registerWarningListener(WarningListener *listener)
EobiHandler & registerStateChangeListener(StateChangeListener *listener)
EobiHandler & registerErrorListener(ErrorListener *listener)
EobiHandler & registerReferenceDataListener(ReferenceDataListener *listener)
EobiHandler & registerTradeDataListener(TradeDataListener *listener)
EobiHandler & registerOrderDataListener(OrderDataListener *listener)
const DataSource & dataSource() const
Returns data source.
Definition MessageBase.h:56
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#pragma once
20
21#include <vector>
22
25
26
27class ListenerBase
28{
29public:
31 virtual ~ListenerBase();
32
34 void processLatencies();
35
37 void saveLatencies(const std::string& filename);
38
40 bool done() const noexcept
41 {
42 return latencies_.size() == maxCount_;
43 }
44
45protected:
47 explicit ListenerBase(size_t count);
48
50 void addLatency(const OnixS::Eurex::MarketData::Timestamp&);
51
52 typedef unsigned long long Latency;
53 typedef std::vector<Latency> Latencies;
54
56 const size_t maxCount_;
57
59 Latencies latencies_;
60
61private:
62 static Latency calculateAdjustment();
63};
Represents time point without time-zone information.
Definition Timestamp.h:451
1/*
2* Copyright Onix Solutions Limited [OnixS]. All rights reserved.
3*
4* This software owned by Onix Solutions Limited [OnixS] and is protected by copyright law
5* and international copyright treaties.
6*
7* Access to and use of the software is governed by the terms of the applicable ONIXS Software
8* Services Agreement (the Agreement) and Customer end user license agreements granting
9* a non-assignable, non-transferable and non-exclusive license to use the software
10* for it's own data processing purposes under the terms defined in the Agreement.
11*
12* Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
13* of this source code or associated reference material to any other location for further reproduction
14* or redistribution, and any amendments to this copyright notice, are expressly prohibited.
15*
16* Any reproduction or redistribution for sale or hiring of the Software not in accordance with
17* the terms of the Agreement is a violation of copyright law.
18*/
19#include <map>
20#include <climits>
21#include <iostream>
22#include <fstream>
23#include <cmath>
24#include <algorithm>
25
26#include "ListenerBase.h"
27
28
29using namespace OnixS::Eurex::MarketData;
30
31/*
32 EobiListener
33*/
34
35ListenerBase::ListenerBase(size_t count)
36 : maxCount_(count)
37{
38 latencies_.reserve(maxCount_);
39}
40
41ListenerBase::~ListenerBase() = default;
42
43void ListenerBase::addLatency(const OnixS::Eurex::MarketData::Timestamp& receivingTime)
44{
45 if ONIXS_EUREX_EMDI_UNLIKELY(latencies_.size() >= maxCount_)
46 return;
47
48 const TimeSpan latency = OnixS::Eurex::MarketData::Timestamp::utcNow() - receivingTime;
49 latencies_.push_back(latency.ticks());
50}
51
52ListenerBase::Latency ListenerBase::calculateAdjustment()
53{
54 const int iterations = 10000;
55 Latencies latencies;
56
57 latencies.reserve(iterations);
58
59 for(int i = 0; i < iterations; ++i)
60 {
61 const TimeSpan latency = Timestamp::utcNow() - Timestamp::utcNow();
62 latencies.push_back(latency.ticks());
63 }
64
65 std::sort(latencies.begin(), latencies.end());
66
67 return(latencies[latencies.size() / 2]);
68}
69
70void ListenerBase::processLatencies()
71{
72 size_t count = latencies_.size();
73
74 if(count == 0)
75 {
76 std::clog << "Nothing to process(latencies list is empty)." << std::endl;
77 return;
78 }
79
80 std::sort(latencies_.begin(), latencies_.end());
81
82 const Latency adjustment = calculateAdjustment();
83
84 const long double medianLatency =
85 static_cast<double>((latencies_[latencies_.size() / 2]) - adjustment);
86
87 std::clog << "Results:" << std::endl;
88 std::clog << "Latency(nanoseconds):" << std::endl;
89 std::clog << "Count: " << count << std::endl;
90 std::clog << "Median: " << medianLatency << std::endl;
91}
92
93void ListenerBase::saveLatencies(const std::string& filename)
94{
95 std::ofstream csvFile;
96
97 csvFile.open(filename.c_str());
98
99 for(auto && latency : latencies_)
100 csvFile << latency << std::endl;
101
102 csvFile.close();
103}
static Timestamp utcNow()
Returns current UTC time.