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)
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)
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
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
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())
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import json import sys from decimal import Decimal from buttonwood.MarketObjects.Endpoint import Endpoint from buttonwood.MarketObjects.Product import Product from buttonwood.MarketObjects.Price import Price from buttonwood.MarketObjects.Price import PriceFactory from buttonwood.MarketObjects.Market import Market from buttonwood.MarketObjects.Price import InvalidPriceException PRODUCT = Product("AAA", "Some Product named AAA") ENDPOINT = Endpoint("GenMatch", "Generic matching venue") PRICE_FACTORY = PriceFactory(Decimal("0.01")) 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 def test_market_creation():
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
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
from buttonwood.MarketObjects.Events.OrderEvents import CancelCommand from buttonwood.MarketObjects.Events.OrderEvents import CancelReplaceCommand from buttonwood.MarketObjects.Events.OrderEvents import CancelReport from buttonwood.MarketObjects.Events.OrderEvents import FullFillReport from buttonwood.MarketObjects.Events.OrderEvents import NewOrderCommand from buttonwood.MarketObjects.Events.OrderEvents import PartialFillReport 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, ASK_SIDE from buttonwood.utils.IDGenerators import MonotonicIntID MARKET = Market(Product("MSFT", "Microsoft"), Endpoint("Nasdaq", "NSDQ"), PriceFactory("0.01")) LOGGER = logging.getLogger() def test_exposure(): e1 = Exposure(Price("1.1"), 2, 12345) e2 = Exposure(Price("1.1"), 2, 12345) assert e1 == e2 assert e1.equivalent_exposure(e2) assert e1.equivalent_exposure(e1) assert e2.equivalent_exposure(e1) e3 = Exposure(Price("1.1"), 2, 6789) assert e1 != e3 assert e1.price() == e2.price() print(e1, e2)
def test_to_detailed_json(): # this is only testing that it isn't broken / bad code prod1 = Product("msft", "mICRoSOFT") prod1.set_identifier("CUSIP", "12345") prod1.set_identifier("internal_id", "8u98792") json.dumps(prod1.to_detailed_json())
def test_to_json(): # this is only testing that it isn't broken / bad code prod1 = Product("msft", "mICRoSOFT") json.dumps(prod1.to_json())
def test_equality_identifiers(): prod1 = Product("msft", "mICRoSOFT") prod2 = Product("MSFT", "Microsoft") # identifier doesn't exist in other then then we can't assume inequality prod1.set_identifier("cusip", "XTR2302") prod2.set_identifier("BBID", "weq34") assert prod1 == prod2 assert (prod1 != prod2) is False # same identifier exists in both with same value, so should be equal prod2.set_identifier("CUSIP", "XTR2302") assert prod1 == prod2 assert (prod1 != prod2) is False # same identifier exists in both with different values, then not equal prod1.set_identifier("bbid", "asads222") assert (prod1 == prod2) is False assert prod1 != prod2
def test_basic_equality(): prod1 = Product("msft", "mICRoSOFT") prod2 = Product("MSFT", "Microsoft") assert prod1 == prod2 assert (prod1 != prod2) is False prod1 = Product("AAPL", "Apple") prod2 = Product("MSFT", "Microsoft") assert (prod1 == prod2) is False assert prod1 != prod2 prod1 = Product("msft", "mICRoSOFT") prod2 = Product("MSFT", "Microsoft") assert (prod1 == prod2) is True assert prod1 == prod2 prod1 = Product("msft", "mICRoSOFT") prod2 = Product("MSFT", "Microsoft") prod2.set_identifier("CUSIP", "20200") prod1.set_identifier("CUSIP", "23222") assert (prod1 == prod2) is False assert prod1 != prod2
def test_product_creation(): prod = Product("MSFT", "Microsoft") assert prod.symbol() == "MSFT" assert prod.name() == "Microsoft"