Exemplo n.º 1
0
def test_to_detailed_json():
    # this is only testing that it isn't broken / bad code
    prod = Product("AAA", "Some Product named AAA")
    prod.set_identifier("CUSIP", "12345")
    prod.set_identifier("internal_id", "8u98792")
    mrkt = Market(prod, ENDPOINT, PRICE_FACTORY)
    json.dumps(mrkt.to_detailed_json())
Exemplo n.º 2
0
def test_failed_instantiation_products_not_the_same():
    market1 = Market(Product("MSFT", "Microsoft"), Endpoint("Nasdaq", "NSDQ"),
                     PriceFactory(".01"))
    market2 = Market(Product("APPL", "Apple"), Endpoint("Nasdaq", "NSDQ"),
                     PriceFactory(".01"))
    bid_quote = Quote(market1, BID_SIDE, "25.23", 18)
    ask_quote = Quote(market2, ASK_SIDE, "26.20", 233)
    with pytest.raises(Exception):
        TwoSidedQuote(bid_quote, ask_quote)
Exemplo n.º 3
0
def test_failed_set_sell_quote_wrong_product():
    market1 = Market(Product("MSFT", "Microsoft"), Endpoint("Nasdaq", "NSDQ"),
                     PriceFactory("0.01"))
    market2 = Market(Product("APPL", "Apple"), Endpoint("Nasdaq", "NSDQ"),
                     PriceFactory("0.01"))
    bid_quote = Quote(market1, BID_SIDE, "25.23", 18)
    ask_quote = Quote(market1, ASK_SIDE, "26.20", 233)
    ask_quote2 = Quote(market2, ASK_SIDE, "25.98", 3)
    tsq = TwoSidedQuote(bid_quote, ask_quote)
    with pytest.raises(Exception):
        tsq.set_sell_quote(ask_quote2)
Exemplo n.º 4
0
def test_default_market_creation():
    mrkt = Market(PRODUCT, ENDPOINT, PRICE_FACTORY)
    assert PRODUCT == mrkt.product()
    assert ENDPOINT == mrkt.endpoint()
    assert mrkt.min_price_increment() == mrkt.mpi() == Decimal("0.01")
    assert mrkt.min_qty() == 1
    assert mrkt.qty_increment() == 1
    assert mrkt.max_qty() == sys.maxsize
Exemplo n.º 5
0
def test_market_creation():
    mrkt = Market(PRODUCT, ENDPOINT, PRICE_FACTORY, min_qty=2, qty_increment=4)
    assert PRODUCT == mrkt.product()
    assert ENDPOINT == mrkt.endpoint()
    assert mrkt.min_price_increment() == mrkt.mpi() == Decimal("0.01")
    assert mrkt.min_qty() == 2
    assert mrkt.qty_increment() == 4
Exemplo n.º 6
0
def test_equality():
    q1 = Quote(MARKET, BID_SIDE, Price("95.42"), 94)
    q2 = Quote(MARKET, BID_SIDE, Price("95.42"), 94)
    assert q1 == q2

    q2 = Quote(
        Market(Product("APPL", "Apple"), Endpoint("Nasdaq", "NSDQ"),
               PriceFactory("0.01")), BID_SIDE, Price("95.42"), 94)
    assert q1 != q2

    q2 = Quote(MARKET, BID_SIDE, Price("95.43"), 94)
    assert q1 != q2

    q2 = Quote(MARKET, BID_SIDE, Price("95.42"), 91)
    assert q1 != q2

    q2 = Quote(MARKET, BID_SIDE, Price("95.42"), 94, 2)
    assert q1 != q2

    q2 = Quote(MARKET, BID_SIDE, Price("95.42"), 94, 0)
    assert q1 == q2

    q1 = Quote(MARKET, BID_SIDE, Price("95.42"), 94, 3)
    q2 = Quote(MARKET, BID_SIDE, Price("95.42"), 94, 3)
    assert q1 == q2
Exemplo n.º 7
0
def test_is_valid_qty_defaaults():
    mrkt = Market(PRODUCT, ENDPOINT, PRICE_FACTORY)
    assert not mrkt.is_valid_qty(0)
    assert mrkt.is_valid_qty(1)
    assert mrkt.is_valid_qty(3)
    assert mrkt.is_valid_qty(234566346)
    assert mrkt.is_valid_qty(sys.maxsize)
    assert not mrkt.is_valid_qty(sys.maxsize + 1)
Exemplo n.º 8
0
def test_basic_equality():
    mrkt1 = Market(PRODUCT, ENDPOINT, PRICE_FACTORY)
    mrkt2 = Market(PRODUCT, ENDPOINT, PRICE_FACTORY)
    assert mrkt1 == mrkt2

    mrkt2 = Market(Product("AAA", "Some Product named AAA"), ENDPOINT,
                   PRICE_FACTORY)
    assert mrkt1 == mrkt2

    mrkt2 = Market(PRODUCT, Endpoint("GenMatch", "Generic matching venue"),
                   PRICE_FACTORY)
    assert mrkt1 == mrkt2

    mrkt2 = Market(Product("BBB", "blah"), ENDPOINT, PRICE_FACTORY)
    assert mrkt1 != mrkt2

    mrkt2 = Market(PRODUCT, Endpoint("xxx", "another endpoint"), PRICE_FACTORY)
    assert mrkt1 != mrkt2
Exemplo n.º 9
0
def test_is_valid_qty():
    mrkt = Market(PRODUCT,
                  ENDPOINT,
                  PRICE_FACTORY,
                  min_qty=2,
                  qty_increment=4,
                  max_qty=1000)
    assert not mrkt.is_valid_qty(0)
    assert not mrkt.is_valid_qty(1)
    assert mrkt.is_valid_qty(2)
    assert not mrkt.is_valid_qty(3)
    assert not mrkt.is_valid_qty(4)
    assert not mrkt.is_valid_qty(5)
    assert mrkt.is_valid_qty(6)
    assert not mrkt.is_valid_qty(7)
    assert not mrkt.is_valid_qty(8)
    assert not mrkt.is_valid_qty(9)
    assert mrkt.is_valid_qty(10)
    assert mrkt.is_valid_qty(14)
    assert not mrkt.is_valid_qty(1001)
Exemplo n.º 10
0
def test_to_json():
    # this is only testing that it isn't broken / bad code
    mrkt = Market(PRODUCT, ENDPOINT, PRICE_FACTORY)
    json.dumps(mrkt.to_json())
Exemplo n.º 11
0
SOFTWARE.
"""

import pytest
from buttonwood.MarketObjects.Events.OrderEventConstants import *
from buttonwood.MarketObjects.Events.OrderEvents import NewOrderCommand
from buttonwood.MarketObjects.Endpoint import Endpoint
from buttonwood.MarketObjects.Market import Market
from buttonwood.MarketObjects.Price import Price
from buttonwood.MarketObjects.Price import PriceFactory
from buttonwood.MarketObjects.Product import Product
from buttonwood.MarketObjects.Side import BID_SIDE
from buttonwood.MarketObjects.Events.OrderEventConstants import MARKET as MARKET_ORDER
from buttonwood.MarketObjects.Events.OrderEventConstants import LIMIT as LIMIT_ORDER

MARKET = Market(Product("MSFT", "Microsoft"), Endpoint("Nasdaq", "NSDQ"),
                PriceFactory("0.01"))


def test_creation():
    new_order = NewOrderCommand(12, 324893458.324313, "342adf24441", "user_x",
                                MARKET, BID_SIDE, FAK, Price("23.01"), 234, 2)
    assert new_order.event_type_str() == "New Order Command"
    assert new_order.price() == Price("23.01")
    assert new_order.market() == MARKET
    assert new_order.user_id() == "user_x"
    assert new_order.timestamp() == 324893458.324313
    assert new_order.event_id() == 12
    assert new_order.side() == BID_SIDE
    assert new_order.qty() == 234
    assert new_order.iceberg_peak_qty() == 2
Exemplo n.º 12
0
def get_events():
    # set up a Market for the events. For that you need at least:
    #  1) the Product
    #  2) the Endpoint
    #  3) the PriceFactory
    prod = Product("AAAA", "Test Product")
    ep = Endpoint("Exchange 1", "EXC1")
    pf = PriceFactory(
        "0.01"
    )  # pricefactory needs the minimum price increment, which is 0.01 for this example
    market = Market(prod, ep, pf)

    # now create a mapping of what we'll parse out of the file to the Market.
    # This comes in even more handy when there are multiple markets
    mrkt_dict = {("AAAA", "EXC1"): market}

    # set up the time stamp parser
    time_stamp_frmt = "%Y-%m-%d %H:%M:%S.%f"

    # we are going to keep a dictionary of event_id to Command so that we can properly create Execution Reports
    id_to_cmd = {}

    created_events = []

    # first we need to parse each line
    for line in EXAMPLE_DATA:
        parts = line[:-1].split(',')
        # skip header
        if parts[0] == "Order ID":
            continue

        # Order Id is the unique identifier of the order chain
        chain_id = parts[0]
        # Index is the unique identifier of the event
        event_id = int(parts[1])
        # Need an identifier of the user that placed the order
        user = parts[7]

        # get the event time
        event_time = datetime.strptime(parts[3], time_stamp_frmt)
        # Event objects what the time stamp as a float (seconds.microseconds) so convert to time since epoch
        time_stamp = datetime_to_epoch(event_time)

        # now get the market
        prod_name = parts[4]
        ep_name = parts[5]
        mrkt = mrkt_dict[(prod_name, ep_name)]

        # get the side: not all events contain side so default is None.
        # Buttonwood provides a helper that converts the most common str representations of Buy & Sell to Side objects
        side = Side.get_side(parts[8])

        # get the time in force. Not all events need time in force so the default is None.
        # Note: could have used OrderEventContants.TIME_IN_FORCE_STR_TO_INT here but wanted to show a more extensive use
        #   of the constants
        if parts[6] == "FAR":
            tif = OrderEventConstants.FAR
        elif parts[6] == "FAK":
            tif = OrderEventConstants.FAK
        elif parts[6] == "FOK":
            tif = OrderEventConstants.FOK
        elif parts[6] == "":
            tif = None
        else:
            raise Exception("Could not convert %s to a known TimeInForce" %
                            parts[6])

        # get event type so we can create the right events
        event_type = parts[2]

        if event_type == "New":  # for event type "New" create a new event
            # get price, using Market's get_price function that will gets a Price object for a string, Decimal, or int
            price = mrkt.get_price(parts[9])
            qty = int(parts[10])
            event = NewOrderCommand(event_id, time_stamp, chain_id, user,
                                    market, side, tif, price, qty)
            # add the event to the event id to command dictionary
            id_to_cmd[event_id] = event
        elif event_type == "Mod":  # for event type "Mod" create a cancel replace event
            # get price, using Market's get_price function that will gets a Price object for a string, Decimal, or int
            price = mrkt.get_price(parts[9])
            qty = int(parts[10])
            event = CancelReplaceCommand(event_id, time_stamp, chain_id, user,
                                         market, side, price, qty)
            # add the event to the event id to command dictionary
            id_to_cmd[event_id] = event
        elif event_type == "Cancel":  # for event type "Cancel" create a Cancel command event
            # there can be different types of cancels, but in this case we are assuming it is a user requested cancel
            cancel_type = CancelReasons.USER_CANCEL
            event = CancelCommand(event_id, time_stamp, chain_id, user, market,
                                  cancel_type)
            # add the event to the event id to command dictionary
            id_to_cmd[event_id] = event
        elif event_type == "Ack":  # for event type "Ack" create an Acknowledgement
            # this example file has no concept of iceberg orders so iceberg_peak is None (which will cause buttonwood to
            #  to treat the entire order qty as an iceberg
            iceberg_peak = None
            # get price, using Market's get_price function that gets a Price object for a string, Decimal, or int
            price = mrkt.get_price(parts[9])
            qty = int(parts[10])
            # response to command is the command it is acknowledging, get that ID and look it up from our id_to_cmd dict
            response_to_id = int(parts[12])
            response_to_cmd = id_to_cmd[response_to_id]
            event = AcknowledgementReport(event_id, time_stamp, chain_id, user,
                                          market, response_to_cmd, price, qty,
                                          iceberg_peak)
        elif event_type == "Cancel Conf":  # for event type "Cancel Conf" create a Cancel report event
            # get the cancel reason
            if parts[15] == "FOK Miss":
                reason = CancelReasons.FOK_CANCEL
            elif parts[15] == "Requested":
                reason = CancelReasons.USER_REQUESTED
            else:
                raise Exception("Could not convert %s to a cancel reason." %
                                parts[15])
            # cancel command is the command that caused the cancel, get that ID and look it up from our id_to_cmd dict
            response_to_id = int(parts[12])
            response_to_cmd = id_to_cmd[response_to_id]
            event = CancelReport(event_id, time_stamp, chain_id, user, market,
                                 response_to_cmd, reason)
        elif event_type == "Part Fill":  # if event type "Part Fill" create a Partial Fill event
            # the aggressing command comes from getting the id and looking it up in the id to cmd dict
            aggressing_id = int(parts[13])
            aggressing_cmd = id_to_cmd[aggressing_id]
            # get fill price, using Market's get_price function that gets a Price object for a string, Decimal, or int
            fill_price = mrkt.get_price(parts[9])
            fill_qty = int(parts[10])
            # get leaves qty from the file
            leaves_qty = int(parts[11])
            # get the match_id from the file
            match_id = parts[14]
            event = PartialFillReport(event_id, time_stamp, chain_id, user,
                                      market, aggressing_cmd, fill_qty,
                                      fill_price, side, match_id, leaves_qty)
        elif event_type == "Full Fill":  # if event type "Full Fill" create a Partial Fill event
            # the aggressing command comes from getting the id and looking it up in the id to cmd dict
            aggressing_id = int(parts[13])
            aggressing_cmd = id_to_cmd[aggressing_id]
            # get fill price, using Market's get_price function that gets a Price object for a string, Decimal, or int
            fill_price = mrkt.get_price(parts[9])
            fill_qty = int(parts[10])
            # full fills don't need/have a leaves qty because nothing is left.
            # get the match_id from the file
            match_id = parts[14]
            event = FullFillReport(event_id, time_stamp, chain_id, user,
                                   market, aggressing_cmd, fill_qty,
                                   fill_price, side, match_id)
        else:
            raise Exception("Could not convert %s to an Event" % event_type)

        created_events.append(event)
    return created_events