Exemplo n.º 1
0
    def test_serialize_and_deserialize_limit_orders_with_expire_time(self):
        # Arrange
        order = LimitOrder(
            ClientOrderId("O-123456"),
            StrategyId("S", "001"),
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000),
            price=Price("1.00000"),
            time_in_force=TimeInForce.GTD,
            expire_time=UNIX_EPOCH,
            init_id=uuid4(),
            timestamp_ns=0,
        )

        # Act
        serialized = self.serializer.serialize(order)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == order
        print(b64encode(serialized))
        print(order)
Exemplo n.º 2
0
    def test_handle_trade_tick_when_count_below_threshold_updates(self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.LAST)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = TickBarAggregator(bar_type, handler, Logger(TestClock()))

        tick1 = TradeTick(
            instrument_id=AUDUSD_SIM.id,
            price=Price("1.00001"),
            size=Quantity(1),
            aggressor_side=AggressorSide.BUY,
            match_id=TradeMatchId("123456"),
            timestamp_ns=0,
        )

        # Act
        aggregator.handle_trade_tick(tick1)

        # Assert
        self.assertEqual(0, len(bar_store.get_store()))
Exemplo n.º 3
0
    def test_apply_order_denied_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000),
        )

        denied = OrderDenied(
            order.cl_ord_id,
            "SOME_REASON",
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        order.apply(denied)

        # Assert
        self.assertEqual(OrderState.DENIED, order.state)
        self.assertEqual(2, order.event_count)
        self.assertEqual(denied, order.last_event)
        self.assertTrue(order.is_completed)
    def test_can_update_order_for_working_order(self):
        # Arrange
        order = self.strategy.order_factory.market(AUDUSD_FXCM, OrderSide.BUY,
                                                   Quantity(100000))
        position_id = self.strategy.position_id_generator.generate()
        self.database.add_order(order, self.strategy.id, position_id)

        order_working = TestStubs.event_order_working(order)
        order.apply(order_working)

        # Act
        self.database.update_order(order)

        # Assert
        self.assertTrue(self.database.order_exists(order.id))
        self.assertTrue(order.id in self.database.get_order_ids())
        self.assertTrue(order.id in self.database.get_orders())
        self.assertTrue(
            order.id in self.database.get_orders_working(self.strategy.id))
        self.assertTrue(order.id in self.database.get_orders_working())
        self.assertTrue(order.id not in self.database.get_orders_completed(
            self.strategy.id))
        self.assertTrue(order.id not in self.database.get_orders_completed())
    def test_can_submit_order(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag='001')
        strategy.change_clock(self.clock)

        self.exec_engine.register_strategy(strategy)

        position_id = strategy.position_id_generator.generate()
        order = strategy.order_factory.market(AUDUSD_FXCM, OrderSide.BUY,
                                              Quantity(100000))

        submit_order = SubmitOrder(self.trader_id, self.account_id,
                                   strategy.id, position_id, order,
                                   self.guid_factory.generate(),
                                   self.clock.time_now())

        # Act
        self.exec_engine.execute_command(submit_order)

        # Assert
        self.assertIn(submit_order, self.exec_client.received_commands)
        self.assertTrue(self.exec_db.order_exists(order.id))
        self.assertEqual(position_id, self.exec_db.get_position_id(order.id))
    def test_serialize_and_deserialize_stop_orders_with_expire_time(self):
        # Arrange
        order = StopMarketOrder(
            ClientOrderId("O-123456"),
            StrategyId("S", "001"),
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
            price=Price("1.00000"),
            time_in_force=TimeInForce.GTD,
            expire_time=UNIX_EPOCH,
            init_id=uuid4(),
            timestamp=UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(order)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(order, deserialized)
        print(b64encode(serialized))
        print(order)
    def test_update_order_for_working_order(self):
        # Arrange
        order = self.strategy.order_factory.stop_market(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
            Price("1.00000"),
        )

        self.database.add_order(order)

        order.apply(TestStubs.event_order_submitted(order))
        self.database.update_order(order)

        order.apply(TestStubs.event_order_accepted(order))
        self.database.update_order(order)

        # Act
        order.apply(TestStubs.event_order_working(order))
        self.database.update_order(order)

        # Assert
        self.assertEqual(order, self.database.load_order(order.cl_ord_id))
Exemplo n.º 8
0
    def test_can_modify_atomic_order_working_stop_loss(self):
        # Arrange
        strategy = TestStrategy1(bar_type=TestStubs.bartype_usdjpy_1min_bid())
        self.data_client.register_strategy(strategy)
        self.exec_engine.register_strategy(strategy)
        strategy.start()

        self.exec_client.process_tick(TestStubs.tick_3decimal(self.usdjpy.symbol))  # Prepare market
        atomic_order = strategy.order_factory.atomic_market(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price(85.000, 3))

        strategy.submit_atomic_order(atomic_order, strategy.position_id_generator.generate())

        # Act
        strategy.modify_order(atomic_order.stop_loss, atomic_order.entry.quantity, Price(85.100, 3))

        # Assert
        self.assertEqual(Price(85.100, 3), strategy.order(atomic_order.stop_loss.id).price)
        self.assertEqual(8, strategy.object_storer.count)
        self.assertTrue(isinstance(strategy.object_storer.get_store()[7], OrderModified))
Exemplo n.º 9
0
def parse_bars_http(
    instrument: Instrument,
    bar_type: BarType,
    data: List[Dict[str, Any]],
    ts_event_delta: int,
    ts_init: int,
) -> List[Bar]:
    bars: List[Bar] = []
    for row in data:
        bar: Bar = Bar(
            bar_type=bar_type,
            open=Price(row["open"], instrument.price_precision),
            high=Price(row["high"], instrument.price_precision),
            low=Price(row["low"], instrument.price_precision),
            close=Price(row["close"], instrument.price_precision),
            volume=Quantity(row["volume"], instrument.size_precision),
            check=True,
            ts_event=secs_to_nanos(row["time"]) + ts_event_delta,
            ts_init=ts_init,
        )
        bars.append(bar)

    return bars
Exemplo n.º 10
0
    def trailing_stop_buy(self, last_bar: Bar):
        """
        Users simple trailing stop BUY for (SHORT positions).

        Parameters
        ----------
        last_bar : Bar
            The last bar received.

        """
        # Round price to nearest 0.5 (for XBT/USD)
        price = (round((last_bar.high +
                        (self.atr.value * self.trail_atr_multiple)) * 2) / 2)
        order: StopMarketOrder = self.order_factory.stop_market(
            instrument_id=self.instrument_id,
            order_side=OrderSide.BUY,
            quantity=Quantity(self.trade_size),
            price=Price(price, self.instrument.price_precision),
            reduce_only=True,
        )

        self.trailing_stop = order
        self.submit_order(order)
Exemplo n.º 11
0
    def test_handle_trade_tick_when_volume_below_threshold_updates(self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        symbol = TestStubs.symbol_audusd_fxcm()
        bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.LAST)
        bar_type = BarType(symbol, bar_spec)
        aggregator = VolumeBarAggregator(bar_type, handler, TestLogger(TestClock()))

        tick1 = TradeTick(
            symbol=AUDUSD_SIM.symbol,
            price=Price("1.00001"),
            size=Quantity(1),
            side=OrderSide.BUY,
            match_id=TradeMatchId("123456"),
            timestamp=UNIX_EPOCH,
        )

        # Act
        aggregator.handle_trade_tick(tick1)

        # Assert
        self.assertEqual(0, len(bar_store.get_store()))
Exemplo n.º 12
0
    def test_limit_buy_post_only_reduce_only_order(self):
        # Arrange
        order = self.order_factory.limit(
            symbol=BTCUSDT,
            order_side=OrderSide.BUY,
            quantity=Quantity("1.0"),
            price=Price("50000"),
            post_only=True,
            reduce_only=True,
        )

        # Act
        result = self.builder.build_py(order)

        # Assert
        expected_args = ['BTC/USDT', 'Limit', 'Buy', '1.0', '50000']
        expected_custom_params = {
            'clOrdID': 'O-19700101-000000-000-001-1',
            'execInst': 'ParticipateDoNotInitiate,ReduceOnly',
            'timeInForce': 'GoodTillCancel'
        }
        self.assertTrue(order.is_post_only)
        self.assertEqual((expected_args, expected_custom_params), result)
    def test_order_serializer_methods_raise_not_implemented_error(self):
        # Arrange
        order_factory = OrderFactory(
            trader_id=TraderId("TESTER", "000"),
            strategy_id=StrategyId("S", "001"),
            clock=TestClock(),
        )

        order = order_factory.market(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000),
        )

        serializer = OrderSerializer()

        # Act
        # Assert
        with pytest.raises(NotImplementedError):
            serializer.serialize(order)

        with pytest.raises(NotImplementedError):
            serializer.deserialize(bytes())
Exemplo n.º 14
0
    def test_submit_bracket_market_order(self):
        # Arrange
        # Prepare market
        tick = TestStubs.quote_tick_3decimal(USDJPY_SIM.symbol)
        self.data_engine.process(tick)
        self.exchange.process_tick(tick)

        entry_order = self.strategy.order_factory.market(
            USDJPY_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
        )

        bracket_order = self.strategy.order_factory.bracket(
            entry_order,
            Price("80.000"),
        )

        # Act
        self.strategy.submit_bracket_order(bracket_order)

        # Assert
        self.assertEqual(OrderState.FILLED, entry_order.state)
Exemplo n.º 15
0
    def test_apply_order_invalid_event(self):
        # Arrange
        order = self.order_factory.market(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
        )

        invalid = OrderInvalid(
            order.cl_ord_id,
            "SOME_REASON",
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        order.apply(invalid)

        # Assert
        self.assertEqual(OrderState.INVALID, order.state)
        self.assertEqual(2, order.event_count)
        self.assertEqual(invalid, order.last_event)
        self.assertTrue(order.is_completed)
Exemplo n.º 16
0
    def test_serialize_and_deserialize_amend_order_commands(self):
        # Arrange
        command = ModifyOrder(
            self.trader_id,
            StrategyId("SCALPER-001"),
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("001"),
            Quantity(100000, precision=0),
            Price(1.00001, precision=5),
            None,
            UUID4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)
Exemplo n.º 17
0
    def test_pack_and_unpack_stop_limit_orders_with_expire_time(self):
        # Arrange
        order = StopLimitOrder(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            OrderSide.BUY,
            Quantity(100000, precision=0),
            price=Price(1.00000, precision=5),
            trigger=Price(1.00010, precision=5),
            time_in_force=TimeInForce.GTD,
            expire_time=UNIX_EPOCH,
            init_id=UUID4(),
            ts_init=0,
        )

        # Act
        packed = OrderInitialized.to_dict(order.last_event)
        unpacked = self.unpacker.unpack(packed)

        # Assert
        assert unpacked == order
Exemplo n.º 18
0
    def test_order_initialized(self):
        # Arrange
        uuid = uuid4()
        event = OrderInitialized(cl_ord_id=ClientOrderId("O-2020872378423"),
                                 strategy_id=StrategyId("SCALPER", "001"),
                                 symbol=Symbol("BTC/USDT",
                                               Exchange("BINANCE")),
                                 order_side=OrderSide.BUY,
                                 order_type=OrderType.LIMIT,
                                 quantity=Quantity("0.561000"),
                                 time_in_force=TimeInForce.DAY,
                                 event_id=uuid,
                                 event_timestamp=UNIX_EPOCH,
                                 options={"Price": "15200.10"})

        # Act
        # Assert
        self.assertEqual(
            f"OrderInitialized(cl_ord_id=O-2020872378423, id={uuid})",
            str(event))
        self.assertEqual(
            f"OrderInitialized(cl_ord_id=O-2020872378423, id={uuid})",
            repr(event))
Exemplo n.º 19
0
    def test_order_amended(self):
        # Arrange
        uuid = uuid4()
        event = OrderAmended(
            account_id=AccountId("SIM", "000"),
            cl_ord_id=ClientOrderId("O-2020872378423"),
            order_id=OrderId("123456"),
            quantity=Quantity(500000),
            price=Price('1.95000'),
            amended_time=UNIX_EPOCH,
            event_id=uuid,
            event_timestamp=UNIX_EPOCH,
        )

        # Act
        self.assertEqual(
            f"OrderAmended(account_id=SIM-000, cl_order_id=O-2020872378423, "
            f"order_id=123456, qty=500,000, price=1.95000, id={uuid})",
            str(event))
        self.assertEqual(
            f"OrderAmended(account_id=SIM-000, cl_order_id=O-2020872378423, "
            f"order_id=123456, qty=500,000, price=1.95000, id={uuid})",
            repr(event))
    def test_cancel_order_when_not_connected_logs_and_does_not_send(self):
        # Arrange
        order = self.order_factory.market(
            ETHUSDT_BINANCE.symbol,
            OrderSide.BUY,
            Quantity(100),
        )

        command = CancelOrder(
            BINANCE,
            self.trader_id,
            self.account_id,
            order.cl_ord_id,
            order.id,
            self.uuid_factory.generate(),
            self.clock.utc_now(),
        )

        # Act
        self.exec_client.cancel_order(command)

        # Assert
        self.assertTrue(True)  # No exceptions raised
Exemplo n.º 21
0
    def test_serialize_and_deserialize_stop_limit_order_initialized_events(self):
        # Arrange
        options = {
            "expire_time_ns": None,
            "price": "1.0005",
            "trigger_price": "1.0010",
        }

        event = OrderInitialized(
            self.trader_id,
            self.strategy_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            OrderSide.SELL,
            OrderType.STOP_LIMIT,
            Quantity(100000, precision=0),
            TimeInForce.DAY,
            post_only=True,
            reduce_only=True,
            options=options,
            order_list_id=OrderListId("1"),
            contingency_type=ContingencyType.OTO,
            linked_order_ids=[ClientOrderId("O-123457"), ClientOrderId("O-123458")],
            parent_order_id=ClientOrderId("O-123455"),
            tags="entry,bulk",
            event_id=UUID4(),
            ts_init=0,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == event
        assert deserialized.options == options
        assert deserialized.tags == "entry,bulk"
Exemplo n.º 22
0
    def test_process_bar_when_subscriber_then_sends_to_registered_handler(
            self):
        # Arrange
        self.data_engine.register_client(self.binance_client)
        self.binance_client.connect()

        bar_spec = BarSpecification(1000, BarAggregation.TICK, PriceType.MID)
        bar_type = BarType(ETHUSDT_BINANCE.id,
                           bar_spec,
                           internal_aggregation=True)

        handler = ObjectStorer()
        subscribe = Subscribe(
            client_id=ClientId(BINANCE.value),
            data_type=DataType(Bar, metadata={"BarType": bar_type}),
            handler=handler.store,
            command_id=self.uuid_factory.generate(),
            timestamp_ns=self.clock.timestamp_ns(),
        )

        self.data_engine.execute(subscribe)

        bar = Bar(
            bar_type,
            Price("1051.00000"),
            Price("1055.00000"),
            Price("1050.00000"),
            Price("1052.00000"),
            Quantity(100),
            0,
        )

        # Act
        self.data_engine.process(bar)

        # Assert
        self.assertEqual([bar], handler.get_store())
Exemplo n.º 23
0
    def test_order_initialized(self):
        # Arrange
        uuid = uuid4()
        event = OrderInitialized(
            client_order_id=ClientOrderId("O-2020872378423"),
            strategy_id=StrategyId("SCALPER", "001"),
            instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")),
            order_side=OrderSide.BUY,
            order_type=OrderType.LIMIT,
            quantity=Quantity("0.561000"),
            time_in_force=TimeInForce.DAY,
            event_id=uuid,
            timestamp_ns=0,
            options={"Price": "15200.10"},
        )

        # Act
        # Assert
        assert (
            f"OrderInitialized(client_order_id=O-2020872378423, strategy_id=SCALPER-001, event_id={uuid})"
            == str(event))
        assert (
            f"OrderInitialized(client_order_id=O-2020872378423, strategy_id=SCALPER-001, event_id={uuid})"
            == repr(event))
Exemplo n.º 24
0
    def test_submit_order(self):
        # Arrange
        self.exec_engine.start()

        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            self.clock,
            self.logger,
        )

        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.market(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
        )

        submit_order = SubmitOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            strategy.id,
            PositionId.null(),
            order,
            self.uuid_factory.generate(),
            self.clock.utc_now(),
        )

        # Act
        self.exec_engine.execute(submit_order)

        # Assert
        self.assertIn(submit_order, self.exec_client.commands)
        self.assertTrue(self.cache.order_exists(order.cl_ord_id))
    def test_serialize_and_deserialize_order_working_events(self):
        # Arrange
        event = OrderWorking(
            self.account_id,
            ClientOrderId("O-123456"),
            OrderId("B-123456"),
            AUDUSD_SIM.symbol,
            OrderSide.SELL,
            OrderType.STOP_MARKET,
            Quantity(100000),
            Price("1.50000"),
            TimeInForce.DAY,
            None,
            UNIX_EPOCH,
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(deserialized, event)
    def test_serialize_and_deserialize_order_initialized_events(self):
        # Arrange
        options = {'Price': '1.0005'}

        event = OrderInitialized(
            ClientOrderId("O-123456"),
            StrategyId("S", "001"),
            AUDUSD_SIM.symbol,
            OrderSide.SELL,
            OrderType.STOP_MARKET,
            Quantity(100000),
            TimeInForce.DAY,
            uuid4(),
            UNIX_EPOCH,
            options=options,
        )

        # Act
        serialized = self.serializer.serialize(event)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(deserialized, event)
        self.assertEqual(options, event.options)
    def test_handle_trade_tick_when_value_below_threshold_updates(self):
        # Arrange
        bar_store = ObjectStorer()
        handler = bar_store.store
        instrument_id = TestStubs.audusd_id()
        bar_spec = BarSpecification(100000, BarAggregation.VALUE, PriceType.LAST)
        bar_type = BarType(instrument_id, bar_spec)
        aggregator = ValueBarAggregator(bar_type, handler, Logger(TestClock()))

        tick1 = TradeTick(
            instrument_id=AUDUSD_SIM.id,
            price=Price("15000.00"),
            size=Quantity("3.5"),
            side=OrderSide.BUY,
            match_id=TradeMatchId("123456"),
            timestamp_ns=0,
        )

        # Act
        aggregator.handle_trade_tick(tick1)

        # Assert
        self.assertEqual(0, len(bar_store.get_store()))
        self.assertEqual(Decimal("52500.000"), aggregator.get_cumulative_value())
    def test_flatten_position(self):
        # Arrange
        strategy = TradingStrategy(order_id_tag="001")
        strategy.register_trader(
            TraderId("TESTER", "000"),
            clock=self.clock,
            uuid_factory=self.uuid_factory,
            logger=self.logger,
        )
        self.exec_engine.register_strategy(strategy)

        order = strategy.order_factory.market(
            USDJPY_FXCM,
            OrderSide.BUY,
            Quantity(100000),
        )

        strategy.submit_order(order)

        filled = TestStubs.event_order_filled(
            order,
            position_id=PositionId("B-USD/JPY-1"),
            strategy_id=strategy.id,
        )
        position = Position(filled)

        # Act
        strategy.flatten_position(position)

        # Assert
        self.assertTrue(order in strategy.execution.orders())
        self.assertEqual(OrderState.FILLED, strategy.execution.orders()[0].state())
        self.assertEqual(PositionSide.FLAT, strategy.execution.positions()[0].side)
        self.assertTrue(strategy.execution.positions()[0].is_closed())
        self.assertTrue(PositionId("B-USD/JPY-1") in strategy.execution.position_closed_ids())
        self.assertTrue(strategy.execution.is_completely_flat())
Exemplo n.º 29
0
def _handle_market_trades(
    runner,
    instrument,
    timestamp_origin_ns,
    timestamp_ns,
):
    trade_ticks = []
    for price, volume in runner.get("trd", []):
        if volume == 0:
            continue
        # Betfair doesn't publish trade ids, so we make our own
        # TODO - should we use clk here for ID instead of the hash?
        trade_id = hash_json(data=(timestamp_ns, price, volume))
        tick = TradeTick(
            instrument_id=instrument.id,
            price=price_to_probability(price, force=True),  # Already wrapping in Price
            size=Quantity(volume, precision=4),
            aggressor_side=AggressorSide.UNKNOWN,
            match_id=TradeMatchId(trade_id),
            timestamp_origin_ns=timestamp_origin_ns,
            timestamp_ns=timestamp_ns,
        )
        trade_ticks.append(tick)
    return trade_ticks
Exemplo n.º 30
0
 def submit_order_command():
     return SubmitOrder(
         client_id=BetfairTestStubs.instrument_id().venue.client_id,
         trader_id=BetfairTestStubs.trader_id(),
         account_id=BetfairTestStubs.account_id(),
         strategy_id=BetfairTestStubs.strategy_id(),
         position_id=BetfairTestStubs.position_id(),
         order=LimitOrder(
             client_order_id=ClientOrderId(
                 f"O-20210410-022422-001-001-{BetfairTestStubs.strategy_id().value}"
             ),
             strategy_id=BetfairTestStubs.strategy_id(),
             instrument_id=BetfairTestStubs.instrument_id(),
             order_side=OrderSide.BUY,
             quantity=Quantity(10),
             price=Price(0.33, 5),
             time_in_force=TimeInForce.GTC,
             expire_time=None,
             init_id=BetfairTestStubs.uuid(),
             timestamp_ns=BetfairTestStubs.clock().timestamp_ns(),
         ),
         command_id=BetfairTestStubs.uuid(),
         timestamp_ns=BetfairTestStubs.clock().timestamp_ns(),
     )