Ejemplo n.º 1
0
def new_order(sender_comp_id, target_comp_id, symbol, quantity, price, side,
              order_type):
    if side.lower() == "buy":
        side = fix.Side_BUY
    else:
        side = fix.Side_SELL

    message = Message()
    header = message.getHeader()
    header.setField(fix.BeginString("FIX.4.2"))
    header.setField(fix.SenderCompID(sender_comp_id))
    header.setField(fix.TargetCompID(target_comp_id))
    header.setField(fix.MsgType("D"))
    ord_id = get_order_id(sender_comp_id, symbol)
    message.setField(fix.ClOrdID(ord_id))
    message.setField(fix.Symbol(symbol))
    message.setField(fix.Side(side))
    message.setField(fix.Price(float(price)))
    if order_type.lower() == "market":
        message.setField(fix.OrdType(fix.OrdType_MARKET))
    else:
        message.setField(fix.OrdType(fix.OrdType_LIMIT))
    message.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION))
    message.setField(fix.TransactTime())
    message.setField(fix.OrderQty(float(quantity)))
    message.setField(fix.Text(f"{side} {symbol} {quantity}@{price}"))

    return message
Ejemplo n.º 2
0
    def process_security_list(self, security_list):

        no_related_sym = quickfix.NoRelatedSym()
        symbol_field = quickfix.Symbol()

        security_list.getField(no_related_sym)

        number_of_instruments = int(no_related_sym.getValue())

        for i in range(number_of_instruments):
            group = quickfix.Group(no_related_sym.getField(),
                                   symbol_field.getField())
            security_list.getGroup(i + 1, group)
            group.getField(symbol_field)

            security_exchange = quickfix.SecurityExchange()
            group.getField(security_exchange)

            exchange = security_exchange.getValue()
            symbol = symbol_field.getValue()

            instrument = self.reference_data.ins_instrument(exchange, symbol)
            print("New Instrument : " + str(instrument))

            text_field = quickfix.Text()
            if group.isSetField(text_field):
                group.getField(text_field)
                text = str(text_field.getValue())
                ref_data = json.loads(text)

                self.reference_data.ins_reference_data(instrument, ref_data)
Ejemplo n.º 3
0
    def fromApp(self, message, sessionID):

        if self.verbose:
            print(f'[fromApp] {sessionID} | {read_FIX_message(message)}')

        log(self.logger,
            f'[fromApp] {sessionID} | {read_FIX_message(message)}')

        # Get incoming message Type
        msgType = fix.MsgType()
        message.getHeader().getField(msgType)
        msgType = msgType.getValue()

        # Get timestamp (tag 52)
        sending_time = extract_message_field_value(fix.SendingTime(), message,
                                                   'datetime')
        # print('sending_time:', sending_time)

        ########## Quote messages ##########

        if msgType == fix.MsgType_MassQuote:

            self.parse_MassQuote(message, sending_time)

        elif msgType == fix.MsgType_MarketDataSnapshotFullRefresh:

            self.parse_MarketDataSnapshotFullRefresh(message, sending_time)

        # 3) Process MarketDataSnapshot_IncrementalRefresh message
        elif msgType == fix.MsgType_MarketDataIncrementalRefresh:

            print(self._server_str + ' {MD} INCREMENTAL REFRESH!')

        ########## Trade messages ##########

        elif msgType == fix.MsgType_ExecutionReport:

            self.parse_ExecutionReport(message, sending_time)

        elif msgType == fix.MsgType_OrderCancelReject:

            # An OrderCancelReject will be sent as an answer to an  OrderCancelRequest, which cannot be executed.
            # Not much to do here as our order dict would stay the same.
            # If it was canceled successfully, we should get an execution report.

            ClOrdID = extract_message_field_value(fix.ClOrdID(), message,
                                                  'int')

            print(
                f'[fromApp] Order Cancel Request Rejected for order: {ClOrdID}'
            )

        elif msgType == fix.MsgType_MarketDataRequestReject:

            text = extract_message_field_value(fix.Text(), message, 'str')
            print(f'[fromApp] Market Data Request Reject with message: {text}')

        elif self.verbose:
            print(f'[fromApp] {sessionID} | {read_FIX_message(message)}')
            print('unknown message type: ', msgType)
Ejemplo n.º 4
0
    def cancel(self, message, sessionID):
        symbol = fix.Symbol()
        side = fix.Side()
        orderQty = fix.OrderQty()
        clOrdID = fix.ClOrdID()
        org = fix.OrigClOrdID()
        message.getField(symbol)
        message.getField(side)
        message.getField(orderQty)
        message.getField(clOrdID)
        message.getField(org)
        log.info("cancel:\nsymbol:{},side:{},orderQty:{},clOrdID:{},org:{} -----"\
            .format(symbol, side, orderQty, clOrdID, org))

        cancel = fix44.OrderCancelReject()
        cancel.setField(clOrdID)
        cancel.setField(fix.OrderID(self.genOrderID()))
        cancel.setField(fix.OrdStatus(fix.OrdStatus_NEW))
        cancel.setField(fix.OrigClOrdID(org.getValue()))
        cancel.setField(fix.Text('order completed'))
        cancel.setField(fix.TransactTime())
        cancel.setField(fix.CxlRejReason(fix.CxlRejReason_BROKER))
        cancel.setField(
            fix.CxlRejResponseTo(fix.CxlRejResponseTo_ORDER_CANCEL_REQUEST))

        fix.Session.sendToTarget(cancel, sessionID)
Ejemplo n.º 5
0
    def toAdmin(self, m: fix.Message, session_id: fix.SessionID):
        if self.username and self.password:
            if m.getHeader().getField(
                    fix.MsgType().getTag()) == fix.MsgType_Logon:
                m.setField(fix.Username(self.username))
                m.setField(fix.Password(self.password))

        if self.autofix_sequence_numbers:
            text_tag = fix.Text().getTag()
            is_seqnum_too_low = (
                m.getHeader().getField(fix.MsgType().getTag())
                == fix.MsgType_Logout and m.isSetField(text_tag)
                and m.getField(text_tag).startswith("MsgSeqNum too low"))

            if is_seqnum_too_low:
                needed_seqnum = int(
                    re.match(
                        "MsgSeqNum too low, expecting (\d+) but received (\d+)",
                        m.getField(text_tag))[2])

                self.log_message("toAdmin", m, session_id, levelize=False)
                logger.warning(
                    f"Resetting MsgSeqNum to {needed_seqnum} as needed. Wait for reconnect..."
                )

                self.session.setNextTargetMsgSeqNum(needed_seqnum)
                return

        self.log_message("toAdmin", m, session_id)
        self.outgoing_messages.put(fix.Message(m))
Ejemplo n.º 6
0
    def put_new_order(self, instrument, side, price, size):
        """Request sample new order single"""
        message = quickfix44.NewOrderSingle()
        header = message.getHeader()

        print("Executing : " + str(instrument) + ":" + str(side) + ":" +
              str(price) + ":" + str(size))

        message.setField(quickfix.ClOrdID(self.genExecID()))
        message.setField(quickfix.Side(side))
        message.setField(quickfix.Symbol(instrument.symbol))
        message.setField(quickfix.SecurityExchange(instrument.exchange))
        message.setField(quickfix.OrderQty(size))
        message.setField(quickfix.Price(int(price)))
        message.setField(quickfix.OrdType(quickfix.OrdType_LIMIT))
        message.setField(quickfix.TimeInForce('0'))
        message.setField(quickfix.Text("NewOrderSingle"))
        trstime = quickfix.TransactTime()
        trstime.setString(
            datetime.utcnow().strftime("%Y%m%d-%H:%M:%S.%f")[:-3])
        message.setField(trstime)

        msg = message.toString().replace(__SOH__, "|")

        print("New Order Single: " + msg)

        quickfix.Session.sendToTarget(message, self.sessionID)
Ejemplo n.º 7
0
    def new_order(self):
        print("Creating the following order: ")
        trade = fix.Message()
        trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX42))  #
        trade.getHeader().setField(fix.MsgType(
            fix.MsgType_NewOrderSingle))  #35=D
        trade.setField(fix.ClOrdID(self.genOrderID()))  #11=Unique order id

        trade.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION)
                       )  #21=3 (Manual order, best executiona)
        trade.setField(fix.Symbol("ethbtc"))  #55=ethbtc
        trade.setField(fix.Side(fix.Side_BUY))  #54=1 Buy
        trade.setField(fix.OrdType(fix.OrdType_LIMIT))  #40=2 Limit order
        trade.setField(fix.OrderQty(9))  #38=9
        trade.setField(fix.Price(1.5))  #44=1.5
        trade.setField(
            fix.StringField(
                60, (datetime.utcnow().strftime("%Y%m%d-%H:%M:%S.%f"))[:-3])
        )  #60 TransactTime, not supported in python, so use tag number
        trade.setField(fix.Text("New Order"))  #58 text
        print(trade.toString())
        try:
            fix.Session.sendToTarget(trade, self.sessionID)
        except (fix.ConfigError, fix.RuntimeError) as e:
            print(e)
Ejemplo n.º 8
0
    def getExecutionReportForNewOrder(self, message):

        beginString = fix.BeginString()
        message.getHeader().getField(beginString)

        symbol = fix.Symbol()
        side = fix.Side()
        ordType = fix.OrdType()
        orderQty = fix.OrderQty()
        price = fix.Price()
        clOrdID = fix.ClOrdID()

        message.getField(ordType)
        if ordType.getValue() != fix.OrdType_LIMIT:
            raise fix.IncorrectTagValue(ordType.getField())

        message.getField(symbol)
        message.getField(side)
        message.getField(orderQty)
        message.getField(price)
        message.getField(clOrdID)

        executionReport = fix.Message()
        executionReport.getHeader().setField(beginString)
        executionReport.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))

        executionReport.setField(fix.OrderID(self.genOrderID()))
        executionReport.setField(fix.ExecID(self.genExecID()))
        executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED))
        executionReport.setField(symbol)
        executionReport.setField(side)
        executionReport.setField(fix.CumQty(orderQty.getValue()))
        executionReport.setField(fix.AvgPx(price.getValue()))
        executionReport.setField(fix.LastShares(orderQty.getValue()))
        executionReport.setField(fix.LastPx(price.getValue()))
        executionReport.setField(clOrdID)
        executionReport.setField(orderQty)
        executionReport.setField(fix.Text("New order accepted!"))

        # Since FIX 4.3, ExecTransType is killed and the values are moved to ExecType
        if beginString.getValue(
        ) == fix.BeginString_FIX40 or beginString.getValue(
        ) == fix.BeginString_FIX41 or beginString.getValue(
        ) == fix.BeginString_FIX42:
            executionReport.setField(fix.ExecTransType(fix.ExecTransType_NEW))

        # ExecType and LeavesQty fields only existsince FIX 4.1
        if beginString.getValue() >= fix.BeginString_FIX41:
            if beginString.getValue() <= fix.BeginString_FIX42:
                executionReport.setField(fix.ExecType(
                    fix.ExecType_FILL))  #150=2 FILL  (or 1 PARTIAL_FILL)
            else:
                # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field
                executionReport.setField(fix.ExecType(
                    fix.ExecType_TRADE))  #150=F TRADE
            executionReport.setField(fix.LeavesQty(0))

        return executionReport
 def sendMarketDataReject(self, requestID, reason, sessionID):
     self.logger.error("FixServer:SEND REJECT %s", reason)
     reject = self.fixVersion.MarketDataRequestReject()
     reject.setField(requestID)
     text = quickfix.Text(reason)
     reject.setField(quickfix.MDReqRejReason("0"))
     reject.setField(text)
     self.sendToTarget(reject, sessionID)
Ejemplo n.º 10
0
    def fromApp(self, message, sessionID):
        print("Received the following message: %s" % message.toString())
        beginString = fix.BeginString()
        msgType = fix.MsgType()
        msgSeqNum = fix.MsgSeqNum()
        message.getHeader().getField(beginString)
        message.getHeader().getField(msgType)
        message.getHeader().getField(msgSeqNum)

        print("Message type = %s" % msgType.getString())

        if msgType.getString() == fix.MsgType_NewOrderSingle:
            print("New Order received")
            if SKIP_AUTHENTICATION:
                executionReport = self.getExecutionReportForNewOrder(message)
            else:
                executionReport = self.getExecutionReportForNewOrder2(message)
            print("Execution report to send: %s" % executionReport.toString())
            self.sendReport(executionReport, sessionID)
        elif msgType.getString() == fix.MsgType_OrderCancelRequest:
            print("Cancel Order received")
            if SKIP_AUTHENTICATION:
                executionReport = self.getExecutionReportForCancelOrder(
                    message)
                # use below 3 lines and comment out above 3 if you want to send order cancel reject message
                # orderCancelReject = self.getOrderCancelReject(message)
                # print("Order cancel reject to send: %s" % orderCancelReject.toString())
                # self.sendReport(orderCancelReject, sessionID)
            else:
                executionReport = self.getExecutionReportForCancelOrder2(
                    message)
            print("Execution report to send: %s" % executionReport.toString())
            self.sendReport(executionReport, sessionID)

        elif msgType.getString() == fix.MsgType_OrderStatusRequest:
            print("Order status request received")
            if SKIP_AUTHENTICATION:
                executionReport = self.getExecutionReportForStatusRequest(
                    message)
            else:
                executionReport = self.getExecutionReportForStatusRequest2(
                    message)
            print("Execution report to send: %s" % executionReport.toString())
            self.sendReport(executionReport, sessionID)
        else:
            print("Unsupported MsgType")
            reject = fix.Message()
            reject.getHeader().setField(beginString)
            reject.getHeader().setField(fix.MsgType(fix.MsgType_Reject))
            reject.setField(fix.RefMsgType(msgType.getString()))
            reject.setField(fix.RefSeqNum(
                msgSeqNum.getValue()))  #45 = RefSeqNum
            reject.setField(
                fix.SessionRejectReason(fix.SessionRejectReason_INVALID_MSGTYPE
                                        ))  #373 = 11 INVALID_MSGTYPE
            reject.setField(
                fix.Text("iSTOX FIX API does not support this message type"))
            self.sendReport(reject, sessionID)
Ejemplo n.º 11
0
    def _create_execution_report(
        self,
        symbol,
        side,
        client_order_id,
        price=None,
        quantity=None,
        order_status=fix.OrdStatus_NEW,
        exec_trans_type=fix.ExecTransType_NEW,
        exec_type=fix.ExecType_NEW,
        text=None,
        reject_reason=None,
        orig_client_order_id=None,
    ):
        # defaults
        execution_report = Message()
        execution_report.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))

        execution_report.setField(
            fix.OrderID(self.generate_order_id(symbol.getValue())))
        execution_report.setField(
            fix.ExecID(self.generate_execution_id(symbol.getValue())))
        execution_report.setField(fix.OrdStatus(order_status))
        execution_report.setField(symbol)
        execution_report.setField(side)
        execution_report.setField(client_order_id)
        execution_report.setField(fix.ExecTransType(exec_trans_type))
        execution_report.setField(fix.ExecType(exec_type))
        execution_report.setField(fix.LeavesQty(0))

        if price:
            execution_report.setField(fix.AvgPx(price.getValue()))
            execution_report.setField(fix.LastPx(price.getValue()))

        if quantity:
            execution_report.setField(fix.CumQty(quantity.getValue()))
            execution_report.setField(fix.LastShares(quantity.getValue()))
            execution_report.setField(quantity)

        if orig_client_order_id:
            execution_report.setField(
                fix.OrigClOrdID(orig_client_order_id.getValue()))

        if text:
            execution_report.setField(fix.Text(text))

        if exec_type == fix.ExecType_REJECTED:
            execution_report.setField(fix.OrdRejReason(reject_reason))

        self.logger.debug(
            f"Created execution report {execution_report.__str__()}")

        return execution_report
Ejemplo n.º 12
0
    def sendOrderCancelRequest(self):
        message = fix.Message()
        header = message.getHeader()

        header.setField(fix.BeginString("FIX.4.2"))
        header.setField(fix.SenderCompID("CLIENT1"))
        header.setField(fix.TargetCompID("EXECUTOR"))
        header.setField(fix.MsgType("D"))
        message.setField(fix.OrigClOrdID("123"))
        message.setField(fix.ClOrdID("321"))
        message.setField(fix.Symbol("LNUX"))
        message.setField(fix.Side(fix.Side_BUY))
        message.setField(fix.Text("Cancel My Order!"))
        fix.Session.sendToTarget(message, self.sessionID)
def sendHelloWorldMessage(sessionID):
    message = fix.Message()
    header = message.getHeader()

    header.setField(fix.BeginString("FIX.4.1"))
    header.setField(fix.SenderCompID("HELLOWORLD_TRADER"))
    header.setField(fix.TargetCompID("HELLOWORLD_EXCHANGE"))
    header.setField(fix.MsgType(fix.MsgType_NewOrderSingle))
    message.setField(fix.ClOrdID('1'))
    message.setField(fix.HandlInst('1'))
    message.setField(fix.Symbol('BMLL'))
    message.setField(fix.Side(fix.Side_BUY))
    message.setField(fix.OrdType(fix.OrdType_MARKET))
    message.setField(fix.Text("Hello Exchange! How are you?"))

    fix.Session.sendToTarget(message, sessionID)
Ejemplo n.º 14
0
    def getExecutionReportForStatusRequest(self, message):

        beginString = fix.BeginString()
        message.getHeader().getField(beginString)

        clOrdID = fix.ClOrdID()
        message.getField(clOrdID)

        executionReport = fix.Message()
        executionReport.getHeader().setField(beginString)
        executionReport.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))

        executionReport.setField(fix.Symbol("ABCD"))
        executionReport.setField(fix.Side(fix.Side_BUY))  #43=1 Buy
        executionReport.setField(fix.OrderID(self.genOrderID()))
        executionReport.setField(fix.ExecID(self.genExecID()))
        executionReport.setField(fix.OrdType(
            fix.OrdType_LIMIT))  #40=2 Limit order
        executionReport.setField(fix.OrderQty(100))  #38=100
        executionReport.setField(fix.Price(10))  #44=10
        executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED))
        executionReport.setField(fix.AvgPx(10))  #6=10
        executionReport.setField(fix.CumQty(100))  #14=100
        executionReport.setField(clOrdID)
        executionReport.setField(fix.Text("Order status retrieved!"))

        # Since FIX 4.3, ExecTransType values are moved to ExecType
        if beginString.getValue(
        ) == fix.BeginString_FIX40 or beginString.getValue(
        ) == fix.BeginString_FIX41 or beginString.getValue(
        ) == fix.BeginString_FIX42:
            executionReport.setField(
                fix.ExecTransType(fix.ExecTransType_STATUS))

        # ExecType and LeavesQty fields only existsince FIX 4.1
        if beginString.getValue() >= fix.BeginString_FIX41:
            if beginString.getValue() <= fix.BeginString_FIX42:
                executionReport.setField(fix.ExecType(
                    fix.ExecType_FILL))  #150=2 FILL  (or 1 PARTIAL_FILL)
            else:
                # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field
                executionReport.setField(fix.ExecType(
                    fix.ExecType_TRADE))  #150=F TRADE
            executionReport.setField(fix.LeavesQty(0))

        return executionReport
Ejemplo n.º 15
0
    def getExecutionReportForCancelOrder(self, message):

        beginString = fix.BeginString()
        message.getHeader().getField(beginString)

        symbol = fix.Symbol()
        side = fix.Side()
        clOrdID = fix.ClOrdID()

        message.getField(symbol)
        message.getField(side)
        message.getField(clOrdID)

        executionReport = fix.Message()
        executionReport.getHeader().setField(beginString)
        executionReport.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))

        executionReport.setField(fix.OrderID(self.genOrderID()))
        executionReport.setField(fix.ExecID(self.genExecID()))
        executionReport.setField(fix.OrdType(
            fix.OrdType_LIMIT))  #40=2 Limit order
        executionReport.setField(fix.OrderQty(100))  #38=100
        executionReport.setField(fix.Price(10))  #44=10
        executionReport.setField(fix.OrdStatus(fix.OrdStatus_FILLED))
        executionReport.setField(symbol)
        executionReport.setField(side)
        executionReport.setField(fix.AvgPx(10))  #6=10
        executionReport.setField(fix.CumQty(100))  #14=100
        executionReport.setField(clOrdID)
        executionReport.setField(fix.Text("Order cancelled!"))

        # Since FIX 4.3, ExecTransType values are moved to ExecType
        if beginString.getValue(
        ) == fix.BeginString_FIX40 or beginString.getValue(
        ) == fix.BeginString_FIX41 or beginString.getValue(
        ) == fix.BeginString_FIX42:
            executionReport.setField(
                fix.ExecTransType(fix.ExecTransType_CANCEL))

        # ExecType and LeavesQty fields only existsince FIX 4.1
        if beginString.getValue() >= fix.BeginString_FIX41:
            executionReport.setField(fix.ExecType(
                fix.ExecType_CANCELED))  #150=4 CANCELED
            executionReport.setField(fix.LeavesQty(0))  #151=0

        return executionReport
Ejemplo n.º 16
0
def delete_order(sender_comp_id, target_comp_id, orig_client_order_id):
    symbol = ORDERS[orig_client_order_id][0].getValue()
    side = ORDERS[orig_client_order_id][3].getValue()

    message = fix44.OrderCancelRequest()
    header = message.getHeader()
    header.setField(fix.SenderCompID(sender_comp_id))
    header.setField(fix.TargetCompID(target_comp_id))
    ord_id = get_order_id(sender_comp_id, symbol)
    message.setField(fix.OrigClOrdID(orig_client_order_id))
    message.setField(fix.ClOrdID(ord_id))
    message.setField(fix.Symbol(symbol))
    message.setField(fix.Side(side))
    message.setField(fix.TransactTime())
    message.setField(fix.Text(f"Delete {orig_client_order_id}"))

    return message
Ejemplo n.º 17
0
    def cancel_parent_order(self, parent_orderid: str):
        """"""
        algo_setting = self.algo_settings.get(parent_orderid, None)
        if not algo_setting:
            print(f"{parent_orderid} algo setting not found.")
            return

        message = new_message(fix.MsgType_OrderCancelRequest)

        self.parent_orderid += 1
        cancel_orderid = f"Cancel_{self.parent_orderid}"
        message.setField(fix.ClOrdID(cancel_orderid))
        message.setField(fix.OrigClOrdID(parent_orderid))
        message.setField(fix.Symbol(algo_setting["symbol"]))
        message.setField(fix.Side(algo_setting["side"]))
        message.setField(847, algo_setting["algo_type"])
        message.setField(fix.Text("vnpy"))

        fix.Session.sendToTarget(message, self.session_id)
Ejemplo n.º 18
0
def msgtofix_reject(reject_msg):
    """
    Converte Reject (message) para Reject (fix).
    """
    reject_text = reject_msg.Text

    contact = get_contact_info()
    if contact:
        reject_text += f' ({contact})'

    response = fix44.Message()
    quoterequest_msg, quoterequest_fix = get_quoterequest(reject_msg.QuoteReqID)
    response.reverseRoute(quoterequest_fix.getHeader())
    response.getHeader().setField(fix.MsgType(fix.MsgType_QuoteAcknowledgement))
    response.setField(fix.QuoteReqID(quoterequest_msg.QuoteReqID))
    response.setField(fix.QuoteAckStatus(5))
    response.setField(fix.QuoteRejectReason(99))
    response.setField(fix.Text(reject_text))
    return response
    def fromApp(self, message, sessionID):

        msgtype = fix.MsgType()
        symbol = fix.Symbol()
        side = fix.Side()
        ordtype = fix.OrdType()
        text = fix.Text()

        message.getHeader().getField(msgtype)
        message.getField(symbol)
        message.getField(side)
        message.getField(ordtype)
        message.getField(text)
        print
        print 'Message received! It reads:'
        print ' = '.join(self.parse(msgtype))
        print self.getFieldName(symbol), '=', symbol.getString()
        print ' = '.join(self.parse(side))
        print ' = '.join(self.parse(ordtype))
        print self.getFieldName(text), '=', text.getString()
Ejemplo n.º 20
0
    def on_parent_order(self, message: fix.Message):
        """"""
        parent_orderid = get_field_value(message, fix.ClOrdID())

        # Get parent orderid of cancel request
        if parent_orderid.startswith("Cancel"):
            parent_orderid = get_field_value(message, fix.OrigClOrdID())

        # If this parent order is from previous session
        if parent_orderid not in self.algo_settings:
            # Cancel it to avoid future update
            self.cancel_parent_order(parent_orderid)
            return

        tradeid = get_field_value(message, fix.ExecID())
        status = get_field_value(message, fix.OrdStatus())
        side = get_field_value(message, fix.Side())
        genus_symbol = get_field_value(message, fix.Symbol())
        order_traded = get_field_value(message, fix.CumQty())

        text = get_field_value(message, fix.Text())
        algo_type = get_field_value(message, fix.StringField(847))

        variables = {"推送编号": tradeid, "已成交": order_traded, "算法信息": text}

        self.algo_settings[parent_orderid] = {
            "symbol": genus_symbol,
            "side": side,
            "algo_type": algo_type
        }

        # Add algo active status
        if status in {"0", "1", "5", "6", "A", "D", "E"}:
            variables["active"] = True
        else:
            variables["active"] = False

        if status == "C":
            self.client.write_log("执行时间已结束,停止算法", parent_orderid)

        self.client.put_variables_event(parent_orderid, variables)
Ejemplo n.º 21
0
 def cancel_order(self):
     message = fix.Message()
     header = message.getHeader()
     header.setField(fix.BeginString(fix.BeginString_FIX42))
     header.setField(fix.MsgType(fix.MsgType_OrderCancelRequest))  #35=F
     originalOrderId = str(int(self.genOrderID()) - 1)
     message.setField(fix.OrigClOrdID(originalOrderId))
     message.setField(fix.ClOrdID(str(int(originalOrderId) +
                                      1)))  #11=Unique order id
     message.setField(fix.OrderID("375"))
     message.setField(fix.Symbol("ABCD"))  #55=ABCD
     message.setField(fix.Side(fix.Side_BUY))  #54=1 Buy
     message.setField(
         fix.StringField(
             60, (datetime.utcnow().strftime("%Y%m%d-%H:%M:%S.%f"))[:-3])
     )  #60 TransactTime, not supported in python, so use tag number
     message.setField(fix.Text("Cancel my Order"))  #58 text
     print(message.toString())
     try:
         fix.Session.sendToTarget(message, self.sessionID)
     except (fix.ConfigError, fix.RuntimeError) as e:
         print(e)
Ejemplo n.º 22
0
def replace_order(sender_comp_id, target_comp_id, quantity, price,
                  orig_client_order_id):
    symbol = ORDERS[orig_client_order_id][0].getValue()
    side = ORDERS[orig_client_order_id][3].getValue()

    message = fix42.OrderCancelReplaceRequest()
    header = message.getHeader()
    header.setField(fix.SenderCompID(sender_comp_id))
    header.setField(fix.TargetCompID(target_comp_id))
    ord_id = get_order_id(sender_comp_id, symbol)
    message.setField(fix.OrigClOrdID(orig_client_order_id))
    message.setField(fix.ClOrdID(ord_id))
    message.setField(fix.Symbol(symbol))
    message.setField(fix.Side(side))
    message.setField(fix.Price(float(price)))
    message.setField(fix.OrdType(fix.OrdType_LIMIT))
    message.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION))
    message.setField(fix.TransactTime())
    message.setField(fix.TransactTime())
    message.setField(fix.OrderQty(float(quantity)))
    message.setField(fix.Text(f"{side} {symbol} {quantity}@{price}"))

    return message
Ejemplo n.º 23
0
    def fromAdmin(self, m: fix.Message, session_id: fix.SessionID):
        if self.autofix_sequence_numbers:
            text_tag = fix.Text().getTag()
            is_seqnum_too_low = (
                m.getHeader().getField(fix.MsgType().getTag())
                == fix.MsgType_Logout and m.isSetField(text_tag)
                and m.getField(text_tag).startswith("MsgSeqNum too low"))

            if is_seqnum_too_low:
                needed_seqnum = int(
                    re.match("MsgSeqNum too low, expecting (\d+)",
                             m.getField(text_tag))[1])

                self.log_message("fromAdmin", m, session_id, levelize=False)
                logger.warning(
                    f"Resetting MsgSeqNum to {needed_seqnum} as needed. Wait for reconnect..."
                )

                self.session.setNextSenderMsgSeqNum(needed_seqnum)
                return

        self.log_message("fromAdmin", m, session_id)
        self.incoming_messages.put(fix.Message(m))
Ejemplo n.º 24
0
    def log_message(self,
                    from_func: str,
                    m: fix.Message,
                    session_id: fix.SessionID,
                    levelize=True):
        logger.debug("{}: {} {}", from_func,
                     m.toString().replace("\x01", "|"), session_id)

        m1 = self.fix_to_dict(m, True)
        msg_type = m.getHeader().getField(fix.MsgType().getTag())

        if not levelize:
            logger.info(f"{from_func}: {m1} {session_id}")
            return

        if msg_type == fix.MsgType_Reject:
            logger.error(f"{from_func}: {m1} {session_id}")
        elif msg_type == fix.MsgType_Heartbeat:
            logger.debug(f"{from_func}: {m1} {session_id}")
        elif msg_type == fix.MsgType_Logout and m.isSetField(
                fix.Text().getTag()):
            logger.error(f"{from_func}: {m1} {session_id}")
        else:
            logger.info(f"{from_func}: {m1} {session_id}")
Ejemplo n.º 25
0
    def put_new_order(self):
        """Request sample new order single"""
        message = fix.Message()
        header = message.getHeader()

        header.setField(fix.MsgType(fix.MsgType_NewOrderSingle))  #39 = D

        message.setField(fix.ClOrdID(
            self.genExecID()))  #11 = Unique Sequence Number
        message.setField(fix.Side(fix.Side_BUY))  #43 = 1 BUY
        message.setField(fix.Symbol("MSFT"))  #55 = MSFT
        message.setField(fix.OrderQty(10000))  #38 = 1000
        message.setField(fix.Price(100))
        message.setField(fix.OrdType(fix.OrdType_LIMIT))  #40=2 Limit Order
        message.setField(
            fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION))  #21 = 3
        message.setField(fix.TimeInForce('0'))
        message.setField(fix.Text("NewOrderSingle"))
        trstime = fix.TransactTime()
        trstime.setString(
            datetime.utcnow().strftime("%Y%m%d-%H:%M:%S.%f")[:-3])
        message.setField(trstime)

        fix.Session.sendToTarget(message, self.sessionID)
Ejemplo n.º 26
0
    def getExecutionReportForNewOrder2(self, message):

        beginString = fix.BeginString()
        message.getHeader().getField(beginString)
        msgSeqNum = fix.MsgSeqNum()
        message.getHeader().getField(msgSeqNum)

        symbol = fix.Symbol()
        side = fix.Side()
        ordType = fix.OrdType()
        orderQty = fix.OrderQty()
        price = fix.Price()
        clOrdID = fix.ClOrdID()

        message.getField(ordType)
        # todo handle market order
        if ordType.getValue() != fix.OrdType_LIMIT:
            raise fix.IncorrectTagValue(ordType.getField())

        message.getField(symbol)
        message.getField(side)
        message.getField(orderQty)
        message.getField(price)
        message.getField(clOrdID)

        data = {}
        data['market'] = symbol.getValue()
        data['price'] = price.getValue()
        data['side'] = 'buy' if side.getValue() == fix.Side_BUY else 'sell'
        data['volume'] = orderQty.getValue()
        response = createOrder(self.accessKey, self.secretKey, data)

        jResponse = json.loads(response)

        executionReport = fix.Message()
        executionReport.getHeader().setField(beginString)
        executionReport.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))
        # todo exec id?
        executionReport.setField(fix.ExecID(self.genExecID()))
        executionReport.setField(symbol)
        executionReport.setField(side)
        executionReport.setField(fix.CumQty(orderQty.getValue()))
        executionReport.setField(fix.AvgPx(price.getValue()))
        executionReport.setField(fix.LastShares(orderQty.getValue()))
        executionReport.setField(fix.LastPx(price.getValue()))
        # todo save Client order id to DB?
        executionReport.setField(clOrdID)
        executionReport.setField(orderQty)

        if 'error' in jResponse and jResponse['error']:
            executionReport.setField(fix.OrderID("nil"))
            executionReport.setField(fix.OrdStatus(fix.OrdStatus_REJECTED))
            executionReport.setField(fix.Text(jResponse['error']['message']))
            # todo Reject reason for each case
            executionReport.setField(
                fix.OrdRejReason(fix.OrdRejReason_UNKNOWN_SYMBOL))
        else:
            executionReport.setField(fix.OrderID(str(jResponse['id'])))
            # todo check trades_count from json response and set FILL status?
            executionReport.setField(fix.OrdStatus(fix.OrdStatus_NEW))
            executionReport.setField(fix.Text('New order accpeted!'))

        # Since FIX 4.3, ExecTransType is killed and the values are moved to ExecType
        if beginString.getValue(
        ) == fix.BeginString_FIX40 or beginString.getValue(
        ) == fix.BeginString_FIX41 or beginString.getValue(
        ) == fix.BeginString_FIX42:
            executionReport.setField(fix.ExecTransType(fix.ExecTransType_NEW))

        # todo check trades_count from json response and set FILL status?
        # ExecType and LeavesQty fields only existsince FIX 4.1
        if beginString.getValue() >= fix.BeginString_FIX41:
            if beginString.getValue() <= fix.BeginString_FIX42:
                executionReport.setField(fix.ExecType(
                    fix.ExecType_FILL))  #150=2 FILL  (or 1 PARTIAL_FILL)
            else:
                # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field
                executionReport.setField(fix.ExecType(
                    fix.ExecType_TRADE))  #150=F TRADE
            executionReport.setField(fix.LeavesQty(0))
        """if 'error' in jResponse and jResponse['error']:
            reject = fix.Message()
            reject.getHeader().setField(beginString)
            reject.getHeader().setField(fix.MsgType(fix.MsgType_Reject))
            reject.setField(fix.RefMsgType(fix.MsgType_NewOrderSingle))
            reject.setField(fix.RefSeqNum(msgSeqNum.getValue())) #45 = RefSeqNum
            reject.setField(fix.SessionRejectReason(fix.SessionRejectReason_OTHER)) #373 = 99 OTHER
            reject.setField(fix.Text(jResponse['message'])) 
            return reject """

        return executionReport
Ejemplo n.º 27
0
    def getExecutionReportForCancelOrder2(self, message):

        beginString = fix.BeginString()
        message.getHeader().getField(beginString)

        symbol = fix.Symbol()
        side = fix.Side()
        clOrdID = fix.ClOrdID()
        orderID = fix.OrderID()
        origClOrdID = fix.OrigClOrdID()

        message.getField(symbol)
        message.getField(side)
        message.getField(clOrdID)
        message.getField(orderID)
        message.getField(origClOrdID)

        executionReport = fix.Message()
        executionReport.getHeader().setField(beginString)
        executionReport.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))

        data = {}
        data['id'] = orderID.getValue()
        response = cancelOrder(self.accessKey, self.secretKey,
                               orderID.getValue())

        jResponse = json.loads(response)

        executionReport.setField(fix.OrderID(orderID.getValue()))
        # todo get client order id
        executionReport.setField(clOrdID)
        executionReport.setField(fix.ExecID(self.genExecID()))

        if 'error' in jResponse and jResponse['error']:
            orderCancelReject = fix.Message()
            orderCancelReject.getHeader().setField(beginString)
            orderCancelReject.getHeader().setField(
                fix.MsgType(fix.MsgType_OrderCancelReject))

            orderCancelReject.setField(clOrdID)
            orderCancelReject.setField(orderID)
            orderCancelReject.setField(origClOrdID)
            # todo reject reason
            orderCancelReject.setField(fix.OrdStatus(
                fix.OrdStatus_FILLED))  #39 = 2 FILLED
            orderCancelReject.setField(
                fix.CxlRejReason(0))  #102=0 TOO_LATE_TO_CANCEL

            orderCancelReject.setField(
                fix.CxlRejResponseTo(1))  #434=1  ORDER_CANCEL_REQUEST
            orderCancelReject.setField(fix.Text(jResponse['error']['message']))

            return orderCancelReject
        else:
            executionReport.setField(fix.OrderID(str(jResponse['id'])))
            # todo check trades_count from json response and set FILL status?
            executionReport.setField(fix.OrdStatus(fix.OrdStatus_CANCELED))
            executionReport.setField(
                fix.Side(fix.Side_BUY if jResponse['side'] ==
                         'buy' else fix.Side_SELL))
            executionReport.setField(
                fix.OrdType(
                    fix.OrdType_LIMIT if jResponse['ord_type'] ==
                    'limit' else fix.OrdType_MARKET))  #40=2 Limit order
            executionReport.setField(fix.Symbol(jResponse['market']))
            executionReport.setField(fix.Price(float(jResponse['price'])))  #44
            executionReport.setField(fix.OrderQty(float(
                jResponse['volume'])))  #38
            executionReport.setField(
                fix.CumQty(float(jResponse['executed_volume'])))  #14=100
            executionReport.setField(fix.AvgPx(float(
                jResponse['avg_price'])))  #6
            executionReport.setField(fix.Text("Order cancelled!"))

        # Since FIX 4.3, ExecTransType values are moved to ExecType
        if beginString.getValue(
        ) == fix.BeginString_FIX40 or beginString.getValue(
        ) == fix.BeginString_FIX41 or beginString.getValue(
        ) == fix.BeginString_FIX42:
            executionReport.setField(
                fix.ExecTransType(fix.ExecTransType_CANCEL))

        # ExecType and LeavesQty fields only existsince FIX 4.1
        if beginString.getValue() >= fix.BeginString_FIX41:
            executionReport.setField(fix.ExecType(
                fix.ExecType_CANCELED))  #150=4 CANCELED
            executionReport.setField(fix.LeavesQty(0))  #151=0

        return executionReport
Ejemplo n.º 28
0
    def getExecutionReportForStatusRequest2(self, message):

        beginString = fix.BeginString()
        message.getHeader().getField(beginString)

        clOrdID = fix.ClOrdID()
        orderID = fix.OrderID()
        message.getField(clOrdID)
        message.getField(orderID)

        response = getOrder(self.accessKey, self.secretKey, orderID.getValue())
        jResponse = json.loads(response)

        executionReport = fix.Message()
        executionReport.getHeader().setField(beginString)
        executionReport.getHeader().setField(
            fix.MsgType(fix.MsgType_ExecutionReport))

        executionReport.setField(fix.ExecID(self.genExecID()))
        # todo get client order id
        executionReport.setField(clOrdID)

        if 'error' in jResponse and jResponse['error']:
            executionReport.setField(fix.OrderID(orderID.getValue()))
            executionReport.setField(fix.OrdStatus(fix.OrdStatus_REJECTED))
            executionReport.setField(fix.Text(jResponse['error']['message']))
            # todo Reject reason for each case
            executionReport.setField(
                fix.OrdRejReason(fix.OrdRejReason_UNKNOWN_ORDER))
        else:
            executionReport.setField(fix.OrderID(str(jResponse['id'])))
            # todo check trades_count from json response and set FILL status?
            executionReport.setField(fix.OrdStatus(fix.OrdStatus_NEW))
            executionReport.setField(
                fix.Side(fix.Side_BUY if jResponse['side'] ==
                         'buy' else fix.Side_SELL))
            executionReport.setField(
                fix.OrdType(
                    fix.OrdType_LIMIT if jResponse['ord_type'] ==
                    'limit' else fix.OrdType_MARKET))  #40=2 Limit order
            executionReport.setField(fix.Symbol(jResponse['market']))
            executionReport.setField(fix.Price(float(jResponse['price'])))  #44
            executionReport.setField(fix.OrderQty(float(
                jResponse['volume'])))  #38
            executionReport.setField(
                fix.CumQty(float(jResponse['executed_volume'])))  #14=100
            executionReport.setField(fix.AvgPx(float(
                jResponse['avg_price'])))  #6
            executionReport.setField(fix.Text('Order status retrieved!'))

        # Since FIX 4.3, ExecTransType values are moved to ExecType
        if beginString.getValue(
        ) == fix.BeginString_FIX40 or beginString.getValue(
        ) == fix.BeginString_FIX41 or beginString.getValue(
        ) == fix.BeginString_FIX42:
            executionReport.setField(
                fix.ExecTransType(fix.ExecTransType_STATUS))

        # ExecType and LeavesQty fields only existsince FIX 4.1
        if beginString.getValue() >= fix.BeginString_FIX41:
            if beginString.getValue() <= fix.BeginString_FIX42:
                executionReport.setField(fix.ExecType(
                    fix.ExecType_FILL))  #150=2 FILL  (or 1 PARTIAL_FILL)
            else:
                # FILL and PARTIAL_FILL are removed and replaced by TRADE (F) since FIX 4.3 as these info can be retrieved from OrdStatus field
                executionReport.setField(fix.ExecType(
                    fix.ExecType_TRADE))  #150=F TRADE
            executionReport.setField(fix.LeavesQty(0))

        return executionReport
Ejemplo n.º 29
0
    def send_parent_order(self, setting: dict):
        """"""
        vt_symbol = setting["vt_symbol"]
        volume = setting["volume"]
        price = setting["price"]
        order_type = OrderType(setting["order_type"])
        direction = Direction(setting["direction"])
        offset = Offset(setting["offset"])
        template_name = setting["template_name"]
        algo_type = template_name.replace("Genus", "")

        message = new_message(fix.MsgType_NewOrderSingle)

        symbol, exchange = extract_vt_symbol(vt_symbol)
        genus_exchange = EXCHANGE_VT2GNS[exchange]
        genus_symbol = f"{symbol}.{genus_exchange}"

        side = DIRECTION_VT2GNS[direction]
        genus_type = ORDERTYPE_VT2GNS[order_type]

        self.parent_orderid += 1
        parent_orderid = f"{template_name}_{self.parent_orderid}"
        message.setField(fix.ClOrdID(parent_orderid))

        message.setField(fix.HandlInst("2"))
        message.setField(fix.Currency("CNY"))

        message.setField(fix.ExDestination(genus_exchange))
        message.setField(fix.Symbol(genus_symbol))
        message.setField(fix.Side(side))
        message.setField(fix.OrdType(genus_type))
        message.setField(fix.OrderQty(volume))
        message.setField(526, parent_orderid)
        message.setField(fix.Text("vnpy"))

        if order_type == OrderType.LIMIT:
            message.setField(fix.Price(price))

        seconds = setting["time"]
        dt = datetime.now() + timedelta(seconds=seconds)
        local_dt = CHINA_TZ.localize(dt)
        utc_dt = local_dt.astimezone(pytz.utc)
        utc_end = utc_dt.strftime("%Y%m%d-%H:%M:%S")

        parameters = f"EndTime;{utc_end}"

        message.setField(847, algo_type)
        message.setField(848, parameters)

        fix.Session.sendToTarget(message, self.session_id)

        self.algo_settings[parent_orderid] = {
            "symbol": genus_symbol,
            "side": side,
            "algo_type": algo_type
        }

        self.client.set_parent_offset(parent_orderid, offset)
        self.client.put_parameters_event(parent_orderid, setting)

        return parent_orderid