@@ -2325,24 +2325,20 @@ <h3>Handling Liquibook Events</h3>
23252325} } // End namespace
23262326</ pre >
23272327
2328+ < h3 > Initialization</ h3 >
23282329< p >
23292330 At this point the publisher has all the necessary parts to publish a trade
23302331 feed and an incremental depth feed for the exchange. The only things that
23312332 remains are to create, initialize, and associate the various parts, and to
23322333 generate the random orders.
23332334</ p >
23342335
2335- < h3 > Initialization</ h3 >
2336- publisher_main.cpp
2337-
2338- < h3 > Setting up the Exchange</ h3 >
2339-
23402336< p >
23412337 The exchange is initialized in the file < code > publisher_main.cpp</ code > .
23422338 The < code > main()</ code > function starts by establishing the securities to
2343- "trade" in our exchange - in this case the NASDAQ 100 - taken from a snapshot
2344- in April 2013. < code > main()</ code > records the symbol and a base price in
2345- a structure:
2339+ "trade" in our exchange - in this case the NASDAQ 100 - taken from a
2340+ snapshot in April 2013. < code > main()</ code > records the symbol and a base
2341+ price in a structure:
23462342</ p >
23472343
23482344< div class ="listing "> publisher_main.cpp: SecurityInfo structure</ div >
@@ -2364,17 +2360,14 @@ <h3>Setting up the Exchange</h3>
23642360< p >
23652361 The base price serves as a basis for generating random prices for the
23662362 example exchange. < code > main()</ code > keeps this security information in a
2367- < code > SecurityVector</ code > and populates it the
2363+ < code > SecurityVector</ code > and populates it in the
23682364 < code > create_securities()</ code > method, later in < code > main()</ code > .
23692365</ p >
23702366
2371- < h3 > Listening for Client Connections</ h3 >
2372-
23732367< p >
2374- An exchange must accept connections from feed clients in order to
2375- disseminate market data to them. The publisher does this through a class
2376- called < code > DepthFeedConnection</ code > , which is created in
2377- < code > main()</ code > :
2368+ The < code > main()</ code > function begins by creating the
2369+ < code > DepthFeedConnection</ code > , and having it accept connections in a
2370+ background thread, using Boost's thread library:
23782371</ p >
23792372
23802373< div class ="listing "> publisher_main.cpp: main() function</ div >
@@ -2392,109 +2385,136 @@ <h3>Listening for Client Connections</h3>
23922385</ pre >
23932386
23942387< p >
2395- The example exchange creates an instance of < code > DepthFeedConnection</ code > ,
2396- passing in the command-line arguments to configure it. The publisher then
2397- calls < code > DepthFeedConnection::accept()</ code > creates a background thread
2398- to execute < code > DepthFeedConnection::run()</ code > , using Boost's thread
2399- library.
2388+ Next, the < code > DepthFeedPublisher</ code > and the < code > Exchange</ code > are
2389+ created, and the< code > DepthFeedPublisher</ code > is made aware of the
2390+ < code > DepthFeedConnection</ code > :
24002391</ p >
24012392
2393+ < div class ="listing "> publisher_main.cpp: main() function, continued</ div >
2394+ < pre class ="code ">
2395+ // Create feed publisher
2396+ examples::DepthFeedPublisher feed;
2397+ feed.set_connection(&connection);
2398+
2399+ // Create exchange
2400+ examples::Exchange exchange(&feed, &feed);
2401+ </ pre >
2402+
24022403< p >
2404+ Note that the exchange constructor requires a < code > TradeListrner</ code > and
2405+ a < code > DepthListener</ code > , both of which the
2406+ < code > DepthFeedPublisher</ code > implements.
24032407</ p >
24042408
2405- < h3 > Populating the Exhange with Securities</ h3 >
24062409< p >
2407- The body of < code > create_securities()</ code > is not shown here, but it adds
2408- each of the one hundred constituents of the NASDAQ-100 to the vector. These
2409- are later added to the exchange, and also referenced while generating random
2410- orders.
2410+ Finally, the securities are created and used to populate the exchange, and
2411+ orders are generated.
24112412</ p >
24122413
2413- < h3 > Establishing the Publisher</ h3 >
2414+ < div class ="listing "> publisher_main.cpp: main() function, continued</ div >
2415+ < pre class ="code ">
2416+ // Create securities
2417+ SecurityVector securities;
2418+ create_securities(securities);
24142419
2415- < h3 > Populating the Exchange</ h3 >
2420+ // Populate exchange with securities
2421+ populate_exchange(exchange, securities);
2422+
2423+ // Generate random orders
2424+ generate_orders(exchange, securities);
24162425
2417- < h3 > Generating Random Orders</ h3 >
2426+ return 0;
2427+ }
2428+ </ pre >
24182429
2419- < h2 > Subscriber Application</ h2 >
24202430< p >
2421- There is also one or more subscribers, who are responsible for decoding the
2422- FAST messages and displaying the results in the console. The publisher
2423- listens for connections, and the subscribers connect to the publisher .
2431+ The final function call, to < code > generate_orders() </ code > is an infinite
2432+ loop, so there is no need to worry about the < code > main() </ code > method
2433+ returning .
24242434</ p >
24252435
24262436< p >
2427- The example exchange's order class inherits from < code > book::Order</ code >
2428- and implements its 3 pure virtual functions. Inheriting from the
2429- < code > book::Order</ code > class is not strictly necessary as the rest of
2430- Liquibook uses templates to bind to a specific order class. The trivial
2431- implementation of this class is omitted from this paper.
2437+ The helper function < code > create_securities()</ code > adds 100 securities to
2438+ the < code > SecurityVector</ code > :
24322439</ p >
24332440
2434- < h3 > Handling Trade Events</ h3 >
2435-
2436- < p >
2437- </ p >
2441+ < div class ="listing "> publisher_main.cpp: main() helper functions</ div >
2442+ < pre class ="code ">
2443+ void
2444+ create_securities(SecurityVector& securities) {
2445+ securities.push_back(SecurityInfo("AAPL", 436.36));
2446+ securities.push_back(SecurityInfo("ADBE", 45.06));
2447+ securities.push_back(SecurityInfo("ADI", 43.93));
24382448
2439- < h3 > Handling Order Book Events</ h3 >
2449+ // Repeated for 100 securities...
2450+ }
2451+ </ pre >
24402452
2441- < p >
24422453</ p >
2443-
2444- < h3 > </ h3 >
2445- < h3 > </ h3 >
2446-
2447- < h3 > The Feed Protocol</ h3 >
2448-
2454+ Due to the mercy of the author, the other 97 securities were omitted from
2455+ this paper. The next helper function, < code > populate_exchange()</ code > adds
2456+ these securities to the exchange:
24492457< p >
2450- </ p >
24512458
2452- < p >
2453- Here is an example of using some code in a sentence. When using the
2454- < code > String</ code > class, be sure to use < code > equals()</ code >
2455- instead of < code > =</ code > when comparing two strings.
2456- </ p >
2459+ < div class ="listing "> publisher_main.cpp: main() helper functions, continued</ div >
2460+ < pre class ="code ">
2461+ void
2462+ populate_exchange(examples::Exchange& exchange, const SecurityVector& securities) {
2463+ SecurityVector::const_iterator sec;
2464+ for (sec = securities.begin(); sec != securities.end(); ++sec) {
2465+ exchange.add_order_book(sec->symbol);
2466+ }
2467+ }
2468+ </ pre >
24572469
2458- < p >
2459- See < a href ="http://sett.ociweb.com/sett/settOct2012.html "> October 2012 SETT article</ a > for
2460- an example of displaying code. This method displays line numbers and handles multiple languages.
24612470</ p >
2462-
2471+ The final helper function, < code > generate_orders()</ code > creates random
2472+ orders and adds them to the exchange:
24632473< p >
2464- Make sure to put all referenced files used by the article in a folder called settMmmYyyy_files where Mmm is the
2465- article month and Yyyy is the article year. For example, settOct2012_files.
2466- </ p >
24672474
2468- < p >
2469- Also, make sure your article contains standard ascii characters. Use ", ', - instead of
2470- forward/backward quotes or ticks. Microsoft word replaces these characters by default. Please
2471- ensure your article encode these characters properly.
2472- </ p >
2473- < table border ="2 " cellpadding ="2 " cellspacing ="5 ">
2474- < tr >
2475- < th > Bad Example</ th >
2476- < th > Good Example</ th >
2477- </ tr >
2478- < tr >
2479- < td > “example quotes”</ td >
2480- < td > “example quotes”</ td >
2481- </ tr >
2482- < tr >
2483- < td > ‘another example’</ td >
2484- < td > ‘another example’</ td >
2485- </ tr >
2486- < tr >
2487- < td > hyphens – anyone?</ td >
2488- < td > hyphens — anyone?</ td >
2489- </ tr >
2490- < tr >
2491- < td > dot dot dot</ td >
2492- < td > dot dot dot …</ td >
2493- </ tr >
2494- </ table >
2475+ < div class ="listing "> publisher_main.cpp: main() helper functions, continued</ div >
2476+ < pre class ="code ">
2477+
2478+ void
2479+ generate_orders(examples::Exchange& exchange, const SecurityVector& securities) {
2480+ time_t now;
2481+ time(&now);
2482+ std::srand(now);
2483+
2484+ size_t num_securities = securities.size();
2485+ while (true) {
2486+ // which security
2487+ size_t index = std::rand() % num_securities;
2488+ const SecurityInfo& sec = securities[index];
2489+ // side
2490+ bool is_buy = std::rand() % 2;
2491+ // price
2492+ uint32_t price_base = sec.ref_price * 100;
2493+ uint32_t delta_range = price_base / 50; // +/- 2% of base
2494+ int32_t delta = std::rand() % delta_range;
2495+ delta -= (delta_range / 2);
2496+ double price = double (price_base + delta) / 100;
2497+
2498+ // qty
2499+ book::Quantity qty = (std::rand() % 10 + 1) * 100;
2500+
2501+ // order
2502+ examples::OrderPtr order(new examples::Order(is_buy, price, qty));
2503+
2504+ // add order
2505+ exchange.add_order(sec.symbol, order);
2506+
2507+ // Wait for eyes to read
2508+ sleep(1);
2509+ }
2510+ }
2511+ </ pre >
24952512
24962513< p >
2497- If you need to use these, be sure to use the appropriate unicode escape sequence.
2514+ The implementation of < code > generate_orders()</ code > is somewhat complex, but
2515+ not relevant. There is a call to < code > sleep()</ code > inside the loop, so
2516+ that the data stream is produced at a somewhat readable pace. At this
2517+ point, the publisher is complete.
24982518</ p >
24992519
25002520< h2 > Final Big Topic</ h2 >
0 commit comments