コード例 #1
0
def test_malformed():

    expected = {
        'BeginString':
        'FIX.4.2',
        'BodyLength':
        '156',
        'CheckSum':
        '228',
        'MsgSeqNum':
        '2',
        'MsgType':
        'J',
        'NoAllocs': [{
            'AllocAccount': 'Marcin',
            'AllocShares': '10',
            'NoMiscFees': [{
                'MiscFeeAmt': '7.99'
            }]
        }, {
            'AllocAccount': 'Jason',
            'AllocShares': '5'
        }],
        'NoOrders': [{
            'ClOrdID': 'C11111',
            'OrderID': 'O11111'
        }, {
            'ClOrdID': 'C22222',
            'OrderID': 'O22222'
        }, {
            'OrderID': 'O33333'
        }],
        'SenderCompID':
        'PXMD',
        'SendingTime':
        '20140922-14:48:49.825',
        'TargetCompID':
        'Q037'
    }

    _expected = expected.copy()

    # this one is good

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |||||

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|||||79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |a|a|a|a|

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|a|a|a|a|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |=|

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|=|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |==|=|

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|==|=|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |22|=|

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|22|=|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |=asdf|

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|=asdf|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |A=A| (not a digit)

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|A=A|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # ||

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|22||79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # |9001=12345|

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|9001=12345|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|'''
    expected['Field9001'] = '12345'
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))
    del expected['Field9001']

    # note, we still don't have a test where the group breaks by a rogue tag mid-group
    # is that something necessary? at that point, it's pretty badly broken.

    # Bad BeginString 8=FIX.

    formatted = '''8=FIX.|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|'''
    original = expected.pop('BeginString')
    assert parse_message(formatted) == dict(expected,
                                            BeginString='FIX.'), pprint(
                                                parse_message(formatted))

    # put BeginString back
    expected['BeginString'] = original

    # note, we chop off the CheckSum here because we're gonna mess it up badly
    formatted = '''8=FIX.4.2|9=156|35=X|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|'''
    checksum = expected.pop('CheckSum')

    # update MsgType
    expected['MsgType'] = 'X'

    assert parse_message(formatted) != expected, pprint(
        parse_message(formatted))
    assert parse_message(formatted,
                         cls=FIX.FIX42.Allocation) == expected, pprint(
                             parse_message(formatted))

    # put those fields back to how they were

    expected['MsgType'] = 'J'
    expected['CheckSum'] = checksum

    expected = {
        'BeginString': 'FIX.4.2',
        'BodyLength': '74',
        'CheckSum': '213',
        'EncryptMethod': '1',
        'HeartBtInt': '3503',
        'MsgType': 'A',
        'RawData': 'AAAAAAAAAAAAAAAA\001AAA',
        'RawDataLength': '20',
        'SendingTime': '20150407-04:12:54.885'
    }

    # we're messing with Logon RawData and RawDataLength, disparity between purpoted length and data
    # behavior should observe the length field, and ignore bytes unaccounted for

    # RawDataLength < len(RawData)

    expected['RawDataLength'] = '17'

    formatted = '8=FIX.4.2\0019=74\00135=A\00152=20150407-04:12:54.885\00198=1\001108=3503\00195=%s\00196=AAAAAAAAAAAAAAAA\001AAA\00110=213\001' % (
        expected['RawDataLength'], )
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    # RawDataLength > len(RawData)
    # We lose CheckSum tag to RawData

    expected[
        'RawDataLength'] = '23'  #TODO should we not expect to handle overlylong values here?
    expected['RawData'] = 'AAAAAAAAAAAAAAAA\001AAA\00110=213'
    expected.pop('CheckSum')

    formatted = '8=FIX.4.2\0019=74\00135=A\00152=20150407-04:12:54.885\00198=1\001108=3503\00195=%s\00196=AAAAAAAAAAAAAAAA\001AAA\00110=213\001' % (
        expected['RawDataLength'], )
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))
コード例 #2
0
def test_parser():
    expected = {
        'BeginString':
        'FIX.4.2',
        'BodyLength':
        '295',
        'CheckSum':
        '215',
        'MsgSeqNum':
        '2',
        'MsgType':
        'i',
        'NoQuoteSets': [{
            'NoQuoteEntries': [{
                'BidSize': '1000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '900000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '0'
            }, {
                'BidSize': '7000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '800000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '1'
            }],
            'QuoteSetID':
            '123'
        }, {
            'NoQuoteEntries': [{
                'BidSize': '1000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '900000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '2'
            }, {
                'BidSize': '7000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '800000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '3'
            }],
            'QuoteSetID':
            '234'
        }],
        'QuoteID':
        '1',
        'SenderCompID':
        'PXMD',
        'SendingTime':
        '20140922-14:48:49.825',
        'TargetCompID':
        'Q037'
    }

    formatted = '''8=FIX.4.2|9=295|35=i|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|117=1|296=2|302=123|295=2|299=0|134=1000000|135=900000|188=1.4363|190=1.4365|299=1|134=7000000|135=800000|188=1.4363|190=1.4365|302=234|295=2|299=2|134=1000000|135=900000|188=1.4363|190=1.4365|299=3|134=7000000|135=800000|188=1.4363|190=1.4365|10=215|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    message = FIX.FIX42.MassQuote(**expected)
    assert repr(message) == formatted

    message = FIX.FIXMessage(**expected)
    assert repr(message) == formatted

    fromstring = FIX.FIX42.MassQuote.fromstring(formatted)
    assert repr(fromstring) == formatted

    fromstring = FIX.FIXMessage.fromstring(formatted)
    assert repr(fromstring) == formatted

    # since this is going to mess up the CheckSum and change the MsgType
    # field as rendered in the formatted string, let's account for that

    fromstring = FIX.FIX42.MassQuote.fromstring(formatted, MsgType='A')
    assert repr(fromstring)[:-4] == formatted.replace('35=i', '35=A')[:-4]
    assert isinstance(fromstring, FIX.FIX42.MassQuote)
    assert not isinstance(fromstring, FIX.FIX42.Logon)

    fromstring = FIX.FIXMessage.fromstring(formatted, MsgType='A')
    #assert repr(fromstring)[:-4] == formatted.replace('35=i', '35=A')[:-4]
    assert isinstance(fromstring, FIX.FIX42.Logon)

    expected = {
        'BeginString':
        'FIX.4.2',
        'BodyLength':
        '156',
        'CheckSum':
        '228',
        'MsgSeqNum':
        '2',
        'MsgType':
        'J',
        'NoAllocs': [{
            'AllocAccount': 'Marcin',
            'AllocShares': '10',
            'NoMiscFees': [{
                'MiscFeeAmt': '7.99'
            }]
        }, {
            'AllocAccount': 'Jason',
            'AllocShares': '5'
        }],
        'NoOrders': [{
            'ClOrdID': 'C11111',
            'OrderID': 'O11111'
        }, {
            'ClOrdID': 'C22222',
            'OrderID': 'O22222'
        }, {
            'OrderID': 'O33333'
        }],
        'SenderCompID':
        'PXMD',
        'SendingTime':
        '20140922-14:48:49.825',
        'TargetCompID':
        'Q037'
    }

    formatted = '''8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|'''
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    message = FIX.FIX42.Allocation(**expected)
    assert repr(message) == formatted

    message = FIX.FIXMessage(**expected)
    assert repr(message) == formatted

    fromstring = FIX.FIX42.Allocation.fromstring(formatted)
    assert repr(fromstring) == formatted

    fromstring = FIX.FIXMessage.fromstring(formatted)
    assert repr(fromstring) == formatted

    expected = {
        'BeginString':
        'FIX.4.2',
        'BodyLength':
        '182',
        'CheckSum':
        '005',
        'MsgSeqNum':
        '2',
        'MsgType':
        'J',
        'NoAllocs': [
            {
                'AllocAccount': 'Marcin',
                'AllocShares': '10',
                'NoMiscFees': [{
                    'MiscFeeAmt': '7.99'
                }]
            },
            {
                'AllocAccount': 'Jason',
                'AllocShares': '5'
            },
            {
                'AllocShares': '10'
            },
            {
                'AllocAccount': 'Tester'
            },
        ],
        'NoOrders': [{
            'ClOrdID': 'C11111',
            'OrderID': 'O11111'
        }, {
            'ClOrdID': 'C22222',
            'OrderID': 'O22222'
        }, {
            'OrderID': 'O33333'
        }, {
            'ClOrdID': 'O44444'
        }],
        'SenderCompID':
        'PXMD',
        'SendingTime':
        '20140922-14:48:49.825',
        'TargetCompID':
        'Q037'
    }

    formatted = '8=FIX.4.2|9=182|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=4|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|11=O44444|78=4|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|80=10|79=Tester|10=005|'
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    message = FIX.FIX42.Allocation(**expected)
    assert repr(message) == formatted

    message = FIX.FIXMessage(**expected)
    assert repr(message) == formatted

    fromstring = FIX.FIX42.Allocation.fromstring(formatted)
    assert repr(fromstring) == formatted

    fromstring = FIX.FIXMessage.fromstring(formatted)
    assert repr(fromstring) == formatted

    #FIX.register_version('phixlib/spec/FIX50SP2.xml')
    #fromstring = FIX.FIX50.AllocationInstruction.fromstring(formatted, BeginString='FIX.5.0')
    #assert repr(fromstring)[9:-7] == formatted[9:-7]
    #print repr(fromstring)
    '''
    expected = {
         'BeginString': 'FIX.4.2',
         'BodyLength': '197',
         'CheckSum': '225',
         'MsgSeqNum': '2',
         'MsgType': 'BBBBBBBBBBBBBBBB',
         'NoAllocs': [{'AllocAccount': 'Marcin',
                       'AllocShares': '10',
                       'NoMiscFees': [{'MiscFeeAmt': '7.99'}]},
                      {'AllocAccount': 'Jason', 'AllocShares': '5'},
                      {'AllocShares': '10'},
                      {'AllocAccount': 'Tester'},
                      ],
         'NoOrders': [{'ClOrdID': 'C11111', 'OrderID': 'O11111'},
                      {'ClOrdID': 'C22222', 'OrderID': 'O22222'},
                      {'OrderID': 'O33333'},
                      {'ClOrdID': 'O44444'}],
         'SenderCompID': 'PXMD',
         'SendingTime': '20140922-14:48:49.825',
         'TargetCompID': 'Q037'}

    message.header._initialized['MsgType'].value = 'BBBBBBBBBBBBBBBB'
    formatted = '8=FIX.4.2|9=197|35=BBBBBBBBBBBBBBBB|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=4|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|11=O44444|78=4|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|80=10|79=Tester|10=225|'
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))
    '''

    expected = {
        'BeginString': 'FIX.4.2',
        'BodyLength': '74',
        'CheckSum': '213',
        'EncryptMethod': '1',
        'HeartBtInt': '3503',
        'MsgType': 'A',
        'RawData': 'AAAAAAAAAAAAAAAA\001AAA',
        'RawDataLength': '20',
        'SendingTime': '20150407-04:12:54.885'
    }

    formatted = '8=FIX.4.2\0019=74\00135=A\00152=20150407-04:12:54.885\00198=1\001108=3503\00195=20\00196=AAAAAAAAAAAAAAAA\001AAA\00110=213\001'
    assert parse_message(formatted) == expected, pprint(
        parse_message(formatted))

    fromstring = FIX.FIX42.Logon.fromstring(formatted)
    assert str(fromstring) == formatted
コード例 #3
0
def test_initialize():

    m = FIX.FIX42.NewOrderSingle()
    m.initialize()

    for field in m._all.itervalues():
        if field.required:
            assert field in m
            assert m.get(field).value, field.name + ' not initialized'

    expected = {
        'BeginString':
        'FIX.4.2',
        'BodyLength':
        '312',
        'CheckSum':
        '206',
        'MsgSeqNum':
        '2',
        'MsgType':
        'i',
        'NoQuoteSets': [{
            'NoQuoteEntries': [{
                'BidSize': '1000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '900000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '0'
            }, {
                'BidSize': '7000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '800000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '1'
            }],
            'QuoteSetID':
            '123'
        }, {
            'NoQuoteEntries': [{
                'BidSize': '1000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '900000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '2'
            }, {
                'BidSize': '7000000',
                'BidSpotRate': '1.4363',
                'OfferSize': '800000',
                'OfferSpotRate': '1.4365',
                'QuoteEntryID': '3'
            }],
            'QuoteSetID':
            '234'
        }],
        'QuoteID':
        '1',
        'SenderCompID':
        'PXMD',
        'SendingTime':
        '20140922-14:48:49.825',
        'Signature':
        'TestSignature',
        'TargetCompID':
        'Q037'
    }

    data = {'NoQuoteSets': expected.pop('NoQuoteSets')}
    data['SendingTime'] = expected.pop('SendingTime')
    data['Signature'] = expected.pop('Signature')

    m = FIX.FIX42.MassQuote(**expected)
    m.initialize(**data)

    for field in m._all.itervalues():
        if field.required:
            assert field.name in m
            assert m.get(field).value, field.name + ' not initialized'

    # don't assert repr/str, as intialize order will be different
    # also, we can't achieve 100% code coverage with this test as we'd need
    # to supply optional=True
    expected.update(data)
    assert parse_message(str(m)) == expected, pprint(parse_message(str(m)))

    m = FIX.FIX42.Logon()
    m.initialize(HeartBtInt=60, optional=True)

    for field in m.header._all:
        if field in (
                'BeginString',
                'BodyLength',
                'SenderCompID',
                'TargetCompID',
                'MsgSeqNum',
        ):
            continue
        assert field in m.header._initialized

    for field in m._all:
        assert field in m._initialized

    for field in m.trailer._all:
        if field == 'CheckSum':
            continue
        assert field in m.trailer._initialized

    assert m.get(FIX.FIX42.Logon.HeartBtInt).value == 60
コード例 #4
0
ファイル: test_phixlib.py プロジェクト: nagyist/phixlib
def test_initialize():

    m = FIX.FIX42.NewOrderSingle()
    m.initialize()

    for field in m._all.itervalues():
        if field.required:
            assert field in m
            assert m.get(field).value, field.name + " not initialized"

    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "312",
        "CheckSum": "206",
        "MsgSeqNum": "2",
        "MsgType": "i",
        "NoQuoteSets": [
            {
                "NoQuoteEntries": [
                    {
                        "BidSize": "1000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "900000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "0",
                    },
                    {
                        "BidSize": "7000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "800000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "1",
                    },
                ],
                "QuoteSetID": "123",
            },
            {
                "NoQuoteEntries": [
                    {
                        "BidSize": "1000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "900000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "2",
                    },
                    {
                        "BidSize": "7000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "800000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "3",
                    },
                ],
                "QuoteSetID": "234",
            },
        ],
        "QuoteID": "1",
        "SenderCompID": "PXMD",
        "SendingTime": "20140922-14:48:49.825",
        "Signature": "TestSignature",
        "TargetCompID": "Q037",
    }

    data = {"NoQuoteSets": expected.pop("NoQuoteSets")}
    data["SendingTime"] = expected.pop("SendingTime")
    data["Signature"] = expected.pop("Signature")

    m = FIX.FIX42.MassQuote(**expected)
    m.initialize(**data)

    for field in m._all.itervalues():
        if field.required:
            assert field.name in m
            assert m.get(field).value, field.name + " not initialized"

    # don't assert repr/str, as intialize order will be different
    # also, we can't achieve 100% code coverage with this test as we'd need
    # to supply optional=True
    expected.update(data)
    assert parse_message(str(m)) == expected, pprint(parse_message(str(m)))

    m = FIX.FIX42.Logon()
    m.initialize(HeartBtInt=60, optional=True)

    for field in m.header._all:
        if field in ("BeginString", "BodyLength", "SenderCompID", "TargetCompID", "MsgSeqNum"):
            continue
        assert field in m.header._initialized

    for field in m._all:
        assert field in m._initialized

    for field in m.trailer._all:
        if field == "CheckSum":
            continue
        assert field in m.trailer._initialized

    assert m.get(FIX.FIX42.Logon.HeartBtInt).value == 60
コード例 #5
0
ファイル: test_phixlib.py プロジェクト: nagyist/phixlib
def test_malformed():

    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "156",
        "CheckSum": "228",
        "MsgSeqNum": "2",
        "MsgType": "J",
        "NoAllocs": [
            {"AllocAccount": "Marcin", "AllocShares": "10", "NoMiscFees": [{"MiscFeeAmt": "7.99"}]},
            {"AllocAccount": "Jason", "AllocShares": "5"},
        ],
        "NoOrders": [
            {"ClOrdID": "C11111", "OrderID": "O11111"},
            {"ClOrdID": "C22222", "OrderID": "O22222"},
            {"OrderID": "O33333"},
        ],
        "SenderCompID": "PXMD",
        "SendingTime": "20140922-14:48:49.825",
        "TargetCompID": "Q037",
    }

    _expected = expected.copy()

    # this one is good

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |||||

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|||||79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |a|a|a|a|

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|a|a|a|a|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |=|

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|=|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |==|=|

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|==|=|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |22|=|

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|22|=|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |=asdf|

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|=asdf|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |A=A| (not a digit)

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|A=A|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # ||

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|22||79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # |9001=12345|

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|9001=12345|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|"""
    expected["Field9001"] = "12345"
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))
    del expected["Field9001"]

    # note, we still don't have a test where the group breaks by a rogue tag mid-group
    # is that something necessary? at that point, it's pretty badly broken.

    # Bad BeginString 8=FIX.

    formatted = """8=FIX.|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|"""
    original = expected.pop("BeginString")
    assert parse_message(formatted) == dict(expected, BeginString="FIX."), pprint(parse_message(formatted))

    # put BeginString back
    expected["BeginString"] = original

    # note, we chop off the CheckSum here because we're gonna mess it up badly
    formatted = """8=FIX.4.2|9=156|35=X|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|"""
    checksum = expected.pop("CheckSum")

    # update MsgType
    expected["MsgType"] = "X"

    assert parse_message(formatted) != expected, pprint(parse_message(formatted))
    assert parse_message(formatted, cls=FIX.FIX42.Allocation) == expected, pprint(parse_message(formatted))

    # put those fields back to how they were

    expected["MsgType"] = "J"
    expected["CheckSum"] = checksum

    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "74",
        "CheckSum": "213",
        "EncryptMethod": "1",
        "HeartBtInt": "3503",
        "MsgType": "A",
        "RawData": "AAAAAAAAAAAAAAAA\001AAA",
        "RawDataLength": "20",
        "SendingTime": "20150407-04:12:54.885",
    }

    # we're messing with Logon RawData and RawDataLength, disparity between purpoted length and data
    # behavior should observe the length field, and ignore bytes unaccounted for

    # RawDataLength < len(RawData)

    expected["RawDataLength"] = "17"

    formatted = (
        "8=FIX.4.2\0019=74\00135=A\00152=20150407-04:12:54.885\00198=1\001108=3503\00195=%s\00196=AAAAAAAAAAAAAAAA\001AAA\00110=213\001"
        % (expected["RawDataLength"],)
    )
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    # RawDataLength > len(RawData)
    # We lose CheckSum tag to RawData

    expected["RawDataLength"] = "23"  # TODO should we not expect to handle overlylong values here?
    expected["RawData"] = "AAAAAAAAAAAAAAAA\001AAA\00110=213"
    expected.pop("CheckSum")

    formatted = (
        "8=FIX.4.2\0019=74\00135=A\00152=20150407-04:12:54.885\00198=1\001108=3503\00195=%s\00196=AAAAAAAAAAAAAAAA\001AAA\00110=213\001"
        % (expected["RawDataLength"],)
    )
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))
コード例 #6
0
ファイル: test_phixlib.py プロジェクト: nagyist/phixlib
def test_parser():
    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "295",
        "CheckSum": "215",
        "MsgSeqNum": "2",
        "MsgType": "i",
        "NoQuoteSets": [
            {
                "NoQuoteEntries": [
                    {
                        "BidSize": "1000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "900000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "0",
                    },
                    {
                        "BidSize": "7000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "800000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "1",
                    },
                ],
                "QuoteSetID": "123",
            },
            {
                "NoQuoteEntries": [
                    {
                        "BidSize": "1000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "900000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "2",
                    },
                    {
                        "BidSize": "7000000",
                        "BidSpotRate": "1.4363",
                        "OfferSize": "800000",
                        "OfferSpotRate": "1.4365",
                        "QuoteEntryID": "3",
                    },
                ],
                "QuoteSetID": "234",
            },
        ],
        "QuoteID": "1",
        "SenderCompID": "PXMD",
        "SendingTime": "20140922-14:48:49.825",
        "TargetCompID": "Q037",
    }

    formatted = """8=FIX.4.2|9=295|35=i|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|117=1|296=2|302=123|295=2|299=0|134=1000000|135=900000|188=1.4363|190=1.4365|299=1|134=7000000|135=800000|188=1.4363|190=1.4365|302=234|295=2|299=2|134=1000000|135=900000|188=1.4363|190=1.4365|299=3|134=7000000|135=800000|188=1.4363|190=1.4365|10=215|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    message = FIX.FIX42.MassQuote(**expected)
    assert repr(message) == formatted

    message = FIX.FIXMessage(**expected)
    assert repr(message) == formatted

    fromstring = FIX.FIX42.MassQuote.fromstring(formatted)
    assert repr(fromstring) == formatted

    fromstring = FIX.FIXMessage.fromstring(formatted)
    assert repr(fromstring) == formatted

    # since this is going to mess up the CheckSum and change the MsgType
    # field as rendered in the formatted string, let's account for that

    fromstring = FIX.FIX42.MassQuote.fromstring(formatted, MsgType="A")
    assert repr(fromstring)[:-4] == formatted.replace("35=i", "35=A")[:-4]
    assert isinstance(fromstring, FIX.FIX42.MassQuote)
    assert not isinstance(fromstring, FIX.FIX42.Logon)

    fromstring = FIX.FIXMessage.fromstring(formatted, MsgType="A")
    # assert repr(fromstring)[:-4] == formatted.replace('35=i', '35=A')[:-4]
    assert isinstance(fromstring, FIX.FIX42.Logon)

    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "156",
        "CheckSum": "228",
        "MsgSeqNum": "2",
        "MsgType": "J",
        "NoAllocs": [
            {"AllocAccount": "Marcin", "AllocShares": "10", "NoMiscFees": [{"MiscFeeAmt": "7.99"}]},
            {"AllocAccount": "Jason", "AllocShares": "5"},
        ],
        "NoOrders": [
            {"ClOrdID": "C11111", "OrderID": "O11111"},
            {"ClOrdID": "C22222", "OrderID": "O22222"},
            {"OrderID": "O33333"},
        ],
        "SenderCompID": "PXMD",
        "SendingTime": "20140922-14:48:49.825",
        "TargetCompID": "Q037",
    }

    formatted = """8=FIX.4.2|9=156|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=3|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|78=2|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|10=228|"""
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    message = FIX.FIX42.Allocation(**expected)
    assert repr(message) == formatted

    message = FIX.FIXMessage(**expected)
    assert repr(message) == formatted

    fromstring = FIX.FIX42.Allocation.fromstring(formatted)
    assert repr(fromstring) == formatted

    fromstring = FIX.FIXMessage.fromstring(formatted)
    assert repr(fromstring) == formatted

    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "182",
        "CheckSum": "005",
        "MsgSeqNum": "2",
        "MsgType": "J",
        "NoAllocs": [
            {"AllocAccount": "Marcin", "AllocShares": "10", "NoMiscFees": [{"MiscFeeAmt": "7.99"}]},
            {"AllocAccount": "Jason", "AllocShares": "5"},
            {"AllocShares": "10"},
            {"AllocAccount": "Tester"},
        ],
        "NoOrders": [
            {"ClOrdID": "C11111", "OrderID": "O11111"},
            {"ClOrdID": "C22222", "OrderID": "O22222"},
            {"OrderID": "O33333"},
            {"ClOrdID": "O44444"},
        ],
        "SenderCompID": "PXMD",
        "SendingTime": "20140922-14:48:49.825",
        "TargetCompID": "Q037",
    }

    formatted = "8=FIX.4.2|9=182|35=J|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=4|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|11=O44444|78=4|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|80=10|79=Tester|10=005|"
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    message = FIX.FIX42.Allocation(**expected)
    assert repr(message) == formatted

    message = FIX.FIXMessage(**expected)
    assert repr(message) == formatted

    fromstring = FIX.FIX42.Allocation.fromstring(formatted)
    assert repr(fromstring) == formatted

    fromstring = FIX.FIXMessage.fromstring(formatted)
    assert repr(fromstring) == formatted

    # FIX.register_version('phixlib/spec/FIX50SP2.xml')
    # fromstring = FIX.FIX50.AllocationInstruction.fromstring(formatted, BeginString='FIX.5.0')
    # assert repr(fromstring)[9:-7] == formatted[9:-7]
    # print repr(fromstring)

    """
    expected = {
         'BeginString': 'FIX.4.2',
         'BodyLength': '197',
         'CheckSum': '225',
         'MsgSeqNum': '2',
         'MsgType': 'BBBBBBBBBBBBBBBB',
         'NoAllocs': [{'AllocAccount': 'Marcin',
                       'AllocShares': '10',
                       'NoMiscFees': [{'MiscFeeAmt': '7.99'}]},
                      {'AllocAccount': 'Jason', 'AllocShares': '5'},
                      {'AllocShares': '10'},
                      {'AllocAccount': 'Tester'},
                      ],
         'NoOrders': [{'ClOrdID': 'C11111', 'OrderID': 'O11111'},
                      {'ClOrdID': 'C22222', 'OrderID': 'O22222'},
                      {'OrderID': 'O33333'},
                      {'ClOrdID': 'O44444'}],
         'SenderCompID': 'PXMD',
         'SendingTime': '20140922-14:48:49.825',
         'TargetCompID': 'Q037'}

    message.header._initialized['MsgType'].value = 'BBBBBBBBBBBBBBBB'
    formatted = '8=FIX.4.2|9=197|35=BBBBBBBBBBBBBBBB|49=PXMD|56=Q037|34=2|52=20140922-14:48:49.825|73=4|11=C11111|37=O11111|11=C22222|37=O22222|37=O33333|11=O44444|78=4|79=Marcin|80=10|136=1|137=7.99|79=Jason|80=5|80=10|79=Tester|10=225|'
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))
    """

    expected = {
        "BeginString": "FIX.4.2",
        "BodyLength": "74",
        "CheckSum": "213",
        "EncryptMethod": "1",
        "HeartBtInt": "3503",
        "MsgType": "A",
        "RawData": "AAAAAAAAAAAAAAAA\001AAA",
        "RawDataLength": "20",
        "SendingTime": "20150407-04:12:54.885",
    }

    formatted = "8=FIX.4.2\0019=74\00135=A\00152=20150407-04:12:54.885\00198=1\001108=3503\00195=20\00196=AAAAAAAAAAAAAAAA\001AAA\00110=213\001"
    assert parse_message(formatted) == expected, pprint(parse_message(formatted))

    fromstring = FIX.FIX42.Logon.fromstring(formatted)
    assert str(fromstring) == formatted