### Clone and Build JsPureFix Source: https://context7.com/timelorduk/jspurefix/llms.txt Steps to clone the JsPureFix repository, install dependencies, and build the project. ```bash git clone https://github.com/TimelordUK/jspurefix.git cd jspurefix npm install npm run unzip-repo npm run build ``` -------------------------------- ### Install jspurefix and Unpack Repository Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Install the jspurefix package from npm and then unpack the repository data. This is a prerequisite for generating custom messages. ```shell npm install jspurefix cd node_modules/jspurefix && npm run unzip-repo ``` -------------------------------- ### Unit Test Execution Output Source: https://github.com/timelorduk/jspurefix/blob/master/README.md This is an example output from running the unit tests, showing the status of various test suites and individual tests, including pass/fail status and execution times. ```bash PASS src/test/elastic-buffer.test.ts RUNS src/test/session.test.ts PASS src/test/encode-proxy.test.tsst.ts PASS src/test/execution-report.test.ts PASS src/test/view-decode.test.ts PASS src/test/ascii-encoder.test.ts PASS src/test/ascii-parser.test.ts PASS src/test/includes.test.ts PASS src/test/fixml-alloc-parse.test.ts (9.433s) PASS src/test/repo-full-fixml-msg.test.ts (6.025s) PASS src/test/fixml-mkt-data-settle-parse.test.ts (6.021s) PASS src/test/qf-full-msg.test.ts PASS src/test/logon.test.ts PASS src/test/fixml-mkt-data-fut-parse.test.ts (7.761s) PASS src/test/time-formatter.test.ts PASS src/test/ascii-segment.test.ts PASS src/test/session-state.test.ts PASS src/test/fixml-tc-bi-lateral-parse.test.ts (7.534s) PASS src/test/ascii-tag-pos.test.ts PASS src/test/fix-log-replay.test.ts PASS src/test/repo-full-ascii-msg.test.ts PASS src/test/session.test.ts (52.637s) Test Suites: 21 passed, 21 total Tests: 204 passed, 204 total Snapshots: 0 total Time: 54.606s, estimated 65s Ran all test suites. ``` -------------------------------- ### JsPureFix Command Line Tool Usage Source: https://context7.com/timelorduk/jspurefix/llms.txt Install and use the JsPureFix command-line tool for parsing FIX logs, generating message types, and benchmarking. Includes commands for installation and log analysis. ```bash # Install the package npm install jspurefix cd node_modules/jspurefix && npm run unzip-repo # Parse FIX log and show tokens npm run cmd -- --dict=repo44 --fix=data/examples/FIX.4.4/jsfix.test_client.txt --delimiter="|" --type=AD --tokens # Output: # [0] 8 (BeginString) = FIX4.4, [1] 9 (BodyLength) = 0000135 # [2] 35 (MsgType) = AD[TradeCaptureReportRequest], [3] 49 (SenderCompID) = init-comp ``` -------------------------------- ### Build jspurefix on Windows Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Clone the jspurefix repository and execute the build script for Windows. This includes installing dependencies and compiling TypeScript. ```shell git clone https://github.com/TimelordUK/jspurefix.git cd jspurefix script\build.cmd ``` ```shell git clone https://github.com/TimelordUK/jspurefix.git cd jspurefix npm install npm run unzip-repo node_modules/.bin/tsc npm run tcp-tc ``` -------------------------------- ### Build jspurefix on Unix Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Clone the jspurefix repository and execute the build script for Unix-based systems. This includes installing dependencies and compiling TypeScript. ```shell git clone https://github.com/TimelordUK/jspurefix.git cd jspurefix script/build.sh ``` ```shell npm install npm run unzip-repo ./node_modules/.bin/tsc --version ./node_modules/.bin/tsc npm run tcp-tc ``` -------------------------------- ### Example FIX Message for Resending Source: https://github.com/timelorduk/jspurefix/blob/master/README.md This JSON represents a FIX message example that includes the 'PossDupFlag' set to true within the 'StandardHeader', indicating it's a duplicate message. This is used in conjunction with resending logic. ```json { "ClOrdID": "acceptor-order-id", "HandlInst": "2", "OrdType": "2", "Side": "2", "TransactTime": "2021-08-03T08:23:57.041Z", "Symbol": "some ticker", "StandardHeader": { "PossDupFlag": true, "MsgSeqNum": 2 } } ``` -------------------------------- ### Implement Custom FIX Session Launcher Source: https://context7.com/timelorduk/jspurefix/llms.txt Extend SessionLauncher to provide custom FIX session implementations by overriding makeFactory. This example shows launching both client and server sessions. ```typescript import 'reflect-metadata' import { EngineFactory, SessionLauncher } from 'jspurefix' import { IJsFixConfig } from 'jspurefix' import { TradeCaptureClient } from './trade-capture-client' import { TradeCaptureServer } from './trade-capture-server' class AppLauncher extends SessionLauncher { public constructor() { super( 'data/session/test-initiator.json', // Client config 'data/session/test-acceptor.json' // Server config ) } protected override makeFactory(config: IJsFixConfig): EngineFactory { const isInitiator = this.isInitiator(config.description) return { makeSession: () => isInitiator ? new TradeCaptureClient(config) : new TradeCaptureServer(config) } as EngineFactory } } // Launch both client and server const launcher = new AppLauncher() launcher.exec() ``` -------------------------------- ### Example FIX Message with Non-Contiguous Tags Source: https://github.com/timelorduk/jspurefix/blob/master/BACKPORT_PLAN.md An example FIX message (NewOrderSingle) illustrating valid but non-contiguous placement of component tags (e.g., Instrument tags) among other order tags. This format challenges parsers that expect contiguous blocks. ```plaintext 8=FIX.4.4|9=193|35=D|34=5|49=FIXSIMDEMO|52=20241013-14:09:45.126|56=sjames8888@gmail_com| 11=567638644253361428000|15=GBP|21=2|22=5|38=100|40=2|44=100|48=VOD.L|54=1|55=VOD.L| 59=0|60=20241013-14:09:45.126|388=1|10=091| ``` -------------------------------- ### Get Component View and Object Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Retrieves a component (like 'Instrument') from a parent message view, both as a view object and as a parsed object. ```typescript const instrumentView: MsgView = view.getView('Instrument') const instrumentObject: IInstrument = view.getView('Instrument').toObject() ``` -------------------------------- ### Resending Messages with Duplicate Flag Source: https://github.com/timelorduk/jspurefix/blob/master/README.md This TypeScript example demonstrates how to format a message for resending, including the 'PossDupFlag' set to true and the 'MsgSeqNum' in the StandardHeader. This is necessary when overriding the default 'onResendRequest' logic. ```typescript { ...messageBodyData, StandardHeader: { PossDupFlag: true, MsgSeqNum: sequenceNumber}, } ``` -------------------------------- ### Run Skeleton Session Sample Source: https://context7.com/timelorduk/jspurefix/llms.txt Launches the skeleton session sample application. ```bash npm run tcp-sk ``` -------------------------------- ### Run Market Data Sample Source: https://context7.com/timelorduk/jspurefix/llms.txt Executes the market data sample application. ```bash npm run tcp-qf-md ``` -------------------------------- ### Run Trade Capture Sample Source: https://context7.com/timelorduk/jspurefix/llms.txt Executes the trade capture sample application, which includes both client and server components. ```bash npm run tcp-tc ``` -------------------------------- ### Run QuickFIX Benchmark Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Execute a QuickFIX benchmark test. This command is used to measure performance. ```shell npm run qf-bench-lo ``` -------------------------------- ### Run QuickFIX Heartbeat Benchmark Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Command to run the benchmark for QuickFIX heartbeats. ```shell npm run qf-bench-hb ``` -------------------------------- ### Configure Initiator Session (JSON) Source: https://context7.com/timelorduk/jspurefix/llms.txt Defines connection parameters, credentials, and protocol settings for a FIX client/initiator. Ensure the 'dictionary' matches your FIX version repository. ```json // data/session/test-initiator.json - Client/Initiator configuration { "application": { "reconnectSeconds": 10, "type": "initiator", "name": "test_client", "tcp": { "host": "localhost", "port": 2344 }, "protocol": "ascii", "dictionary": "repo44" }, "Username": "js-client", "Password": "pwd-client", "EncryptMethod": 0, "ResetSeqNumFlag": true, "HeartBtInt": 30, "SenderCompId": "init-comp", "TargetCompID": "accept-comp", "TargetSubID": "fix", "BeginString": "FIX.4.4" } ``` -------------------------------- ### Add CLI Entry Point Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Create the main entry point for the CLI application, responsible for parsing command-line arguments and invoking the application launcher. ```typescript index.ts: // Entry point that parses argv and calls the launcher. ``` -------------------------------- ### Hardening Server Timer Logic Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Track the setInterval handle as a class field and clear it in onStopped() and at the start of any new request handler for defensive programming. ```typescript trade-capture-server.ts: // Track setInterval handle as a class field. // Clear it in onStopped() AND at the start of any new request handler. ``` -------------------------------- ### Run FIXML over HTTP Order Management Source: https://context7.com/timelorduk/jspurefix/llms.txt Launches the order management sample application using FIXML over HTTP transport. ```bash npm run http-oms ``` -------------------------------- ### Get First Item from Nested Group Object Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Extracts the first item from a nested repeating group within a message view, converting it to an object for easier access to its properties. ```typescript import { IUndInstrmtGrp } from '../types/FIX4.4/quickfix/set/und_instrmt_grp' import { IUnderlyingInstrument } from '../types/FIX4.4/quickfix/set/underlying_instrument' const erView: MsgView = views[0] const undInstrmtGrpView: MsgView = erView.getView('UndInstrmtGrp') const undInstrmtGrpViewAsObject: IUndInstrmtGrp = undInstrmtGrpView.toObject() expect(undInstrmtGrpViewAsObject.NoUnderlyings.length).toEqual(2) const underlying0: IUnderlyingInstrument = undInstrmtGrpViewAsObject.NoUnderlyings[0].UnderlyingInstrument expect(underlying0.UnderlyingSymbol).toEqual('massa.') ``` -------------------------------- ### Resilience Smoke Test Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md A smoke test to verify resilience by starting the server, connecting a client, forcing a disconnect, reconnecting, and ensuring exactly one set of trades is exchanged. ```typescript trade-capture-resilience.test.ts: // Smoke test: start server, connect client, force disconnect, reconnect, verify exactly one set of trades is exchanged. ``` -------------------------------- ### Configure Multi-Client Acceptor with Wildcard TargetCompID Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Configuration for an acceptor that supports multiple clients by using a wildcard for TargetCompID. ```json { "port": 2345, "store": "store/acceptor", "TargetCompID": "*" } ``` -------------------------------- ### Configure Acceptor Session (JSON) Source: https://context7.com/timelorduk/jspurefix/llms.txt Defines connection parameters, credentials, and protocol settings for a FIX server/acceptor. Ensure the 'dictionary' matches your FIX version repository. ```json // data/session/test-acceptor.json - Server/Acceptor configuration { "application": { "type": "acceptor", "name": "test_server", "tcp": { "host": "localhost", "port": 2344 }, "protocol": "ascii", "dictionary": "repo44" }, "Username": "js-server", "Password": "pwd-server", "EncryptMethod": 0, "ResetSeqNumFlag": true, "HeartBtInt": 30, "SenderCompId": "accept-comp", "TargetCompID": "init-comp", "TargetSubID": "fix", "BeginString": "FIX.4.4" } ``` -------------------------------- ### Run TLS Encrypted Trade Capture Source: https://context7.com/timelorduk/jspurefix/llms.txt Executes the trade capture sample application with TLS encryption enabled for secure communication. ```bash npm run tcp-tls-tc ``` -------------------------------- ### Refactor AppLauncher for CLI Options Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Refactor the AppLauncher to accept CliOptions and dispatch to runClient(), runServer(), or runBoth(). Preserves 'run both' as the default for backward compatibility. ```typescript app.ts: // Refactor AppLauncher to accept CliOptions. // Dispatch to runClient(), runServer(), or runBoth(). ``` -------------------------------- ### Run Unit Tests Source: https://github.com/timelorduk/jspurefix/blob/master/README.md This shell command executes the comprehensive unit test suite for the jspurefix library using npm. ```shell npm t ``` -------------------------------- ### Run FIX.4.4 Trade Capture Benchmark Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Command to run the benchmark for FIX.4.4 trade captures. ```shell npm run repo44-bench-tc ``` -------------------------------- ### Performance Benchmark Results (Windows Intel Core I7-4770, 22 Fields) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance benchmark results with a higher number of fields (22) on older hardware. Shows iterations, fields, message length, and elapsed time. ```shell [A]: iterations = 250000, fields = 22, length = 214 chars, elapsed ms 1466, 5.864 micros per msg ``` -------------------------------- ### Configure Default Reset Mode Sessions Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Default configurations for initiator and acceptor sessions in reset mode. ```json { "port": 2345, "store": "store/initiator" } ``` ```json { "port": 2345, "store": "store/acceptor" } ``` -------------------------------- ### Initialize Trade Capture Client Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Initializes the TradeCaptureClient, setting up logging and a dictionary for reports. Inherits from AsciiSession for session management. ```typescript constructor (public readonly config: IJsFixConfig) { super(config) this.logReceivedMsgs = true this.reports = new Dictionary() this.fixLog = config.logFactory.plain(`jsfix.${config.description.application.name}.txt`) this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`) } ``` -------------------------------- ### Add npm Scripts for Scenarios Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Updates the package.json file to include npm scripts for running individual scenario tests and a wrapper script to run all scenarios. ```json { "scripts": { "scenario:seq-mismatch": "node scripts/test-scenarios/seq-mismatch.ts", "scenario:server-bounce": "node scripts/test-scenarios/server-bounce.ts", "scenario:client-bounce": "node scripts/test-scenarios/client-bounce.ts", "scenario:broker-reset": "node scripts/test-scenarios/broker-reset.ts", "scenario:all": "bash scripts/test-scenarios/run-all.sh" } } ``` -------------------------------- ### Run Unit Tests Source: https://context7.com/timelorduk/jspurefix/llms.txt Executes the unit tests for the JsPureFix library. ```bash npm test ``` -------------------------------- ### Run FIX.4.4 Execution Report Benchmark Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Command to run the benchmark for FIX.4.4 execution reports. ```shell npm run repo44-bench-er ``` -------------------------------- ### Run FIX.4.4 Security Definition Benchmark Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Command to run the benchmark for FIX.4.4 security definitions. ```shell npm run repo44-bench-sd ``` -------------------------------- ### Performance Benchmark Results (Windows 12th Gen Intel i7-12700H, 22 Fields) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance benchmark results with a higher number of fields (22) on newer hardware. Shows iterations, fields, message length, and elapsed time. ```shell [A]: iterations = 250000, fields = 22, length = 214 chars, elapsed ms 693, 2.7720000000000002 micros per msg ``` -------------------------------- ### Performance Benchmark Results (Windows Intel Core I7-4770) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance benchmark results for a specific hardware configuration. Shows iterations, fields, message length, and elapsed time in milliseconds and microseconds per message. ```shell [0]: iterations = 250000, fields = 10, length = 131 chars, elapsed ms 950, 3.8 micros per msg ``` -------------------------------- ### Reset Server State on Ready Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Implement onReady() state reset for the server. The next trade ID counter is allowed to remain monotonic across reconnects, but this behavior should be verified. ```typescript trade-capture-server.ts: // Same onReady() reset for any server-side state. // Verify next trade ID counter is OK to keep monotonic across reconnects. ``` -------------------------------- ### Run FIX Benchmark Source: https://context7.com/timelorduk/jspurefix/llms.txt Executes a benchmark test on a FIX file. Specifies the dictionary, FIX file, delimiter, and number of repeats. ```bash npm run cmd -- --dict=repo44 --fix=data/examples/FIX.4.4/repo/execution-report/fix.txt --benchmark --delimiter="|" --repeats=80000 ``` -------------------------------- ### Configure File Store for Session Recovery Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Configuration for file-based session storage, specifying store directory and reset sequence flag behavior. ```json { "store": "store/initiator", "ResetSeqNumFlag": "N", "port": 2345 } ``` ```json { "store": "store/acceptor", "ResetSeqNumFlag": "N", "port": 2345 } ``` ```json { "store": "store/broker-initiator", "client": true, "reconnectSeconds": 10, "ResetSeqNumFlag": "N" } ``` ```json { "store": "store/broker-acceptor", "ResetSeqNumFlag": "Y" } ``` -------------------------------- ### Run All Scenarios Script Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md A shell script to execute all defined scenario tests sequentially and report overall pass/fail status. ```shell #!/bin/bash set -e echo "Running all scenarios..." # Run individual scenarios npm run scenario:seq-mismatch npm run scenario:server-bounce npm run scenario:client-bounce npm run scenario:broker-reset echo "All scenarios passed!" ``` -------------------------------- ### FIXML Server Implementation Source: https://context7.com/timelorduk/jspurefix/llms.txt Implement a FIXML server session to receive orders and respond with execution reports. Extends FixmlSession and handles incoming order messages. ```typescript import { FixmlSession } from 'jspurefix/dist/transport/fixml' import { MsgView } from 'jspurefix' import { IJsFixLogger, IJsFixConfig } from 'jspurefix' import { INewOrderSingle, IExecutionReport, Side, OrdType, TimeInForce, SecurityIDSource, ExecType, OrdStatus } from 'jspurefix/dist/types/FIXML50SP2' // HTTP Server - receives orders and sends execution reports export class HttpServer extends FixmlSession { private readonly logger: IJsFixLogger private execId: number = 1 constructor(public readonly config: IJsFixConfig) { super(config) this.logger = config.logFactory.logger(`${this.me}`) } protected onApplicationMsg(msgType: string, view: MsgView): void { this.logger.info(view.toJson()) if (msgType === 'Order') { const order = view.toObject() as INewOrderSingle this.logger.info(`received order: ${order.ClOrdID}`) // Create execution report (fill) const fill: IExecutionReport = { ClOrdID: order.ClOrdID, OrdType: order.OrdType, TransactTime: new Date(), AvgPx: order.Price, LeavesQty: 0, LastPx: order.Price, ExecType: ExecType.OrderStatus, OrdStatus: OrdStatus.Filled, ExecID: `exec${this.execId++}`, Side: order.Side, Price: order.Price, OrderQtyData: { OrderQty: order?.OrderQtyData?.OrderQty }, Instrument: { Symbol: order?.Instrument?.Symbol, SecurityID: order?.Instrument?.SecurityID, SecurityIDSource: SecurityIDSource.IsinNumber } } as IExecutionReport this.send('ExecutionReport', fill) } } protected onReady(view: MsgView): void { this.logger.info('onReady') } protected onLogon(view: MsgView, user: string, password: string): boolean { return true } protected onStopped(): void { this.logger.info('stopped') } } ``` -------------------------------- ### Reset Client State on Ready Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Implement onReady() state reset for the client, including clearing the received trades map and resetting guard flags. Add a hasSentTradeRequest guard to prevent double-sending on reconnect. ```typescript trade-capture-client.ts: // Add onReady() state reset: clear received trades map, reset guard flags. // Add hasSentTradeRequest guard to prevent double-sending on reconnect. // Guard the 'done()' scheduler against firing twice on reconnect. ``` -------------------------------- ### Update npm Scripts for CLI Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Update package.json bin/scripts to ensure 'npm run tcp-tc' continues to work while also making the new CLI available. ```json package.json: // Update bin/scripts. // Ensure 'npm run tcp-tc' works and new CLI is available. ``` -------------------------------- ### Performance Benchmark Results (Windows 12th Gen Intel i7-12700H) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance benchmark results for a newer hardware configuration. Shows iterations, fields, message length, and elapsed time in milliseconds and microseconds per message. ```shell [0]: iterations = 250000, fields = 10, length = 131 chars, elapsed ms 468, 1.8719999999999999 micros per msg ``` -------------------------------- ### Implement File Store Roundtrip Test Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md A smoke test for the file store, verifying session recovery after termination and restart. ```typescript import { test, expect } from '@playwright/test'; test.describe('FileStore roundtrip', () => { test('should resume session after restart', async ({ page }) => { // ... test implementation ... }); }); ``` -------------------------------- ### FIXML Client Implementation Source: https://context7.com/timelorduk/jspurefix/llms.txt Implement a FIXML client session to send new orders and handle execution reports. Requires extending FixmlSession and defining message handling logic. ```typescript import { FixmlSession } from 'jspurefix/dist/transport/fixml' import { MsgView } from 'jspurefix' import { IJsFixLogger, IJsFixConfig } from 'jspurefix' import { INewOrderSingle, IExecutionReport, Side, OrdType, TimeInForce, SecurityIDSource, ExecType, OrdStatus } from 'jspurefix/dist/types/FIXML50SP2' // HTTP Client - sends orders export class HttpClient extends FixmlSession { private readonly logger: IJsFixLogger private orderId: number = 1 constructor(public readonly config: IJsFixConfig) { super(config) this.logger = config.logFactory.logger(`${this.me}`) } protected onReady(_: MsgView): void { this.logger.info('onReady') // Create and send a new order const order: INewOrderSingle = { ClOrdID: `Cli${this.orderId++}`, Account: 'TradersRUs', Side: Side.Buy, Price: 100.12, OrdType: OrdType.Limit, OrderQtyData: { OrderQty: 10000 }, Instrument: { Symbol: 'IBM', SecurityID: '459200101', SecurityIDSource: SecurityIDSource.IsinNumber }, TimeInForce: TimeInForce.GoodTillCancelGtc } as INewOrderSingle this.send('NewOrderSingle', order) // Logout after 11 seconds setTimeout(() => this.done(), 11 * 1000) } protected onApplicationMsg(msgType: string, view: MsgView): void { this.logger.info(view.toJson()) if (msgType === 'ExecRpt') { const fill = view.toObject() as IExecutionReport this.logger.info(`execution report: ${fill?.OrderQtyData?.OrderQty}@${fill.Price}`) } } protected onLogon(view: MsgView, user: string, password: string): boolean { return true } protected onStopped(): void { this.logger.info('stopped') } } ``` -------------------------------- ### Compile Dictionary Interfaces Source: https://github.com/timelorduk/jspurefix/blob/master/README.md This shell command compiles dictionary interfaces using npm, specifying the dictionary repository ('repo42') and the compile action. This is part of the process for defining and using custom FIX dictionaries. ```shell npm run cmd -- --dict=repo42 --compile ``` -------------------------------- ### Implement Multi-Client Test Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md A test case to verify the functionality of multiple concurrent clients connecting to the same acceptor without data corruption or cross-talk. ```typescript import { test, expect } from '@playwright/test'; test.describe('Multi-client', () => { test('should handle concurrent clients', async ({ page }) => { // ... test implementation ... }); }); ``` -------------------------------- ### Implement Trade Capture Client (TypeScript) Source: https://context7.com/timelorduk/jspurefix/llms.txt Extends AsciiSession to handle FIX protocol communications for trading applications. Override lifecycle methods like onReady, onApplicationMsg, and onLogon to implement custom logic. ```typescript import { MsgView } from 'jspurefix' import { AsciiSession } from 'jspurefix' import { MsgType } from 'jspurefix' import { IJsFixLogger, IJsFixConfig } from 'jspurefix' import { ITradeCaptureReport, ITradeCaptureReportRequest, ITradeCaptureReportRequestAck } from 'jspurefix/dist/types/FIX4.4/repo' export class TradeCaptureClient extends AsciiSession { private readonly logger: IJsFixLogger private readonly reports: Map constructor(public readonly config: IJsFixConfig) { super(config) this.logReceivedMsgs = true this.reports = new Map() this.logger = config.logFactory.logger(`${this.me}:TradeCaptureClient`) } // Called when session is ready after successful logon protected onReady(view: MsgView): void { this.logger.info('ready') // Create and send a trade capture report request const tcr: ITradeCaptureReportRequest = { TradeRequestID: 'all-trades', TradeRequestType: 0, // AllTrades SubscriptionRequestType: '1', // SnapshotAndUpdates TrdCapDtGrp: [{ TransactTime: new Date() }] } as ITradeCaptureReportRequest this.send(MsgType.TradeCaptureReportRequest, tcr) // Schedule logout after 32 seconds setTimeout(() => this.done(), 32 * 1000) } // Called when an application message is received protected onApplicationMsg(msgType: string, view: MsgView): void { this.logger.info(`${view.toJson()}`) switch (msgType) { case MsgType.TradeCaptureReport: { const tc: ITradeCaptureReport = view.toObject() as ITradeCaptureReport this.reports.set(tc.TradeReportID, tc) this.logger.info(`received trade: ${tc.Instrument.Symbol} ${tc.LastQty} @ ${tc.LastPx}`) break } case MsgType.TradeCaptureReportRequestAck: { const ack: ITradeCaptureReportRequestAck = view.toObject() as ITradeCaptureReportRequestAck this.logger.info(`received ack: ${ack.TradeRequestID} status: ${ack.TradeRequestStatus}`) break } } } // Called during logon to validate credentials protected onLogon(view: MsgView, user: string, password: string): boolean { this.logger.info(`onLogon user ${user}`) return true // Accept logon } protected onStopped(): void { this.logger.info('stopped') } } ``` -------------------------------- ### Configure TLS/SSL Encryption for Initiator Source: https://github.com/timelorduk/jspurefix/blob/master/README.md This JSON configuration enables TLS/SSL encryption for an initiator session. It specifies connection details, TLS timeouts, certificate paths, and enables tracing for diagnostics. The 'ca' field is only needed for self-certified certificates. ```json { "application": { "reconnectSeconds": 10, "type": "initiator", "name": "test_client", "tcp": { "host" : "localhost", "port": 2344, "tls": { "timeout": 10000, "sessionTimeout": 10000, "enableTrace": true, "key": "data/session/certs/client/client.key", "cert": "data/session/certs/client/client.crt", "ca": [ "data/session/certs/ca/ca.crt" ] } }, "protocol": "ascii", "dictionary": "repo44" }, "Username": "js-tls-client", "Password": "pwd-tls-client", "EncryptMethod": 0, "ResetSeqNumFlag": true, "LastSentSeqNum": 10, "LastReceivedSeqNum": 11, "HeartBtInt": 30, "SenderCompId": "init-tls-comp", "TargetCompID": "accept-tls-comp", "TargetSubID": "fix", "BeginString": "FIX4.4", "BodyLengthChars": 6 } ``` -------------------------------- ### Implement Session Registry Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md A TypeScript implementation of a session registry to manage multiple concurrent FIX sessions. ```typescript import { Session } from './session'; export type SessionKey = string; export class SessionRegistry { private sessions: Map = new Map(); add(key: SessionKey, session: Session) { // ... implementation ... } get(key: SessionKey): Session | undefined { // ... implementation ... } remove(key: SessionKey) { // ... implementation ... } } ``` -------------------------------- ### Benchmark Parsing with Repeats Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Benchmark the parsing of a FIX log file with repeated reads. This command measures performance over multiple iterations. ```cmd npm run cmd -- --dict=repo44 --fix=data/examples/FIX.4.4/jsfix.test_client.txt --delimiter="|" --stats --repeats=20 ``` -------------------------------- ### Define CLI Options with Commander Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Define the command-line interface shape using the 'commander' library. Includes options for client/server modes, configuration paths, timeouts, and logging. ```typescript cli-options.ts: // Define CLI shape using commander. // Options: --client, --server, --config , --store , --disconnect-after , --timeout , --skeleton, --log. ``` -------------------------------- ### Handle Wildcard TargetCompID in App Configuration Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Adjust the application configuration to clone session descriptions when TargetCompID is a wildcard, ensuring each session has a unique TargetCompID. ```typescript const sessionDescription = { // ... other properties ... TargetCompID: opts.targetCompId === "*" ? `session_${uuidv4()}` : opts.targetCompId, // ... }; if (opts.targetCompId === "*") { // Clone description for each session } ``` -------------------------------- ### Initiate Trade Capture Request on Connection Ready Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Called when a connection is established and logon is confirmed. Sends a TradeCaptureReportRequest to the server and schedules a logout. ```typescript protected onReady (view: MsgView): void { this.logger.info('ready') const tcr: ITradeCaptureReportRequest = TradeFactory.tradeCaptureReportRequest('all-trades', new Date()) // send request to server this.send(MsgType.TradeCaptureReportRequest, tcr) const logoutSeconds = 32 this.logger.info(`will logout after ${logoutSeconds}`) setTimeout(() => { this.done() }, logoutSeconds * 1000) } ``` -------------------------------- ### FIX.4.4 Execution Report Benchmark Results (Windows Intel Core I7-4770) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance metrics for FIX.4.4 execution reports on a Windows system with an Intel Core I7-4770 processor. ```text [8]: repeats = 250000, fields = 58, length = 604 chars, elapsed ms 3658, 14.632 micros per msg [8]: iterations = 80000, fields = 646, length = 6572 chars, elapsed ms 16499, 206.23749999999998 micros per msg ``` -------------------------------- ### Import jspurefix Types Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Import core components and specific FIX dialect types for use with a client. Ensure the correct FIX version and repository types are imported. ```typescript import { AsciiSession, MsgView, IJsFixConfig, IJsFixLogger, Dictionary, MsgType, initiator, acceptor, makeConfig } from 'jspurefix' // types for the specific FIX dialect import { ITradeCaptureReport, ITradeCaptureReportRequest, ITradeCaptureReportRequestAck } from 'jspurefix/dist/types/FIX4.4/repo' ``` -------------------------------- ### Scenario Test Script: Broker Reset Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md TypeScript script to test the broker reset scenario. It establishes initial sequences, then simulates a server-side reset (ResetSeqNumFlag=Y) and verifies sequences reset to 1. ```typescript import { test } from '@playwright/test'; test('broker reset', async ({ page }) => { // ... test implementation ... }); ``` -------------------------------- ### FIX.4.4 Security Definition Benchmark Results (Windows Intel Core I7-4770) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance metrics for FIX.4.4 security definitions on a Windows system with an Intel Core I7-4770 processor. ```text [d]: repeats = 150000, fields = 223, length = 2233 chars, elapsed ms 7962, 53.080000000000005 micros per msg d]: iterations = 150000, fields = 229, length = 2466 chars, elapsed ms 8672, 57.81333333333333 micros per msg ``` -------------------------------- ### FIX.4.4 Trade Capture Benchmark Results (Windows Intel Core I7-4770) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance metrics for FIX.4.4 trade captures on a Windows system with an Intel Core I7-4770 processor. ```text [AE]: repeats = 30000, fields = 613, length = 5818 chars, elapsed ms 5206, 173.53333333333333 micros per msg [AE]: iterations = 30000, fields = 578, length = 5741 chars, elapsed ms 5245, 174.83333333333334 micros per msg ``` -------------------------------- ### Integrate Session Registry in Trade Capture Server Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Modify the trade capture server to utilize the session registry for detecting and stopping stale sessions. ```typescript import { SessionRegistry } from './session-registry'; export class TradeCaptureServer { private registry: SessionRegistry; constructor() { this.registry = new SessionRegistry(); } async handleLogon(session: Session) { const key = session.getKey(); const existingSession = this.registry.get(key); if (existingSession) { await existingSession.stop(); } this.registry.add(key, session); // ... rest of logon handling ... } // ... other methods ... } ``` -------------------------------- ### Scenario Test Script: Server Bounce Recovery Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md TypeScript script to test recovery when the server experiences a timeout and restarts. The client should resume the session. ```typescript import { test } from '@playwright/test'; test('server bounce recovery', async ({ page }) => { // ... test implementation ... }); ``` -------------------------------- ### FIX.4.4 Execution Report Benchmark Results (Windows 12th Gen Intel i7-12700H) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance metrics for FIX.4.4 execution reports on a Windows system with a 12th Gen Intel Core i7-12700H processor. ```text [8]: iterations = 80000, fields = 646, length = 6572 chars, elapsed ms 7476, 93.45 micros per msg ``` -------------------------------- ### FIX.4.4 Trade Capture Benchmark Results (Windows 12th Gen Intel i7-12700H) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance metrics for FIX.4.4 trade captures on a Windows system with a 12th Gen Intel Core i7-12700H processor. ```text [AE]: iterations = 30000, fields = 578, length = 5741 chars, elapsed ms 2725, 90.83333333333333 micros per msg ``` -------------------------------- ### TypeScript FIX Server Implementation Source: https://context7.com/timelorduk/jspurefix/llms.txt Implement a FIX acceptor by extending `AsciiSession` and handling incoming application messages. This server processes `TradeCaptureReportRequest` and sends back acknowledgments and trade reports. ```typescript import { MsgView } from 'jspurefix' import { AsciiSession } from 'jspurefix' import { MsgType } from 'jspurefix' import { IJsFixLogger, IJsFixConfig } from 'jspurefix' import { ITradeCaptureReportRequest, ITradeCaptureReport, TradeRequestStatus, TradeReportType, TrdType, OrdStatus } from 'jspurefix/dist/types/FIX4.4/repo' export class TradeCaptureServer extends AsciiSession { private readonly logger: IJsFixLogger private nextTradeId: number = 100000 private nextExecId: number = 600000 constructor(public readonly config: IJsFixConfig) { super(config) this.logReceivedMsgs = true this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`) } protected onReady(_: MsgView): void { this.logger.info('ready for requests.') } protected onApplicationMsg(msgType: string, view: MsgView): void { this.logger.info(`${view.toJson()}`) switch (msgType) { case MsgType.TradeCaptureReportRequest: { const tcr = view.toObject() as ITradeCaptureReportRequest this.handleTradeCaptureRequest(tcr) break } } } private handleTradeCaptureRequest(tcr: ITradeCaptureReportRequest): void { this.logger.info(`received request: ${tcr.TradeRequestID}`) // Send acknowledgment this.send(MsgType.TradeCaptureReportRequestAck, { TradeRequestID: tcr.TradeRequestID, TradeRequestType: tcr.TradeRequestType, TradeRequestStatus: TradeRequestStatus.Accepted, TradeRequestResult: 0 // Successful }) // Send batch of trade reports const securities = ['Gold', 'Silver', 'Platinum'] for (let i = 0; i < 5; i++) { const trade: ITradeCaptureReport = { TradeReportID: (this.nextTradeId++).toString(), TradeReportTransType: 0, // New TradeReportType: TradeReportType.Submit, TrdType: TrdType.RegularTrade, TransactTime: new Date(), ExecID: (this.nextExecId++).toString(), PreviouslyReported: false, OrdStatus: OrdStatus.Filled, Instrument: { Symbol: securities[i % securities.length], SecurityID: `${securities[i % securities.length]}.INC` }, TradeDate: new Date(), LastQty: Math.floor(Math.random() * 100) + 100, LastPx: Math.round(Math.random() * 100 * 100) / 100 } as ITradeCaptureReport this.send(MsgType.TradeCaptureReport, trade) } // Send completion acknowledgment this.send(MsgType.TradeCaptureReportRequestAck, { TradeRequestID: tcr.TradeRequestID, TradeRequestType: tcr.TradeRequestType, TradeRequestStatus: TradeRequestStatus.Completed, TradeRequestResult: 0 }) } protected onLogon(view: MsgView, user: string, password: string): boolean { return true } protected onStopped(): void { this.logger.info('stopped') } } ``` -------------------------------- ### Scenario Test Script: Client Bounce Recovery Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md TypeScript script to test recovery when the client experiences a timeout and restarts. The server should accept the resumed client session. ```typescript import { test } from '@playwright/test'; test('client bounce recovery', async ({ page }) => { // ... test implementation ... }); ``` -------------------------------- ### FIX.4.4 Security Definition Benchmark Results (Windows 12th Gen Intel i7-12700H) Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Performance metrics for FIX.4.4 security definitions on a Windows system with a 12th Gen Intel Core i7-12700H processor. ```text [d]: iterations = 150000, fields = 229, length = 2466 chars, elapsed ms 4628, 30.85333333333333 micros per msg ``` -------------------------------- ### Update App Configuration for Store Override Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Modify the application's command-line interface to allow overriding the session store directory at runtime. ```typescript program .option('--store ', 'override session store directory') .action(async (opts) => { const storeFactory = opts.store ? new FileStoreFactory(opts.store) : new DefaultStoreFactory(); await runTradeCaptureServer(storeFactory); }); ``` -------------------------------- ### Output FIX File Statistics Source: https://context7.com/timelorduk/jspurefix/llms.txt Generates statistics for an entire FIX log file. Requires a dictionary file, the input FIX file, and the delimiter. ```bash npm run cmd -- --dict=repo44 --fix=data/examples/FIX.4.4/jsfix.test_client.txt --delimiter="|" --stats ``` -------------------------------- ### Implement Security Definition Request Flow Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Modify the trade capture client to request security definitions before requesting trade capture reports. The server will respond with five security definitions. ```typescript client.ts: // In onReady(): // ... this.send(new SecurityDefinitionRequest({ MarketID: "20" })); // On receiving each SecurityDefinition: // ... increment counter; once 5 received, send TradeCaptureReportRequest. ``` ```typescript server.ts: // Add handler for SecurityDefinitionRequest: // Responds with 5 SecurityDefinition messages (e.g., Gold, Silver, Platinum, Copper, Steel). ``` ```typescript trade-factory.ts: // Add helper for SecurityDefinition message construction. ``` -------------------------------- ### Create New Order Single in TypeScript Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Use this factory method to create a new order request. Ensure the Side enum and other types are correctly imported. ```typescript protected onReady (view: MsgView): void { this.logger.info('onReady') const logoutSeconds = this.logoutSeconds const req = this.factory.createOrder('IBM', Side.Buy, 10000, 100.12) this.send('NewOrderSingle', req) this.logger.info(`will logout after ${logoutSeconds}`) setTimeout(() => { this.done() }, 11 * 1000) } public createOrder (symbol: string, side: Side, qty: number, price: number): INewOrderSingle { const id: number = this.id++ return { ClOrdID: `Cli${id}`, Account: this.account, Side: side, Price: price, OrdType: OrdType.Limit, OrderQtyData: { OrderQty: qty } as IOrderQtyData, Instrument: { Symbol: symbol, SecurityID: '459200101', SecurityIDSource: SecurityIDSource.IsinNumber } as IInstrument, TimeInForce: TimeInForce.GoodTillCancelGtc } as INewOrderSingle } ``` -------------------------------- ### Scenario Test Script: Sequence Mismatch Recovery Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md TypeScript script to test sequence number mismatch recovery. It truncates client sequences, restarts the client, and verifies the recovery loop. ```typescript import { test } from '@playwright/test'; test('sequence mismatch recovery', async ({ page }) => { // ... test implementation ... }); ``` -------------------------------- ### Show Message Structures Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Display the structural components of a FIX message, including tag numbers, positions, and depths. This helps in understanding message layout. ```shell npm run cmd -- --dict=repo44 --fix=data/examples/FIX.4.4/jsfix.test_client.txt --delimiter="|" --type=AD --structures ``` -------------------------------- ### Parse FIX Log with Dictionary Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Parse a FIX log file using a specified dictionary. This command is useful for extracting and analyzing FIX message data. ```shell npm run cmd -- --dict=repo44 --fix=data/examples/FIX.4.4/jsfix.test_client.txt --delimiter="|" --type=AD --tokens ``` -------------------------------- ### Fetch Group View Instance Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Retrieves a specific instance from a repeating group within a message view. The view is only valid within the callback context unless cloned. ```typescript const noMDEntriesView: MsgView = view.getView('NoMDEntries') const mmEntryView: MsgView = noMDEntriesView.getGroupInstance(1) const mmEntryExpireTimeAsString: string = mmEntryView.getString('ExpireTime') expect(mmEntryExpireTimeAsString).toEqual('20180608-20:53:14.000') expect(mmEntryView.getString(126)).toEqual('20180608-20:53:14.000') ``` -------------------------------- ### Convert View to Object Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Converts a message view into a plain JavaScript object, enabling IntelliSense when used with interfaces. ```typescript import { ITradeCaptureReport } from '../../../types/FIX4.4/repo/trade_capture_report' import { ITradeCaptureReportRequest } from '../../../types/FIX4.4/repo/trade_capture_report_request' const tc: ITradeCaptureReport = view.toObject() ``` -------------------------------- ### Update jspurefix Dependency Source: https://github.com/timelorduk/jspurefix/blob/master/DEMO_PORT_PLAN.md Bump the jspurefix dependency to version ^5.5.0. Remove unused dependencies like 'request' and 'typings'. Add a 'test' script. ```json { "dependencies": { "jspurefix": "^5.5.0" }, "devDependencies": { "request": "", "typings": "" }, "scripts": { "test": "echo \"No tests yet!\" && exit 0" } } ``` -------------------------------- ### Fetch Repeated Tags from View Source: https://github.com/timelorduk/jspurefix/blob/master/README.md Retrieves all values for a repeated tag within a message view as an array of strings. ```typescript const erView: MsgView = views[0] expect(erView.getStrings('PartyID')).toEqual(['magna.', 'iaculis', 'vitae,']) ```