UNPKG

jspurefix

Version:
88 lines (77 loc) 3.41 kB
import { AsciiSession } from '../../../transport/ascii' import { MsgView } from '../../../buffer' import { MsgType } from '../../../types/enum' import { IJsFixLogger, IJsFixConfig } from '../../../config' // interfaces generated by compiler to make messages easy in an IDE import { ITradeCaptureReportRequest, ITradeCaptureReport, MsgTag, SessionRejectReason, SubscriptionRequestType, TradeRequestStatus } from '../../../types/FIX4.4/repo' import { TradeFactory } from './trade-factory' export class TradeCaptureServer extends AsciiSession { private readonly logger: IJsFixLogger private readonly fixLog: IJsFixLogger private readonly tradeFactory: TradeFactory = new TradeFactory() private timerHandle: NodeJS.Timer = null constructor (public readonly config: IJsFixConfig) { super(config) this.logReceivedMsgs = true this.logger = config.logFactory.logger(`${this.me}:TradeCaptureServer`) this.fixLog = config.logFactory.plain(`jsfix.${config.description.application.name}.txt`) } protected onApplicationMsg (msgType: string, view: MsgView): void { this.logger.info(`${view.toJson()}`) switch (msgType) { case MsgType.TradeCaptureReportRequest: { this.tradeCaptureReportRequest(view.toObject()) break } default: { const seqNum = view.getTyped(MsgTag.MsgSeqNum) this.send(msgType, this.config.factory.reject(msgType, seqNum, `${this.me}: unexpected msg type '${msgType}'`, SessionRejectReason.InvalidMsgType)) break } } } protected onReady (view: MsgView): void { // server waits for client to make a request this.logger.info('ready for requests.') } protected onStopped (): void { this.logger.info('stopped') if (this.timerHandle) { clearInterval(this.timerHandle) } } protected onLogon (view: MsgView, user: string, password: string): boolean { return true } // use msgType for example to persist only trade capture messages to database protected onDecoded (msgType: string, txt: string): void { this.fixLog.info(txt) } // no delimiter substitution on transmit messages protected onEncoded (msgType: string, txt: string): void { this.fixLog.info(AsciiSession.asPiped(txt)) } private tradeCaptureReportRequest (tcr: ITradeCaptureReportRequest): void { this.logger.info(`received tcr ${tcr.TradeRequestID}`) // send back an ack. this.send(MsgType.TradeCaptureReportRequestAck, TradeFactory.tradeCaptureReportRequestAck(tcr, TradeRequestStatus.Accepted)) // send some trades const batch: ITradeCaptureReport[] = this.tradeFactory.batchOfTradeCaptureReport() batch.forEach((tc: ITradeCaptureReport) => { this.send(MsgType.TradeCaptureReport, tc) }) this.send(MsgType.TradeCaptureReportRequestAck, TradeFactory.tradeCaptureReportRequestAck(tcr, TradeRequestStatus.Completed)) // start sending the odd 'live' trade switch (tcr.SubscriptionRequestType) { case SubscriptionRequestType.SnapshotAndUpdates: { this.timerHandle = setInterval(() => { if (Math.random() < 0.4) { const tc: ITradeCaptureReport = this.tradeFactory.singleTradeCaptureReport() this.send(MsgType.TradeCaptureReport, tc) } }, 5000) break } } } }