예제 #1
0
 def trade_pre_cancel(contract=None, order: IBOrder = None) -> Trade:
     contract = contract or IBTestStubs.contract_details("AAPL").contract
     order = order or IBExecTestStubs.ib_order()
     return Trade(
         contract=contract,
         order=order,
         orderStatus=OrderStatus(
             orderId=41,
             status="PreSubmitted",
             filled=0.0,
             remaining=1.0,
             avgFillPrice=0.0,
             permId=189868420,
             parentId=0,
             lastFillPrice=0.0,
             clientId=1,
             whyHeld="",
             mktCapPrice=0.0,
         ),
         fills=[],
         log=[
             TradeLogEntry(
                 time=datetime.datetime(
                     2022, 3, 6, 2, 17, 18, 455087, tzinfo=datetime.timezone.utc
                 ),
                 status="PendingCancel",
                 message="",
                 errorCode=0,
             )
         ],
     )
예제 #2
0
    def fill_trade(trade: Trade, exec_id: int, date: pd.datetime,
                   price: float) -> Trade:
        quantity = trade.order.totalQuantity
        execution = Execution(execId=exec_id,
                              time=date,
                              acctNumber='',
                              exchange=trade.contract.exchange,
                              side=trade.order.action,
                              shares=quantity,
                              price=price,
                              permId=trade.order.permId,
                              orderId=trade.order.orderId,
                              cumQty=quantity,
                              avgPrice=price,
                              lastLiquidity=quantity)
        commission = CommissionReport()
        fill = Fill(time=date,
                    contract=trade.contract,
                    execution=execution,
                    commissionReport=commission)
        trade.fills.append(fill)
        trade.orderStatus = OrderStatus(status=OrderStatus.Filled,
                                        filled=quantity,
                                        remaining=0,
                                        avgFillPrice=price,
                                        lastFillPrice=price)
        trade.log.append(TradeLogEntry(time=date,
                                       status=trade.orderStatus,
                                       message=f'Fill @{price}'))

        return trade
예제 #3
0
 def trade_pending_submit(contract=None, order: IBOrder = None) -> Trade:
     contract = contract or IBTestStubs.contract_details("AAPL").contract
     order = order or IBExecTestStubs.ib_order()
     return Trade(
         contract=contract,
         order=order,
         orderStatus=OrderStatus(
             orderId=41,
             status="PendingSubmit",
             filled=0.0,
             remaining=0.0,
             avgFillPrice=0.0,
             permId=0,
             parentId=0,
             lastFillPrice=0.0,
             clientId=0,
             whyHeld="",
             mktCapPrice=0.0,
         ),
         fills=[],
         log=[
             TradeLogEntry(
                 time=datetime.datetime(
                     2022, 3, 5, 3, 6, 23, 492613, tzinfo=datetime.timezone.utc
                 ),
                 status="PendingSubmit",
                 message="",
                 errorCode=0,
             ),
         ],
     )
예제 #4
0
 def placeOrder(self, contract: Contract, order: Order) -> Trade:
     orderId = order.orderId or next(self.id)
     now = self.market.date
     trade = self.market.get_trade(order)
     if trade:
         # this is a modification of an existing order
         assert trade.orderStatus.status not in OrderStatus.DoneStates
         logEntry = TradeLogEntry(now, trade.orderStatus.status, 'Modify')
         trade.log.append(logEntry)
         trade.modifyEvent.emit(trade)
         self.orderModifyEvent.emit(trade)
     else:
         # this is a new order
         assert order.totalQuantity != 0, 'Order quantity cannot be zero'
         order.orderId = orderId
         order.permId = orderId
         if order.parentId:
             # this is for bracket order implementation TODO
             orderStatus = OrderStatus(status=OrderStatus.PreSubmitted,
                                       remaining=order.totalQuantity)
             log.error('Why the f**k are we here?')
         else:
             orderStatus = OrderStatus(status=OrderStatus.Submitted,
                                       remaining=order.totalQuantity)
         logEntry = TradeLogEntry(now, orderStatus, '')
         trade = Trade(contract, order, orderStatus, [], [logEntry])
         self.newOrderEvent.emit(trade)
         self.market.append_trade(trade)
     return trade
예제 #5
0
    def test_cancel_order(self):
        # Arrange
        instrument = IBTestStubs.instrument("AAPL")
        contract_details = IBTestStubs.contract_details("AAPL")
        contract = contract_details.contract
        order = IBTestStubs.create_order()
        self.instrument_setup(instrument=instrument,
                              contract_details=contract_details)
        self.exec_client._ib_insync_orders[
            TestIdStubs.client_order_id()] = Trade(contract=contract,
                                                   order=order)

        # Act
        command = TestCommandStubs.cancel_order_command(
            instrument_id=instrument.id)
        with patch.object(self.exec_client._client, "cancelOrder") as mock:
            self.exec_client.cancel_order(command=command)

        # Assert
        expected = {
            "contract":
            Contract(
                secType="STK",
                conId=265598,
                symbol="AAPL",
                exchange="SMART",
                primaryExchange="NASDAQ",
                currency="USD",
                localSymbol="AAPL",
                tradingClass="NMS",
            ),
            "order":
            LimitOrder(action="BUY", totalQuantity=100_000, lmtPrice=105.0),
        }
예제 #6
0
 def cancel_trade(self, trade: Trade) -> None:
     log.debug(f'will cancel trade: {trade}')
     now = self.date
     if not trade.isDone():
         newStatus = OrderStatus.Cancelled
         logEntry = TradeLogEntry(now, newStatus, '')
         trade.log.append(logEntry)
         trade.orderStatus.status = newStatus
         trade.cancelEvent.emit(trade)
         trade.statusEvent.emit(trade)
         trade.cancelledEvent.emit(trade)
         log.debug(f'cancelled trade: {trade}')
         log.debug(f'isDone: {trade.isDone()}')
예제 #7
0
 def monitor(self, trade: Trade) -> bool:
     c = 0
     while c < 5:
         c += 1
         self._trader.ib.sleep(15)
         if trade.isDone():
             return True
         else:
             log.debug(f'{trade.contract.localSymbol} attempt {c} to amend '
                       f'{trade.order.orderType}')
             trade.order.limitPrice = self.price(trade.order.action,
                                                 trade.contract)
             self.trade(trade.contract, trade.order)
     return False
예제 #8
0
    def test_update_order(self):
        # Arrange
        instrument = IBTestStubs.instrument("AAPL")
        contract_details = IBTestStubs.contract_details("AAPL")
        contract = contract_details.contract
        order = IBTestStubs.create_order()
        self.instrument_setup(instrument=instrument,
                              contract_details=contract_details)
        self.exec_client._ib_insync_orders[
            TestIdStubs.client_order_id()] = Trade(contract=contract,
                                                   order=order)

        # Act
        command = TestCommandStubs.modify_order_command(
            instrument_id=instrument.id,
            price=Price.from_int(10),
            quantity=Quantity.from_str("100"),
        )
        with patch.object(self.exec_client._client, "placeOrder") as mock:
            self.exec_client.modify_order(command=command)

        # Assert
        expected = {
            "contract":
            Contract(
                secType="STK",
                conId=265598,
                symbol="AAPL",
                exchange="SMART",
                primaryExchange="NASDAQ",
                currency="USD",
                localSymbol="AAPL",
                tradingClass="NMS",
            ),
            "order":
            LimitOrder(action="BUY", totalQuantity=100, lmtPrice=10.0),
        }
        name, args, kwargs = mock.mock_calls[0]
        # Can't directly compare kwargs for some reason?
        assert kwargs["contract"] == expected["contract"]
        assert kwargs["order"].action == expected["order"].action
        assert kwargs["order"].totalQuantity == expected["order"].totalQuantity
        assert kwargs["order"].lmtPrice == expected["order"].lmtPrice
예제 #9
0
 def trade_canceled(contract=None, order: IBOrder = None) -> Trade:
     contract = contract or IBTestStubs.contract_details("AAPL").contract
     order = order or IBExecTestStubs.ib_order()
     return Trade(
         contract=contract,
         order=order,
         orderStatus=OrderStatus(
             orderId=41,
             status="Cancelled",
             filled=0.0,
             remaining=1.0,
             avgFillPrice=0.0,
             permId=189868420,
             parentId=0,
             lastFillPrice=0.0,
             clientId=1,
             whyHeld="",
             mktCapPrice=0.0,
         ),
         fills=[],
         log=[
             TradeLogEntry(
                 time=datetime.datetime(
                     2022, 3, 6, 2, 17, 18, 455087, tzinfo=datetime.timezone.utc
                 ),
                 status="PendingCancel",
                 message="",
                 errorCode=0,
             ),
             TradeLogEntry(
                 time=datetime.datetime(2022, 3, 6, 2, 23, 2, 847, tzinfo=datetime.timezone.utc),
                 status="Cancelled",
                 message="Error 10148, reqId 45: OrderId 45 that needs to be cancelled cannot be cancelled, state: PendingCancel.",
                 errorCode=10148,
             ),
         ],
     )
예제 #10
0
    async def wait_for_fill(self, trade: ibs.Trade):
        while not trade.isDone():
            await self.ib.updateEvent

        # noinspection PyUnresolvedReferences
        return trade.orderStatus.status == 'Filled'