fixparser-plugin-mcp 9.1.7-38cee007 → 9.1.7-3c6fd297
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/MCPLocal.js +40 -666
- package/build/cjs/MCPLocal.js.map +4 -4
- package/build/cjs/MCPRemote.js +126 -752
- package/build/cjs/MCPRemote.js.map +4 -4
- package/build/cjs/index.js +127 -753
- package/build/cjs/index.js.map +4 -4
- package/build/esm/MCPLocal.mjs +40 -666
- package/build/esm/MCPLocal.mjs.map +4 -4
- package/build/esm/MCPRemote.mjs +126 -752
- package/build/esm/MCPRemote.mjs.map +4 -4
- package/build/esm/index.mjs +127 -753
- package/build/esm/index.mjs.map +4 -4
- package/build-examples/cjs/example_mcp_local.js +7 -9
- package/build-examples/cjs/example_mcp_local.js.map +4 -4
- package/build-examples/cjs/example_mcp_remote.js +7 -9
- package/build-examples/cjs/example_mcp_remote.js.map +4 -4
- package/build-examples/esm/example_mcp_local.mjs +7 -9
- package/build-examples/esm/example_mcp_local.mjs.map +4 -4
- package/build-examples/esm/example_mcp_remote.mjs +6 -8
- package/build-examples/esm/example_mcp_remote.mjs.map +4 -4
- package/package.json +2 -2
- package/types/MCPBase.d.ts +49 -0
- package/types/MCPLocal.d.ts +40 -0
- package/types/MCPRemote.d.ts +66 -0
- package/types/PluginOptions.d.ts +6 -0
- package/types/index.d.ts +3 -0
- package/types/schemas/index.d.ts +15 -0
- package/types/schemas/schemas.d.ts +168 -0
- package/types/tools/index.d.ts +17 -0
- package/types/tools/marketData.d.ts +40 -0
- package/types/tools/order.d.ts +12 -0
- package/types/tools/parse.d.ts +5 -0
- package/types/tools/parseToJSON.d.ts +5 -0
- package/types/utils/messageHandler.d.ts +18 -0
package/build/cjs/MCPLocal.js
CHANGED
|
@@ -163,7 +163,7 @@ var toolSchemas = {
|
|
|
163
163
|
}
|
|
164
164
|
},
|
|
165
165
|
executeOrder: {
|
|
166
|
-
description: "Executes a verified order. verifyOrder must be called before executeOrder.",
|
|
166
|
+
description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
|
|
167
167
|
schema: {
|
|
168
168
|
type: "object",
|
|
169
169
|
properties: {
|
|
@@ -307,395 +307,19 @@ var toolSchemas = {
|
|
|
307
307
|
},
|
|
308
308
|
required: ["symbol"]
|
|
309
309
|
}
|
|
310
|
-
},
|
|
311
|
-
technicalAnalysis: {
|
|
312
|
-
description: "Performs comprehensive technical analysis on market data for a given symbol, including indicators like SMA, EMA, RSI, Bollinger Bands, and trading signals",
|
|
313
|
-
schema: {
|
|
314
|
-
type: "object",
|
|
315
|
-
properties: {
|
|
316
|
-
symbol: {
|
|
317
|
-
type: "string",
|
|
318
|
-
description: "The trading symbol to analyze (e.g., AAPL, MSFT, EURUSD)"
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
required: ["symbol"]
|
|
322
|
-
}
|
|
323
310
|
}
|
|
324
311
|
};
|
|
325
312
|
|
|
326
|
-
// src/tools/analytics.ts
|
|
327
|
-
function sum(numbers) {
|
|
328
|
-
return numbers.reduce((acc, val) => acc + val, 0);
|
|
329
|
-
}
|
|
330
|
-
var TechnicalAnalyzer = class {
|
|
331
|
-
prices;
|
|
332
|
-
volumes;
|
|
333
|
-
highs;
|
|
334
|
-
lows;
|
|
335
|
-
constructor(data) {
|
|
336
|
-
this.prices = data.map((d) => d.trade > 0 ? d.trade : d.midPrice);
|
|
337
|
-
this.volumes = data.map((d) => d.volume);
|
|
338
|
-
this.highs = data.map((d) => d.tradingSessionHighPrice > 0 ? d.tradingSessionHighPrice : d.trade);
|
|
339
|
-
this.lows = data.map((d) => d.tradingSessionLowPrice > 0 ? d.tradingSessionLowPrice : d.trade);
|
|
340
|
-
}
|
|
341
|
-
// Calculate Simple Moving Average
|
|
342
|
-
calculateSMA(data, period) {
|
|
343
|
-
const sma = [];
|
|
344
|
-
for (let i = period - 1; i < data.length; i++) {
|
|
345
|
-
const sum2 = data.slice(i - period + 1, i + 1).reduce((a, b) => a + b, 0);
|
|
346
|
-
sma.push(sum2 / period);
|
|
347
|
-
}
|
|
348
|
-
return sma;
|
|
349
|
-
}
|
|
350
|
-
// Calculate Exponential Moving Average
|
|
351
|
-
calculateEMA(data, period) {
|
|
352
|
-
const multiplier = 2 / (period + 1);
|
|
353
|
-
const ema = [data[0]];
|
|
354
|
-
for (let i = 1; i < data.length; i++) {
|
|
355
|
-
ema.push(data[i] * multiplier + ema[i - 1] * (1 - multiplier));
|
|
356
|
-
}
|
|
357
|
-
return ema;
|
|
358
|
-
}
|
|
359
|
-
// Calculate RSI
|
|
360
|
-
calculateRSI(data, period = 14) {
|
|
361
|
-
if (data.length < period + 1) return [];
|
|
362
|
-
const changes = [];
|
|
363
|
-
for (let i = 1; i < data.length; i++) {
|
|
364
|
-
changes.push(data[i] - data[i - 1]);
|
|
365
|
-
}
|
|
366
|
-
const gains = changes.map((change) => change > 0 ? change : 0);
|
|
367
|
-
const losses = changes.map((change) => change < 0 ? Math.abs(change) : 0);
|
|
368
|
-
let avgGain = gains.slice(0, period).reduce((a, b) => a + b, 0) / period;
|
|
369
|
-
let avgLoss = losses.slice(0, period).reduce((a, b) => a + b, 0) / period;
|
|
370
|
-
const rsi = [];
|
|
371
|
-
for (let i = period; i < changes.length; i++) {
|
|
372
|
-
const rs = avgGain / avgLoss;
|
|
373
|
-
rsi.push(100 - 100 / (1 + rs));
|
|
374
|
-
avgGain = (avgGain * (period - 1) + gains[i]) / period;
|
|
375
|
-
avgLoss = (avgLoss * (period - 1) + losses[i]) / period;
|
|
376
|
-
}
|
|
377
|
-
return rsi;
|
|
378
|
-
}
|
|
379
|
-
// Calculate Bollinger Bands
|
|
380
|
-
calculateBollingerBands(data, period = 20, stdDev = 2) {
|
|
381
|
-
if (data.length < period) return [];
|
|
382
|
-
const sma = this.calculateSMA(data, period);
|
|
383
|
-
const bands = [];
|
|
384
|
-
for (let i = 0; i < sma.length; i++) {
|
|
385
|
-
const dataSlice = data.slice(i, i + period);
|
|
386
|
-
const mean = sma[i];
|
|
387
|
-
const variance = dataSlice.reduce((sum2, price) => sum2 + (price - mean) ** 2, 0) / period;
|
|
388
|
-
const standardDeviation = Math.sqrt(variance);
|
|
389
|
-
bands.push({
|
|
390
|
-
upper: mean + standardDeviation * stdDev,
|
|
391
|
-
middle: mean,
|
|
392
|
-
lower: mean - standardDeviation * stdDev
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
return bands;
|
|
396
|
-
}
|
|
397
|
-
// Calculate maximum drawdown
|
|
398
|
-
calculateMaxDrawdown(prices) {
|
|
399
|
-
let maxPrice = prices[0];
|
|
400
|
-
let maxDrawdown = 0;
|
|
401
|
-
for (let i = 1; i < prices.length; i++) {
|
|
402
|
-
if (prices[i] > maxPrice) {
|
|
403
|
-
maxPrice = prices[i];
|
|
404
|
-
}
|
|
405
|
-
const drawdown = (maxPrice - prices[i]) / maxPrice;
|
|
406
|
-
if (drawdown > maxDrawdown) {
|
|
407
|
-
maxDrawdown = drawdown;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return maxDrawdown;
|
|
411
|
-
}
|
|
412
|
-
// Calculate price changes for volatility
|
|
413
|
-
calculatePriceChanges() {
|
|
414
|
-
const changes = [];
|
|
415
|
-
for (let i = 1; i < this.prices.length; i++) {
|
|
416
|
-
changes.push((this.prices[i] - this.prices[i - 1]) / this.prices[i - 1]);
|
|
417
|
-
}
|
|
418
|
-
return changes;
|
|
419
|
-
}
|
|
420
|
-
// Generate comprehensive market analysis
|
|
421
|
-
analyze() {
|
|
422
|
-
const currentPrice = this.prices[this.prices.length - 1];
|
|
423
|
-
const startPrice = this.prices[0];
|
|
424
|
-
const sessionHigh = Math.max(...this.highs);
|
|
425
|
-
const sessionLow = Math.min(...this.lows);
|
|
426
|
-
const totalVolume = sum(this.volumes);
|
|
427
|
-
const avgVolume = totalVolume / this.volumes.length;
|
|
428
|
-
const priceChanges = this.calculatePriceChanges();
|
|
429
|
-
const volatility = priceChanges.length > 0 ? Math.sqrt(
|
|
430
|
-
priceChanges.reduce((sum2, change) => sum2 + change ** 2, 0) / priceChanges.length
|
|
431
|
-
) * Math.sqrt(252) * 100 : 0;
|
|
432
|
-
const sessionReturn = (currentPrice - startPrice) / startPrice * 100;
|
|
433
|
-
const pricePosition = (currentPrice - sessionLow) / (sessionHigh - sessionLow) * 100;
|
|
434
|
-
const trueVWAP = this.prices.reduce((sum2, price, i) => sum2 + price * this.volumes[i], 0) / totalVolume;
|
|
435
|
-
const momentum5 = this.prices.length > 5 ? (currentPrice - this.prices[Math.max(0, this.prices.length - 6)]) / this.prices[Math.max(0, this.prices.length - 6)] * 100 : 0;
|
|
436
|
-
const momentum10 = this.prices.length > 10 ? (currentPrice - this.prices[Math.max(0, this.prices.length - 11)]) / this.prices[Math.max(0, this.prices.length - 11)] * 100 : 0;
|
|
437
|
-
const maxDrawdown = this.calculateMaxDrawdown(this.prices);
|
|
438
|
-
return {
|
|
439
|
-
currentPrice,
|
|
440
|
-
startPrice,
|
|
441
|
-
sessionHigh,
|
|
442
|
-
sessionLow,
|
|
443
|
-
totalVolume,
|
|
444
|
-
avgVolume,
|
|
445
|
-
volatility,
|
|
446
|
-
sessionReturn,
|
|
447
|
-
pricePosition,
|
|
448
|
-
trueVWAP,
|
|
449
|
-
momentum5,
|
|
450
|
-
momentum10,
|
|
451
|
-
maxDrawdown
|
|
452
|
-
};
|
|
453
|
-
}
|
|
454
|
-
// Generate technical indicators
|
|
455
|
-
getTechnicalIndicators() {
|
|
456
|
-
return {
|
|
457
|
-
sma5: this.calculateSMA(this.prices, 5),
|
|
458
|
-
sma10: this.calculateSMA(this.prices, 10),
|
|
459
|
-
ema8: this.calculateEMA(this.prices, 8),
|
|
460
|
-
ema21: this.calculateEMA(this.prices, 21),
|
|
461
|
-
rsi: this.calculateRSI(this.prices, 14),
|
|
462
|
-
bollinger: this.calculateBollingerBands(this.prices, 20, 2)
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
// Generate trading signals
|
|
466
|
-
generateSignals() {
|
|
467
|
-
const analysis = this.analyze();
|
|
468
|
-
let bullishSignals = 0;
|
|
469
|
-
let bearishSignals = 0;
|
|
470
|
-
const signals = [];
|
|
471
|
-
if (analysis.currentPrice > analysis.trueVWAP) {
|
|
472
|
-
signals.push(
|
|
473
|
-
`\u2713 BULLISH: Price above VWAP (+${((analysis.currentPrice - analysis.trueVWAP) / analysis.trueVWAP * 100).toFixed(2)}%)`
|
|
474
|
-
);
|
|
475
|
-
bullishSignals++;
|
|
476
|
-
} else {
|
|
477
|
-
signals.push(
|
|
478
|
-
`\u2717 BEARISH: Price below VWAP (${((analysis.currentPrice - analysis.trueVWAP) / analysis.trueVWAP * 100).toFixed(2)}%)`
|
|
479
|
-
);
|
|
480
|
-
bearishSignals++;
|
|
481
|
-
}
|
|
482
|
-
if (analysis.momentum5 > 0 && analysis.momentum10 > 0) {
|
|
483
|
-
signals.push("\u2713 BULLISH: Positive momentum on both timeframes");
|
|
484
|
-
bullishSignals++;
|
|
485
|
-
} else if (analysis.momentum5 < 0 && analysis.momentum10 < 0) {
|
|
486
|
-
signals.push("\u2717 BEARISH: Negative momentum on both timeframes");
|
|
487
|
-
bearishSignals++;
|
|
488
|
-
} else {
|
|
489
|
-
signals.push("\u25D0 MIXED: Conflicting momentum signals");
|
|
490
|
-
}
|
|
491
|
-
const currentVolume = this.volumes[this.volumes.length - 1];
|
|
492
|
-
const volumeRatio = currentVolume / analysis.avgVolume;
|
|
493
|
-
if (volumeRatio > 1.2 && analysis.sessionReturn > 0) {
|
|
494
|
-
signals.push("\u2713 BULLISH: Above-average volume supporting upward move");
|
|
495
|
-
bullishSignals++;
|
|
496
|
-
} else if (volumeRatio > 1.2 && analysis.sessionReturn < 0) {
|
|
497
|
-
signals.push("\u2717 BEARISH: Above-average volume supporting downward move");
|
|
498
|
-
bearishSignals++;
|
|
499
|
-
} else {
|
|
500
|
-
signals.push("\u25D0 NEUTRAL: Volume not providing clear direction");
|
|
501
|
-
}
|
|
502
|
-
if (analysis.pricePosition > 65 && analysis.volatility > 30) {
|
|
503
|
-
signals.push("\u2717 BEARISH: High in range with elevated volatility - reversal risk");
|
|
504
|
-
bearishSignals++;
|
|
505
|
-
} else if (analysis.pricePosition < 35 && analysis.volatility > 30) {
|
|
506
|
-
signals.push("\u2713 BULLISH: Low in range with volatility - potential bounce");
|
|
507
|
-
bullishSignals++;
|
|
508
|
-
} else {
|
|
509
|
-
signals.push("\u25D0 NEUTRAL: Price position and volatility not extreme");
|
|
510
|
-
}
|
|
511
|
-
return { bullishSignals, bearishSignals, signals };
|
|
512
|
-
}
|
|
513
|
-
// Generate comprehensive JSON analysis
|
|
514
|
-
generateJSONAnalysis(symbol) {
|
|
515
|
-
const analysis = this.analyze();
|
|
516
|
-
const indicators = this.getTechnicalIndicators();
|
|
517
|
-
const signals = this.generateSignals();
|
|
518
|
-
const currentSMA5 = indicators.sma5.length > 0 ? indicators.sma5[indicators.sma5.length - 1] : null;
|
|
519
|
-
const currentSMA10 = indicators.sma10.length > 0 ? indicators.sma10[indicators.sma10.length - 1] : null;
|
|
520
|
-
const currentEMA8 = indicators.ema8[indicators.ema8.length - 1];
|
|
521
|
-
const currentEMA21 = indicators.ema21[indicators.ema21.length - 1];
|
|
522
|
-
const currentRSI = indicators.rsi.length > 0 ? indicators.rsi[indicators.rsi.length - 1] : null;
|
|
523
|
-
const currentBB = indicators.bollinger.length > 0 ? indicators.bollinger[indicators.bollinger.length - 1] : null;
|
|
524
|
-
const currentVolume = this.volumes[this.volumes.length - 1];
|
|
525
|
-
const volumeRatio = currentVolume / analysis.avgVolume;
|
|
526
|
-
const currentDrawdown = (analysis.sessionHigh - analysis.currentPrice) / analysis.sessionHigh * 100;
|
|
527
|
-
const rangeWidth = (analysis.sessionHigh - analysis.sessionLow) / analysis.sessionLow * 100;
|
|
528
|
-
const priceVsVWAP = (analysis.currentPrice - analysis.trueVWAP) / analysis.trueVWAP * 100;
|
|
529
|
-
const totalScore = signals.bullishSignals - signals.bearishSignals;
|
|
530
|
-
const overallSignal = totalScore > 0 ? "BULLISH_BIAS" : totalScore < 0 ? "BEARISH_BIAS" : "NEUTRAL";
|
|
531
|
-
const targetEntry = Math.max(analysis.sessionLow * 1.005, analysis.trueVWAP * 0.998);
|
|
532
|
-
const stopLoss = analysis.sessionLow * 0.995;
|
|
533
|
-
const profitTarget = analysis.sessionHigh * 0.995;
|
|
534
|
-
const riskRewardRatio = (profitTarget - analysis.currentPrice) / (analysis.currentPrice - stopLoss);
|
|
535
|
-
return {
|
|
536
|
-
symbol,
|
|
537
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
538
|
-
marketStructure: {
|
|
539
|
-
currentPrice: analysis.currentPrice,
|
|
540
|
-
startPrice: analysis.startPrice,
|
|
541
|
-
sessionHigh: analysis.sessionHigh,
|
|
542
|
-
sessionLow: analysis.sessionLow,
|
|
543
|
-
rangeWidth,
|
|
544
|
-
totalVolume: analysis.totalVolume,
|
|
545
|
-
sessionPerformance: analysis.sessionReturn,
|
|
546
|
-
positionInRange: analysis.pricePosition
|
|
547
|
-
},
|
|
548
|
-
volatility: {
|
|
549
|
-
impliedVolatility: analysis.volatility,
|
|
550
|
-
maxDrawdown: analysis.maxDrawdown * 100,
|
|
551
|
-
currentDrawdown
|
|
552
|
-
},
|
|
553
|
-
technicalIndicators: {
|
|
554
|
-
sma5: currentSMA5,
|
|
555
|
-
sma10: currentSMA10,
|
|
556
|
-
ema8: currentEMA8,
|
|
557
|
-
ema21: currentEMA21,
|
|
558
|
-
rsi: currentRSI,
|
|
559
|
-
bollingerBands: currentBB ? {
|
|
560
|
-
upper: currentBB.upper,
|
|
561
|
-
middle: currentBB.middle,
|
|
562
|
-
lower: currentBB.lower,
|
|
563
|
-
position: (analysis.currentPrice - currentBB.lower) / (currentBB.upper - currentBB.lower) * 100
|
|
564
|
-
} : null
|
|
565
|
-
},
|
|
566
|
-
volumeAnalysis: {
|
|
567
|
-
currentVolume,
|
|
568
|
-
averageVolume: Math.round(analysis.avgVolume),
|
|
569
|
-
volumeRatio,
|
|
570
|
-
trueVWAP: analysis.trueVWAP,
|
|
571
|
-
priceVsVWAP
|
|
572
|
-
},
|
|
573
|
-
momentum: {
|
|
574
|
-
momentum5: analysis.momentum5,
|
|
575
|
-
momentum10: analysis.momentum10,
|
|
576
|
-
sessionROC: analysis.sessionReturn
|
|
577
|
-
},
|
|
578
|
-
tradingSignals: {
|
|
579
|
-
...signals,
|
|
580
|
-
overallSignal,
|
|
581
|
-
signalScore: totalScore
|
|
582
|
-
},
|
|
583
|
-
riskManagement: {
|
|
584
|
-
targetEntry,
|
|
585
|
-
stopLoss,
|
|
586
|
-
profitTarget,
|
|
587
|
-
riskRewardRatio
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
var createTechnicalAnalysisHandler = (marketDataPrices) => {
|
|
593
|
-
return async (args) => {
|
|
594
|
-
try {
|
|
595
|
-
const symbol = args.symbol;
|
|
596
|
-
const priceHistory = marketDataPrices.get(symbol) || [];
|
|
597
|
-
if (priceHistory.length === 0) {
|
|
598
|
-
return {
|
|
599
|
-
content: [
|
|
600
|
-
{
|
|
601
|
-
type: "text",
|
|
602
|
-
text: `No price data available for ${symbol}. Please request market data first.`,
|
|
603
|
-
uri: "technicalAnalysis"
|
|
604
|
-
}
|
|
605
|
-
]
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
const analyzer = new TechnicalAnalyzer(priceHistory);
|
|
609
|
-
const analysis = analyzer.generateJSONAnalysis(symbol);
|
|
610
|
-
return {
|
|
611
|
-
content: [
|
|
612
|
-
{
|
|
613
|
-
type: "text",
|
|
614
|
-
text: `Technical Analysis for ${symbol}:
|
|
615
|
-
|
|
616
|
-
${JSON.stringify(analysis, null, 2)}`,
|
|
617
|
-
uri: "technicalAnalysis"
|
|
618
|
-
}
|
|
619
|
-
]
|
|
620
|
-
};
|
|
621
|
-
} catch (error) {
|
|
622
|
-
return {
|
|
623
|
-
content: [
|
|
624
|
-
{
|
|
625
|
-
type: "text",
|
|
626
|
-
text: `Error performing technical analysis: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
627
|
-
uri: "technicalAnalysis"
|
|
628
|
-
}
|
|
629
|
-
],
|
|
630
|
-
isError: true
|
|
631
|
-
};
|
|
632
|
-
}
|
|
633
|
-
};
|
|
634
|
-
};
|
|
635
|
-
|
|
636
313
|
// src/tools/marketData.ts
|
|
637
314
|
var import_fixparser = require("fixparser");
|
|
638
315
|
var import_quickchart_js = __toESM(require("quickchart-js"), 1);
|
|
639
316
|
var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
640
317
|
return async (args) => {
|
|
641
318
|
try {
|
|
642
|
-
parser.logger.log({
|
|
643
|
-
level: "info",
|
|
644
|
-
message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
|
|
645
|
-
});
|
|
646
319
|
const response = new Promise((resolve) => {
|
|
647
320
|
pendingRequests.set(args.mdReqID, resolve);
|
|
648
|
-
parser.logger.log({
|
|
649
|
-
level: "info",
|
|
650
|
-
message: `Registered callback for market data request ID: ${args.mdReqID}`
|
|
651
|
-
});
|
|
652
321
|
});
|
|
653
|
-
const entryTypes = args.mdEntryTypes || [
|
|
654
|
-
import_fixparser.MDEntryType.Bid,
|
|
655
|
-
import_fixparser.MDEntryType.Offer,
|
|
656
|
-
import_fixparser.MDEntryType.Trade,
|
|
657
|
-
import_fixparser.MDEntryType.IndexValue,
|
|
658
|
-
import_fixparser.MDEntryType.OpeningPrice,
|
|
659
|
-
import_fixparser.MDEntryType.ClosingPrice,
|
|
660
|
-
import_fixparser.MDEntryType.SettlementPrice,
|
|
661
|
-
import_fixparser.MDEntryType.TradingSessionHighPrice,
|
|
662
|
-
import_fixparser.MDEntryType.TradingSessionLowPrice,
|
|
663
|
-
import_fixparser.MDEntryType.VWAP,
|
|
664
|
-
import_fixparser.MDEntryType.Imbalance,
|
|
665
|
-
import_fixparser.MDEntryType.TradeVolume,
|
|
666
|
-
import_fixparser.MDEntryType.OpenInterest,
|
|
667
|
-
import_fixparser.MDEntryType.CompositeUnderlyingPrice,
|
|
668
|
-
import_fixparser.MDEntryType.SimulatedSellPrice,
|
|
669
|
-
import_fixparser.MDEntryType.SimulatedBuyPrice,
|
|
670
|
-
import_fixparser.MDEntryType.MarginRate,
|
|
671
|
-
import_fixparser.MDEntryType.MidPrice,
|
|
672
|
-
import_fixparser.MDEntryType.EmptyBook,
|
|
673
|
-
import_fixparser.MDEntryType.SettleHighPrice,
|
|
674
|
-
import_fixparser.MDEntryType.SettleLowPrice,
|
|
675
|
-
import_fixparser.MDEntryType.PriorSettlePrice,
|
|
676
|
-
import_fixparser.MDEntryType.SessionHighBid,
|
|
677
|
-
import_fixparser.MDEntryType.SessionLowOffer,
|
|
678
|
-
import_fixparser.MDEntryType.EarlyPrices,
|
|
679
|
-
import_fixparser.MDEntryType.AuctionClearingPrice,
|
|
680
|
-
import_fixparser.MDEntryType.SwapValueFactor,
|
|
681
|
-
import_fixparser.MDEntryType.DailyValueAdjustmentForLongPositions,
|
|
682
|
-
import_fixparser.MDEntryType.CumulativeValueAdjustmentForLongPositions,
|
|
683
|
-
import_fixparser.MDEntryType.DailyValueAdjustmentForShortPositions,
|
|
684
|
-
import_fixparser.MDEntryType.CumulativeValueAdjustmentForShortPositions,
|
|
685
|
-
import_fixparser.MDEntryType.FixingPrice,
|
|
686
|
-
import_fixparser.MDEntryType.CashRate,
|
|
687
|
-
import_fixparser.MDEntryType.RecoveryRate,
|
|
688
|
-
import_fixparser.MDEntryType.RecoveryRateForLong,
|
|
689
|
-
import_fixparser.MDEntryType.RecoveryRateForShort,
|
|
690
|
-
import_fixparser.MDEntryType.MarketBid,
|
|
691
|
-
import_fixparser.MDEntryType.MarketOffer,
|
|
692
|
-
import_fixparser.MDEntryType.ShortSaleMinPrice,
|
|
693
|
-
import_fixparser.MDEntryType.PreviousClosingPrice,
|
|
694
|
-
import_fixparser.MDEntryType.ThresholdLimitPriceBanding,
|
|
695
|
-
import_fixparser.MDEntryType.DailyFinancingValue,
|
|
696
|
-
import_fixparser.MDEntryType.AccruedFinancingValue,
|
|
697
|
-
import_fixparser.MDEntryType.TWAP
|
|
698
|
-
];
|
|
322
|
+
const entryTypes = args.mdEntryTypes || [import_fixparser.MDEntryType.Bid, import_fixparser.MDEntryType.Offer, import_fixparser.MDEntryType.TradeVolume];
|
|
699
323
|
const messageFields = [
|
|
700
324
|
new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
|
|
701
325
|
new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
|
|
@@ -717,10 +341,6 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
717
341
|
});
|
|
718
342
|
const mdr = parser.createMessage(...messageFields);
|
|
719
343
|
if (!parser.connected) {
|
|
720
|
-
parser.logger.log({
|
|
721
|
-
level: "error",
|
|
722
|
-
message: "Not connected. Cannot send market data request."
|
|
723
|
-
});
|
|
724
344
|
return {
|
|
725
345
|
content: [
|
|
726
346
|
{
|
|
@@ -732,16 +352,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
732
352
|
isError: true
|
|
733
353
|
};
|
|
734
354
|
}
|
|
735
|
-
parser.logger.log({
|
|
736
|
-
level: "info",
|
|
737
|
-
message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
|
|
738
|
-
});
|
|
739
355
|
parser.send(mdr);
|
|
740
356
|
const fixData = await response;
|
|
741
|
-
parser.logger.log({
|
|
742
|
-
level: "info",
|
|
743
|
-
message: `Received market data response for request ID: ${args.mdReqID}`
|
|
744
|
-
});
|
|
745
357
|
return {
|
|
746
358
|
content: [
|
|
747
359
|
{
|
|
@@ -790,9 +402,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
790
402
|
const offerData = priceHistory.map((point) => point.offer);
|
|
791
403
|
const spreadData = priceHistory.map((point) => point.spread);
|
|
792
404
|
const volumeData = priceHistory.map((point) => point.volume);
|
|
793
|
-
const tradeData = priceHistory.map((point) => point.trade);
|
|
794
|
-
const vwapData = priceHistory.map((point) => point.vwap);
|
|
795
|
-
const twapData = priceHistory.map((point) => point.twap);
|
|
796
405
|
const config = {
|
|
797
406
|
type: "line",
|
|
798
407
|
data: {
|
|
@@ -822,30 +431,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
822
431
|
fill: false,
|
|
823
432
|
tension: 0.4
|
|
824
433
|
},
|
|
825
|
-
{
|
|
826
|
-
label: "Trade",
|
|
827
|
-
data: tradeData,
|
|
828
|
-
borderColor: "#ffc107",
|
|
829
|
-
backgroundColor: "rgba(255, 193, 7, 0.1)",
|
|
830
|
-
fill: false,
|
|
831
|
-
tension: 0.4
|
|
832
|
-
},
|
|
833
|
-
{
|
|
834
|
-
label: "VWAP",
|
|
835
|
-
data: vwapData,
|
|
836
|
-
borderColor: "#17a2b8",
|
|
837
|
-
backgroundColor: "rgba(23, 162, 184, 0.1)",
|
|
838
|
-
fill: false,
|
|
839
|
-
tension: 0.4
|
|
840
|
-
},
|
|
841
|
-
{
|
|
842
|
-
label: "TWAP",
|
|
843
|
-
data: twapData,
|
|
844
|
-
borderColor: "#6610f2",
|
|
845
|
-
backgroundColor: "rgba(102, 16, 242, 0.1)",
|
|
846
|
-
fill: false,
|
|
847
|
-
tension: 0.4
|
|
848
|
-
},
|
|
849
434
|
{
|
|
850
435
|
label: "Volume",
|
|
851
436
|
data: volumeData,
|
|
@@ -891,7 +476,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
891
476
|
content: [
|
|
892
477
|
{
|
|
893
478
|
type: "text",
|
|
894
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate
|
|
479
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
|
|
895
480
|
uri: "getStockGraph"
|
|
896
481
|
}
|
|
897
482
|
],
|
|
@@ -929,48 +514,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
929
514
|
bid: point.bid,
|
|
930
515
|
offer: point.offer,
|
|
931
516
|
spread: point.spread,
|
|
932
|
-
volume: point.volume
|
|
933
|
-
trade: point.trade,
|
|
934
|
-
indexValue: point.indexValue,
|
|
935
|
-
openingPrice: point.openingPrice,
|
|
936
|
-
closingPrice: point.closingPrice,
|
|
937
|
-
settlementPrice: point.settlementPrice,
|
|
938
|
-
tradingSessionHighPrice: point.tradingSessionHighPrice,
|
|
939
|
-
tradingSessionLowPrice: point.tradingSessionLowPrice,
|
|
940
|
-
vwap: point.vwap,
|
|
941
|
-
imbalance: point.imbalance,
|
|
942
|
-
openInterest: point.openInterest,
|
|
943
|
-
compositeUnderlyingPrice: point.compositeUnderlyingPrice,
|
|
944
|
-
simulatedSellPrice: point.simulatedSellPrice,
|
|
945
|
-
simulatedBuyPrice: point.simulatedBuyPrice,
|
|
946
|
-
marginRate: point.marginRate,
|
|
947
|
-
midPrice: point.midPrice,
|
|
948
|
-
emptyBook: point.emptyBook,
|
|
949
|
-
settleHighPrice: point.settleHighPrice,
|
|
950
|
-
settleLowPrice: point.settleLowPrice,
|
|
951
|
-
priorSettlePrice: point.priorSettlePrice,
|
|
952
|
-
sessionHighBid: point.sessionHighBid,
|
|
953
|
-
sessionLowOffer: point.sessionLowOffer,
|
|
954
|
-
earlyPrices: point.earlyPrices,
|
|
955
|
-
auctionClearingPrice: point.auctionClearingPrice,
|
|
956
|
-
swapValueFactor: point.swapValueFactor,
|
|
957
|
-
dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
|
|
958
|
-
cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
|
|
959
|
-
dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
|
|
960
|
-
cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
|
|
961
|
-
fixingPrice: point.fixingPrice,
|
|
962
|
-
cashRate: point.cashRate,
|
|
963
|
-
recoveryRate: point.recoveryRate,
|
|
964
|
-
recoveryRateForLong: point.recoveryRateForLong,
|
|
965
|
-
recoveryRateForShort: point.recoveryRateForShort,
|
|
966
|
-
marketBid: point.marketBid,
|
|
967
|
-
marketOffer: point.marketOffer,
|
|
968
|
-
shortSaleMinPrice: point.shortSaleMinPrice,
|
|
969
|
-
previousClosingPrice: point.previousClosingPrice,
|
|
970
|
-
thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
|
|
971
|
-
dailyFinancingValue: point.dailyFinancingValue,
|
|
972
|
-
accruedFinancingValue: point.accruedFinancingValue,
|
|
973
|
-
twap: point.twap
|
|
517
|
+
volume: point.volume
|
|
974
518
|
}))
|
|
975
519
|
},
|
|
976
520
|
null,
|
|
@@ -985,7 +529,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
985
529
|
content: [
|
|
986
530
|
{
|
|
987
531
|
type: "text",
|
|
988
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
532
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
|
|
989
533
|
uri: "getStockPriceHistory"
|
|
990
534
|
}
|
|
991
535
|
],
|
|
@@ -1093,7 +637,7 @@ Parameters verified:
|
|
|
1093
637
|
- Symbol: ${args.symbol}
|
|
1094
638
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
1095
639
|
|
|
1096
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
640
|
+
To execute this order, call the executeOrder tool with these exact same parameters.`,
|
|
1097
641
|
uri: "verifyOrder"
|
|
1098
642
|
}
|
|
1099
643
|
]
|
|
@@ -1289,210 +833,48 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
1289
833
|
executeOrder: createExecuteOrderHandler(parser, verifiedOrders, pendingRequests),
|
|
1290
834
|
marketDataRequest: createMarketDataRequestHandler(parser, pendingRequests),
|
|
1291
835
|
getStockGraph: createGetStockGraphHandler(marketDataPrices),
|
|
1292
|
-
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
1293
|
-
technicalAnalysis: createTechnicalAnalysisHandler(marketDataPrices)
|
|
836
|
+
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
1294
837
|
});
|
|
1295
838
|
|
|
1296
839
|
// src/utils/messageHandler.ts
|
|
1297
840
|
var import_fixparser3 = require("fixparser");
|
|
1298
|
-
function getEnumValue(enumObj, name) {
|
|
1299
|
-
return enumObj[name] || name;
|
|
1300
|
-
}
|
|
1301
841
|
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
842
|
+
parser.logger.log({
|
|
843
|
+
level: "info",
|
|
844
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
845
|
+
});
|
|
1302
846
|
const msgType = message.messageType;
|
|
1303
|
-
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh
|
|
847
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
1304
848
|
const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
compositeUnderlyingPrice: 0,
|
|
1324
|
-
simulatedSellPrice: 0,
|
|
1325
|
-
simulatedBuyPrice: 0,
|
|
1326
|
-
marginRate: 0,
|
|
1327
|
-
midPrice: 0,
|
|
1328
|
-
emptyBook: 0,
|
|
1329
|
-
settleHighPrice: 0,
|
|
1330
|
-
settleLowPrice: 0,
|
|
1331
|
-
priorSettlePrice: 0,
|
|
1332
|
-
sessionHighBid: 0,
|
|
1333
|
-
sessionLowOffer: 0,
|
|
1334
|
-
earlyPrices: 0,
|
|
1335
|
-
auctionClearingPrice: 0,
|
|
1336
|
-
swapValueFactor: 0,
|
|
1337
|
-
dailyValueAdjustmentForLongPositions: 0,
|
|
1338
|
-
cumulativeValueAdjustmentForLongPositions: 0,
|
|
1339
|
-
dailyValueAdjustmentForShortPositions: 0,
|
|
1340
|
-
cumulativeValueAdjustmentForShortPositions: 0,
|
|
1341
|
-
fixingPrice: 0,
|
|
1342
|
-
cashRate: 0,
|
|
1343
|
-
recoveryRate: 0,
|
|
1344
|
-
recoveryRateForLong: 0,
|
|
1345
|
-
recoveryRateForShort: 0,
|
|
1346
|
-
marketBid: 0,
|
|
1347
|
-
marketOffer: 0,
|
|
1348
|
-
shortSaleMinPrice: 0,
|
|
1349
|
-
previousClosingPrice: 0,
|
|
1350
|
-
thresholdLimitPriceBanding: 0,
|
|
1351
|
-
dailyFinancingValue: 0,
|
|
1352
|
-
accruedFinancingValue: 0,
|
|
1353
|
-
twap: 0
|
|
1354
|
-
};
|
|
1355
|
-
for (const entry of entries) {
|
|
1356
|
-
const entryType = entry.MDEntryType;
|
|
1357
|
-
const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
|
|
1358
|
-
const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
|
|
1359
|
-
const enumValue = getEnumValue(import_fixparser3.MDEntryType, entryType);
|
|
1360
|
-
switch (enumValue) {
|
|
1361
|
-
case import_fixparser3.MDEntryType.Bid:
|
|
1362
|
-
data.bid = price;
|
|
1363
|
-
break;
|
|
1364
|
-
case import_fixparser3.MDEntryType.Offer:
|
|
1365
|
-
data.offer = price;
|
|
1366
|
-
break;
|
|
1367
|
-
case import_fixparser3.MDEntryType.Trade:
|
|
1368
|
-
data.trade = price;
|
|
1369
|
-
break;
|
|
1370
|
-
case import_fixparser3.MDEntryType.IndexValue:
|
|
1371
|
-
data.indexValue = price;
|
|
1372
|
-
break;
|
|
1373
|
-
case import_fixparser3.MDEntryType.OpeningPrice:
|
|
1374
|
-
data.openingPrice = price;
|
|
1375
|
-
break;
|
|
1376
|
-
case import_fixparser3.MDEntryType.ClosingPrice:
|
|
1377
|
-
data.closingPrice = price;
|
|
1378
|
-
break;
|
|
1379
|
-
case import_fixparser3.MDEntryType.SettlementPrice:
|
|
1380
|
-
data.settlementPrice = price;
|
|
1381
|
-
break;
|
|
1382
|
-
case import_fixparser3.MDEntryType.TradingSessionHighPrice:
|
|
1383
|
-
data.tradingSessionHighPrice = price;
|
|
1384
|
-
break;
|
|
1385
|
-
case import_fixparser3.MDEntryType.TradingSessionLowPrice:
|
|
1386
|
-
data.tradingSessionLowPrice = price;
|
|
1387
|
-
break;
|
|
1388
|
-
case import_fixparser3.MDEntryType.VWAP:
|
|
1389
|
-
data.vwap = price;
|
|
1390
|
-
break;
|
|
1391
|
-
case import_fixparser3.MDEntryType.Imbalance:
|
|
1392
|
-
data.imbalance = size;
|
|
1393
|
-
break;
|
|
1394
|
-
case import_fixparser3.MDEntryType.TradeVolume:
|
|
1395
|
-
data.volume = size;
|
|
1396
|
-
break;
|
|
1397
|
-
case import_fixparser3.MDEntryType.OpenInterest:
|
|
1398
|
-
data.openInterest = size;
|
|
1399
|
-
break;
|
|
1400
|
-
case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
|
|
1401
|
-
data.compositeUnderlyingPrice = price;
|
|
1402
|
-
break;
|
|
1403
|
-
case import_fixparser3.MDEntryType.SimulatedSellPrice:
|
|
1404
|
-
data.simulatedSellPrice = price;
|
|
1405
|
-
break;
|
|
1406
|
-
case import_fixparser3.MDEntryType.SimulatedBuyPrice:
|
|
1407
|
-
data.simulatedBuyPrice = price;
|
|
1408
|
-
break;
|
|
1409
|
-
case import_fixparser3.MDEntryType.MarginRate:
|
|
1410
|
-
data.marginRate = price;
|
|
1411
|
-
break;
|
|
1412
|
-
case import_fixparser3.MDEntryType.MidPrice:
|
|
1413
|
-
data.midPrice = price;
|
|
1414
|
-
break;
|
|
1415
|
-
case import_fixparser3.MDEntryType.EmptyBook:
|
|
1416
|
-
data.emptyBook = 1;
|
|
1417
|
-
break;
|
|
1418
|
-
case import_fixparser3.MDEntryType.SettleHighPrice:
|
|
1419
|
-
data.settleHighPrice = price;
|
|
1420
|
-
break;
|
|
1421
|
-
case import_fixparser3.MDEntryType.SettleLowPrice:
|
|
1422
|
-
data.settleLowPrice = price;
|
|
1423
|
-
break;
|
|
1424
|
-
case import_fixparser3.MDEntryType.PriorSettlePrice:
|
|
1425
|
-
data.priorSettlePrice = price;
|
|
1426
|
-
break;
|
|
1427
|
-
case import_fixparser3.MDEntryType.SessionHighBid:
|
|
1428
|
-
data.sessionHighBid = price;
|
|
1429
|
-
break;
|
|
1430
|
-
case import_fixparser3.MDEntryType.SessionLowOffer:
|
|
1431
|
-
data.sessionLowOffer = price;
|
|
1432
|
-
break;
|
|
1433
|
-
case import_fixparser3.MDEntryType.EarlyPrices:
|
|
1434
|
-
data.earlyPrices = price;
|
|
1435
|
-
break;
|
|
1436
|
-
case import_fixparser3.MDEntryType.AuctionClearingPrice:
|
|
1437
|
-
data.auctionClearingPrice = price;
|
|
1438
|
-
break;
|
|
1439
|
-
case import_fixparser3.MDEntryType.SwapValueFactor:
|
|
1440
|
-
data.swapValueFactor = price;
|
|
1441
|
-
break;
|
|
1442
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
|
|
1443
|
-
data.dailyValueAdjustmentForLongPositions = price;
|
|
1444
|
-
break;
|
|
1445
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
|
|
1446
|
-
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1447
|
-
break;
|
|
1448
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
|
|
1449
|
-
data.dailyValueAdjustmentForShortPositions = price;
|
|
1450
|
-
break;
|
|
1451
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
|
|
1452
|
-
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1453
|
-
break;
|
|
1454
|
-
case import_fixparser3.MDEntryType.FixingPrice:
|
|
1455
|
-
data.fixingPrice = price;
|
|
1456
|
-
break;
|
|
1457
|
-
case import_fixparser3.MDEntryType.CashRate:
|
|
1458
|
-
data.cashRate = price;
|
|
1459
|
-
break;
|
|
1460
|
-
case import_fixparser3.MDEntryType.RecoveryRate:
|
|
1461
|
-
data.recoveryRate = price;
|
|
1462
|
-
break;
|
|
1463
|
-
case import_fixparser3.MDEntryType.RecoveryRateForLong:
|
|
1464
|
-
data.recoveryRateForLong = price;
|
|
1465
|
-
break;
|
|
1466
|
-
case import_fixparser3.MDEntryType.RecoveryRateForShort:
|
|
1467
|
-
data.recoveryRateForShort = price;
|
|
1468
|
-
break;
|
|
1469
|
-
case import_fixparser3.MDEntryType.MarketBid:
|
|
1470
|
-
data.marketBid = price;
|
|
1471
|
-
break;
|
|
1472
|
-
case import_fixparser3.MDEntryType.MarketOffer:
|
|
1473
|
-
data.marketOffer = price;
|
|
1474
|
-
break;
|
|
1475
|
-
case import_fixparser3.MDEntryType.ShortSaleMinPrice:
|
|
1476
|
-
data.shortSaleMinPrice = price;
|
|
1477
|
-
break;
|
|
1478
|
-
case import_fixparser3.MDEntryType.PreviousClosingPrice:
|
|
1479
|
-
data.previousClosingPrice = price;
|
|
1480
|
-
break;
|
|
1481
|
-
case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
|
|
1482
|
-
data.thresholdLimitPriceBanding = price;
|
|
1483
|
-
break;
|
|
1484
|
-
case import_fixparser3.MDEntryType.DailyFinancingValue:
|
|
1485
|
-
data.dailyFinancingValue = price;
|
|
1486
|
-
break;
|
|
1487
|
-
case import_fixparser3.MDEntryType.AccruedFinancingValue:
|
|
1488
|
-
data.accruedFinancingValue = price;
|
|
1489
|
-
break;
|
|
1490
|
-
case import_fixparser3.MDEntryType.TWAP:
|
|
1491
|
-
data.twap = price;
|
|
1492
|
-
break;
|
|
849
|
+
const entries = message.getField(import_fixparser3.Fields.NoMDEntries)?.value;
|
|
850
|
+
let bid = 0;
|
|
851
|
+
let offer = 0;
|
|
852
|
+
let volume = 0;
|
|
853
|
+
const entryTypes = message.getFields(import_fixparser3.Fields.MDEntryType);
|
|
854
|
+
const entryPrices = message.getFields(import_fixparser3.Fields.MDEntryPx);
|
|
855
|
+
const entrySizes = message.getFields(import_fixparser3.Fields.MDEntrySize);
|
|
856
|
+
if (entryTypes && entryPrices && entrySizes) {
|
|
857
|
+
for (let i = 0; i < entries; i++) {
|
|
858
|
+
const entryType = entryTypes[i]?.value;
|
|
859
|
+
const entryPrice = Number.parseFloat(entryPrices[i]?.value);
|
|
860
|
+
const entrySize = Number.parseFloat(entrySizes[i]?.value);
|
|
861
|
+
if (entryType === import_fixparser3.MDEntryType.Bid) {
|
|
862
|
+
bid = entryPrice;
|
|
863
|
+
} else if (entryType === import_fixparser3.MDEntryType.Offer) {
|
|
864
|
+
offer = entryPrice;
|
|
865
|
+
}
|
|
866
|
+
volume += entrySize;
|
|
1493
867
|
}
|
|
1494
868
|
}
|
|
1495
|
-
|
|
869
|
+
const spread = offer - bid;
|
|
870
|
+
const timestamp = Date.now();
|
|
871
|
+
const data = {
|
|
872
|
+
timestamp,
|
|
873
|
+
bid,
|
|
874
|
+
offer,
|
|
875
|
+
spread,
|
|
876
|
+
volume
|
|
877
|
+
};
|
|
1496
878
|
if (!marketDataPrices.has(symbol)) {
|
|
1497
879
|
marketDataPrices.set(symbol, []);
|
|
1498
880
|
}
|
|
@@ -1502,14 +884,6 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
|
|
|
1502
884
|
prices.splice(0, prices.length - maxPriceHistory);
|
|
1503
885
|
}
|
|
1504
886
|
onPriceUpdate?.(symbol, data);
|
|
1505
|
-
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
|
|
1506
|
-
if (mdReqID) {
|
|
1507
|
-
const callback = pendingRequests.get(mdReqID);
|
|
1508
|
-
if (callback) {
|
|
1509
|
-
callback(message);
|
|
1510
|
-
pendingRequests.delete(mdReqID);
|
|
1511
|
-
}
|
|
1512
|
-
}
|
|
1513
887
|
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
1514
888
|
const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
|
|
1515
889
|
const callback = pendingRequests.get(reqId);
|
|
@@ -1538,7 +912,7 @@ var MCPLocal = class extends MCPBase {
|
|
|
1538
912
|
*/
|
|
1539
913
|
marketDataPrices = /* @__PURE__ */ new Map();
|
|
1540
914
|
/**
|
|
1541
|
-
* Maximum number of price
|
|
915
|
+
* Maximum number of price points to store per symbol
|
|
1542
916
|
* @private
|
|
1543
917
|
*/
|
|
1544
918
|
MAX_PRICE_HISTORY = 1e5;
|