class OrderTests(unittest.TestCase): def setUp(self): # Fixture Setup self.account_id = TestStubs.account_id() self.order_factory = OrderFactory( strategy_id=StrategyId("S", "001"), id_tag_trader=IdTag("001"), id_tag_strategy=IdTag("001"), clock=TestClock(), uuid_factory=TestUUIDFactory(), ) def test_get_opposite_side_returns_expected_sides(self): # Arrange # Act result1 = opposite_side(OrderSide.BUY) result2 = opposite_side(OrderSide.SELL) # Assert self.assertEqual(OrderSide.SELL, result1) self.assertEqual(OrderSide.BUY, result2) def test_get_flatten_side_with_long_or_short_position_side_returns_expected_sides(self): # Arrange # Act result1 = flatten_side(PositionSide.LONG) result2 = flatten_side(PositionSide.SHORT) # Assert self.assertEqual(OrderSide.SELL, result1) self.assertEqual(OrderSide.BUY, result2) def test_market_order_with_quantity_zero_raises_exception(self): # Arrange # Act self.assertRaises( ValueError, MarketOrder, ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_FXCM, OrderSide.BUY, Quantity(), TimeInForce.DAY, uuid4(), UNIX_EPOCH, ) def test_market_order_with_invalid_tif_raises_exception(self): # Arrange # Act self.assertRaises( ValueError, MarketOrder, ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_FXCM, OrderSide.BUY, Quantity(100), TimeInForce.GTD, uuid4(), UNIX_EPOCH, ) def test_stop_order_with_gtd_and_expire_time_none_raises_exception(self): # Arrange # Act self.assertRaises( TypeError, StopMarketOrder, ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), price=Price("1.00000"), init_id=uuid4(), timestamp=UNIX_EPOCH, time_in_force=TimeInForce.GTD, expire_time=None, ) def test_reset_order_factory(self): # Arrange self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) # Act self.order_factory.reset() order2 = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) self.assertEqual(ClientOrderId("O-19700101-000000-001-001-1"), order2.cl_ord_id) def test_limit_order_can_create_expected_decimal_price(self): # Arrange # Act order1 = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order2 = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order3 = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order4 = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00001"), ) # Assert self.assertEqual(Price("1.00000"), order1.price) self.assertEqual(Price("1.00000"), order2.price) self.assertEqual(Price("1.00000"), order3.price) self.assertEqual(Price("1.00001"), order4.price) def test_initialize_buy_market_order(self): # Arrange # Act order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) # Assert self.assertEqual(OrderType.MARKET, order.type) self.assertEqual(OrderState.INITIALIZED, order.state()) self.assertEqual(1, order.event_count()) self.assertTrue(isinstance(order.last_event(), OrderInitialized)) self.assertFalse(order.is_working()) self.assertFalse(order.is_completed()) self.assertTrue(order.is_buy()) self.assertFalse(order.is_sell()) self.assertEqual(None, order.filled_timestamp) self.assertEqual(UNIX_EPOCH, order.last_event().timestamp) def test_initialize_sell_market_order(self): # Arrange # Act order = self.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(100000),) # Assert self.assertEqual(OrderType.MARKET, order.type) self.assertEqual(OrderState.INITIALIZED, order.state()) self.assertEqual(1, order.event_count()) self.assertTrue(isinstance(order.last_event(), OrderInitialized)) self.assertFalse(order.is_working()) self.assertFalse(order.is_completed()) self.assertFalse(order.is_buy()) self.assertTrue(order.is_sell()) self.assertEqual(None, order.filled_timestamp) # def test_order_str_and_repr(self): # # Arrange # # Act # order = self.order_factory.market( # AUDUSD_FXCM, # OrderSide.BUY, # Quantity(100000), # ) # Assert TODO: String formatting # self.assertEqual("MarketOrder(cl_ord_id=O-19700101-000000-001-001-1, state=INITIALIZED, BUY 100K AUD/USD.FXCM MARKET DAY)", str(order)) # noqa # self.assertTrue(repr(order).startswith("<MarketOrder(cl_ord_id=O-19700101-000000-001-001-1, state=INITIALIZED, BUY 100K AUD/USD.FXCM MARKET DAY) object at")) # noqa def test_initialize_limit_order(self): # Arrange # Act order = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) # Assert self.assertEqual(OrderType.LIMIT, order.type) self.assertEqual(OrderState.INITIALIZED, order.state()) self.assertEqual(TimeInForce.DAY, order.time_in_force) self.assertFalse(order.is_completed()) def test_initialize_limit_order_with_expire_time(self): # Arrange # Act order = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), TimeInForce.GTD, UNIX_EPOCH, ) # Assert self.assertEqual(AUDUSD_FXCM, order.symbol) self.assertEqual(OrderType.LIMIT, order.type) self.assertEqual(Price("1.00000"), order.price) self.assertEqual(OrderState.INITIALIZED, order.state()) self.assertEqual(TimeInForce.GTD, order.time_in_force) self.assertEqual(UNIX_EPOCH, order.expire_time) self.assertFalse(order.is_completed()) def test_initialize_stop_order(self): # Arrange # Act order = self.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) # Assert self.assertEqual(OrderType.STOP_MARKET, order.type) self.assertEqual(OrderState.INITIALIZED, order.state()) self.assertEqual(TimeInForce.DAY, order.time_in_force) self.assertFalse(order.is_completed()) def test_initialize_bracket_order_market_with_no_take_profit(self): # Arrange entry_order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Act bracket_order = self.order_factory.bracket(entry_order, Price("0.99990")) # Assert self.assertEqual(AUDUSD_FXCM, bracket_order.stop_loss.symbol) self.assertFalse(bracket_order.has_take_profit) self.assertEqual(ClientOrderId("O-19700101-000000-001-001-1"), bracket_order.entry.cl_ord_id) self.assertEqual(ClientOrderId("O-19700101-000000-001-001-2"), bracket_order.stop_loss.cl_ord_id) self.assertEqual(OrderSide.SELL, bracket_order.stop_loss.side) self.assertEqual(Quantity(100000), bracket_order.entry.quantity) self.assertEqual(Quantity(100000), bracket_order.stop_loss.quantity) self.assertEqual(Price("0.99990"), bracket_order.stop_loss.price) self.assertEqual(TimeInForce.GTC, bracket_order.stop_loss.time_in_force) self.assertEqual(None, bracket_order.stop_loss.expire_time) self.assertEqual(BracketOrderId("BO-19700101-000000-001-001-1"), bracket_order.id) self.assertEqual(UNIX_EPOCH, bracket_order.timestamp) def test_can_initialize_bracket_order_stop_with_take_profit(self): # Arrange entry_order = self.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("0.99995"), ) # Act bracket_order = self.order_factory.bracket( entry_order, Price("0.99990"), Price("1.00010"), ) # Assert self.assertEqual(AUDUSD_FXCM, bracket_order.stop_loss.symbol) self.assertTrue(bracket_order.has_take_profit) self.assertEqual(AUDUSD_FXCM, bracket_order.take_profit.symbol) self.assertEqual(ClientOrderId("O-19700101-000000-001-001-1"), bracket_order.entry.cl_ord_id) self.assertEqual(ClientOrderId("O-19700101-000000-001-001-2"), bracket_order.stop_loss.cl_ord_id) self.assertEqual(ClientOrderId("O-19700101-000000-001-001-3"), bracket_order.take_profit.cl_ord_id) self.assertEqual(OrderSide.SELL, bracket_order.stop_loss.side) self.assertEqual(OrderSide.SELL, bracket_order.take_profit.side) self.assertEqual(Quantity(100000), bracket_order.stop_loss.quantity) self.assertEqual(Quantity(100000), bracket_order.take_profit.quantity) self.assertEqual(Price("0.99990"), bracket_order.stop_loss.price) self.assertEqual(Price("1.00010"), bracket_order.take_profit.price) self.assertEqual(TimeInForce.GTC, bracket_order.stop_loss.time_in_force) self.assertEqual(TimeInForce.GTC, bracket_order.take_profit.time_in_force) self.assertEqual(None, bracket_order.entry.expire_time) self.assertEqual(None, bracket_order.stop_loss.expire_time) self.assertEqual(None, bracket_order.take_profit.expire_time) self.assertEqual(BracketOrderId("BO-19700101-000000-001-001-1"), bracket_order.id) self.assertEqual(UNIX_EPOCH, bracket_order.timestamp) # def test_bracket_order_str_and_repr(self): # # Arrange # # Act # entry_order = self.order_factory.market( # AUDUSD_FXCM, # OrderSide.BUY, # Quantity(100000), # ) # # bracket_order = self.order_factory.bracket( # entry_order, # Price("0.99990"), # Price("1.00010"), # ) # Assert # TODO: Fix string formatting # self.assertEqual("BracketOrder(id=BO-19700101-000000-001-001-1, EntryMarketOrder(cl_ord_id=O-19700101-000000-001-001-1, state=INITIALIZED, BUY 100K AUD/USD.FXCM MARKET DAY), SL=0.99990, TP=1.00010)", str(bracket_order)) # noqa # self.assertTrue(repr(bracket_order).startswith("<BracketOrder(id=BO-19700101-000000-001-001-1, EntryMarketOrder(cl_ord_id=O-19700101-000000-001-001-1, state=INITIALIZED, BUY 100K AUD/USD.FXCM MARKET DAY), SL=0.99990, TP=1.00010) object at")) # noqa # self.assertTrue(repr(bracket_order).endswith(">")) def test_can_apply_order_submitted_event_to_order(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) submitted = TestStubs.event_order_submitted(order) # Act order.apply(submitted) # Assert self.assertEqual(OrderState.SUBMITTED, order.state()) self.assertEqual(2, order.event_count()) self.assertEqual(submitted, order.last_event()) self.assertFalse(order.is_completed()) def test_can_apply_order_accepted_event_to_order(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) order.apply(submitted) # Act order.apply(accepted) # Assert self.assertEqual(OrderState.ACCEPTED, order.state()) self.assertFalse(order.is_completed()) def test_can_apply_order_rejected_event_to_order(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) submitted = TestStubs.event_order_submitted(order) rejected = TestStubs.event_order_rejected(order) order.apply(submitted) # Act order.apply(rejected) # Assert self.assertEqual(OrderState.REJECTED, order.state()) self.assertTrue(order.is_completed()) def test_can_apply_order_working_event_to_stop_order(self): # Arrange order = self.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) working = TestStubs.event_order_working(order) order.apply(submitted) order.apply(accepted) # Act order.apply(working) # Assert # print(order) self.assertEqual(OrderState.WORKING, order.state()) self.assertEqual(OrderId("1"), order.id) self.assertFalse(order.is_completed()) self.assertTrue(order.is_working()) self.assertEqual(None, order.filled_timestamp) def test_can_apply_order_expired_event_to_stop_order(self): # Arrange order = self.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("0.99990"), TimeInForce.GTD, UNIX_EPOCH) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) working = TestStubs.event_order_working(order) expired = TestStubs.event_order_expired(order) order.apply(submitted) order.apply(accepted) order.apply(working) # Act order.apply(expired) # Assert self.assertEqual(OrderState.EXPIRED, order.state()) self.assertTrue(order.is_completed()) def test_can_apply_order_cancelled_event_to_order(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) cancelled = TestStubs.event_order_cancelled(order) order.apply(submitted) order.apply(accepted) # Act order.apply(cancelled) # Assert self.assertEqual(OrderState.CANCELLED, order.state()) self.assertTrue(order.is_completed()) def test_can_apply_order_modified_event_to_stop_order(self): # Arrange order = self.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000")) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) working = TestStubs.event_order_working(order) modified = OrderModified( self.account_id, order.cl_ord_id, OrderId("1"), Quantity(120000), Price("1.00001"), UNIX_EPOCH, uuid4(), UNIX_EPOCH) order.apply(submitted) order.apply(accepted) order.apply(working) # Act order.apply(modified) # Assert self.assertEqual(OrderState.WORKING, order.state()) self.assertEqual(OrderId("1"), order.id) self.assertEqual(Quantity(120000), order.quantity) self.assertEqual(Price("1.00001"), order.price) self.assertTrue(order.is_working()) self.assertFalse(order.is_completed()) self.assertEqual(5, order.event_count()) def test_can_apply_order_filled_event_to_market_order(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) filled = TestStubs.event_order_filled( order, PositionId("P-123456"), StrategyId("S", "001"), Price("1.00001")) order.apply(submitted) order.apply(accepted) # Act order.apply(filled) # Assert self.assertEqual(OrderState.FILLED, order.state()) self.assertEqual(Quantity(100000), order.filled_qty) self.assertEqual(Price("1.00001"), order.avg_price) self.assertTrue(order.is_completed()) self.assertEqual(UNIX_EPOCH, order.filled_timestamp) def test_can_apply_order_filled_event_to_buy_limit_order(self): # Arrange order = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000")) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) working = TestStubs.event_order_working(order) filled = OrderFilled( self.account_id, order.cl_ord_id, OrderId("1"), ExecutionId("E-1"), PositionId("P-1"), StrategyId("S", "NULL"), order.symbol, order.side, order.quantity, Quantity(), Price("1.00001"), Money(0, USD), LiquiditySide.MAKER, USD, USD, UNIX_EPOCH, uuid4(), UNIX_EPOCH, ) order.apply(submitted) order.apply(accepted) order.apply(working) # Act order.apply(filled) # Assert self.assertEqual(OrderState.FILLED, order.state()) self.assertEqual(Quantity(100000), order.filled_qty) self.assertEqual(Price("1.00000"), order.price) self.assertEqual(Price("1.00001"), order.avg_price) self.assertEqual(Decimal("0.00001"), order.slippage) self.assertTrue(order.is_completed()) self.assertEqual(UNIX_EPOCH, order.filled_timestamp) def test_can_apply_order_partially_filled_event_to_buy_limit_order(self): # Arrange order = self.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000")) submitted = TestStubs.event_order_submitted(order) accepted = TestStubs.event_order_accepted(order) working = TestStubs.event_order_working(order) partially = OrderFilled( self.account_id, order.cl_ord_id, OrderId("1"), ExecutionId("E-1"), PositionId("P-1"), StrategyId("S", "NULL"), order.symbol, order.side, Quantity(50000), Quantity(50000), Price("0.999999"), Money(0, USD), LiquiditySide.MAKER, USD, USD, UNIX_EPOCH, uuid4(), UNIX_EPOCH) order.apply(submitted) order.apply(accepted) order.apply(working) # Act order.apply(partially) # Assert self.assertEqual(OrderState.PARTIALLY_FILLED, order.state()) self.assertEqual(Quantity(50000), order.filled_qty) self.assertEqual(Price("1.00000"), order.price) self.assertEqual(Price("0.999999"), order.avg_price) self.assertEqual(Decimal("-0.000001"), order.slippage) self.assertFalse(order.is_completed()) self.assertEqual(UNIX_EPOCH, order.filled_timestamp)
class OrderTests(unittest.TestCase): def setUp(self): # Fixture Setup self.account_id = TestStubs.account_id() self.order_factory = OrderFactory(id_tag_trader=IdTag('001'), id_tag_strategy=IdTag('001'), clock=TestClock(), guid_factory=TestGuidFactory()) def test_market_order_with_quantity_zero_raises_exception(self): # Arrange # Act self.assertRaises(ValueError, Order, OrderId('O-123456'), AUDUSD_FXCM, OrderSide.BUY, OrderType.MARKET, Quantity(), GUID(uuid.uuid4()), UNIX_EPOCH) def test_priced_order_with_GTD_time_in_force_and_expire_time_none_raises_exception( self): # Arrange # Act self.assertRaises(ValueError, Order, OrderId('O-123456'), AUDUSD_FXCM, OrderSide.BUY, OrderType.LIMIT, Quantity(100000), GUID(uuid.uuid4()), UNIX_EPOCH, price=Price(1.00000, 5), time_in_force=TimeInForce.GTD, expire_time=None) def test_market_order_with_price_input_raises_exception(self): # Arrange # Act self.assertRaises(ValueError, Order, OrderId('O-123456'), AUDUSD_FXCM, OrderSide.BUY, OrderType.MARKET, Quantity(100000), GUID(uuid.uuid4()), UNIX_EPOCH, price=Price(1.00000, 5)) def test_stop_order_with_no_price_input_raises_exception(self): # Arrange # Act self.assertRaises(ValueError, Order, OrderId('O-123456'), AUDUSD_FXCM, OrderSide.BUY, OrderType.STOP, Quantity(100000), GUID(uuid.uuid4()), UNIX_EPOCH) def test_stop_order_with_zero_price_input_raises_exception(self): # Arrange # Act self.assertRaises(ValueError, Order, OrderId('O-123456'), AUDUSD_FXCM, OrderSide.BUY, OrderType.STOP, Quantity(100000), GUID(uuid.uuid4()), UNIX_EPOCH, price=None) def test_can_reset_order_factory(self): # Arrange self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) # Act self.order_factory.reset() order2 = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) self.assertEqual(OrderId('O-19700101-000000-001-001-1'), order2.id) def test_limit_order_can_create_expected_decimal_price(self): # Arrange # Act order1 = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) order2 = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) order3 = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) order4 = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00001, 5)) # Assert self.assertEqual(Price(1.00000, 5), order1.price) self.assertEqual(Price(1.00000, 5), order2.price) self.assertEqual(Price(1.00000, 5), order3.price) self.assertEqual(Price(1.00001, 5), order4.price) def test_can_initialize_buy_market_order(self): # Arrange # Act order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) # Assert self.assertEqual(OrderType.MARKET, order.type) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertEqual(1, order.event_count) self.assertTrue(isinstance(order.last_event, OrderInitialized)) self.assertFalse(order.is_working) self.assertFalse(order.is_completed) self.assertTrue(order.is_buy) self.assertFalse(order.is_sell) self.assertEqual(None, order.filled_timestamp) def test_can_initialize_sell_market_order(self): # Arrange # Act order = self.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(100000), ) # Assert self.assertEqual(OrderType.MARKET, order.type) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertEqual(1, order.event_count) self.assertTrue(isinstance(order.last_event, OrderInitialized)) self.assertFalse(order.is_working) self.assertFalse(order.is_completed) self.assertFalse(order.is_buy) self.assertTrue(order.is_sell) self.assertEqual(None, order.filled_timestamp) def test_order_str_and_repr(self): # Arrange # Act order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Assert self.assertEqual( 'Order(id=O-19700101-000000-001-001-1, state=INITIALIZED, BUY 100K AUDUSD.FXCM MARKET DAY)', str(order)) self.assertTrue( repr(order).startswith( '<Order(id=O-19700101-000000-001-001-1, state=INITIALIZED, BUY 100K AUDUSD.FXCM MARKET DAY) object at' )) def test_can_initialize_limit_order(self): # Arrange # Act order = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) # Assert self.assertEqual(OrderType.LIMIT, order.type) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertEqual(TimeInForce.DAY, order.time_in_force) self.assertFalse(order.is_completed) def test_can_initialize_limit_order_with_expire_time(self): # Arrange # Act order = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5), Label('U1_TP'), OrderPurpose.NONE, TimeInForce.GTD, UNIX_EPOCH) # Assert self.assertEqual(AUDUSD_FXCM, order.symbol) self.assertEqual(OrderType.LIMIT, order.type) self.assertEqual(Price(1.00000, 5), order.price) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertEqual(TimeInForce.GTD, order.time_in_force) self.assertEqual(UNIX_EPOCH, order.expire_time) self.assertFalse(order.is_completed) def test_can_initialize_stop_market_order(self): # Arrange # Act order = self.order_factory.stop(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) # Assert self.assertEqual(OrderType.STOP, order.type) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertEqual(TimeInForce.DAY, order.time_in_force) self.assertFalse(order.is_completed) def test_can_initialize_stop_limit_order(self): # Arrange # Act order = self.order_factory.stop_limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) # Assert self.assertEqual(OrderType.STOP_LIMIT, order.type) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertFalse(order.is_completed) def test_can_initialize_market_if_touched_order(self): # Arrange # Act order = self.order_factory.market_if_touched(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) # Assert self.assertEqual(OrderType.MIT, order.type) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertFalse(order.is_completed) def test_can_initialize_fill_or_kill_order(self): # Arrange # Act order = self.order_factory.fill_or_kill(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Assert self.assertEqual(OrderType.MARKET, order.type) self.assertEqual(TimeInForce.FOC, order.time_in_force) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertFalse(order.is_completed) def test_can_initialize_immediate_or_cancel_order(self): # Arrange # Act order = self.order_factory.immediate_or_cancel(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Assert self.assertEqual(OrderType.MARKET, order.type) self.assertEqual(TimeInForce.IOC, order.time_in_force) self.assertEqual(OrderState.INITIALIZED, order.state) self.assertFalse(order.is_completed) def test_can_initialize_atomic_order_market_with_no_take_profit_or_label( self): # Arrange # Act atomic_order = self.order_factory.atomic_market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(0.99990, 5)) # Assert self.assertEqual(AUDUSD_FXCM, atomic_order.stop_loss.symbol) self.assertFalse(atomic_order.has_take_profit) self.assertEqual(OrderId('O-19700101-000000-001-001-1'), atomic_order.entry.id) self.assertEqual(OrderId('O-19700101-000000-001-001-2'), atomic_order.stop_loss.id) self.assertEqual(OrderSide.SELL, atomic_order.stop_loss.side) self.assertEqual(Quantity(100000), atomic_order.entry.quantity) self.assertEqual(Quantity(100000), atomic_order.stop_loss.quantity) self.assertEqual(Price(0.99990, 5), atomic_order.stop_loss.price) self.assertEqual(None, atomic_order.entry.label) self.assertEqual(None, atomic_order.stop_loss.label) self.assertEqual(TimeInForce.GTC, atomic_order.stop_loss.time_in_force) self.assertEqual(None, atomic_order.entry.expire_time) self.assertEqual(None, atomic_order.stop_loss.expire_time) self.assertEqual(AtomicOrderId('AO-19700101-000000-001-001-1'), atomic_order.id) self.assertEqual(UNIX_EPOCH, atomic_order.timestamp) def test_can_initialize_atomic_order_market_with_take_profit_and_label( self): # Arrange # Act atomic_order = self.order_factory.atomic_market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(0.99990, 5), Price(1.00010, 5), Label('U1')) # Assert self.assertEqual(AUDUSD_FXCM, atomic_order.stop_loss.symbol) self.assertTrue(atomic_order.has_take_profit) self.assertEqual(AUDUSD_FXCM, atomic_order.take_profit.symbol) self.assertEqual(OrderId('O-19700101-000000-001-001-1'), atomic_order.entry.id) self.assertEqual(OrderId('O-19700101-000000-001-001-2'), atomic_order.stop_loss.id) self.assertEqual(OrderId('O-19700101-000000-001-001-3'), atomic_order.take_profit.id) self.assertEqual(OrderSide.SELL, atomic_order.stop_loss.side) self.assertEqual(OrderSide.SELL, atomic_order.take_profit.side) self.assertEqual(Quantity(100000), atomic_order.stop_loss.quantity) self.assertEqual(Quantity(100000), atomic_order.take_profit.quantity) self.assertEqual(Price(0.99990, 5), atomic_order.stop_loss.price) self.assertEqual(Price(1.00010, 5), atomic_order.take_profit.price) self.assertEqual(Label('U1_E'), atomic_order.entry.label) self.assertEqual(Label('U1_SL'), atomic_order.stop_loss.label) self.assertEqual(Label('U1_TP'), atomic_order.take_profit.label) self.assertEqual(TimeInForce.GTC, atomic_order.stop_loss.time_in_force) self.assertEqual(TimeInForce.GTC, atomic_order.take_profit.time_in_force) self.assertEqual(None, atomic_order.entry.expire_time) self.assertEqual(None, atomic_order.stop_loss.expire_time) self.assertEqual(None, atomic_order.take_profit.expire_time) self.assertEqual(AtomicOrderId('AO-19700101-000000-001-001-1'), atomic_order.id) self.assertEqual(UNIX_EPOCH, atomic_order.timestamp) def test_atomic_order_str_and_repr(self): # Arrange # Act atomic_order = self.order_factory.atomic_market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(0.99990, 5), Price(1.00010, 5), Label('U1')) # Assert self.assertEqual( 'AtomicOrder(id=AO-19700101-000000-001-001-1, EntryOrder(id=O-19700101-000000-001-001-1, state=INITIALIZED, label=U1_E, BUY 100K AUDUSD.FXCM MARKET DAY), SL=0.99990, TP=1.00010)', str(atomic_order)) self.assertTrue( repr(atomic_order).startswith( '<AtomicOrder(id=AO-19700101-000000-001-001-1, EntryOrder(id=O-19700101-000000-001-001-1, state=INITIALIZED, label=U1_E, BUY 100K AUDUSD.FXCM MARKET DAY), SL=0.99990, TP=1.00010) object at' )) self.assertTrue(repr(atomic_order).endswith('>')) def test_can_apply_order_submitted_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderSubmitted(self.account_id, order.id, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.SUBMITTED, order.state) self.assertEqual(2, order.event_count) self.assertEqual(event, order.last_event) self.assertFalse(order.is_completed) def test_can_apply_order_accepted_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderAccepted(self.account_id, order.id, OrderIdBroker('B' + order.id.value), Label('E'), UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.ACCEPTED, order.state) self.assertFalse(order.is_completed) def test_can_apply_order_rejected_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderRejected(self.account_id, order.id, UNIX_EPOCH, ValidString('ORDER ID INVALID'), GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.REJECTED, order.state) self.assertTrue(order.is_completed) def test_can_apply_order_working_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderWorking(self.account_id, order.id, OrderIdBroker('SOME_BROKER_ID'), order.symbol, order.label, order.side, order.type, order.quantity, Price(1.0, 1), order.time_in_force, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH, order.expire_time) # Act order.apply(event) # Assert # print(order) self.assertEqual(OrderState.WORKING, order.state) self.assertEqual(OrderIdBroker('SOME_BROKER_ID'), order.id_broker) self.assertFalse(order.is_completed) self.assertTrue(order.is_working) self.assertEqual(None, order.filled_timestamp) def test_can_apply_order_expired_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderExpired(self.account_id, order.id, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.EXPIRED, order.state) self.assertTrue(order.is_completed) def test_can_apply_order_cancelled_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderCancelled(self.account_id, order.id, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.CANCELLED, order.state) self.assertTrue(order.is_completed) def test_can_apply_order_cancel_reject_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderCancelReject(self.account_id, order.id, UNIX_EPOCH, ValidString('REJECT_RESPONSE'), ValidString('ORDER DOES NOT EXIST'), GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.INITIALIZED, order.state) def test_can_apply_order_modified_event_to_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) order_working = OrderWorking(self.account_id, order.id, OrderIdBroker('SOME_BROKER_ID_1'), order.symbol, order.label, order.side, order.type, order.quantity, Price(1.00000, 5), order.time_in_force, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH, order.expire_time) order_modified = OrderModified(self.account_id, order.id, OrderIdBroker('SOME_BROKER_ID_2'), Quantity(120000), Price(1.00001, 5), UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) order.apply(order_working) # Act order.apply(order_modified) # Assert self.assertEqual(OrderState.WORKING, order.state) self.assertEqual(OrderIdBroker('SOME_BROKER_ID_2'), order.id_broker) self.assertEqual(Quantity(120000), order.quantity) self.assertEqual(Price(1.00001, 5), order.price) self.assertTrue(order.is_working) self.assertFalse(order.is_completed) self.assertEqual(3, order.event_count) def test_can_apply_order_filled_event_to_market_order(self): # Arrange order = self.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) event = OrderFilled(self.account_id, order.id, ExecutionId('SOME_EXEC_ID_1'), PositionIdBroker('SOME_EXEC_TICKET_1'), order.symbol, order.side, order.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.FILLED, order.state) self.assertEqual(Quantity(100000), order.filled_quantity) self.assertEqual(Price(1.00001, 5), order.average_price) self.assertTrue(order.is_completed) self.assertEqual(UNIX_EPOCH, order.filled_timestamp) def test_can_apply_order_filled_event_to_buy_limit_order(self): # Arrange order = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) event = OrderFilled(self.account_id, order.id, ExecutionId('SOME_EXEC_ID_1'), PositionIdBroker('SOME_EXEC_TICKET_1'), order.symbol, order.side, order.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.FILLED, order.state) self.assertEqual(Quantity(100000), order.filled_quantity) self.assertEqual(Price(1.00000, 5), order.price) self.assertEqual(Price(1.00001, 5), order.average_price) self.assertEqual(Decimal(0.00001, 5), order.slippage) self.assertTrue(order.is_completed) self.assertEqual(UNIX_EPOCH, order.filled_timestamp) def test_can_apply_order_partially_filled_event_to_buy_limit_order(self): # Arrange order = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) event = OrderPartiallyFilled(self.account_id, order.id, ExecutionId('SOME_EXEC_ID_1'), PositionIdBroker('SOME_EXEC_TICKET_1'), order.symbol, order.side, Quantity(50000), Quantity(50000), Price(0.999999, 6), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.PARTIALLY_FILLED, order.state) self.assertEqual(Quantity(50000), order.filled_quantity) self.assertEqual(Price(1.00000, 5), order.price) self.assertEqual(Price(0.999999, 6), order.average_price) self.assertEqual(Decimal(-0.000001, 6), order.slippage) self.assertFalse(order.is_completed) self.assertEqual(UNIX_EPOCH, order.filled_timestamp) def test_can_apply_order_overfilled_event_to_buy_limit_order(self): # Arrange order = self.order_factory.limit(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) event = OrderFilled(self.account_id, order.id, ExecutionId('SOME_EXEC_ID_1'), PositionIdBroker('SOME_EXEC_TICKET_1'), order.symbol, order.side, Quantity(150000), Price(0.99999, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act order.apply(event) # Assert self.assertEqual(OrderState.OVER_FILLED, order.state) self.assertEqual(Quantity(150000), order.filled_quantity) self.assertFalse(order.is_completed) self.assertEqual(UNIX_EPOCH, order.filled_timestamp)