Example #1
0
    def set_persister(self, persister):
        self.persister = persister
        self.in_db, self.out_db = persister.getTodayPersister()
        #self.persister.report( self.inDb)
        #self.persister.report( self.outDb)
        p = SynchronousParser(self.fix)
        import time

        for db in (self.in_db, self.out_db):
            start = time.time()
            i = 0.0
            c = db.cursor()
            while True:
                v = c.next()
                if not v:
                    break
                msg, _, _ = p.feed(v[1])
                i += 1
            endTime = time.time()
            dur = endTime - start

            print "%s parsed %s messages in %s secs (%s/sec)" % (db, i, dur,
                                                                 i / dur)

        self.in_msg_seq_num = self.persister.getNextSeq(self.in_db)
        self.out_msg_seq_num = self.persister.getNextSeq(self.out_db)
        print "Setting sequence numbers %s %s" % (self.in_msg_seq_num,
                                                  self.out_msg_seq_num)
Example #2
0
    def set_persister(self, persister):
        self.persister = persister
        self.in_db, self.out_db = persister.getTodayPersister()
        #self.persister.report( self.inDb)
        #self.persister.report( self.outDb)
        p = SynchronousParser(self.fix)
        import time

        for db in (self.in_db, self.out_db):
            start = time.time()
            i = 0.0
            c = db.cursor()
            while True:
                v = c.next()
                if not v:
                    break
                msg, _, _ = p.feed(v[1])
                i += 1
            endTime = time.time()
            dur = endTime - start

            print "%s parsed %s messages in %s secs (%s/sec)" % (db, i, dur, i / dur )

        self.in_msg_seq_num = self.persister.getNextSeq(self.in_db)
        self.out_msg_seq_num = self.persister.getNextSeq(self.out_db)
        print "Setting sequence numbers %s %s" % ( self.in_msg_seq_num, self.out_msg_seq_num)
Example #3
0
    def __init__(self, session_manager, fix, config):
        self.session_manager = session_manager
        self.protocol = None
        self.fix = fix
        self.sender = config.sender
        self.target = config.target
        self.sender_compid = fix.SenderCompID(self.sender)
        self.target_compid = fix.TargetCompID(self.target)
        self.begin_string = fix.BeginString(fix.version)
        self.out_msg_seq_num = 1
        self.in_msg_seq_num = 1
        self.set_persister(
            BerkeleyPersister(config.persistRoot, self.sender, self.target))
        self.heartbeat_interval = config.heartbeatInterval
        # Why do we need an sp?
        self.sp = SynchronousParser(self.fix)
        self.last_by_type = {}
        self.state = None
        if config.app:
            self.set_app(config.app)
        else:
            self.set_app(FIXApplication(fix))

        self.on_integrity_exception = None
        self.last_integrity_exception = None
        self.want_to_be_logged_in = True
Example #4
0
    def __init__(self, session_manager, fix, config):
        self.session_manager = session_manager
        self.protocol = None
        self.fix = fix
        self.sender = config.sender
        self.target = config.target
        self.sender_compid = fix.SenderCompID(self.sender)
        self.target_compid = fix.TargetCompID(self.target)
        self.begin_string = fix.BeginString(fix.version)
        self.out_msg_seq_num = 1
        self.in_msg_seq_num = 1
        self.set_persister(BerkeleyPersister(config.persistRoot, self.sender, self.target))
        self.heartbeat_interval = config.heartbeatInterval
        # Why do we need an sp?
        self.sp = SynchronousParser(self.fix)
        self.last_by_type = {}
        self.state = None
        if config.app:
            self.set_app(config.app)
        else:
            self.set_app(FIXApplication(fix))

        self.on_integrity_exception = None
        self.last_integrity_exception = None
        self.want_to_be_logged_in = True
Example #5
0
    def setUp(self):
        self.fix = parse_specification(self.version)
        self.fp = SynchronousParser(self.fix)

        self.sendConfig = SessionConfig(
            'initiator',
            0,
            'localhost',
            'INITIATOR',
            'ACCEPTOR',
            os.path.join(tempfile.mktemp(), "sender"),  # Will be tempfile
            60,
            None)
        self.ds = Session(None, self.fix, self.sendConfig)
        major, minor = self.version.split('.')[1:]
        self.numVersion = int(major) * 10 + int(minor)
        print "NV = %s" % self.numVersion
Example #6
0
 def recover(self):
     assert self.session is not None
     self.in_recovery = True
     sp = SynchronousParser(self.fix)
     c = self.session.persister.ledger.cursor()
     while True:
         d = c.next()
         if not d:
             break
         try:
             msg, _, _ = sp.parse(d[1])
             self.recovered_message(msg)
         except ParseException:
             msg = cPickle.loads(d[1])
             self.recovered_message(msg)
     c.close()
     self.on_recovery_done()
     self.in_recovery = False
Example #7
0
 def recover(self):
     assert self.session is not None
     self.in_recovery = True
     sp = SynchronousParser(self.fix)
     c = self.session.persister.ledger.cursor()
     while True:
         d = c.next()
         if not d:
             break
         try:
             msg, _, _ = sp.parse(d[1])
             self.recovered_message(msg)
         except ParseException:
             msg = cPickle.loads(d[1])
             self.recovered_message(msg)
     c.close()
     self.on_recovery_done()
     self.in_recovery = False
Example #8
0
    def __init__(self,
                 fix,
                 config,
                 initiatorProtocol=InitiatorFIXProtocol,
                 acceptorProtocol=AcceptorFIXProtocol):
        self.fix = fix
        self.config = config
        self.sessionLookup = {}

        self.initiatorProtocol = initiatorProtocol
        self.acceptorProtocol = acceptorProtocol

        self.beginString = self.fix.BeginString(self.fix.version)

        self.sessionByTuple = {}
        self.acceptorsByTuple = {}
        self.initiatorsByTuple = {}

        self.acceptorsByPort = defaultdict(lambda: {})
        self.initiatorFactories = []
        self.acceptorFactories = {}
        self.sessions = []

        self.perspective = None
        for s in config:
            idTuple = (s.sender, s.target)
            session = Session(self, fix, s)
            self.sessions.append(session)
            self.sessionByTuple[idTuple] = idTuple
            if s.connectionType == 'initiator':
                #session.host = s.host
                #session.port = s.port
                f = InitiatorFactory(self, session, s.host, s.port)
                session.factory = f
                self.initiatorFactories.append(f)
                self.initiatorsByTuple[idTuple] = session
            else:
                assert s.connectionType == 'acceptor', "Must be acceptor or initiator"
                self.acceptorsByPort[s.port][idTuple] = session
                self.acceptorsByTuple[idTuple] = session
            self.sessionByTuple[idTuple] = session

        for port, sessionMap in self.acceptorsByPort.items():
            af = AcceptorFactory(self, sessionMap)
            self.acceptorFactories[port] = af
        self.sp = SynchronousParser(self.fix)
Example #9
0
 def setUp( self):
     self.fix = parse_specification( self.version )
     self.fp = SynchronousParser(self.fix)
     
     self.sendConfig = SessionConfig( 'initiator',
                                      0,
                                      'localhost',
                                      'INITIATOR',
                                      'ACCEPTOR',
                                      os.path.join( tempfile.mktemp(), "sender" ), # Will be tempfile
                                      60,
                                      None
                                      )
     self.ds = Session( None, self.fix, self.sendConfig)
     major, minor = self.version.split('.')[1:]
     self.numVersion = int(major) * 10 + int(minor)
     print "NV = %s" % self.numVersion 
Example #10
0
class SpecTester(unittest.TestCase):
    version = '4.1'

    def __repr__(self):
        return "SpecTester(%s,%s)" % (self.version, self.testMethod)

    __str__ = __repr__

    def __init__(self, testMethod, version='FIX.4.0'):
        # NB nose wants the init method of a testcase to
        unittest.TestCase.__init__(self, methodName=testMethod)
        self.version = version
        self.testMethod = testMethod

    def setUp(self):
        self.fix = parse_specification(self.version)
        self.fp = SynchronousParser(self.fix)

        self.sendConfig = SessionConfig(
            'initiator',
            0,
            'localhost',
            'INITIATOR',
            'ACCEPTOR',
            os.path.join(tempfile.mktemp(), "sender"),  # Will be tempfile
            60,
            None)
        self.ds = Session(None, self.fix, self.sendConfig)
        major, minor = self.version.split('.')[1:]
        self.numVersion = int(major) * 10 + int(minor)
        print "NV = %s" % self.numVersion

    def test_parse(self):
        codex = [
            ["ExecID('102')", None],
            ["OrdStatus.FILLED", None],
            ["OrderID('myOrderID')", None],
            ["ExecTransType.NEW", lambda x, y: y < 43],  # Got dropped in 43
            ["Symbol( 'CSCO')", None],
            ["AvgPx( 32.34 )", None],
            ["LastPx( 32.34 )", None],
            ["Side.BUY", None],
            ["ExecType.NEW", lambda x, y: y > 40],
            ["OrderQty(300)", None],
            ["CumQty( 100)", None],
            ["LastShares( 100)", lambda x, y: y < 43],
            ["LastQty( 100)", lambda x, y: y > 42],
            ["LeavesQty( 200)", lambda x, y: y > 40],
            ["ClOrdID( 'MYOrder')", None]
        ]

        fields = []
        for expr, cond in codex:
            if cond is None or cond(self.fix.version, self.numVersion):
                fields.append(eval("self.pyfix.%s" % expr))


##         msg = self.pyfix.ExecutionReport( fields = [self.pyfix.ExecID( '102'),
##                                              self.pyfix.OrdStatus.FILLED,
##                                              self.pyfix.OrderID('myOrderID'),
##                                              self.pyfix.ExecTransType.NEW,
##                                              self.pyfix.Symbol( 'CSCO'),
##                                              self.pyfix.AvgPx( 32.34 ),
##                                              self.pyfix.Side.BUY,
##                                              self.pyfix.ExecType.NEW,
##                                              self.pyfix.OrderQty(300),
##                                              self.pyfix.CumQty( 100),
##                                              self.pyfix.LeavesQty( 200),
##                                              self.pyfix.ClOrdID( "ORDER_2232") ] )
        msg = self.fix.ExecutionReport(fields=fields)
        asFix = self.ds.compile_message(msg)
        msg2, _, _ = self.fp.feed(asFix)
        self.assertEqual(msg2.to_fix(), asFix)
Example #11
0
class Session(object):
    def __init__(self, session_manager, fix, config):
        self.session_manager = session_manager
        self.protocol = None
        self.fix = fix
        self.sender = config.sender
        self.target = config.target
        self.sender_compid = fix.SenderCompID(self.sender)
        self.target_compid = fix.TargetCompID(self.target)
        self.begin_string = fix.BeginString(fix.version)
        self.out_msg_seq_num = 1
        self.in_msg_seq_num = 1
        self.set_persister(
            BerkeleyPersister(config.persistRoot, self.sender, self.target))
        self.heartbeat_interval = config.heartbeatInterval
        # Why do we need an sp?
        self.sp = SynchronousParser(self.fix)
        self.last_by_type = {}
        self.state = None
        if config.app:
            self.set_app(config.app)
        else:
            self.set_app(FIXApplication(fix))

        self.on_integrity_exception = None
        self.last_integrity_exception = None
        self.want_to_be_logged_in = True

    def set_app(self, app):
        self.app = app
        self.app.set_session(self)

    def set_state(self, old_state, new_state):
        self.app.set_state(old_state, new_state)

    def bind_protocol(self, protocol):
        assert self.protocol is None
        assert protocol.session is None
        protocol.session = self
        self.protocol = protocol
        self.app.set_protocol(protocol)

    def release_protocol(self):
        assert self.protocol.session == self
        assert self.protocol is not None
        self.protocol.session = None
        self.protocol = None

    def str_connected(self):
        return {
            True: " Connected  ",
            False: "Disconnected"
        }[self.isConnected()]

    def __repr__(self):
        return "Session(%s-%s %s [%s,%s] )" % (
            self.sender, self.target, self.str_connected(),
            self.in_msg_seq_num, self.out_msg_seq_num)

    def dump_in(self, x):
        self.dump_msg(self.in_db, x)

    def dump_out(self, x):
        self.dump_msg(self.out_db, x)

    def logoff(self, want_to_be_logged_on=False):
        assert self.isConnected()
        self.want_to_be_logged_in = want_to_be_logged_on
        # TODO - investigate - I put this in for a reason!
        self.protocol._logoff()

    def logon(self
              ):  # This translates to "want to be logged on" for an acceptor!
        assert not self.isConnected()
        self.want_to_be_logged_in = True
        if self.factory:
            assert self.factory.__class__ == InitiatorFactory, "Logic error only initiators keep track of factory"
            self.factory.logon()

    def dump_msg(self, db, x):
        raw_msg = db[x]
        msg, x, y = self.sp.feed(raw_msg)
        msg.dump()
        print x, y

    def parse(self, msg):
        return self.sp.feed(msg)[0]

    def isConnected(self):
        return self.protocol is not None

    def set_persister(self, persister):
        self.persister = persister
        self.in_db, self.out_db = persister.getTodayPersister()
        #self.persister.report( self.inDb)
        #self.persister.report( self.outDb)
        p = SynchronousParser(self.fix)
        import time

        for db in (self.in_db, self.out_db):
            start = time.time()
            i = 0.0
            c = db.cursor()
            while True:
                v = c.next()
                if not v:
                    break
                msg, _, _ = p.feed(v[1])
                i += 1
            endTime = time.time()
            dur = endTime - start

            print "%s parsed %s messages in %s secs (%s/sec)" % (db, i, dur,
                                                                 i / dur)

        self.in_msg_seq_num = self.persister.getNextSeq(self.in_db)
        self.out_msg_seq_num = self.persister.getNextSeq(self.out_db)
        print "Setting sequence numbers %s %s" % (self.in_msg_seq_num,
                                                  self.out_msg_seq_num)

    def persist_and_advance(self, message_string, check_in_sequence=True):
        msg, _, _ = self.sp.feed(message_string)
        msg_seq = msg.get_header_field_value(self.fix.MsgSeqNum)
        if check_in_sequence:
            seq = self.persister.getNextSeq(self.in_db)
            seq2 = self.persister.getNextSeq(self.out_db)
            assert msg_seq >= seq, "Received %s vs %s %s" % (msg_seq, seq,
                                                             seq2)

        self.persister.persistInMsg(msg_seq, message_string)
        self.in_msg_seq_num = msg_seq + 1

    def compile_message(self,
                        msg,
                        poss_dup=False,
                        force_sequence_number=None,
                        orig_sending_time=None,
                        persist=True,
                        disable_validation=False):

        sending_time = self.fix.SendingTime(datetime.datetime.now())
        body_length = self.fix.BodyLength(0)
        check_sum = self.fix.CheckSum(0)

        if force_sequence_number:
            seq = force_sequence_number
        else:
            seq = self.out_msg_seq_num

        header = [
            self.begin_string, body_length, msg.msgTypeField,
            self.sender_compid, self.target_compid,
            self.fix.MsgSeqNum(seq), sending_time
        ]

        if poss_dup:
            header = header[:-1] + [self.fix.PossDupFlag('Y')] + header[-1:]

        if orig_sending_time:
            header = header[:-1] + [
                self.fix.OrigSendingTime(orig_sending_time)
            ] + header[-1:]

        footer = [check_sum]
        msg.header_fields = header
        msg.footer_fields = footer

        # this will check what we've done so far
        #msg.checkStructure()
        #msg.validate()
        msg.calc_body_length(mutate=True)
        msg.calc_check_sum(mutate=True)
        #msg.checkBodyLength()
        #bl2 = msg.calcBodyLength( )
        #cs2 = msg.calcCheckSum()

        if not disable_validation:
            msg.validate()
            #assert bl==bl2, "Body Length failed before/after consistency check"
        #assert cs==cs2, "Checksum failed before/after consistency check"

        ret = msg.to_fix()
        if not poss_dup:
            if persist:
                self.persister.persistOutMsg(self.out_msg_seq_num, ret)
                #self.outDb[self.outMsgSeqNum] = ret
            #self.outDb.sync()
            self.out_msg_seq_num += 1
        return ret
Example #12
0
class Session(object):
    def __init__(self, session_manager, fix, config):
        self.session_manager = session_manager
        self.protocol = None
        self.fix = fix
        self.sender = config.sender
        self.target = config.target
        self.sender_compid = fix.SenderCompID(self.sender)
        self.target_compid = fix.TargetCompID(self.target)
        self.begin_string = fix.BeginString(fix.version)
        self.out_msg_seq_num = 1
        self.in_msg_seq_num = 1
        self.set_persister(BerkeleyPersister(config.persistRoot, self.sender, self.target))
        self.heartbeat_interval = config.heartbeatInterval
        # Why do we need an sp?
        self.sp = SynchronousParser(self.fix)
        self.last_by_type = {}
        self.state = None
        if config.app:
            self.set_app(config.app)
        else:
            self.set_app(FIXApplication(fix))

        self.on_integrity_exception = None
        self.last_integrity_exception = None
        self.want_to_be_logged_in = True

    def set_app(self, app):
        self.app = app
        self.app.set_session(self)

    def set_state(self, old_state, new_state):
        self.app.set_state(old_state, new_state)

    def bind_protocol(self, protocol):
        assert self.protocol is None
        assert protocol.session is None
        protocol.session = self
        self.protocol = protocol
        self.app.set_protocol(protocol)

    def release_protocol(self):
        assert self.protocol.session == self
        assert self.protocol is not None
        self.protocol.session = None
        self.protocol = None

    def str_connected(self):
        return {True: " Connected  ",
                False: "Disconnected"}[self.isConnected()]

    def __repr__(self):
        return "Session(%s-%s %s [%s,%s] )" % (self.sender,
                                               self.target,
                                               self.str_connected(),
                                               self.in_msg_seq_num,
                                               self.out_msg_seq_num)

    def dump_in(self, x):
        self.dump_msg(self.in_db, x)

    def dump_out(self, x):
        self.dump_msg(self.out_db, x)

    def logoff(self, want_to_be_logged_on=False):
        assert self.isConnected()
        self.want_to_be_logged_in = want_to_be_logged_on
        # TODO - investigate - I put this in for a reason!
        self.protocol._logoff()

    def logon(self): # This translates to "want to be logged on" for an acceptor!
        assert not self.isConnected()
        self.want_to_be_logged_in = True
        if self.factory:
            assert self.factory.__class__ == InitiatorFactory, "Logic error only initiators keep track of factory"
            self.factory.logon()

    def dump_msg(self, db, x):
        raw_msg = db[x]
        msg, x, y = self.sp.feed(raw_msg)
        msg.dump()
        print x, y

    def parse(self, msg):
        return self.sp.feed(msg)[0]

    def isConnected(self):
        return self.protocol is not None

    def set_persister(self, persister):
        self.persister = persister
        self.in_db, self.out_db = persister.getTodayPersister()
        #self.persister.report( self.inDb)
        #self.persister.report( self.outDb)
        p = SynchronousParser(self.fix)
        import time

        for db in (self.in_db, self.out_db):
            start = time.time()
            i = 0.0
            c = db.cursor()
            while True:
                v = c.next()
                if not v:
                    break
                msg, _, _ = p.feed(v[1])
                i += 1
            endTime = time.time()
            dur = endTime - start

            print "%s parsed %s messages in %s secs (%s/sec)" % (db, i, dur, i / dur )

        self.in_msg_seq_num = self.persister.getNextSeq(self.in_db)
        self.out_msg_seq_num = self.persister.getNextSeq(self.out_db)
        print "Setting sequence numbers %s %s" % ( self.in_msg_seq_num, self.out_msg_seq_num)

    def persist_and_advance(self,
                            message_string,
                            check_in_sequence=True):
        msg, _, _ = self.sp.feed(message_string)
        msg_seq = msg.get_header_field_value(self.fix.MsgSeqNum)
        if check_in_sequence:
            seq = self.persister.getNextSeq(self.in_db)
            seq2 = self.persister.getNextSeq(self.out_db)
            assert msg_seq >= seq, "Received %s vs %s %s" % (msg_seq, seq, seq2)

        self.persister.persistInMsg(msg_seq, message_string)
        self.in_msg_seq_num = msg_seq + 1

    def compile_message(self,
                        msg,
                        poss_dup=False,
                        force_sequence_number=None,
                        orig_sending_time=None,
                        persist=True,
                        disable_validation=False):

        sending_time = self.fix.SendingTime(datetime.datetime.now())
        body_length = self.fix.BodyLength(0)
        check_sum = self.fix.CheckSum(0)

        if force_sequence_number:
            seq = force_sequence_number
        else:
            seq = self.out_msg_seq_num

        header = [self.begin_string,
                  body_length,
                  msg.msgTypeField,
                  self.sender_compid,
                  self.target_compid,
                  self.fix.MsgSeqNum(seq),
                  sending_time
        ]

        if poss_dup:
            header = header[:-1] + [self.fix.PossDupFlag('Y')] + header[-1:]

        if orig_sending_time:
            header = header[:-1] + [self.fix.OrigSendingTime(orig_sending_time)] + header[-1:]

        footer = [check_sum]
        msg.header_fields = header
        msg.footer_fields = footer

        # this will check what we've done so far
        #msg.checkStructure()
        #msg.validate()
        msg.calc_body_length(mutate=True)
        msg.calc_check_sum(mutate=True)
        #msg.checkBodyLength()
        #bl2 = msg.calcBodyLength( )
        #cs2 = msg.calcCheckSum()

        if not disable_validation:
            msg.validate()
            #assert bl==bl2, "Body Length failed before/after consistency check"
        #assert cs==cs2, "Checksum failed before/after consistency check"

        ret = msg.to_fix()
        if not poss_dup:
            if persist:
                self.persister.persistOutMsg(self.out_msg_seq_num, ret)
                #self.outDb[self.outMsgSeqNum] = ret
            #self.outDb.sync()
            self.out_msg_seq_num += 1
        return ret
Example #13
0
class SpecTester(unittest.TestCase):
    version = '4.1'
    
    def __repr__(self):
        return "SpecTester(%s,%s)" % (self.version, self.testMethod)

    __str__=__repr__
    
    def __init__(self, testMethod, version = 'FIX.4.0' ):
        # NB nose wants the init method of a testcase to 
        unittest.TestCase.__init__(self, methodName = testMethod)
        self.version = version
        self.testMethod = testMethod

    def setUp( self):
        self.fix = parse_specification( self.version )
        self.fp = SynchronousParser(self.fix)
        
        self.sendConfig = SessionConfig( 'initiator',
                                         0,
                                         'localhost',
                                         'INITIATOR',
                                         'ACCEPTOR',
                                         os.path.join( tempfile.mktemp(), "sender" ), # Will be tempfile
                                         60,
                                         None
                                         )
        self.ds = Session( None, self.fix, self.sendConfig)
        major, minor = self.version.split('.')[1:]
        self.numVersion = int(major) * 10 + int(minor)
        print "NV = %s" % self.numVersion 

    def test_parse(self):
        codex = [
            [ "ExecID('102')"        , None ],
            [ "OrdStatus.FILLED"     , None ],
            [ "OrderID('myOrderID')" , None ],
            [ "ExecTransType.NEW"    , lambda x,y: y<43 ], # Got dropped in 43
            [ "Symbol( 'CSCO')"      , None ],
            [ "AvgPx( 32.34 )"       , None ],
            [ "LastPx( 32.34 )"      , None ],
            [ "Side.BUY"             , None ],
            [ "ExecType.NEW"         , lambda x,y: y>40 ],
            [ "OrderQty(300)"        , None ],
            [ "CumQty( 100)"         , None ],
            [ "LastShares( 100)"     , lambda x,y: y<43],
            [ "LastQty( 100)"        , lambda x,y: y>42 ],
            [ "LeavesQty( 200)"      , lambda x,y: y>40 ],
            [ "ClOrdID( 'MYOrder')"  , None ] ]

        fields = []
        for expr, cond in codex:
            if cond is None or cond(self.fix.version, self.numVersion ):
                fields.append( eval("self.pyfix.%s" % expr ) )
        
##         msg = self.pyfix.ExecutionReport( fields = [self.pyfix.ExecID( '102'),
##                                              self.pyfix.OrdStatus.FILLED,
##                                              self.pyfix.OrderID('myOrderID'),
##                                              self.pyfix.ExecTransType.NEW,
##                                              self.pyfix.Symbol( 'CSCO'),
##                                              self.pyfix.AvgPx( 32.34 ),
##                                              self.pyfix.Side.BUY,
##                                              self.pyfix.ExecType.NEW,
##                                              self.pyfix.OrderQty(300),
##                                              self.pyfix.CumQty( 100),
##                                              self.pyfix.LeavesQty( 200),
##                                              self.pyfix.ClOrdID( "ORDER_2232") ] )
        msg = self.fix.ExecutionReport( fields = fields )
        asFix = self.ds.compile_message(msg)
        msg2, _ ,_ = self.fp.feed(asFix)
        self.assertEqual( msg2.to_fix(), asFix)