Beispiel #1
0
class TwsClient(object):
    logger = logging.getLogger(__name__)
    """Represents Interactive Broker's TWS."""
    _next_request_id = 0

    def __init__(self, client_id: int):
        """Initialises an instance for the specified client id."""
        self._client_id = client_id
        self._requests_lock = threading.Lock()
        self._requests = {}
        self._wrapper = _MulticastWrapper(self._requests, self._requests_lock)
        self._socket = EPosixClientSocket(self._wrapper)

    @property
    def client_id(self):
        return self._client_id

    def connect(self, host: str = "", port: int = 7496) -> Disconnecting:
        """Connects to TWS."""
        if not self._socket.eConnect(host, port, self.client_id):
            raise RuntimeError("Client[%d] Failed to connect at Host: %s, Port: %d" % \
            (self._client_id, host, port))
        TwsClient.logger.info("Client[%d] connected at Host: %s, Port: %d" %
                              (self._client_id, host, port))
        return Disconnecting(self._socket)

    def reqHistoricalData(self,
                          handler,
                          contract: Contract,
                          end_datetime: str,
                          duration: str = "1 D",
                          bar_size: BarSize = BarSize.Min1,
                          what_to_show: WhatToShow = WhatToShow.Trades,
                          use_rth: UseRth = UseRth.WithinTradingHour,
                          format_date: FormatDate = FormatDate.InString):
        """"""
        request = self._createRequest(RequestType.HistoricalData, handler)
        self._socket.reqHistoricalData(request.request_id, contract,
                                       end_datetime, duration, bar_size.value,
                                       what_to_show.value, use_rth.value,
                                       format_date.value)
        return request

    def reqMarketData(self,
                      handler,
                      contract: Contract,
                      generic_tick: str,
                      snapshot: bool = False):
        """"""
        request = self._createRequest(RequestType.MarketData, handler)
        self._socket.reqMktData(request.request_id, contract, generic_tick,
                                snapshot)
        return request

    def reqOpenOrders(self):
        return self._socket.reqOpenOrders()

    def cancelRequest(self, request: Request):
        """"""
        req_id = request.request_id
        with self._requests_lock:
            if self._requests.get(req_id) != request:
                return False
            del self._requests[req_id]
            try:
                {
                    RequestType.HistoricalData:
                    lambda: self._socket.cancelHistoricalData(req_id),
                    RequestType.MarketData:
                    lambda: self.cancelMktData(req_id)
                }[request.request_type]()
            except KeyError:
                raise LookupError(
                    "Client[%d] Reqest: %d - Unable to cancel unknown request type [%s]."
                    % (self._client_id, req_id, request.request_type.value))

    def cancelMktData(self, req_id):
        TwsClient.logger.info('MarketData request[%d] is cancelled.' % req_id)
        self._socket.cancelMktData(req_id)

    def _createRequest(self, req_type: RequestType, handler) -> Request:
        TwsClient._next_request_id += 1
        req_id = TwsClient._next_request_id
        request = Request(self, req_type, req_id, handler)
        with self._requests_lock:
            self._requests[req_id] = request
        return request