Пример #1
0
 def get_open_orders(self, sid=None, accountCode='default'):
     self.log.debug(__name__ + '::get_open_orders')
     accountCode = self.validateAccountCode(accountCode)
     if sid == None:
         ans = {}
         for orderId in self.PORTFOLIO.orderStatusBook:
             if self.PORTFOLIO.orderStatusBook[orderId].status in [
                     'PreSubmitted', 'Submitted'
             ]:
                 tp = self.PORTFOLIO.orderStatusBook[orderId].contract
                 security = from_contract_to_security(tp)
                 security = search_security_in_Qdata(
                     self.qData, security, self.logLevel)
                 if security not in ans:
                     ans[security] = [
                         self.PORTFOLIO.orderStatusBook[orderId]
                     ]
                 else:
                     ans[security].append(
                         self.PORTFOLIO.orderStatusBook[orderId])
         return ans
     else:
         ans = []
         for orderId in self.PORTFOLIO.orderStatusBook:
             if self.PORTFOLIO.orderStatusBook[orderId].status in [
                     'PreSubmitted', 'Submitted'
             ]:
                 tp = self.PORTFOLIO.orderStatusBook[orderId].contract
                 security = from_contract_to_security(tp)
                 security = search_security_in_Qdata(
                     self.qData, security, self.logLevel)
                 if same_security(sid, security):
                     ans.append(self.PORTFOLIO.orderStatusBook[orderId])
         return ans
Пример #2
0
 def order_status_monitor(self,
                          orderId,
                          target_status,
                          waitingTimeInSeconds=30):
     self.log.notset(__name__ + '::order_status_monitor')
     if orderId == -1:
         self.log.error(__name__ +
                        '::order_status_monitor: EXIT, orderId=-1')
         exit()
     elif orderId == 0:
         return True
     else:
         timer = dt.datetime.now()
         exit_flag = True
         while (exit_flag):
             time.sleep(0.1)
             self.processMessages()
             accountCode = self.orderId_to_accountcode(orderId)
             accountCode = self.validateAccountCode(accountCode)
             if (dt.datetime.now() -
                     timer).total_seconds() <= waitingTimeInSeconds:
                 if self.PORTFOLIO.orderStatusBook[
                         orderId].status == 'Filled':
                     self.log.info(
                         __name__ + '::order_status_monitor: Filled ' +
                         str(self.PORTFOLIO.orderStatusBook[orderId]))
                     return True
             elif self.PORTFOLIO.orderStatusBook[
                     orderId].status == target_status:
                 return True
             elif self.PORTFOLIO.orderStatusBook[
                     orderId].status == 'Inactive':
                 self.log.error(
                     __name__ +
                     '::order_status_monitor: EXIT, status=Inactive!!!, orderId=%i, %s'
                     % (orderId,
                        str(
                            from_contract_to_security(
                                self.PORTFOLIO.orderStatusBook[orderId].
                                contract))))
                 exit()
             else:
                 self.log.error(
                     __name__ +
                     '::order_status_monitor: EXIT, waiting time is too long, >%i, orderId=%i, %s, %s'
                     % (waitingTimeInSeconds, orderId,
                        str(
                            from_contract_to_security(
                                self.PORTFOLIO.orderStatusBook[orderId].
                                contract)),
                        self.PORTFOLIO.orderStatusBook[orderId].status))
                 exit()
Пример #3
0
    def execDetails(self, reqId, contract, execution):
        self.log.debug(__name__+'::execDetails: reqId= %i' %(int(reqId),) \
        + str(from_contract_to_security(contract)))
        self.log.debug(__name__+'::execDetails: %s %s %s %s %s %s'\
        %(str(execution.side),str(execution.shares),str(execution.price),\
        str(execution.orderRef), str(execution.orderId), str(execution.clientId)))
        if self.validateAccountCode(execution.acctNumber):
            cashChange = execution.shares * float(execution.price)
            if execution.side == 'BOT':
                self.PORTFOLIO.cash -= cashChange
            elif execution.side == 'SLD':
                self.PORTFOLIO.cash += cashChange
            else:
                self.log.error(
                    __name__ +
                    '::execDetails: EXIT, cannot handle execution.side=' +
                    execution.side)
                exit()
            self.log.debug(__name__ + '::execDetails: cash= %f' %
                           (float(self.PORTFOLIO.cash), ))
            if execution.orderRef not in self.PORTFOLIO.performanceTracking:
                self.PORTFOLIO.performanceTracking[execution.orderRef]=\
                pd.DataFrame({'security':'NA',
                          'action':'NA',
                          'quantity':0,
                          'avgFillPrice':0,
                          'virtualStrategyBalance':0},
                          index=[self.get_datetime()])

            security = from_contract_to_security(contract)
            action = str(execution.side)
            quantity = float(execution.shares)
            avgFillPrice = float(execution.price)
            virtualStrategyBalance = self.track_performance(
                execution.orderRef, security, action, quantity, avgFillPrice,
                execution.acctNumber)
            #print self.PORTFOLIO.virtualHoldings
            #prev=self.PORTFOLIO.performanceTracking[execution.orderRef].ix[-1, 'virtualStrategyBalance']
            #print prev,virtualStrategyBalance
            if virtualStrategyBalance == None:
                virtualStrategyBalance = np.nan
            newRow = pd.DataFrame(
                {
                    'security': str(security),
                    'action': action,
                    'quantity': quantity,
                    'avgFillPrice': avgFillPrice,
                    'virtualStrategyBalance': virtualStrategyBalance
                },
                index=[self.get_datetime()])
            self.PORTFOLIO.performanceTracking[execution.orderRef]=\
            self.PORTFOLIO.performanceTracking[execution.orderRef].append(newRow)
    def placeOrderWrapper(self, contract, order, ibpyRequest):
        self._log.debug(
            __name__ + '::placeOrderWrapper: contract=%s order=%s' %
            (print_IBCpp_contract(contract), print_IBCpp_order(order)))

        if isinstance(order.orderId, int):
            int_orderId = order.orderId
        else:
            int_orderId = self.use_next_id()
            order.orderId = int_orderId

        # Set for ending flat.
        # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId
        # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId)
        ibpyRequest.param['int_orderId'] = int_orderId

        ibpyOrderId = self._idConverter.fromIBtoBroker(int_orderId)

        # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId
        self._singleTrader.set_from_send_req_to_server(self.name,
                                                       order.account,
                                                       ibpyOrderId)

        self.orderToBeProcessed[int_orderId] = (contract, order)
        self.simulateOpenOrder(
            int_orderId, contract, order, IBCpp.OrderState(),
            from_contract_to_security(contract).full_print())  # IBCpp function
        self.simulateOrderStatus(int_orderId, 'Submitted', 0,
                                 order.totalQuantity, 0.0, 0, 0, 0, 0,
                                 '')  # IBCpp function
        self.simulate_process_order(self.get_datetime())
    def reqHistoricalDataWrapper(self, reqId, contract, endTime, goBack,
                                 barSize, whatToShow, useRTH, formatDate):
        self._log.debug(
            __name__ +
            '::reqHistoricalDataWrapper: reqId=%s endTime=%s goBack=%s' %
            (reqId, endTime, goBack))
        if endTime == '':
            # endTime='' is acceptable for clientIB, but not for brokerClient_Local
            # When endTime is processed, it will be converted to string from datetime.
            # However, the strptime function has difficulty with some timezones, for example, 'EDT'
            # The safe way is to convert to UTC first.
            endTime = self._timeGenerator.get_current_time().astimezone(
                pytz.timezone('UTC'))
            endTime = dt.datetime.strftime(
                endTime, "%Y%m%d %H:%M:%S %Z")  # datetime -> string

        security = from_contract_to_security(contract)
        try:
            hist = self._dataProvider.provide_historical_data_from_local_variable_hist(
                security, endTime, goBack, barSize, whatToShow, useRTH,
                formatDate)
        except NotEnoughHist:
            self._log.info(
                'Cannot find ingested hist for security=%s endTime=%s goBack=%s barSize=%s'
                % (security, endTime, goBack, barSize))
            self._log.info(
                'IBridgePy has to request historical data from broker %s to continue backtesting but it will be slow. Recommend to add HistIngestPlan in TEST_ME.py'
                % (self.getDataProvider().name, ))
            hist = self._dataProvider.provide_hist_from_a_true_dataProvider(
                security, endTime, goBack, barSize, whatToShow, useRTH,
                formatDate)

        # completion signals here
        self._sendHistoricalData(hist, reqId, formatDate)
Пример #6
0
    def placeOrderWrapper(self, contract, order, ibpyRequest):
        self._validate_contract(contract, 'placeOrderWrapper')
        self._log.info('Place Order to %s security=%s order=%s' % (self.name, print_IBCpp_contract(contract), print_IBCpp_order(order)))

        tdOrder = OrderConverter().fromIBtoTD(contract, order)
        try:
            ibpyOrderId = self._tdClient.place_orders(order.account, tdOrder)
        except RuntimeError as e:
            if 'buying power' in str(e):
                raise NotEnoughFund()
            else:
                raise RuntimeError(e)
        if ibpyOrderId is None:
            raise RuntimeError('Place order to TD failed but there is not RuntimeError.')
        self._log.info('Order was placed to %s successfully. ibpyOrderId=%s' % (self.name, ibpyOrderId))

        # Register int_orderId in _idConverter so that brokerClient::CallBack::orderStatus knows how to handle int_orderId
        int_orderId = self._idConverter.fromBrokerToIB(ibpyOrderId)
        self._idConverter.setRelationship(int_orderId, ibpyOrderId)

        # Set for ending flat.
        # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId
        # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId)
        ibpyRequest.param['int_orderId'] = int_orderId

        # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId
        self._singleTrader.set_from_send_req_to_server(self.name, order.account, ibpyOrderId)

        # IBCpp function
        order.orderId = int_orderId
        self.simulateOpenOrder(int_orderId, contract, order, IBCpp.OrderState(),
                               from_contract_to_security(contract).full_print())  # IBCpp function
        # IBCpp function, this is the ending flag for PlaceOrder
        self.simulateOrderStatus(int_orderId, 'Submitted', 0, order.totalQuantity, 0.0, 0, 0, 0, 0, '')
Пример #7
0
    def reqMktDataWrapper(self, reqId, contract, genericTickList, snapshot):
        self._validate_contract(contract, 'reqMktDataWrapper')
        ans = None
        count = 1
        while count <= 3:
            tp = self._tdClient.quote(str(contract.symbol))
            ans = None
            symb = contract.symbol.upper()
            if symb in tp:
                ans = tp[symb]
                break
            else:
                self._log.error(__name__ + '::reqMktDataWrapper: requested %s to TD and error=%s. '
                                           'Hint: Sometimes, TD does not response to reqMktData for unknown reasons. '
                                           'IBridgePy will retry 3 times. attempt=%s' % (contract.symbol, tp, count))
            count += 1
        if count == 4:
            raise RuntimeError('EXIT, TD does not response to reqMktData for %s. IBridgePy retried and gave up.' % (contract.symbol,))

        str_security = from_contract_to_security(contract).full_print()
        self.simulateTickPrice(reqId, IBCpp.TickType.ASK, float(ans['askPrice']), True, str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.BID, float(ans['bidPrice']), True, str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.LAST, float(ans['lastPrice']), True, str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.OPEN, float(ans['openPrice']), True, str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.CLOSE, float(ans['closePrice']), True, str_security)
        self.simulateTickSize(reqId, IBCpp.TickType.ASK_SIZE, int(ans['askSize']), str_security)
        self.simulateTickSize(reqId, IBCpp.TickType.BID_SIZE, int(ans['bidSize']), str_security)
 def _get_all_positions(self, accountCode):
     allPositions = self._singleTrader.get_all_positions(self.brokerName, accountCode)
     ans = {}
     for str_security in allPositions:
         contract = allPositions[str_security].contract
         security = from_contract_to_security(contract)
         # adj_security = self.add_exchange_primaryExchange_to_security(security)
         # ans[adj_security] = allPositions[str_security]
         ans[security] = allPositions[str_security]
     return ans
Пример #9
0
    def placeOrderWrapper(self, contract, order, ibpyRequest):
        instrument = self._robinhoodClient.instruments(contract.symbol)[0]
        action = OrderActionConverter().fromIBtoRB(order.action)
        tif = OrderTifConverter().fromIBtoRB(order.tif)
        quantity = int(order.totalQuantity)
        ans = None
        if order.orderType == OrderType.MKT:
            ans = self._robinhoodClient.place_market_order(
                action, instrument, quantity, tif)
        elif order.orderType == OrderType.LMT:
            ans = self._robinhoodClient.place_limit_order(
                action,
                instrument=instrument,
                limit_price=order.lmtPrice,
                quantity=quantity,
                time_in_force=tif)
        elif order.orderType == OrderType.STP:
            ans = self._robinhoodClient.place_stop_order(
                action,
                instrument=instrument,
                stop_price=order.auxPrice,
                quantity=quantity,
                time_in_force=tif)
        else:
            self._log.error(
                __name__ +
                '::placeOrderWrapper: EXIT, cannot handle orderType=%s' %
                (order.orderType, ))
            exit()
        ibpyOrderId = str(ans['id'])
        self._log.info('Order was placed to %s successfully. ibpyOrderId=%s' %
                       (self.name, ibpyOrderId))

        # Register int_orderId in _idConverter so that brokerClient::CallBack::orderStatus knows how to handle int_orderId
        int_orderId = self._idConverter.fromBrokerToIB(ibpyOrderId)
        self._idConverter.setRelationship(int_orderId, ibpyOrderId)

        # Set for ending flat.
        # Otherwise, the following line in broker_client_factory::CallBacks::orderStatus will not be able to find a reqId
        # reqId = self.activeRequests.find_reqId_by_int_orderId(int_orderId)
        ibpyRequest.param['int_orderId'] = int_orderId

        # Register ibpyOrderId in SingleTrader so that it can search accountCode by incoming int_orderId
        self._singleTrader.set_from_send_req_to_server(self.name,
                                                       order.account,
                                                       ibpyOrderId)

        # IBCpp function
        order.orderId = int_orderId
        self.simulateOpenOrder(
            int_orderId, contract, order, IBCpp.OrderState(),
            from_contract_to_security(contract).full_print())  # IBCpp function
        # IBCpp function, this is the ending flag for PlaceOrder
        self.simulateOrderStatus(int_orderId, 'Submitted', 0,
                                 order.totalQuantity, 0.0, 0, 0, 0, 0, '')
Пример #10
0
 def count_open_orders(self, security='All', accountCode='default'):
     self.log.debug(__name__ + '::count_open_orders')
     accountCode = self.validateAccountCode(accountCode)
     count = 0
     for orderId in self.PORTFOLIO.orderStatusBook:
         if self.PORTFOLIO.orderStatusBook[orderId].status not in [
                 'Filled', 'Cancelled', 'Inactive'
         ]:
             if security == 'All':
                 count += self.PORTFOLIO.orderStatusBook[orderId].amount
             else:
                 tp = self.PORTFOLIO.orderStatusBook[orderId].contract
                 tp = from_contract_to_security(tp)
                 if same_security(tp, security):
                     count += self.PORTFOLIO.orderStatusBook[orderId].amount
     return count
Пример #11
0
    def reqMktDataWrapper(self, reqId, contract, genericTickList, snapshot):
        ans = self._robinhoodClient.get_quote(str(contract.symbol))
        str_security = from_contract_to_security(contract).full_print()

        self.simulateTickPrice(reqId, IBCpp.TickType.ASK,
                               float(ans['ask_price']), True, str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.BID,
                               float(ans['bid_price']), True, str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.LAST,
                               float(ans['last_trade_price']), True,
                               str_security)
        self.simulateTickPrice(reqId, IBCpp.TickType.CLOSE,
                               float(ans['previous_close']), True,
                               str_security)
        self.simulateTickSize(reqId, IBCpp.TickType.ASK_SIZE,
                              int(ans['ask_size']), str_security)
        self.simulateTickSize(reqId, IBCpp.TickType.BID_SIZE,
                              int(ans['bid_size']), str_security)
Пример #12
0
 def scannerData(self, reqId, rank, contractDetails, distance, benchmark,
                 projection, legsStr):
     self._log.debug(
         __name__ +
         '::scannerData: reqId=%s rank=%s contractDetails.summary%s distance=%s benchmark=%s project=%s legsStr=%s'
         % (reqId, rank, print_IBCpp_contract(contractDetails.summary),
            distance, benchmark, projection, legsStr))
     aRequest = self._activeRequests.get_by_reqId_otherwise_exit(reqId)
     security = from_contract_to_security(contractDetails.summary)
     newRow = pd.DataFrame(
         {
             'rank': rank,
             # 'contractDetails': contractDetails,
             'security': security,
             # 'distance': distance,
             # 'benchmark': benchmark,
             # 'projection': projection,
             # 'legsStr': legsStr
         },
         index=[len(aRequest.returnedResult)])
     aRequest.returnedResult = aRequest.returnedResult.append(newRow)
Пример #13
0
 def contractDetails(self, reqId, contractDetails):
     """
     IB callback function to receive str_security info
     """
     self._log.notset(__name__ +
                      '::contractDetails: reqId=%s contractDetails=%s' %
                      (reqId, print_IBCpp_contractDetails(contractDetails)))
     aRequest = self._activeRequests.get_by_reqId_otherwise_exit(reqId)
     newRow = pd.DataFrame(
         {
             'right': contractDetails.summary.right,
             'strike': float(contractDetails.summary.strike),
             'expiry': contractDetails.summary.expiry,
             'contractName': print_IBCpp_contract(contractDetails.summary),
             'security': from_contract_to_security(contractDetails.summary),
             'contract': contractDetails.summary,
             'multiplier': contractDetails.summary.multiplier,
             'contractDetails': contractDetails
         },
         index=[len(aRequest.returnedResult)])
     aRequest.returnedResult = aRequest.returnedResult.append(newRow)
Пример #14
0
    def position(self, accountCode, contract, position, price):
        """
        call back function of IB C++ API which updates the position of a contract
        of a account
        """
        self.log.debug(__name__ + '::position: ' + accountCode + ' ' +
                       self._print_contract(contract) + ',' + str(position) +
                       ', ' + str(price))
        self.validateAccountCode(accountCode)
        security = from_contract_to_security(contract)
        adj_security = search_security_in_Qdata(self.qData, security,
                                                self.logLevel)

        if (not self.PORTFOLIO.positions) or (adj_security
                                              not in self.PORTFOLIO.positions):
            # a_security is not in positions,  add it in it
            self.PORTFOLIO.positions[adj_security] = PositionClass()

        if position:
            self.PORTFOLIO.positions[adj_security].amount = position
            self.PORTFOLIO.positions[adj_security].cost_basis = price
            self.PORTFOLIO.positions[adj_security].accountCode = accountCode
        else:
            del self.PORTFOLIO.positions[adj_security]
Пример #15
0
def stripe_exchange_primaryExchange_from_contract(contract):
    security = from_contract_to_security(contract)
    return stripe_exchange_primaryExchange_from_security(security)
    def simulate_process_order(self, timeNow):  # to simulate placing order
        self._log.debug(__name__ + '::simulate_process_order: timeNow=%s' %
                        (timeNow, ))
        if len(self.orderToBeProcessed) == 0:
            self._log.debug(__name__ + '::processOrder: No order to process')
            return
        for int_orderId in list(self.orderToBeProcessed.keys())[:]:
            contract, order = self.orderToBeProcessed[int_orderId]
            security = from_contract_to_security(contract)

            ask_price, bid_price, high_price, low_price = \
                self._dataProvider.provide_real_time_price_from_local_variable_hist(security, timeNow, [IBCpp.TickType.ASK, IBCpp.TickType.BID, IBCpp.TickType.HIGH, IBCpp.TickType.LOW])
            flag = False  # if a order meets the processing conditions
            # based on the current prices, decide which pending orders should be processed/simulated this round.
            ex_price = 0.0  # avoid PEP8 warning
            if order.orderType == 'MKT':  # for MKT order, just Fill it
                if order.action == 'BUY':
                    ex_price = ask_price
                else:
                    ex_price = bid_price
                flag = True
            elif order.orderType == 'LMT':
                # always assume simulation sequence: ask_price -> low_price -> high_price -> close_price
                if order.action == 'BUY':
                    if order.lmtPrice >= ask_price:
                        flag = True
                        ex_price = ask_price
                    elif low_price <= order.lmtPrice < ask_price:
                        flag = True
                        ex_price = order.lmtPrice
                    else:
                        flag = False
                else:  # SELL
                    if order.lmtPrice <= ask_price:
                        flag = True
                        ex_price = ask_price
                    elif ask_price < order.lmtPrice <= high_price:
                        flag = True
                        ex_price = order.lmtPrice
                    else:
                        flag = False

            elif order.orderType == 'STP':
                ex_price = order.auxPrice
                if order.action == 'BUY':
                    if order.auxPrice <= ask_price:
                        flag = True
                        ex_price = ask_price
                    elif ask_price < order.auxPrice <= high_price:
                        flag = True
                        ex_price = order.auxPrice
                    else:
                        flag = False
                else:
                    if order.auxPrice >= bid_price:
                        flag = True
                        ex_price = bid_price
                    elif low_price <= order.auxPrice < bid_price:
                        flag = True
                        ex_price = order.auxPrice
                    else:
                        flag = False
            else:
                self._log.error(
                    __name__ +
                    '::simulate_process_order: cannot handle order.orderType = %s'
                    % (order.orderType, ))
                exit()

            # this order should be processed/simulated right now
            if flag and ex_price > 0.001:
                # IBCpp call-back function
                self.simulateOrderStatus(int_orderId, 'Filled',
                                         order.totalQuantity, 0, ex_price, 0,
                                         0, 0, 0, '')
                del self.orderToBeProcessed[int_orderId]

                # after an order is executed, need to simulate execDetails (call-back function)
                execution = IBCpp.Execution()
                execution.acctNumber = order.account
                execution.orderId = int_orderId
                if order.action == 'BUY':
                    execution.side = 'BOT'
                else:
                    execution.side = 'SLD'
                execution.shares = int(order.totalQuantity)
                execution.price = ex_price
                execution.orderRef = order.orderRef
                self.simulateExecDetails(
                    -1, contract, execution,
                    from_contract_to_security(contract).full_print())

                # IBCpp::simulatePosition needs more calculation because it needs to consider the current
                # positions.
                oldPosition = self._singleTrader.get_position(
                    self.name, self._accountCode, security)
                # print(__name__ + '::simulate_process_order:: oldPosition=%s' % (position,))
                oldPrice = oldPosition.price
                hold = oldPosition.amount
                amount = None
                price = None
                if order.action == 'BUY':
                    if hold + order.totalQuantity != 0:
                        price = (oldPrice * hold +
                                 ex_price * order.totalQuantity) / (
                                     hold + order.totalQuantity)
                    else:
                        price = 0.0
                    amount = hold + order.totalQuantity

                elif order.action == 'SELL':
                    if hold == order.totalQuantity:
                        price = 0.0
                    else:
                        price = (oldPrice * hold -
                                 ex_price * order.totalQuantity) / (
                                     hold - order.totalQuantity)
                    amount = hold - order.totalQuantity
                self.simulatePosition(
                    order.account, contract, amount, price,
                    from_contract_to_security(contract).full_print())

                self._transactionLog.info(
                    '%s %s %s %s %s %s' %
                    (self.get_datetime(), execution.orderId,
                     from_contract_to_security(contract).full_print(),
                     execution.side, execution.shares, execution.price))