fixparser
Version:
FIX.Latest / 5.0 SP2 Parser / AI Agent Trading
138 lines (130 loc) • 6.14 kB
text/typescript
import {
type ConnectionOptions,
EncryptMethod,
FIXParser,
Field,
Fields,
HandlInst,
LicenseManager,
type Message,
Messages,
OrdType,
ResetSeqNumFlag,
Side,
TimeInForce,
} from 'fixparser';
const initializeConnection = async () => {
// NOTE: This feature requires a FIXParser Pro license
await LicenseManager.setLicenseKey(process.env.FIXPARSER_LICENSE_KEY);
const fixParser = new FIXParser();
const SENDER = 'CLIENT';
const TARGET = 'SERVER';
const tlsOptions = {
minVersion: 'TLSv1.3',
cert: `-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUAq3bE3+GehnCjrl6M74Ik6qjrVMwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTAxMjcyMTQ4MzlaFw00NTAx
MjIyMTQ4MzlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCIS+66TMfEgfm23isscqJ/8rGUUvP0NLqmCvCDBfeA
SeLjOAdNkLO+XnIbPgXPx5RmvNZuk8NrXwDAS5zbZCngbFyS3HQFRxokj/6uH0Bi
dLXaaVHZHXnMmUglaN21dav1wOPTD4IM5pTCIGs4k7fS7zJCQK8/GunAZbv0TLVd
+Cb9NdD/q4qyJKTRxm8QREWXMlJPZCPO48xqNMAtVC2ywGk7UueQu1UPH/uiOtV0
GpW339eRodSYrHOXbwwNk0K5xyHHXVISs+iXIJ1nUlRVUzHkIQCQXK+Fdn5iIqRN
MjnUDvMndqheWDmO64ISTPddnR1v/Ly5Ftwv1v8TaJ85AgMBAAGjUzBRMB0GA1Ud
DgQWBBRI9AX+Nm/RHncJZQktGhvIw5tJ+TAfBgNVHSMEGDAWgBRI9AX+Nm/RHncJ
ZQktGhvIw5tJ+TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBb
ph8nB374X7EdLHZI4Ulj3itszcSmCeWqS3+x3WZLOnLZUzmbqpoxohqtWapTcD8n
eJ41ZMo/5FFC20/ywMl2i51ofGBupeAXwy9euFna9/JmYWaSf1OmE5AFNAWqmQIK
qHppaphAHjHRpLRO+tp6ezVAFmgXaKk2b09FChZolOorjuPP/7DpcWtwUG9esJHY
LwMaEBMRu37SZCJEoUDDj0wKl7+QQwlAcvXqIsvFxanvdxQn0Q62k1qLa5lMNGtp
DhUtJAY2zkWxFsbGpMcN3B9SxdZO9aZWjbyvsa54D7/EZqTzucDsOt4JNGWwX8x4
BCFxH2tIR7zcDgGRVDE3
-----END CERTIFICATE-----`,
key: `-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCIS+66TMfEgfm2
3isscqJ/8rGUUvP0NLqmCvCDBfeASeLjOAdNkLO+XnIbPgXPx5RmvNZuk8NrXwDA
S5zbZCngbFyS3HQFRxokj/6uH0BidLXaaVHZHXnMmUglaN21dav1wOPTD4IM5pTC
IGs4k7fS7zJCQK8/GunAZbv0TLVd+Cb9NdD/q4qyJKTRxm8QREWXMlJPZCPO48xq
NMAtVC2ywGk7UueQu1UPH/uiOtV0GpW339eRodSYrHOXbwwNk0K5xyHHXVISs+iX
IJ1nUlRVUzHkIQCQXK+Fdn5iIqRNMjnUDvMndqheWDmO64ISTPddnR1v/Ly5Ftwv
1v8TaJ85AgMBAAECggEAAKG1B7qKsGbec2xja17w2i3YUbzSLqecQ1bq48KQOuOI
M9H9R6zfYdA/66sCHZDHx7OdBihHHw93R/qVKSVZ49VlTcu5zCRABXauBcEZ3CCq
83MhZmzJR2IzQ476YMiTfT//H3MPAO/ER7FBqfTNKVnMevS7igviuVe1Exhmjv9M
yBqDmaqxzv9UeacuX/7fqhAcO6A4euODpLgUyGPBdcpwExdG1OLruWsRD/oG8VY6
2ZvQ0CPLusiN7rMem5mRt1GmW2zhHbZaAa960LVy/ikHD6A9k3O0nYYRMtbmOWOn
I0DRZSWTkG3DR7/sD6F5zw8UL25NYTuJFYl/K8fc8QKBgQC9TQz/W05mniLo3SZ7
KxG1s2Wphp4DxufLsbM6EXdzQ09adQyGzHaqtG5bycL54ed8wJgp7EShDBX4RX6U
rg4iMgBipC2S/N9EIBZ7Dg3P0Mayvfqd3+qrg32CWqc0mLIep4k9XkSsWffsghSx
XO7MVRiRnWAaawYxFiDpTHBz6QKBgQC4UeMz1PhtI4cfeJgpsEeiSk4eRJOGc01D
79bYegSehZ9RL04DjgIEazccmIB5eprZ43BSR5SrHyOwAnjeb+Gxxmz4avm1hqYl
fq6QbBlgpk5FQSNHyBgD2DfcNxSs+YWbaT6mgkjZeJRCzhZLMWLLYswSoAGehyYu
FklodWFO0QKBgDEooDZ0BKEbcd9dBtA3eArigoUKo2BBuBIqnGt4+7cgBKxt9wnO
cQaVgo8tjweLRa0c6qcAZzYXSGFH0r5TkPIKYBU9o2QnbOdpGc1s8eNEyUTDlyCG
dI+DvwUp+3/qI19YjIg2QcksN/jgMvV4N78yXgX6g2l434vBvlw3cIB5AoGALzt8
t1mJ153VEHF8vKIZmTLlVchI7Zk6YYBiU9LgwCaJruoqWarYRX2b/83sjjSm3dL0
g4EoTbmLEZ1wj7+n3EB2yCnRl3zLsqwF26h30FaNlB2fBtP1o3aSyfGrcK/4Vtzf
WxfjxyapB318JQSgxnGozdUG1TLYy9KWORhrOSECgYAfyo+EynjQIwM0IkMqLA/3
JvyGxVXv886rjT3wibUATaRfR0ZTfGql+Tszr/fB60M4UqlBN7JRzWFuBLCh7IN/
Ks9adwa81pZEJ3kIkCGewK2fG5lTwEbaJpf2hw/Jf2FYwsp0uI/0O7NgVWDid8sx
tswAkG7yU9ZI15CXgOhekg==
-----END PRIVATE KEY-----`,
rejectUnauthorized: false,
};
fixParser.connect({
host: 'localhost',
port: 9878,
protocol: 'tls-tcp',
sender: SENDER,
target: TARGET,
fixVersion: 'FIX.4.4',
tlsOptions: tlsOptions as ConnectionOptions,
logging: true,
onOpen: () => {
console.log('Open');
sendLogon();
setInterval(() => {
sendOrder();
}, 500);
},
onMessage: (message: Message) => console.log('received message', message.description, message.messageString),
onClose: () => console.log('Disconnected'),
});
const sendLogon = () => {
const logon = fixParser.createMessage(
new Field(Fields.MsgType, Messages.Logon),
new Field(Fields.MsgSeqNum, fixParser.getNextTargetMsgSeqNum()),
new Field(Fields.SenderCompID, SENDER),
new Field(Fields.SendingTime, fixParser.getTimestamp()),
new Field(Fields.TargetCompID, TARGET),
new Field(Fields.ResetSeqNumFlag, ResetSeqNumFlag.Yes),
new Field(Fields.EncryptMethod, EncryptMethod.None),
new Field(Fields.HeartBtInt, 10),
);
const messages = fixParser.parse(logon.encode());
console.log('sending message', messages[0].description, messages[0].messageString);
fixParser.send(logon);
};
const sendOrder = () => {
const order = fixParser.createMessage(
new Field(Fields.MsgType, Messages.NewOrderSingle),
new Field(Fields.MsgSeqNum, fixParser.getNextTargetMsgSeqNum()),
new Field(Fields.SenderCompID, SENDER),
new Field(Fields.SendingTime, fixParser.getTimestamp()),
new Field(Fields.TargetCompID, TARGET),
new Field(Fields.ClOrdID, '11223344'),
new Field(Fields.HandlInst, HandlInst.AutomatedExecutionNoIntervention),
new Field(Fields.OrderQty, '123'),
new Field(Fields.TransactTime, fixParser.getTimestamp()),
new Field(Fields.OrdType, OrdType.Market),
new Field(Fields.Side, Side.Buy),
new Field(Fields.Symbol, '700.HK'),
new Field(Fields.TimeInForce, TimeInForce.Day),
);
const messages = fixParser.parse(order.encode());
console.log('sending message', messages[0].description, messages[0].messageString.replace(/\x01/g, '|'));
fixParser.send(order);
};
};
initializeConnection().catch((err) => console.error('Error initializing connection:', err));