def test_basic_partial_fill_replenish_visible():
    n = NewOrderCommand(121234, 1234235.123, 2342, "user_x", MARKET, BID_SIDE, FAR, Price("34.52"), 100, 40)
    oec = OrderEventChain(n, LOGGER, MonotonicIntID())
    # now ack it
    ack = AcknowledgementReport(121235, 1234235.123, 2342, "user_x", MARKET, n, Price("34.52"), 100, 40)
    oec.apply_acknowledgement_report(ack)
    aggressor = NewOrderCommand(1111, 1234237.123, 22222, "user_y", MARKET, ASK_SIDE, FAR, Price("34.52"), 40)
    # now resting partial fill
    pf = PartialFillReport(121236, 1234237.123, 2342, "user_x", MARKET, aggressor, 40, Price("34.52"),
                           BID_SIDE, 99999, 100-40)
    oec.apply_partial_fill_report(pf)

    assert oec.open_exposure_requests() == []
    assert oec.current_exposure().price() == Price("34.52")
    assert oec.current_exposure().qty() == 100-40
    assert oec.visible_qty() == 40  # should have replenished
    assert oec.iceberg_peak_qty() == 40  # should not have changed
    assert oec.has_partial_fill()

    # now test the partial fill wipes out 40 more, so visible is min
    aggressor2 = NewOrderCommand(1114, 1234237.123, 33333, "user_y", MARKET, ASK_SIDE, FAR, Price("34.52"), 40)
    # now resting partial fill
    pf2 = PartialFillReport(121236, 1234237.123, 2342, "user_x", MARKET, aggressor2, 40, Price("34.52"),
                            BID_SIDE, 99999, 100-40-40)  # subtract out the size of 2 40 lot fills now
    oec.apply_partial_fill_report(pf2)
    assert oec.open_exposure_requests() == []
    assert oec.current_exposure().price() == Price("34.52")
    assert oec.current_exposure().qty() == 100-40-40
    assert oec.visible_qty() == 100-40-40  # should have replenished to min of 40 and 100-40-40
    assert oec.iceberg_peak_qty() == 40  # should not have changed
    assert oec.has_partial_fill()
示例#2
0
def test_parital_passive_fill():
    ob = build_base_order_book()
    # get baseline
    chain_aggressed_into = ob.best_priority_chain(ASK_SIDE)
    visible_qty = ob.visible_qty_at_price(ASK_SIDE, Price("34.52"))
    hidden_qty = ob.hidden_qty_at_price(ASK_SIDE, Price("34.52"))
    num_orders = ob.num_orders_at_price(ASK_SIDE, Price("34.52"))
    best_price = ob.best_price(ASK_SIDE)

    # the ack'd order getting aggresed into:
    # a1_ack = AcknowledgementReport(4, 1234000.888, 1002, "user_b", MARKET, a1, Price("34.52"), 35, 10)
    agg_new = NewOrderCommand(101, 1234002.123, 1008, "user_z", MARKET, BID_SIDE, FAR,
                              Price("34.52"), 5)
    pf = PartialFillReport(102, 1234002.123, 1002, "user_b", MARKET, agg_new, 5, Price('34.52'),
                           ASK_SIDE, 3333, 30)
    chain_aggressed_into.apply_partial_fill_report(pf)
    ob.handle_partial_fill_report(pf, chain_aggressed_into)
    # now test for changes
    # ask visible should be 5 less
    assert ob.visible_qty_at_price(ASK_SIDE, Price("34.52")) == visible_qty - 5
    # ask hidden should stay the same
    assert hidden_qty == ob.hidden_qty_at_price(ASK_SIDE, Price("34.52"))
    # best price should be the same
    assert ob.best_ask_price() == best_price == Price("34.52")
    # num orders should stay the same
    assert num_orders == ob.num_orders_at_price(ASK_SIDE, Price("34.52"))
    # best chain on the ask should be the same
    assert ob.best_priority_chain(ASK_SIDE).chain_id() == chain_aggressed_into.chain_id() == 1002

    # nothing on bid should have changed
    bid_prices = ob.bid_prices()
    assert len(bid_prices) == 1
    assert bid_prices[0] == Price("34.50")
    assert ob.best_bid_price() == Price("34.50")
    assert ob.best_bid_level() == PriceLevel(Price("34.50"), 120, 0, 2)
示例#3
0
def test_partial_aggressive_fill():
    # nothing should change as we only update orderbook for passive partial fills
    ob = build_base_order_book()
    # get baseline
    ask_prices = ob.ask_prices()
    bid_prices = ob.bid_prices()
    best_ask_price = ob.best_ask_price()
    best_bid_price = ob.best_bid_price()
    bast_ask_level = ob.best_ask_level()
    bast_bid_level = ob.best_bid_level()

    agg_new = NewOrderCommand(101, 1234002.123, 1008, "user_z", MARKET, BID_SIDE, FAR,
                              Price("34.52"), 45)
    oec = OrderEventChain(agg_new, LOGGER, SUBCHAIN_ID_GENERATOR)
    pf = PartialFillReport(102, 1234002.123, 1008, "user_z", MARKET, agg_new, 35, Price('34.52'),
                           BID_SIDE, 3333, 10)
    oec.apply_partial_fill_report(pf)
    ob.handle_partial_fill_report(pf, oec)
    # nothing at the order book should have changed
    assert ask_prices == ob.ask_prices()
    assert bid_prices == ob.bid_prices()
    assert best_ask_price == ob.best_ask_price()
    assert best_bid_price == ob.best_bid_price()
    assert bast_ask_level == ob.best_ask_level()
    assert bast_bid_level == ob.best_bid_level()
def test_partial_fill_on_unacked_order():
    # when an unacked order is filled the requested exposure gets impacted
    n = NewOrderCommand(121234, 1234235.123, 2342, "user_x", MARKET, BID_SIDE, FAR, Price("34.52"), 100)
    oec = OrderEventChain(n, LOGGER, MonotonicIntID())
    assert oec.current_exposure() is None
    assert oec.most_recent_requested_exposure().qty() == 100
    assert oec.most_recent_requested_exposure().price() == Price("34.52")

    # now resting partial fill
    pf = PartialFillReport(1212344, 1234237.123, 2342, "user_x", MARKET, n, 10, Price("34.52"),
                           BID_SIDE, 99999, 90)
    oec.apply_partial_fill_report(pf)
    assert oec.current_exposure() is None
    assert oec.most_recent_requested_exposure().qty() == 90
    assert oec.most_recent_requested_exposure().price() == Price("34.52")
def test_partial_fill_to_zero_closes_out_order():
    # when a partialfill closses out to an order there should be a balking because it is a paritial fill so shouldn't happen, but should allow
    n = NewOrderCommand(121234, 1234235.123, 2342, "user_x", MARKET, BID_SIDE, FAR, Price("34.52"), 100)
    oec = OrderEventChain(n, LOGGER, MonotonicIntID())
    # now ack it
    ack = AcknowledgementReport(121235, 1234235.123, 2342, "user_x", MARKET, n, Price("34.52"), 100, 100)
    oec.apply_acknowledgement_report(ack)
    aggressor = NewOrderCommand(1111, 1234237.123, 22222, "user_y", MARKET, ASK_SIDE, FAR, Price("34.52"), 100)
    # now resting partial fill
    pf = PartialFillReport(1212344, 1234237.123, 2342, "user_x", MARKET, aggressor, 100, Price("34.52"),
                           BID_SIDE, 99999, 0)
    oec.apply_partial_fill_report(pf)
    assert oec.open_exposure_requests() == []
    assert oec.is_open() is False
    assert oec.visible_qty() == 0
    assert oec.current_exposure() == Exposure(None, 0, 1212344)
def test_subchain_getters_partial_fill_before_ack():
    # pretty basic, just testing that it doesn't break
    n = NewOrderCommand(121234, 1234235.123, 2342, "user_x", MARKET, BID_SIDE, FAR, Price("34.52"), 1000)
    oec = OrderEventChain(n, LOGGER, MonotonicIntID())
    # now aggressive partial fill
    pf = PartialFillReport(121236, 1234237.123, 2342, "user_x", MARKET, n, 44, Price("34.52"),
                           BID_SIDE, 99999, 1000 - 44)
    oec.apply_partial_fill_report(pf)
    # now ack it
    ack = AcknowledgementReport(121235, 1234235.123, 2342, "user_x", MARKET, n, Price("34.52"), 1000-44, None)
    oec.apply_acknowledgement_report(ack)

    subchain = oec.most_recent_subchain()
    assert subchain.open_event() == n
    assert subchain.first_execution_report() == pf
    assert subchain.fills() == [pf]
    assert subchain.last_event() == ack
示例#7
0
def test_partial_passive_fill_for_all_qty():
    # a partial fill for eveything should balk with some logs but should still be successful.
    # NOTE: this scenario is crazy and shouldn't actually happen (hidden getting filled before visible)
    #       but what the hell, let's cut corners on a test
    ob = build_base_order_book()
    # get baseline
    chain_aggressed_into = ob.best_priority_chain(ASK_SIDE)
    second_ask_back = ob.order_chains_at_price(ASK_SIDE, Price("34.52"))[1]
    visible_qty = ob.visible_qty_at_price(ASK_SIDE, Price("34.52"))
    hidden_qty = ob.hidden_qty_at_price(ASK_SIDE, Price("34.52"))
    num_orders = ob.num_orders_at_price(ASK_SIDE, Price("34.52"))
    best_price = ob.best_price(ASK_SIDE)

    # the ack'd order getting aggresed into:
    # a1_ack = AcknowledgementReport(4, 1234000.888, 1002, "user_b", MARKET, a1, Price("34.52"), 35, 10)
    agg_new = NewOrderCommand(101, 1234002.123, 1008, "user_z", MARKET, BID_SIDE, FAR,
                              Price("34.52"), 35)
    pf = PartialFillReport(102, 1234002.123, 1002, "user_b", MARKET, agg_new, 35, Price('34.52'),
                           ASK_SIDE, 3333, 25)
    chain_aggressed_into.apply_partial_fill_report(pf)
    ob.handle_partial_fill_report(pf, chain_aggressed_into)
    # now test for changes
    # ask visible qty should be 10 less (the rest came from hidden)
    assert ob.visible_qty_at_price(ASK_SIDE, Price("34.52")) == visible_qty - 10
    # ask hidden should be 25 (35-10 visible) less
    assert hidden_qty - 25 == ob.hidden_qty_at_price(ASK_SIDE, Price("34.52"))
    # best price should be the same
    assert ob.best_ask_price() == best_price == Price("34.52")
    # should be 1 less order
    assert num_orders - 1 == ob.num_orders_at_price(ASK_SIDE, Price("34.52"))
    # best chain on the ask should be what was the second back
    assert ob.best_priority_chain(ASK_SIDE).chain_id() == second_ask_back.chain_id()
    # chain should no longer exist in book
    chains = ob.order_chains_at_price(ASK_SIDE, Price("34.52"))
    found = False
    for chain in chains:
        if chain.chain_id() == chain_aggressed_into.chain_id():
            found = True
    assert not found

    # nothing on bid should have changed
    bid_prices = ob.bid_prices()
    assert len(bid_prices) == 1
    assert bid_prices[0] == Price("34.50")
    assert ob.best_bid_price() == Price("34.50")
    assert ob.best_bid_level() == PriceLevel(Price("34.50"), 120, 0, 2)
def test_basic_partial_fill():
    n = NewOrderCommand(121234, 1234235.123, 2342, "user_x", MARKET, BID_SIDE, FAR, Price("34.52"), 1000)
    oec = OrderEventChain(n, LOGGER, MonotonicIntID())
    # now ack it
    ack = AcknowledgementReport(121235, 1234235.123, 2342, "user_x", MARKET, n, Price("34.52"), 1000, 1000)
    oec.apply_acknowledgement_report(ack)
    aggressor = NewOrderCommand(1111, 1234237.123, 22222, "user_x", MARKET, ASK_SIDE, FAR, Price("34.52"), 44)
    # now resting partial fill
    pf = PartialFillReport(121236, 1234237.123, 2342, "user_x", MARKET, aggressor, 44, Price("34.52"),
                           BID_SIDE, 99999, 1000-44)
    oec.apply_partial_fill_report(pf)

    assert oec.open_exposure_requests() == []
    assert oec.current_exposure().price() == Price("34.52")
    assert oec.current_exposure().qty() == 1000-44
    assert oec.visible_qty() == 1000-44
    assert oec.iceberg_peak_qty() == 1000  # should not have changed
    assert oec.has_partial_fill()
示例#9
0
def test_partial_passive_fill_resets_visible_qty():
    ob = build_base_order_book()
    # get baseline
    chain_aggressed_into = ob.best_priority_chain(ASK_SIDE)
    second_ask_back = ob.order_chains_at_price(ASK_SIDE, Price("34.52"))[1]
    visible_qty = ob.visible_qty_at_price(ASK_SIDE, Price("34.52"))
    hidden_qty = ob.hidden_qty_at_price(ASK_SIDE, Price("34.52"))
    num_orders = ob.num_orders_at_price(ASK_SIDE, Price("34.52"))
    best_price = ob.best_price(ASK_SIDE)

    # the ack'd order getting aggresed into:
    # a1_ack = AcknowledgementReport(4, 1234000.888, 1002, "user_b", MARKET, a1, Price("34.52"), 35, 10)
    agg_new = NewOrderCommand(101, 1234002.123, 1008, "user_z", MARKET, BID_SIDE, FAR,
                              Price("34.52"), 10)
    pf = PartialFillReport(102, 1234002.123, 1002, "user_b", MARKET, agg_new, 10, Price('34.52'),
                           ASK_SIDE, 3333, 25)
    chain_aggressed_into.apply_partial_fill_report(pf)
    ob.handle_partial_fill_report(pf, chain_aggressed_into)
    # now test for changes
    # ask visible qty should stay the same because the 10 was filled and then replenished due to iceberg activity
    assert ob.visible_qty_at_price(ASK_SIDE, Price("34.52")) == visible_qty
    # ask hidden should be 10 less becaue of replenishment of iceberg peak
    assert hidden_qty - 10 == ob.hidden_qty_at_price(ASK_SIDE, Price("34.52"))
    # best price should be the same
    assert ob.best_ask_price() == best_price == Price("34.52")
    # num orders should stay the same
    assert num_orders == ob.num_orders_at_price(ASK_SIDE, Price("34.52"))
    # best chain on the ask should be what was the second back
    assert ob.best_priority_chain(ASK_SIDE).chain_id() == second_ask_back.chain_id()
    # worst chain on the ask should be what was the first
    assert ob.order_chains_at_price(ASK_SIDE, Price("34.52"))[-1].chain_id() == chain_aggressed_into.chain_id()

    # nothing on bid should have changed
    bid_prices = ob.bid_prices()
    assert len(bid_prices) == 1
    assert bid_prices[0] == Price("34.50")
    assert ob.best_bid_price() == Price("34.50")
    assert ob.best_bid_level() == PriceLevel(Price("34.50"), 120, 0, 2)
def test_partial_fill_on_multiple_unacked_requests():
    n = NewOrderCommand(1, 1234235.123, 2342, "user_x", MARKET, BID_SIDE, FAR, Price("34.52"), 1000)
    oec = OrderEventChain(n, LOGGER, MonotonicIntID())
    # should have 1 open exposure
    assert len(oec.open_exposure_requests()) == 1
    assert oec.most_recent_requested_exposure() == Exposure(Price("34.52"), 1000, 1)

    cr1 = CancelReplaceCommand(2, 1234235.863, 2342, "user_x", MARKET, BID_SIDE, Price("34.51"), 800)
    oec.apply_cancel_replace_command(cr1)
    # now should have 2 open exposures
    assert len(oec.open_exposure_requests()) == 2
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.52"), 1000, 1)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.51"), 800, 2)

    cr2 = CancelReplaceCommand(3, 1234236.842, 2342, "user_x", MARKET, BID_SIDE, Price("34.55"), 800)
    oec.apply_cancel_replace_command(cr2)
    # now should have 2 open exposures
    assert len(oec.open_exposure_requests()) == 3
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.52"), 1000, 1)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.51"), 800, 2)
    assert oec.open_exposure_requests()[2] == Exposure(Price("34.55"), 800, 3)

    cr3 = CancelReplaceCommand(4, 1234236.842, 2342, "user_x", MARKET, BID_SIDE, Price("34.56"), 800)
    oec.apply_cancel_replace_command(cr3)
    # now should have 2 open exposures
    assert len(oec.open_exposure_requests()) == 4
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.52"), 1000, 1)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.51"), 800, 2)
    assert oec.open_exposure_requests()[2] == Exposure(Price("34.55"), 800, 3)
    assert oec.open_exposure_requests()[3] == Exposure(Price("34.56"), 800, 4)

    # a partial fill should should only impact the one the partial fill is for
    # partially filling orderid 3 (cr2)
    pf1 = PartialFillReport(5, 1234237.123, 2342, "user_x", MARKET, cr2, 10, Price("34.55"),
                            BID_SIDE, 999, 790)
    oec.apply_partial_fill_report(pf1)
    assert len(oec.open_exposure_requests()) == 4
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.52"), 1000, 1)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.51"), 800, 2)
    assert oec.open_exposure_requests()[2] == Exposure(Price("34.55"), 790, 3)
    assert oec.open_exposure_requests()[3] == Exposure(Price("34.56"), 800, 4)

    # and again
    pf2 = PartialFillReport(6, 1234237.123, 2342, "user_x", MARKET, cr2, 10, Price("34.55"),
                            BID_SIDE, 1000, 780)
    oec.apply_partial_fill_report(pf2)
    assert len(oec.open_exposure_requests()) == 4
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.52"), 1000, 1)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.51"), 800, 2)
    assert oec.open_exposure_requests()[2] == Exposure(Price("34.55"), 780, 3)
    assert oec.open_exposure_requests()[3] == Exposure(Price("34.56"), 800, 4)

    # and now I can fill order id 4 (cr 3)
    pf3 = PartialFillReport(6, 1234237.123, 2342, "user_x", MARKET, cr3, 50, Price("34.56"),
                            BID_SIDE, 1001, 750)
    oec.apply_partial_fill_report(pf3)
    assert len(oec.open_exposure_requests()) == 4
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.52"), 1000, 1)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.51"), 800, 2)
    assert oec.open_exposure_requests()[2] == Exposure(Price("34.55"), 780, 3)
    assert oec.open_exposure_requests()[3] == Exposure(Price("34.56"), 750, 4)

    # now start acking them
    ack1 = AcknowledgementReport(10, 1234235.123, 2342, "user_x", MARKET, n, Price("34.52"), 1000, None)
    oec.apply_acknowledgement_report(ack1)
    assert len(oec.open_exposure_requests()) == 3
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.51"), 800, 2)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.55"), 780, 3)
    assert oec.open_exposure_requests()[2] == Exposure(Price("34.56"), 750, 4)
    assert oec.current_exposure() == Exposure(Price("34.52"), 1000, 10)

    ack2 = AcknowledgementReport(11, 1234235.123, 2342, "user_x", MARKET, cr1, Price("34.51"), 800, None)
    oec.apply_acknowledgement_report(ack2)
    assert len(oec.open_exposure_requests()) == 2
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.55"), 780, 3)
    assert oec.open_exposure_requests()[1] == Exposure(Price("34.56"), 750, 4)
    assert oec.current_exposure() == Exposure(Price("34.51"), 800, 11)

    ack3 = AcknowledgementReport(12, 1234235.123, 2342, "user_x", MARKET, cr2, Price("34.55"), 780, None)
    oec.apply_acknowledgement_report(ack3)
    assert len(oec.open_exposure_requests()) == 1
    print(oec.open_exposure_requests()[0])
    assert oec.open_exposure_requests()[0] == Exposure(Price("34.56"), 750, 4)
    assert oec.current_exposure() == Exposure(Price("34.55"), 780, 12)

    ack4 = AcknowledgementReport(13, 1234235.123, 2342, "user_x", MARKET, cr3, Price("34.56"), 750, None)
    oec.apply_acknowledgement_report(ack4)
    assert len(oec.open_exposure_requests()) == 0
    assert oec.current_exposure() == Exposure(Price("34.56"), 750, 13)
示例#11
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