defcon-fixparser
Version:
FIX 5.0SP2 Parser
805 lines (685 loc) • 37.4 kB
JavaScript
import { testMessages } from './test-messages';
import FIXParser from '../src/FIXParser';
import { ContraTradeTime, MsgSeqNum } from '../src/constants/ConstantsField';
describe('FIXParser', () => {
const fixParser = new FIXParser();
describe('#parse: constructor validation', () => {
it('should return null when having no arguments', () => {
expect(fixParser.parse()).toEqual([]);
});
});
describe('#parse: unknown SOH "/"', () => {
it('should parse the message, SOH "/"', () => {
expect(
fixParser.parse(
'8=FIX.4.2/9=106/35=A/34=1/49=U1par/50=U1fix/52=20090206-21:13:36.887/56=FixServer/98=0/108=30/141=Y/553=U1fix/554=hotspot/10=061/',
)[0].data.length,
).toEqual(14);
});
});
describe('#parse: invalid message', () => {
it('should return null when having incorrect message', () => {
expect(fixParser.parse('aabbccddeeffgghhii').length).toEqual(0);
});
});
describe('#parse: SDBK Price Correction of Previous Execution', () => {
let messages = fixParser.parse(
'8=FIX.4.2^A 9=440^A 35=8^A 128=LZJ^A 34=549^A 49=CCG^A 56=LEH_LZJ02^A 52=20100302- 22:36:15^A 55=IOC^A 37=NF 0039/03022010^A 11=NF 0039/03022010^A 17=NF 0039/03022010 001001002^A 20=2^A 39=2^A 150=2^A 54=1^A 38=100^A 40=1^A 59=0^A 31=49.3700^A 32=100^A 14=0^A 6=0^A 151=0^A 60=20100302-22:36:16^A 58=Trade correction^A 19=NF 0039/03022010 001001001^A 1=ABC123ZYX^A 30=N^A 207=N^A 47=A^A 9430=NX^A 9483=000010^A 9578=1^A 9425=5^A 9579=0000100002^A 9704=0000100001^A 382=1^A 375=TOD^A 337=0000^A 437=100^A 438=1736^A 29=1^A 63=0^A 9440=001001002^A 10=235^A ',
),
index = 0;
afterAll(() => {
messages = null;
index = 0;
});
it('should have parsed the FIX message', () => {
expect(messages.length).toEqual(1);
});
it('should have BeginString value FIX.4.2', () => {
expect(messages[0].data[index].tag).toBe(8);
expect(messages[0].data[index].value).toBe('FIX.4.2');
index++;
});
it('should have BodyLength value 440 (validated)', () => {
expect(messages[0].data[index].tag).toBe(9);
expect(messages[0].data[index].value).toBe(440);
expect(messages[0].bodyLengthValid).toBeTruthy();
index++;
});
it('should have MsgType value 8', () => {
expect(messages[0].data[index].tag).toBe(35);
expect(messages[0].data[index].value).toBe('8');
index++;
});
it('should have DeliverToCompID value LZJ', () => {
expect(messages[0].data[index].tag).toBe(128);
expect(messages[0].data[index].value).toBe('LZJ');
index++;
});
it('should have MsgSeqNum value LZJ', () => {
expect(messages[0].data[index].tag).toBe(34);
expect(messages[0].data[index].value).toBe(549);
index++;
});
it('should have SenderCompID value CCG', () => {
expect(messages[0].data[index].tag).toBe(49);
expect(messages[0].data[index].value).toBe('CCG');
index++;
});
it('should have TargetCompID value LEH_LZJ02', () => {
expect(messages[0].data[index].tag).toBe(56);
expect(messages[0].data[index].value).toBe('LEH_LZJ02');
index++;
});
it('should have SendingTime value 20100302- 22:36:15', () => {
expect(messages[0].data[index].tag).toBe(52);
expect(messages[0].data[index].value).toBe('20100302- 22:36:15');
index++;
});
it('should have Symbol value IOC', () => {
expect(messages[0].data[index].tag).toBe(55);
expect(messages[0].data[index].value).toBe('IOC');
index++;
});
it('should have OrderID value NF 0039/03022010', () => {
expect(messages[0].data[index].tag).toBe(37);
expect(messages[0].data[index].value).toBe('NF 0039/03022010');
index++;
});
it('should have ClOrdID value NF 0039/03022010', () => {
expect(messages[0].data[index].tag).toBe(11);
expect(messages[0].data[index].value).toBe('NF 0039/03022010');
index++;
});
it('should have ExecID value NF 0039/03022010 001001002', () => {
expect(messages[0].data[index].tag).toBe(17);
expect(messages[0].data[index].value).toBe(
'NF 0039/03022010 001001002',
);
index++;
});
it('should have ExecTransType value 2 (Correct)', () => {
expect(messages[0].data[index].tag).toBe(20);
expect(messages[0].data[index].value).toBe('2');
index++;
});
it('should have OrdStatus value 2', () => {
expect(messages[0].data[index].tag).toBe(39);
expect(messages[0].data[index].value).toBe('2');
index++;
});
it('should have ExecType value 2', () => {
expect(messages[0].data[index].tag).toBe(150);
expect(messages[0].data[index].value).toBe('2');
index++;
});
it('should have Side value 1', () => {
expect(messages[0].data[index].tag).toBe(54);
expect(messages[0].data[index].value).toBe('1');
index++;
});
it('should have OrderQty value 100', () => {
expect(messages[0].data[index].tag).toBe(38);
expect(messages[0].data[index].value).toBe(100);
expect(messages[0].data[index].value).toBe(100);
index++;
});
it('should have OrdType value 1', () => {
expect(messages[0].data[index].tag).toBe(40);
expect(messages[0].data[index].value).toBe('1');
index++;
});
it('should have TimeInForce value 0', () => {
expect(messages[0].data[index].tag).toBe(59);
expect(messages[0].data[index].value).toBe('0');
index++;
});
it('should have LastPx value 49.3700', () => {
expect(messages[0].data[index].tag).toBe(31);
expect(messages[0].data[index].value).toBe(49.37);
index++;
});
it('should have LastQty value 100', () => {
expect(messages[0].data[index].tag).toBe(32);
expect(messages[0].data[index].value).toBe(100);
index++;
});
it('should have CumQty value 0', () => {
expect(messages[0].data[index].tag).toBe(14);
expect(messages[0].data[index].value).toBe(0);
index++;
});
it('should have AvgPx value 0', () => {
expect(messages[0].data[index].tag).toBe(6);
expect(messages[0].data[index].value).toBe(0.0);
index++;
});
it('should have LeavesQty value 0', () => {
expect(messages[0].data[index].tag).toBe(151);
expect(messages[0].data[index].value).toBe(0);
index++;
});
it('should have TransactTime value 20100302-22:36:16', () => {
expect(messages[0].data[index].tag).toBe(60);
expect(messages[0].data[index].value).toBe('20100302-22:36:16');
index++;
});
it('should have Text value Trade correction', () => {
expect(messages[0].data[index].tag).toBe(58);
expect(messages[0].data[index].value).toBe('Trade correction');
index++;
});
it('should have ExecRefID value NF 0039/03022010 001001001', () => {
expect(messages[0].data[index].tag).toBe(19);
expect(messages[0].data[index].value).toBe(
'NF 0039/03022010 001001001',
);
index++;
});
it('should have Account value ABC123ZYX', () => {
expect(messages[0].data[index].tag).toBe(1);
expect(messages[0].data[index].value).toBe('ABC123ZYX');
index++;
});
it('should have LastMkt value N', () => {
expect(messages[0].data[index].tag).toBe(30);
expect(messages[0].data[index].value).toBe('N');
index++;
});
it('should have SecurityExchange value N', () => {
expect(messages[0].data[index].tag).toBe(207);
expect(messages[0].data[index].value).toBe('N');
index++;
});
it('should have Rule80A value A', () => {
expect(messages[0].data[index].tag).toBe(47);
expect(messages[0].data[index].value).toBe('A');
index++;
});
it('NySE extensions: should have NYSEDirect value NX', () => {
expect(messages[0].data[index].tag).toBe(9430);
expect(messages[0].data[index].value).toBe('NX');
index++;
});
it('NySE extensions: should have DBExecID value 000010', () => {
expect(messages[0].data[index].tag).toBe(9483);
expect(messages[0].data[index].value).toBe('000010');
index++;
});
it('NySE extensions: should have BillingIndicator value 1', () => {
expect(messages[0].data[index].tag).toBe(9578);
expect(messages[0].data[index].value).toBe('1');
index++;
});
it('NySE extensions: should have StatusResp value 5', () => {
expect(messages[0].data[index].tag).toBe(9425);
expect(messages[0].data[index].value).toBe('5');
index++;
});
it('NySE extensions: should have ExpERCReferenceNumber value 0000100002', () => {
expect(messages[0].data[index].tag).toBe(9579);
expect(messages[0].data[index].value).toBe('0000100002');
index++;
});
it('NySE extensions: should have PrevExpERCReferenceNumber value 0000100001', () => {
expect(messages[0].data[index].tag).toBe(9704);
expect(messages[0].data[index].value).toBe('0000100001');
index++;
});
it('should have NoContraBrokers value 1', () => {
expect(messages[0].data[index].tag).toBe(382);
expect(messages[0].data[index].value).toBe(1);
index++;
});
it('should have ContraBroker value TOD', () => {
expect(messages[0].data[index].tag).toBe(375);
expect(messages[0].data[index].value).toBe('TOD');
index++;
});
it('should have ContraTrader value 0000', () => {
expect(messages[0].data[index].tag).toBe(337);
expect(messages[0].data[index].value).toBe('0000');
index++;
});
it('should have ContraTradeQty value 100', () => {
expect(messages[0].data[index].tag).toBe(437);
expect(messages[0].data[index].value).toBe(100);
index++;
});
it('should have ContraTradeTime value 1736', () => {
expect(messages[0].data[index].tag).toBe(438);
expect(messages[0].data[index].value).toBe('1736');
index++;
});
it('should have LastCapacity value 1', () => {
expect(messages[0].data[index].tag).toBe(29);
expect(messages[0].data[index].value).toBe('1');
index++;
});
it('should have SettlType value 0', () => {
expect(messages[0].data[index].tag).toBe(63);
expect(messages[0].data[index].value).toBe('0');
index++;
});
it('NySE extensions: should have ERCReferenceNumber value 001001002', () => {
expect(messages[0].data[index].tag).toBe(9440);
expect(messages[0].data[index].value).toBe('001001002');
index++;
});
it('should have invalid CheckSum value 235', () => {
expect(messages[0].data[index].tag).toBe(10);
expect(messages[0].data[index].value).toBe('235');
expect(messages[0].checksumValid).toBe(false);
index++;
});
it('should get the correct field', () => {
expect(messages[0].getField(ContraTradeTime).tag).toBe(438);
expect(messages[0].getField(ContraTradeTime).value).toBe('1736');
});
});
describe('#parse: New order', () => {
let messages = fixParser.parse(
'8=FIX.4.2|9=154|35=E|49=INST|56=BROK|52=20050908-15:51:22|34=200|66=14|394=1|68=2|73=2|11=order- 1|67=1|55=IBM|54=2|38=2000|40=1|11=order-2|67=2|55=AOL|54=2|38=1000|40=1|',
),
index = 0;
afterAll(() => {
messages = null;
index = 0;
});
it('should have parsed the FIX message', () => {
expect(messages).toBeTruthy();
});
it('should have BeginString value FIX.4.2', () => {
expect(messages[0].data[index].tag).toBe(8);
expect(messages[0].data[index].value).toBe('FIX.4.2');
index++;
});
it('should have BodyLength value 154 (validated)', () => {
expect(messages[0].data[index].tag).toBe(9);
expect(messages[0].data[index].value).toBe(154);
expect(messages[0].bodyLengthValid).toBe(true);
index++;
});
it('should have MsgType value E', () => {
expect(messages[0].data[index].tag).toBe(35);
expect(messages[0].data[index].value).toBe('E');
index++;
});
it('should have SenderCompID value INST', () => {
expect(messages[0].data[index].tag).toBe(49);
expect(messages[0].data[index].value).toBe('INST');
index++;
});
it('should have MsgSeqNum value BROK', () => {
expect(messages[0].data[index].tag).toBe(56);
expect(messages[0].data[index].value).toBe('BROK');
index++;
});
it('should have SendingTime value 20050908-15:51:22', () => {
expect(messages[0].data[index].tag).toBe(52);
expect(messages[0].data[index].value).toBe('20050908-15:51:22');
index++;
});
it('should have MsgSeqNum value 200', () => {
expect(messages[0].data[index].tag).toBe(34);
expect(messages[0].data[index].value).toBe(200);
index++;
});
it('should have ListID value 14', () => {
expect(messages[0].data[index].tag).toBe(66);
expect(messages[0].data[index].value).toBe('14');
index++;
});
it('should have BidType value 1', () => {
expect(messages[0].data[index].tag).toBe(394);
expect(messages[0].data[index].value).toBe(1);
index++;
});
it('should have TotNoOrders value 2', () => {
expect(messages[0].data[index].tag).toBe(68);
expect(messages[0].data[index].value).toBe(2);
index++;
});
it('should have NoOrders value 2', () => {
expect(messages[0].data[index].tag).toBe(73);
expect(messages[0].data[index].value).toBe(2);
index++;
});
it('should have ClOrdID value order- 1', () => {
expect(messages[0].data[index].tag).toBe(11);
expect(messages[0].data[index].value).toBe('order- 1');
index++;
});
it('should have ListSeqNo value 1', () => {
expect(messages[0].data[index].tag).toBe(67);
expect(messages[0].data[index].value).toBe(1);
index++;
});
it('should have Symbol value IBM', () => {
expect(messages[0].data[index].tag).toBe(55);
expect(messages[0].data[index].value).toBe('IBM');
index++;
});
it('should have Side value 2', () => {
expect(messages[0].data[index].tag).toBe(54);
expect(messages[0].data[index].value).toBe('2');
index++;
});
it('should have OrderQty value 2000', () => {
expect(messages[0].data[index].tag).toBe(38);
expect(messages[0].data[index].value).toBe(2000);
index++;
});
it('should have OrdType value 1', () => {
expect(messages[0].data[index].tag).toBe(40);
expect(messages[0].data[index].value).toBe('1');
index++;
});
it('should have ClOrdID value order-2', () => {
expect(messages[0].data[index].tag).toBe(11);
expect(messages[0].data[index].value).toBe('order-2');
index++;
});
it('should have ListSeqNo value 2', () => {
expect(messages[0].data[index].tag).toBe(67);
expect(messages[0].data[index].value).toBe(2);
index++;
});
it('should have Symbol value AOL', () => {
expect(messages[0].data[index].tag).toBe(55);
expect(messages[0].data[index].value).toBe('AOL');
index++;
});
it('should have Side value 2', () => {
expect(messages[0].data[index].tag).toBe(54);
expect(messages[0].data[index].value).toBe('2');
index++;
});
it('should have OrderQty value 1000', () => {
expect(messages[0].data[index].tag).toBe(38);
expect(messages[0].data[index].value).toBe(1000);
index++;
});
it('should have OrdType value 1', () => {
expect(messages[0].data[index].tag).toBe(40);
expect(messages[0].data[index].value).toBe('1');
index++;
});
});
describe('#parse: ExecutionReport', () => {
let messages = fixParser.parse(
'8=FIX.4.4\x019=1753\x0135=8\x01523=S|E|B Auto-pricing\x01',
),
index = 0;
afterAll(() => {
messages = null;
index = 0;
});
it('should have parsed the FIX message', () => {
expect(messages.length).toEqual(1);
});
it('should have BeginString value FIX.4.4', () => {
expect(messages[0].data[index].tag).toBe(8);
expect(messages[0].data[index].value).toBe('FIX.4.4');
index++;
});
it('should have BodyLength value 1753 (validated)', () => {
expect(messages[0].data[index].tag).toBe(9);
expect(messages[0].data[index].value).toBe(1753);
expect(messages[0].bodyLengthValid).toBeFalsy();
index++;
});
it('should have MsgType value 8', () => {
expect(messages[0].data[index].tag).toBe(35);
expect(messages[0].data[index].value).toBe('8');
index++;
});
it('should have PartySubID value 8', () => {
expect(messages[0].data[index].tag).toBe(523);
expect(messages[0].data[index].value).toBe('S|E|B Auto-pricing');
index++;
});
});
describe('#getBriefDescription', () => {
describe('should generate a brief description', () => {
let messages = null;
afterAll(() => {
messages = null;
});
afterEach(() => {
messages = null;
});
it('New Order Single', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=145\x0135=D\x0134=4\x0149=ABC_DEFG01\x0152=20090323-15:40:29\x0156=CCG\x01115=XYZ\x0111=NF 0542/03232009\x0154=1\x0138=100\x0155=CVS\x0140=1\x0159=0\x0147=A\x0160=20090323-15:40:29\x0121=1\x01207=N\x0110=139\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 100 CVS MKT DAY',
);
});
it('CBS Direct-To-Handheld New Order Single', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=154\x0135=D\x0134=57\x0149=ABC_DEFG04\x0152=20090402-18:15:40\x0156=CCG\x01115=XYZ\x01143=100\x0111=NF 0646/04022009\x0154=1\x0138=100\x0155=PAC\x0140=1\x0159=0\x0147=A\x0160=20090402-18:15:40\x0121=1\x01207=N\x0110=013\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 100 PAC MKT DAY',
);
});
it('BBSS Execution', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=451\x0135=8\x01128=XYZ\x0134=52\x0149=CCG\x0156=ABC_DEFG04\x0152=20090402- 18:13:13\x0155=PAC\x0137=NF 0645/04022009\x0111=NF 0645/04022009\x0117=NF 0645/04022009 001001001\x0120=0\x0139=2\x01150=2\x0154=1\x0138=1000\x0140=1\x0159=0\x0131=17.00\x0132=1000\x0114=0\x016=0\x01151=0\x0160=20090402-18:13:11\x0158=Fill\x0176=0123\x019433=0123\x0147=A\x019579=0000100001\x019440=001001001\x01382=1\x01375=SB\x01337=0234\x01437=1000\x01438=1413\x0163=0\x0129=1\x01207=N\x0130=N\x0110=116\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'1000 @17.00 LvsQty 0',
);
});
it('BBSS Trade Bust of Previous Execution', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=397\x0135=8\x01128=XYZ\x0134=70\x0149=CCG\x0156=ABC_DEFG04\x0152=20090402- 18:20:41\x0155=PAC\x0137=NF 0644/04022009\x0111=NF 0644/04022009\x0117=NF 0644/04022009 001001003\x0120=1\x0139=1\x01150=1\x0154=1\x0138=100\x0140=1\x0159=0\x0131=16.77\x0132=100\x0114=0\x016=0\x01151=100\x0160=20090402-18:20:40\x019579=0000100003\x019440=001001003\x01382=1\x01375=BARC\x01337=0000\x01437=100\x01438=1420\x0176=8080\x019433=8080\x0119=NF 0644/04022009 001001002\x019704=0000100002\x019425=1\x0147=A\x0163=0\x0129=1\x01207=N\x0130=N\x0110=004\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'100 @16.77 LvsQty 100',
);
});
it('Cancel Replace (changing quantity) of previously reduced order', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=197\x0135=G\x0134=131\x0149=ABC_DEFG01\x0152=20090325-15:20:32\x0156=CCG\x01115=XYZ\x0111=NF 0578/03252009\x0137=NF 0576/03252009\x0141=NF 0576/03252009\x0154=1\x0138=2000\x0155=CVS\x0140=2\x0144=25.47\x0159=0\x0147=A\x0160=20090325-15:20:32\x0121=1\x01207=N\x0110=172\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 2000 CVS LMT @25.47 DAY',
);
});
it('Closing Offset (New Order Single)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=156\x0135=D\x0134=124\x0149=ABC_DEFG04\x0152=20100208-18:51:42\x0156=CCG\x01115=XYZ\x0111=NF 0015/02082010\x0154=2\x0138=1000\x0155=RRC\x0140=2\x0144=55.36\x0159=0\x011=ABC123ZYX\x0121=1\x01207=N\x0147=A\x019487=CO\x0110=050\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'SL 1000 RRC LMT @55.36 DAY',
);
});
it('MatchPoint (New Order Single)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=153\x0135=D\x0134=11\x0149=ABC_DEFG04\x0152=20091216-17:23:52\x0156=CCG\x0157=ARCA\x01115=XYZ\x01128=MP\x0111=NF 0921/12162009\x0154=2\x0138=1000\x0155=MMM\x0140=1\x0159=0\x011=ABC123ZYX\x0121=1\x01207=N\x0147=A\x0110=172\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'SL 1000 MMM MKT DAY',
);
});
it('Sub-Penny (New Order Single)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=147\x0135=D\x0134=215\x0149=ABC_DEFG04\x0152=20100208-19:36:45\x0156=CCG\x01115=XYZ\x0111=NF 0016/02082010\x0154=1\x0138=1000\x0155=VOD\x0140=2\x0144=.995\x0159=0\x011=ABC123ZYX\x0121=1\x01207=N\x0147=A\x0110=100\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 1000 VOD LMT @.995 DAY',
);
});
it('Dot Reserve Order Type (Max Floor)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=154\x0135=D\x0134=578\x0149=LEH_LZJ02\x0152=20100302-22:50:34\x0156=CCG\x01115=LZJ\x0111=NF 0040/03022010\x0154=1\x0138=1000\x0155=IOC\x0140=2\x0144=49.38\x0159=0\x011=ABC123ZYX\x0121=1\x01207=N\x0147=A\x01111=0\x0110=121\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 1000 IOC LMT @49.38 DAY',
);
});
it('BBSS Max Quantity Order (99,999,900 shares)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=162\x0135=D\x0134=3\x0149=LEH_LZJ02\x0152=20100303-15:17:05\x0156=CCG\x0157=4\x01115=LZJ\x01143=ER\x0111=NF 0041/03032010\x0154=1\x0138=99999900\x0155=MMM\x0140=2\x0144=50.00\x0159=0\x011=ABC123ZYX\x0121=1\x01207=N\x0147=A\x0110=069\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 99999900 MMM LMT @50.00 DAY',
);
});
it('Symbol with a Suffix', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=150\x0135=D\x0134=13\x0149=LEH_LZJ02\x0152=20100303-15:21:52\x0156=CCG\x01115=LZJ\x0111=NF 0043/03032010\x0154=1\x0138=100\x0155=ADM\x0165=PRA\x0140=2\x0144=25\x0159=0\x011=ABC123ZYX\x0121=1\x01207=N\x0147=A\x0110=237\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 100 ADM LMT @25.00 DAY',
);
});
it('Partial Fill Followed by Full Fill', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=389\x0135=8\x01128=XYZ\x0134=27\x0149=CCG\x0156=ABC_DEFG01\x0152=20090325- 14:28:10\x0155=CVS\x0137=NF 0568/03252009\x0111=NF 0568/03252009\x0117=NF 0568/03252009 001001001\x0120=0\x0139=1\x01150=1\x0154=2\x0138=500\x0140=1\x0159=0\x0131=25.4700\x0132=100\x0114=0\x016=0\x01151=400\x0160=20090325-14:28:12\x0158=Partial Fill\x0130=N\x0176=0034\x01207=N\x0147=A\x019430=NX\x019483=000006\x019578=1\x01382=1\x01375=TOD\x01337=0000\x01437=100\x01438=1134\x019579=0000100001\x019426=1\x019433=0034\x0129=1\x0163=0\x019440=001001001\x0110=251\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'100 @25.47 LvsQty 400',
);
});
it('Execution Filling the Order', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=379\x0135=8\x01128=XYZ\x0134=28\x0149=CCG\x0156=ABC_DEFG01\x0152=20090325- 14:28:10\x0155=CVS\x0137=NF 0568/03252009\x0111=NF 0568/03252009\x0117=NF 0568/03252009 002002002\x0120=0\x0139=2\x01150=2\x0154=2\x0138=500\x0140=1\x0159=0\x0131=25.2800\x0132=400\x0114=0\x016=0\x01151=0\x0160=20090325-14:28:12\x0158=Fill\x0130=N\x0176=0034\x01207=N\x0147=A\x019430=NX\x019483=000007\x019578=1\x01382=1\x01375=TOD\x01337=0000\x01437=400\x01438=1134\x019579=0000200002\x019433=0034\x0129=1\x0163=0\x019440=002002002\x0110=186\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'400 @25.28 LvsQty 0',
);
});
it('MatchPoint (Execution Report)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=258\x0135=8\x0150=ARCA\x01128=XYZ\x0134=87\x0149=CCG\x0156=ABC_DEFG04\x0152=20091216-18:00:24\x0155=MMM\x0137=0000002\x0111=NF 0921/12162009\x0117=2000005\x0120=0\x0139=2\x01150=2\x0154=2\x0138=1000\x0140=1\x0159=0\x0131=82.245\x0132=1000\x0114=1000\x016=82.245\x01151=0\x0160=20091216-18:00:25\x0158=Fill\x01583=91XYZ\x0130=MP\x01207=N\x019426=N/MP\x019570=N/MP\x0110=088\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'1000 @82.25 LvsQty 0',
);
});
it('Sub-Penny (Execution Report)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=404\x0135=8\x01128=XYZ\x0134=216\x0149=CCG\x0156=ABC_DEFG04\x0152=20100208-19:36:45\x0155=VOD\x0137=NF 0016/02082010\x0111=NF 0016/02082010\x0117=NF 0016/02082010 001001001\x0120=0\x0139=2\x01150=2\x0154=1\x0138=1000\x0140=2\x0144=0.9950\x0159=0\x0131=0.4000\x0132=1000\x0114=0\x016=0\x01151=0\x0160=20100208-19:36:45\x0158=Fill\x011=ABC123ZYX\x0130=A\x0176=0210\x01207=A\x0147=A\x019430=NX\x019483=000004\x019578=1\x01382=1\x01375=LOC\x01337=0000\x01437=1000\x01438=1437\x019579=0000100001\x019426=1\x019433=0210\x0129=1\x0163=0\x019440=001001001\x0110=121\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'1000 @0.40 LvsQty 0',
);
});
it('New Order (order to be replaced)', () => {
messages = fixParser.parse(
'8=FIX.4.2\x019=157\x0135=D\x0134=117\x0149=ABC_DEFG01\x0152=20090325-15:14:27\x0156=CCG\x01115=XYZ\x0111=NF 0573/03252009\x0154=1\x0138=1000\x0155=CVS\x0140=2\x0144=25.47\x0159=0\x0147=A\x0160=20090325-15:14:27\x0121=1\x01207=N\x0110=210\x01',
);
expect(messages[0].getBriefDescription()).toBe(
'BUY 1000 CVS LMT @25.47 DAY',
);
});
it('Multiple messages', () => {
messages = fixParser.parse(
'8=FIX.4.1\x019=61\x0135=A\x0134=1\x0149=EXEC\x0152=20121105-23:24:06\x0156=BANZAI\x0198=0\x01108=30\x0110=003\x018=FIX.4.1\x019=61\x0135=A\x0134=1\x0149=BANZAI\x0152=20121105-23:24:06\x0156=EXEC\x0198=0\x01108=30\x0110=003\x018=FIX.4.1\x019=49\x0135=0\x0134=2\x0149=BANZAI\x0152=20121105-23:24:37\x0156=EXEC\x0110=228\x018=FIX.4.1\x019=49\x0135=0\x0134=2\x0149=EXEC\x0152=20121105-23:24:37\x0156=BANZAI\x0110=228\x018=FIX.4.1\x019=103\x0135=D\x0134=3\x0149=BANZAI\x0152=20121105-23:24:42\x0156=EXEC\x0111=1352157882577\x0121=1\x0138=10000\x0140=1\x0154=1\x0155=MSFT\x0159=0\x0110=062\x018=FIX.4.1\x019=139\x0135=8\x0134=3\x0149=EXEC\x0152=20121105-23:24:42\x0156=BANZAI\x016=0\x0111=1352157882577\x0114=0\x0117=1\x0120=0\x0131=0\x0132=0\x0137=1\x0138=10000\x0139=0\x0154=1\x0155=MSFT\x01150=2\x01151=0\x0110=059\x018=FIX.4.1\x019=153\x0135=8\x0134=4\x0149=EXEC\x0152=20121105-23:24:42\x0156=BANZAI\x016=12.3\x0111=1352157882577\x0114=10000\x0117=2\x0120=0\x0131=12.3\x0132=10000\x0137=2\x0138=10000\x0139=2\x0154=1\x0155=MSFT\x01150=2\x01151=0\x0110=230\x018=FIX.4.1\x019=103\x0135=D\x0134=4\x0149=BANZAI\x0152=20121105-23:24:55\x0156=EXEC\x0111=1352157895032\x0121=1\x0138=10000\x0140=1\x0154=1\x0155=ORCL\x0159=0\x0110=047\x018=FIX.4.1\x019=139\x0135=8\x0134=5\x0149=EXEC\x0152=20121105-23:24:55\x0156=BANZAI\x016=0\x0111=1352157895032\x0114=0\x0117=3\x0120=0\x0131=0\x0132=0\x0137=3\x0138=10000\x0139=0\x0154=1\x0155=ORCL\x01150=2\x01151=0\x0110=049\x018=FIX.4.1\x019=153\x0135=8\x0134=6\x0149=EXEC\x0152=20121105-23:24:55\x0156=BANZAI\x016=12.3\x0111=1352157895032\x0114=10000\x0117=4\x0120=0\x0131=12.3\x0132=10000\x0137=4\x0138=10000\x0139=2\x0154=1\x0155=ORCL\x01150=2\x01151=0\x0110=220\x018=FIX.4.1\x019=108\x0135=D\x0134=5\x0149=BANZAI\x0152=20121105-23:25:12\x0156=EXEC\x0111=1352157912357\x0121=1\x0138=10000\x0140=2\x0144=10\x0154=1\x0155=SPY\x0159=0\x0110=003\x018=FIX.4.1\x019=138\x0135=8\x0134=7\x0149=EXEC\x0152=20121105-23:25:12\x0156=BANZAI\x016=0\x0111=1352157912357\x0114=0\x0117=5\x0120=0\x0131=0\x0132=0\x0137=5\x0138=10000\x0139=0\x0154=1\x0155=SPY\x01150=2\x01151=0\x0110=252\x018=FIX.4.1\x019=104\x0135=F\x0134=6\x0149=BANZAI\x0152=20121105-23:25:16\x0156=EXEC\x0111=1352157916437\x0138=10000\x0141=1352157912357\x0154=1\x0155=SPY\x0110=198\x018=FIX.4.1\x019=82\x0135=3\x0134=8\x0149=EXEC\x0152=20121105-23:25:16\x0156=BANZAI\x0145=6\x0158=Unsupported message type\x0110=000\x018=FIX.4.1\x019=104\x0135=F\x0134=7\x0149=BANZAI\x0152=20121105-23:25:25\x0156=EXEC\x0111=1352157925309\x0138=10000\x0141=1352157912357\x0154=1\x0155=SPY\x0110=197\x018=FIX.4.1\x019=82\x0135=3\x0134=9\x0149=EXEC\x0152=20121105-23:25:25\x0156=BANZAI\x0145=7\x0158=Unsupported message type\x0110=002\x01',
);
expect(messages[0].getBriefDescription()).toBe('Logon');
expect(messages[1].getBriefDescription()).toBe('Logon');
expect(messages[2].getBriefDescription()).toBe('Heartbeat');
expect(messages[3].getBriefDescription()).toBe('Heartbeat');
expect(messages[4].getBriefDescription()).toBe(
'BUY 10000 MSFT MKT DAY',
);
expect(messages[5].getBriefDescription()).toBe(
'10000 @0.00 LvsQty 0',
);
expect(messages[6].getBriefDescription()).toBe(
'10000 @12.30 LvsQty 0',
);
expect(messages[7].getBriefDescription()).toBe(
'BUY 10000 ORCL MKT DAY',
);
expect(messages[8].getBriefDescription()).toBe(
'10000 @0.00 LvsQty 0',
);
expect(messages[9].getBriefDescription()).toBe(
'10000 @12.30 LvsQty 0',
);
expect(messages[10].getBriefDescription()).toBe(
'BUY 10000 SPY LMT @10.00 DAY',
);
expect(messages[11].getBriefDescription()).toBe(
'10000 @0.00 LvsQty 0',
);
expect(messages[12].getBriefDescription()).toBe(
'BUY 10000 SPY',
);
expect(messages[13].getBriefDescription()).toBe('Reject');
expect(messages[14].getBriefDescription()).toBe(
'BUY 10000 SPY',
);
expect(messages[15].getBriefDescription()).toBe('Reject');
});
});
});
describe('#getField: ExecutionReport', () => {
let messages = fixParser.parse(
'8=FIX.4.2|9=266|35=8|49=ABC|56=XYZ|50=AZ12|57=NA|34=833|52=20100130-08:00:51.992|55=GLD|48=PL11YA|167=FUT|207=LIFFE|1=AA1|37=ABC1|17=INDNTHDOG|58=Fill|200=201009|205=13|32=25|151=0|14=25|54=2|40=2|77=O|59=0|150=2|20=0|39=2|442=1|44=99.06|38=25|31=99.06|6=99.06|60=20100130-08:00:52|10=136|',
);
afterAll(() => {
messages = null;
});
it('should get the correct field', () => {
expect(messages[0].getField(MsgSeqNum).tag).toBe(34);
expect(messages[0].getField(MsgSeqNum).value).toBe(833);
});
});
function processTest(fixMessage) {
describe(`#parse: ${fixMessage.description}`, () => {
let messages = fixParser.parse(fixMessage.fix);
afterAll(() => {
messages = null;
});
it('should have parsed the FIX message', () => {
expect(messages.length).toEqual(
fixMessage.numMessages ? fixMessage.numMessages : 1,
);
expect(messages[0].data[0].name).toBe('BeginString');
expect(messages[0].data[1].name).toBe('BodyLength');
expect(messages[0].data[2].name).toBe('MsgType');
});
it(`should have MsgType ${messages[0].description}`, () => {
expect(messages[0].description).toBe(fixMessage.description);
});
it(`should have valid BodyLength: ${messages[0].bodyLengthValid}`, () => {
expect(messages[0].bodyLengthValid).toBe(
fixMessage.bodyLengthValid,
`[actual: ${messages[0].bodyLengthValue}, expected: ${messages[0].bodyLengthExpected}]`,
);
});
it(`should have valid CheckSum: ${messages[0].checksumValid}`, () => {
expect(messages[0].checksumValid).toBe(
fixMessage.checksumValid,
`[actual: ${messages[0].checksumValue}, expected: ${messages[0].checksumExpected}]`,
);
});
});
}
testMessages.forEach((messages) => {
processTest(messages);
});
describe('#parse: unknown SOH', () => {
it('should parse the message, SOH " "', () => {
expect(
fixParser.parse(
'8=FIX.4.2 9=106 35=A 34=1 49=U1par 50=U1fix 52=20090206-21:13:36.887 56=FixServer 98=0 108=30 141=Y 553=U1fix 554=hotspot 10=061 ',
)[0].data.length,
).toEqual(14);
});
});
describe('#parse: checksum validation', () => {
const messages = fixParser.parse(
'8=FIX.4.4|9=109|35=AN|49=ctrader.1546785|56=cServer|57=TRADE|50=1546785|34=2|52=20190109-10:48:02|710=140511|721=5305215|10=175|',
);
it('should validate checksum correctly', () => {
expect(messages[0].checksumValid).toBe(false);
});
});
});