Coder Social home page Coder Social logo

liquibook's Introduction

Liquibook

Open source order matching engine

Liquibook provides the low-level components that make up an order matching engine.

Order matching is the process of accepting buy and sell orders for a security (or other fungible asset) and matching them to allow trading between parties who are otherwise unknown to each other.

An order matching engine is the heart of every financial exchange, and may be used in many other circumstances including trading non-financial assets, serving as a test-bed for trading algorithms, etc.

A typical Liquibook-based application might look something like this: Market Application

In addition to the order matching process itself, Liquibook can be configured to maintain an "depth book" that records the number of open orders and total quantity represented by those orders at individual price levels.

Example of an depth book

  • Symbol XYZ:
    • Buy Side:
      • $53.20 per share: 1203 orders; 150,398 shares.
      • $53.19 per share: 87 orders; 63,28 shares
      • $52.00 per share 3 orders; 2,150 shares
    • Sell Side
      • $54.00 per share 507 orders; 120,700 shares
      • etc...

Order properties supported by Liquibook.

Liquibook is aware of the following order properties.

  • Side: Buy or Sell
  • Quantity
  • Symbol to represent the asset to be traded
    • Liquibook imposes no restrictions on the symbol. It is treated as a simple character string.
  • Desired price or "Market" to accept the current price defined by the market.
    • Trades will be generated at the specified price or any better price (higher price for sell orders, lower price for buy orders)
  • Stop loss price to hold the order until the market price reaches the specified value.
    • This is often referred to as simply a stop price.
  • All or None flag to specify that the entire order should be filled or no trades should happen.
  • Immediate or Cancel flag to specify that after all trades that can be made against existing orders on the market have been made, the remainder of the order should be canceled.
    • Note combining All or None and Immediate or Cancel produces an order commonly described as Fill or Kill.

The only required properties are side, quantity and price. Default values are available for the other properties.

The application can define addtional properties on the order object as necessary. These properties will have no impact on the behavior of Liquibook.

Operations on Orders

In addition to submitting orders, traders may also submit requests to cancel or modify existing orders. (Modify is also know as cancel/replace) The requests may succeed or fail depending on previous trades executed against the order.

Notifications returned to the application.

Liquibook will notify the application when significant events occur to allow the application to actually execute the trades identified by Liquibook, and to allow the application to publish market data for use by traders.

The notifications generated include:

  • Notifications intended for trader submitting an order:
    • Order accepted
    • Order rejected
    • Order filled (full or partial)
    • Order replaced
    • Replace request rejected
    • Order canceled
    • Cancel request rejected.
  • Notifications intended to be published as Market Data
    • Trade
      • Note this should also trigger the application to do what it needs to do to make the trade happen.
    • Security changed
      • Triggered by any event that effects a security
        • Does not include rejected requests.
    • Notification of changes in the depth book (if enabled)
      • Depth book changed
      • Best Bid or Best Offer (BBO) changed.

Performance

  • Liquibook is written in C++ using modern, high-performance techniques. This repository includes the source of a test program that can be used to measure Liquibook performance.
    • Benchmark testing with this program shows sustained rates of
      2.0 million to 2.5 million inserts per second.

As always, the results of this type of performance test can vary depending on the hardware and operating system on which you run the test, so use these numbers as a rough order-of-magnitude estimate of the type of performance your application can expect from Liquibook.

Works with Your Design

  • Allows an application to use smart or regular pointers to orders.
  • Compatible with existing order model,
    • Requires a trivial interface which can be added to or wrapped around an existing Order object.
  • Compatible with existing identifiers for securities, accounts, exchanges, orders, fills

Example

This repository contains two complete example programs. These programs can be used to evaluate Liquibook to see if it meets your needs. They can also be used as models for your application or even incorporated directly into your application thanks to the liberal license under which Liquibook is distributed.

The examples are:

  • Depth feed publisher and subscriber

    • Generates orders that are submitted to Liquibook and publishes the resulting market data.
    • Uses QuickFAST to publish the market data
  • Manual Order Entry

Building Liquibook

The good news is you don't need to build Liquibook. The core of Liquibook is a header-only library, so you can simply add Liquibook/src to your include path then #include <book/order_book.h> to your source, and Liquibook will be available to be used in your application.

However, this repository includes tests and example programs for Liquibook. These programs need to be compiled and built in order to run them. The remainder of this section describes how to do this.

Dependencies

Liquibook has no runtime dependencies. It will run in any environment that can run C++ programs.

To build the Liquibook test and example programs from source you need to create makefiles (for linux, et al.) or Project and Solution files for Windows Visual Studio.

Liquibook uses MPC to create these platform-dependent files from a common build definition:

  • MPC for cross-platform builds.

    MPC itself is written in perl, so your environment needs a working Perl compiler. Most linux systems already have this. If you need a Perl compiler on Windows, OCI recommends Active State Perl V5.x or later

If you wish to build the unit tests for Liquibook, you will also need the boost test library:

  • BOOST (optional) for unit testing.

One of the example programs (publish and subscribe to market data) uses QuickFAST to encode and decode market data messages. If you wish to run this example you need QuickFAST:

  • QuickFAST (optional) for building the example depth feed publisher/subscriber.

    QuickFAST his its own dependencies which are described on its web page.

Submodule Note

The Assertive test framework was used in previous versions, but it is no longer needed.
If you have imported this submodule to support previous versions, you may delete the liquibook/test/unit/assertiv directory.

Getting ready to build the tests and example programs.

Boost Test

If you want to run the Liquibook unit tests (highly recommended!) you should install and/or build boost test before trying to build Liquibook. Boost test is used in the multifile-test mode rather than simple header-only mode so the compiled boost test library must be available.

Please follow the instructions on the boost web site for building/installing the library in your environment. When you are done you should export the $BOOST_ROOT environment varialble.

Because of the many boost build options, please check to be sure that the include files and library files are in the expected locations. MPC expects to find:

  • Include files in $BOOST_ROOT/include/boost
  • Library files in $BOOST_ROOT/lib

If you prefer not to install boost you can edit the liquibook.features file to change the appropriate line to say boost=0 This will disable building the unit tests.

QuickFAST

The publish and subscribe example program uses QuickFAST. If you want to run this example program, please see the QuickFAST web site to download and build this library.

Set the environment variable $QUICKFAST_ROOT to point to the location where you installed and build QuickFAST.

Before running MPC you should also edit the file liquibook.features to set the value QuickFAST=1

If you do not plan to run this example program, set the environment variable QUICKFAST_ROOT to liquibook/noQuickFAST.

Building Liquibook on Linux

The env.sh script uses the readlink program which is present on most Linux/Unix systems. If you don't have readlink, set the $LIQUIBOOK_ROOT environment variable the directory containing liquibook before running env.sh

Open a shell and type:

$ cd liquibook
$ . ./env.sh
$ $MPC_ROOT/mwc.pl -type make liquibook.mwc
$ make depend
$ make all

Output from build

  • The Liquibook test and example libraries will be in $LIQUIBOOK_ROOT/lib
  • The Liquibook example programs will be in $LIQUIBOOK_ROOT/bin
  • The Liquibook test programs will be in $LIQUIBOOK_ROOT/bin/test

Building Liquibook examples and test programs with Visual Studio

Use the following commands to set up the build environment and create Visual Studio project and solution files. Note if you are using MinGW or other linux-on-Windows techniques, follow the Linux instructions; however, OCI does not normally test this.

> cd liquibook
> copy winenv.bat w.bat #optional if you want to keep the original
                        # note that single character batch file names are ignored in 
                        # .getignore so the customized
                        # file will not be checked into the git repository (a good thing.)
> edit w.bat            # edit is your choice of text editor
                        # follow the instructions in the file itself.
> w.bat                 # sets and verifies environment variables
> mpc.bat               # generate the visual studio solution and project files.

Then:

  • Start Visual Studio from the command line by typing liquibook.sln or
  • Start Visual Studio from the Windows menu and use the menu File|Open|Project or Solution to load liquibook.sln.

For any platform

Liquibook should work on any platform with a modern C++ compiler (supporting at least C++11.)

The MPC program used to create the build files and the Boost library used in the tests and some of the examples support a wide variety of platforms.

See the MPC documentation for details about using MPC in your enviornment.

See the Boost website for details about using Boost in your environment.

liquibook's People

Contributors

bschne avatar dale-wilson avatar damanpreet-bittmax avatar doomhz avatar enewhuis avatar iamtheschmitzer avatar jrw972 avatar thakkarparth007 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

liquibook's Issues

Compile error

OS: Ubuntu 16.04.3 LTS
Compiler: gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5)

g++ -std=c++11 -I/usr/local/boost-1.63.0/include -I/usr/local/boost-1.63.0/include/boost -fPIC -O -D_REENTRANT -I"/usr/local/boost-1.63.0/include/boost-1.63.0" -I"/usr/local/boost-1.63.0/." -I"/home/ubuntu/liquiboo/quickfast/src" -I"/home/ubuntu/liquiboo/liquibook/src" -c -o "subscriber_main.o" subscriber_main.cpp
In file included from /usr/local/boost-1.63.0/include/boost/bind.hpp:22:0,
from subscriber_main.cpp:2:
/usr/local/boost-1.63.0/include/boost/bind/bind.hpp: In instantiation of 'R boost::_bi::list3<A1, A2, A3>::operator()(boost::_bi::type, F&, A&, long int) [with R = bool; F = boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>; A = boost::_bi::rrlist2<boost::shared_ptr<boost::array<unsigned char, 128ul> >, long unsigned int>; A1 = boost::_bi::valueliquibook::examples::DepthFeedSubscriber*; A2 = boost::arg<1>; A3 = boost::arg<2>]':
/usr/local/boost-1.63.0/include/boost/bind/bind.hpp:1318:50: required from 'boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&, A2&&) [with A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; A2 = long unsigned int; R = bool; F = boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>; L = boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> >; boost::_bi::bind_t<R, F, L>::result_type = bool]'
/usr/local/boost-1.63.0/include/boost/function/function_template.hpp:138:22: required from 'static R boost::detail::function::function_obj_invoker2<FunctionObj, R, T0, T1>::invoke(boost::detail::function::function_buffer&, T0, T1) [with FunctionObj = boost::_bi::bind_t<bool, boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int]'
/usr/local/boost-1.63.0/include/boost/function/function_template.hpp:936:38: required from 'void boost::function2<R, T1, T2>::assign_to(Functor) [with Functor = boost::_bi::bind_t<bool, boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int]'
/usr/local/boost-1.63.0/include/boost/function/function_template.hpp:727:7: required from 'boost::function2<R, T1, T2>::function2(Functor, typename boost::enable_if_c<(! boost::is_integral::value), int>::type) [with Functor = boost::_bi::bind_t<bool, boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int; typename boost::enable_if_c<(! boost::is_integral::value), int>::type = int]'
/usr/local/boost-1.63.0/include/boost/function/function_template.hpp:1072:16: required from 'boost::function<R(T0, T1)>::function(Functor, typename boost::enable_if_c<(! boost::is_integral::value), int>::type) [with Functor = boost::bi::bind_t<bool, boost::mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::bi::list3<boost::bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int; typename boost::enable_if_c<(! boost::is_integral::value), int>::type = int]'
subscriber_main.cpp:19:34: required from here
/usr/local/boost-1.63.0/include/boost/bind/bind.hpp:388:42: error: no match for call to '(boost::mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>) (liquibook::examples::DepthFeedSubscriber*&, boost::shared_ptr<boost::array<unsigned char, 128ul> >, long unsigned int)'
return unwrapper::unwrap(f, 0)(a[base_type::a1
], a[base_type::a2
], a[base_type::a3
]);
^
In file included from /usr/local/boost-1.63.0/include/boost/bind/mem_fn.hpp:215:0,
from /usr/local/boost-1.63.0/include/boost/mem_fn.hpp:22,
from /usr/local/boost-1.63.0/include/boost/bind/bind.hpp:26,
from /usr/local/boost-1.63.0/include/boost/bind.hpp:22,
from subscriber_main.cpp:2:
/usr/local/boost-1.63.0/include/boost/bind/mem_fn_template.hpp:278:7: note: candidate: R boost::mfi::mf2<R, T, A1, A2>::operator()(T*, A1, A2) const [with R = bool; T = liquibook::examples::DepthFeedSubscriber; A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >&; A2 = long unsigned int]
R operator()(T * p, A1 a1, A2 a2) const
^
/usr/local/boost-1.63.0/include/boost/bind/mem_fn_template.hpp:278:7: note: conversion of argument 2 would be ill-formed:
In file included from /usr/local/boost-1.63.0/include/boost/bind.hpp:22:0,
from subscriber_main.cpp:2:
/usr/local/boost-1.63.0/include/boost/bind/bind.hpp:388:42: error: invalid initialization of non-const reference of type 'boost::shared_ptr<boost::array<unsigned char, 128ul> >&' from an rvalue of type 'boost::shared_ptr<boost::array<unsigned char, 128ul> >'
return unwrapper::unwrap(f, 0)(a[base_type::a1
], a[base_type::a2
], a[base_type::a3
]);

However, compiles successfully without boost.

Unable to cancel stop order if it has not been triggered

OrderBook::cancel(const OrderPtr& order) function does not check for the order in stop orders during cancellation.
So if you place a cancel order for stop order that has not been triggered yet you will not be able to cancel it and a cancel reject callback is generated.

Correct behaviour:

  1. Try to cancel the order in normal orders.
  2. If order exists, generate cancel callback, else check for the order in stop orders.
  3. If order exists, generate cancel callback else cancel reject callback.

I can submit a pull request if required.

Issue in usage of fill_cost when quantity is in decimal places.

In cb_order_fill callback:

Cost fill_cost = cb.price * cb.quantity;
Both price and quantity have been multiplied their respective precisions to convert to int64_t:
i.e. price = 100.00 USD -> 10000, quantity 5.00 -> 500

so according to the formula fill_cost is 10000 * 500 -> 5000000 or 50000.00
which is wrong,

Correct fill_cost = 100.00 * 5.00 = 500.00

It would be better to not calculate fill_cost as there is no need for it in liquibook and save computation.

unable to compile liquibook on ubuntu 16.04

My OS is ubuntu 16.04
gcc version 6.4.0

I am trying to compile Liquibook
I installed MPC, Xercesc, Boost_1_62_0, Quickfast and all other dependencies
Exposed all variables : QUICKFAST_ROOT, MPC_ROOT, XERCES_ROOT, BOOST_ROOT and all related lib and include variables. env.sh did not run properly so I manually exposed LIQUIBOOK_ROOT to the folder where I extracted the zip downloaded from this git.
I run following :
$MPC_ROOT/mwc.pl -type make liquibook.mwc -- done
$ make depend -- done
$ make all -- error following:

uss1@USS:~/Work/Trade_Server/Liquidbook/liquibook-master/examples/depth_feed_publisher$ make allmake[1]: Entering directory '/home/uss1/Work/Trade_Server/Liquidbook/liquibook-master/examples/depth_feed_publisher'
make[1]: Nothing to be done for 'all'.
make[1]: Leaving directory '/home/uss1/Work/Trade_Server/Liquidbook/liquibook-master/examples/depth_feed_publisher'
make[1]: Entering directory '/home/uss1/Work/Trade_Server/Liquidbook/liquibook-master/examples/depth_feed_publisher'
g++ -fPIC -O -D_REENTRANT -I"/usr/local/lib//include/boost-1_62_0" -I"/usr/local/lib//." -I"/home/uss1/Work/Trade_Server/Liquidbook/quickfast/quickfast-master//src" -I"/home/uss1/Work/Trade_Server/Liquidbook/liquibook-master//src" -c -o "subscriber_main.o" subscriber_main.cpp
In file included from /usr/include/boost/bind.hpp:22:0,
from subscriber_main.cpp:2:
/usr/include/boost/bind/bind.hpp: In instantiation of ‘R boost::_bi::list3<A1, A2, A3>::operator()(boost::_bi::type, F&, A&, long int) [with R = bool; F = boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>; A = boost::_bi::list2<const boost::shared_ptr<boost::array<unsigned char, 128ul> >&, const long unsigned int&>; A1 = boost::_bi::valueliquibook::examples::DepthFeedSubscriber*; A2 = boost::arg<1>; A3 = boost::arg<2>]’:
/usr/include/boost/bind/bind.hpp:917:50: required from ‘boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()(A1&&, A2&&) [with A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; A2 = long unsigned int; R = bool; F = boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>; L = boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> >; boost::_bi::bind_t<R, F, L>::result_type = bool]’
/usr/include/boost/function/function_template.hpp:138:22: required from ‘static R boost::detail::function::function_obj_invoker2<FunctionObj, R, T0, T1>::invoke(boost::detail::function::function_buffer&, T0, T1) [with FunctionObj = boost::_bi::bind_t<bool, boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int]’
/usr/include/boost/function/function_template.hpp:940:38: required from ‘void boost::function2<R, T1, T2>::assign_to(Functor) [with Functor = boost::_bi::bind_t<bool, boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int]’
/usr/include/boost/function/function_template.hpp:728:7: required from ‘boost::function2<R, T1, T2>::function2(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral::value>::value, int>::type) [with Functor = boost::_bi::bind_t<bool, boost::_mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::_bi::list3<boost::_bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral::value>::value, int>::type = int]’
/usr/include/boost/function/function_template.hpp:1077:16: required from ‘boost::function<R(T0, T1)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral::value>::value, int>::type) [with Functor = boost::bi::bind_t<bool, boost::mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>, boost::bi::list3<boost::bi::valueliquibook::examples::DepthFeedSubscriber*, boost::arg<1>, boost::arg<2> > >; R = bool; T0 = boost::shared_ptr<boost::array<unsigned char, 128ul> >; T1 = long unsigned int; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral::value>::value, int>::type = int]’
subscriber_main.cpp:19:34: required from here
/usr/include/boost/bind/bind.hpp:382:42: error: no match for call to ‘(boost::mfi::mf2<bool, liquibook::examples::DepthFeedSubscriber, boost::shared_ptr<boost::array<unsigned char, 128ul> >&, long unsigned int>) (liquibook::examples::DepthFeedSubscriber*&, const boost::shared_ptr<boost::array<unsigned char, 128ul> >&, const long unsigned int&)’
return unwrapper::unwrap(f, 0)(a[base_type::a1
], a[base_type::a2
], a[base_type::a3
]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/bind/bind.hpp:26,
from /usr/include/boost/bind.hpp:22,
from subscriber_main.cpp:2:
/usr/include/boost/bind/mem_fn_template.hpp:278:7: note: candidate: R boost::mfi::mf2<R, T, A1, A2>::operator()(T*, A1, A2) const [with R = bool; T = liquibook::examples::DepthFeedSubscriber; A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >&; A2 = long unsigned int]
R operator()(T * p, A1 a1, A2 a2) const
^~~~~~~~
/usr/include/boost/bind/mem_fn_template.hpp:278:7: note: conversion of argument 2 would be ill-formed:
In file included from /usr/include/boost/bind.hpp:22:0,
from subscriber_main.cpp:2:
/usr/include/boost/bind/bind.hpp:382:42: error: binding ‘const boost::shared_ptr<boost::array<unsigned char, 128ul> >’ to reference of type ‘boost::shared_ptr<boost::array<unsigned char, 128ul> >&’ discards qualifiers
return unwrapper::unwrap(f, 0)(a[base_type::a1
], a[base_type::a2
], a[base_type::a3
]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/bind/bind.hpp:26,
from /usr/include/boost/bind.hpp:22,
from subscriber_main.cpp:2:
/usr/include/boost/bind/mem_fn_template.hpp:283:25: note: candidate: template R boost::mfi::mf2<R, T, A1, A2>::operator()(U&, A1, A2) const [with U = U; R = bool; T = liquibook::examples::DepthFeedSubscriber; A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >&; A2 = long unsigned int]
template R operator()(U & u, A1 a1, A2 a2) const
^~~~~~~~
/usr/include/boost/bind/mem_fn_template.hpp:283:25: note: template argument deduction/substitution failed:
In file included from /usr/include/boost/bind.hpp:22:0,
from subscriber_main.cpp:2:
/usr/include/boost/bind/bind.hpp:382:42: note: cannot convert ‘(& a)->boost::bi::list2<A1, A2>::operator[]<const boost::shared_ptr<boost::array<unsigned char, 128ul> >&, const long unsigned int&>(boost::bi::storage2<A1, boost::arg >::a2<boost::bi::valueliquibook::examples::DepthFeedSubscriber*, 1>)’ (type ‘const boost::shared_ptr<boost::array<unsigned char, 128ul> >’) to type ‘boost::shared_ptr<boost::array<unsigned char, 128ul> >&’
return unwrapper::unwrap(f, 0)(a[base_type::a1
], a[base_type::a2
], a[base_type::a3
]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/bind/bind.hpp:26,
from /usr/include/boost/bind.hpp:22,
from subscriber_main.cpp:2:
/usr/include/boost/bind/mem_fn_template.hpp:291:25: note: candidate: template R boost::mfi::mf2<R, T, A1, A2>::operator()(const U&, A1, A2) const [with U = U; R = bool; T = liquibook::examples::DepthFeedSubscriber; A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >&; A2 = long unsigned int]
template R operator()(U const & u, A1 a1, A2 a2) const
^~~~~~~~
/usr/include/boost/bind/mem_fn_template.hpp:291:25: note: template argument deduction/substitution failed:
In file included from /usr/include/boost/bind.hpp:22:0,
from subscriber_main.cpp:2:
/usr/include/boost/bind/bind.hpp:382:42: note: cannot convert ‘(& a)->boost::bi::list2<A1, A2>::operator[]<const boost::shared_ptr<boost::array<unsigned char, 128ul> >&, const long unsigned int&>(boost::bi::storage2<A1, boost::arg >::a2<boost::bi::valueliquibook::examples::DepthFeedSubscriber*, 1>)’ (type ‘const boost::shared_ptr<boost::array<unsigned char, 128ul> >’) to type ‘boost::shared_ptr<boost::array<unsigned char, 128ul> >&’
return unwrapper::unwrap(f, 0)(a[base_type::a1
], a[base_type::a2
], a[base_type::a3
]);
~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/bind/mem_fn.hpp:215:0,
from /usr/include/boost/mem_fn.hpp:22,
from /usr/include/boost/bind/bind.hpp:26,
from /usr/include/boost/bind.hpp:22,
from subscriber_main.cpp:2:
/usr/include/boost/bind/mem_fn_template.hpp:299:7: note: candidate: R boost::_mfi::mf2<R, T, A1, A2>::operator()(T&, A1, A2) const [with R = bool; T = liquibook::examples::DepthFeedSubscriber; A1 = boost::shared_ptr<boost::array<unsigned char, 128ul> >&; A2 = long unsigned int]
R operator()(T & t, A1 a1, A2 a2) const
^~~~~~~~
/usr/include/boost/bind/mem_fn_template.hpp:299:7: note: no known conversion for argument 1 from ‘liquibook::examples::DepthFeedSubscriber*’ to ‘liquibook::examples::DepthFeedSubscriber&’
Makefile.depth_feed_subscriber:95: recipe for target 'subscriber_main.o' failed
make[1]: *** [subscriber_main.o] Error 1
make[1]: Leaving directory '/home/uss1/Work/Trade_Server/Liquidbook/liquibook-master/examples/depth_feed_publisher'
Makefile:33: recipe for target 'depth_feed_subscriber' failed
make: *** [depth_feed_subscriber] Error 2

Question: how to get Nasdaq orders real time?

sir, i am learning HFT related knowledge, i think your project powerful, but i don't know how to connect nasdaq get stock limit orders data real time, can you share something or documents? thanks !!!!

errors when trying to build on windows

Hi!

question I was hoping someone knowledgeable could assist when building liquibook on windows 7 (64 bit)

I'm trying to build on windows using the command:

mwc.pl -type vc10 liquibook.mwc

for some reason i'm getting the error below about QuickFASTApplication, and depth_feed_publisher,mpc (which does exist) :

c:\GitHub\liquibook>C:\ACE_wrappers\bin\mwc.pl -type vc10 liquibook.mwc
MPC_ROOT was set to C:\ACE_wrappers\MPC.
Using C:/ACE_wrappers/bin/MakeProjectCreator/config/MPC.cfg
CIAO_ROOT was used in the configuration file, but was not defined.
DANCE_ROOT was used in the configuration file, but was not defined.
Generating 'vc10' output using liquibook.mwc
WARNING: liquibook.mwc: Command line files specified in a workspace are ignored.

Skipping ut_order_book_shared_ptr (liquibook_unit.mpc), it requires boost.
depth_feed_publisher.mpc: line 2:
ERROR: Unable to locate parent: QuickFASTApplication
liquibook.mwc: line 5:
ERROR: Unable to process examples/depth_feed_publisher/depth_feed_publisher.mpc
ERROR: Unable to process: liquibook.mwc

What am I missing ?
do i need to download quickfix.dll / other ?

Many thanks
Dror

Unable to compile the Manual Order Entry example on Ubuntu

Hi, I didn't want to install Boost so I followed the instructions as stated (edited env.sh). But when I run ./env.sh I still get this error "Please export BOOST_VERSION, and BOOST_CFG. You can also set BOOST_ROOT if it is not in /usr/boost/BOOST_VERSION". The next command $MPC_ROOT/mwc.pl - type make liquibook.mwc gives the error "No such file or directory". I realized that $MPC_ROOT is not defined but I am not sure what to set it as. Note that I am already able to compile C++ 11 programs in this environment (which I believed was the minimum requirement). I am just trying to build a binary out of your manual order entry example. Please help!

type.h big customized datatypes, allowing to processing large datatypes

Currently liquibook is unable to handle processing large datatypes which are greater than 64-bit values.
It would be great if code allows user to define customized datatypes in order to handle process bigger values under liquibook/src/book/type.h

for example:
instead of

typedef uint32_t Price;
typedef uint32_t Quantity;
typedef uint32_t Cost;

User wants to define something similar to:

include "uint128.h"

typedef uint128_t Price;
typedef uint128_t Quantity;
typedef uint128_t Cost;

Purpose of #if defined LIQUIBOOK_ORDER_KNOWS_CONDITIONS

Hello,

I was working through the code and was just wondering what the purpose of the macro LIQUIBOOK_ORDER_KNOWS_CONDITIONS was. I understand there is some notion of whether the order knows its conditions, but was wondering why the order would not know that.

Multithreaded scenario

Hello, I was wondering if you have done some performance testing of your book in a multithreaded scenario? For e.g. 1 thread per book, and a total of X threads writing to their respective books.

I ask because I noticed you're stl collection and are relying on stl::allocator. With multiple threads hitting the team simultaneously, I wonder how will the performance change.

incorrect test

In test/unit/ut_all_or_none.cpp there is a test TestOneBidTwoAonAsk. But in code test creates aon bid and two asks with no conditions. There is already TestOneAonBidTwoAsk which does the same

Order replace issue

In order_book.h there is issue with order replace. Instead of quantity on market, original quantity is used for modification. It corrupts the book and causes issue in CloseOrder for price modify while deleting older order.

In order_book.h

case TypedCallback::cb_order_replace:
on_replace(cb.order,
cb.order->order_qty(),
cb.order->order_qty() + cb.delta,
cb.price);
if(order_listener_)
{
order_listener_->on_replace(cb.order,
cb.delta,
cb.price);
}
break;

Should be
case TypedCallback::cb_order_replace:
on_replace(cb.order,
cb.quantity_,
cb.quantity_ + cb.delta,
cb.price);
if(order_listener_)
{
order_listener_->on_replace(cb.order,
cb.delta,
cb.price);
}
break;

if liquibook suitable to reconstruct orderbook from FAST?

I'm not sure if this is the right place to ask general, not directly related to code, questions. I'm sorry if it is not so (probably you can suggest newsgroup or something?)

I want to use liquibook for constructing orderbook from FAST. This means that i don't need to do "matching" because it already did by exchange, instead I only need to process and "aggregate" such structures:

struct OrderUpdate {
int32_t instrumentId;
uint32_t MDEntryID;
uint32_t MDUpdateAction; // 0 - New 1 - Change 2 -Delete
int64_t MDEntryPx_Mantissa;
int16_t MDEntryPx_Exponent;
int64_t MDEntrySize_Mantissa;
int16_t MDEntrySize_Exponent;
uint32_t RptSeq;
uint32_t MDEntryTime;
uint32_t OrigTime;
int32_t SecurityTradingStatus;
char MDEntryType; // 0 - buy; 1 - sell;
char MsgType;
};

If liquibook is suitable for such work and probably any suggestions how exactly it should be used? Thanks!

Incorrect behaviour with orderbook::find_bid and orderbook::find_ask

This is a rather subtle bug, but can cause a lot of trouble. The find_bid and ask_bid methods are similar and both have the same bug. Consider the code for find_bid:

template <class OrderPtr>
inline void
OrderBook<OrderPtr>::find_bid(
  const OrderPtr& order,
  typename Bids::iterator& result)
{
  // Find the order search price
  Price search_price = sort_price(order);
  for (result = bids_.find(search_price); result != bids_.end(); ++result) {
    // If this is the correct bid
    if (result->second.ptr() == order) {
      break;
    // Else if this bid's price is too low to match the search price
    } else if (result->first < search_price) {
      // Here lies that bug.
      break; // No more possible
    }
  }
}

If you see carefully, then the value of result is not set to bid_.end() if the loop breaks in the else condition. This can happen if, for example, there are 2 bids of same price (100, 100) and another bid of 101. Now, if by mistake someone cancels 101 twice (which is possible if one isn't careful), or someone cancels an order that doesn't exist (which is again possible, but less probably than the first case), then one of the 100-bid would be cancelled too.

I've checked only the cancel part, but find_bid is also used in replace and similar situation can arise over there.

The tests don't consider this situation, and hence the code builds fine. The solution is to set result = bids_.end() in the else before breaking. The same thing needs to be done in find_ask.

Quickfast application not found

I'm attempting to build the application, I've downloaded and unzipped the MPC build tools, and placed them in a directory relative to my clone of the source.

When I run: ../mpc.pl/mwc.pl -type make liquibook.mwc

I get:

ERROR: Unable to locate parent: QuickFASTApplication

Is this the result of not having set the the $MPC_ROOT env variable?

I tried referencing it set=/home/jordanbuacke/MPC/ but that doesn't help.

Haven't built a C++ app in a while with custom tools so I'm probably just doing something wrong.

Thanks

Btw, I'm in ubuntu server 12.04

"git submodule update" failed

Hi

Thank you OCI for open-sourcing this interesting project!
Just starting, so easy question.
I'm following build instruction and executing this step:

cd liquibook
git submodule init
git submodule update

However the last step is failed. What's wrong and how to fix it? Attaching log.

Thanks,
Oleg

C:\Oleg\wssGit>cd liquibook

C:\Oleg\wssGit\liquibook>git submodule init
Submodule 'test/unit/assertiv' ([email protected]:iamtheschmitzer/assertiv.git) reg
istered for path 'test/unit/assertiv'

C:\Oleg\wssGit\liquibook>git submodule update
Cloning into 'test/unit/assertiv'...
The authenticity of host 'github.com (192.30.252.131)' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:3d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'github.com,192.30.252.131' (RSA) to the list of know
n hosts.
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Clone of '[email protected]:iamtheschmitzer/assertiv.git' into submodule path 'test
/unit/assertiv' failed

Error in test?

First of all, my apologies for not being able to run through the tests, however, both the comments and source and source give an indication of a problem. I ran into this issue as I was porting to C#.

Is there an issue with these two tests, i.e TestAonAskNoMatchMulti and TestAonBidNoMatchMulti?

Re TestAonAskNoMatchMulti, below should be the order book at the time Ask1 is added. I believe there should be no trade because of no match? Ask1+Bid1 (match, remaining q = 500), Ask 1 + Bid2 (match, remaining q = 100) and then finally Ask1 + Bid0 (no match, not enough quantity for Bid0, therefore not enough quantity for Ask1). Therefore, roll back whole transaction.

Bids Asks
Order Time Price Quantity Conditions Order Time Price Quantity Conditions
Bid1 3 1251 100 AON Ask1 5 1250 600 AON
Bid2 4 1251 400 N/A Ask0 1 1252 100 N/A
Bid0 2 1250 400 AON

Here's the order book state for the second test just after bid1 is added. Again I don't expect a match.

Bids Asks
Order Time Price Quantity Conditions Order Time Price Quantity Conditions
Bid1 5 1251 600 AON Ask0 2 1251 400 N/A
Bid0 1 1250 100 N/A Ask1 3 1252 100 N/A
Ask2 4 1252 400 AON

Am I missing something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.