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/MCPRemote.js
CHANGED
|
@@ -166,7 +166,7 @@ var toolSchemas = {
|
|
|
166
166
|
}
|
|
167
167
|
},
|
|
168
168
|
executeOrder: {
|
|
169
|
-
description: "Executes a verified order. verifyOrder must be called before executeOrder.",
|
|
169
|
+
description: "Executes a verified order. verifyOrder must be called before executeOrder. user has to explicitly allow executeOrder.",
|
|
170
170
|
schema: {
|
|
171
171
|
type: "object",
|
|
172
172
|
properties: {
|
|
@@ -310,330 +310,7 @@ var toolSchemas = {
|
|
|
310
310
|
},
|
|
311
311
|
required: ["symbol"]
|
|
312
312
|
}
|
|
313
|
-
},
|
|
314
|
-
technicalAnalysis: {
|
|
315
|
-
description: "Performs comprehensive technical analysis on market data for a given symbol, including indicators like SMA, EMA, RSI, Bollinger Bands, and trading signals",
|
|
316
|
-
schema: {
|
|
317
|
-
type: "object",
|
|
318
|
-
properties: {
|
|
319
|
-
symbol: {
|
|
320
|
-
type: "string",
|
|
321
|
-
description: "The trading symbol to analyze (e.g., AAPL, MSFT, EURUSD)"
|
|
322
|
-
}
|
|
323
|
-
},
|
|
324
|
-
required: ["symbol"]
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
// src/tools/analytics.ts
|
|
330
|
-
function sum(numbers) {
|
|
331
|
-
return numbers.reduce((acc, val) => acc + val, 0);
|
|
332
|
-
}
|
|
333
|
-
var TechnicalAnalyzer = class {
|
|
334
|
-
prices;
|
|
335
|
-
volumes;
|
|
336
|
-
highs;
|
|
337
|
-
lows;
|
|
338
|
-
constructor(data) {
|
|
339
|
-
this.prices = data.map((d) => d.trade > 0 ? d.trade : d.midPrice);
|
|
340
|
-
this.volumes = data.map((d) => d.volume);
|
|
341
|
-
this.highs = data.map((d) => d.tradingSessionHighPrice > 0 ? d.tradingSessionHighPrice : d.trade);
|
|
342
|
-
this.lows = data.map((d) => d.tradingSessionLowPrice > 0 ? d.tradingSessionLowPrice : d.trade);
|
|
343
|
-
}
|
|
344
|
-
// Calculate Simple Moving Average
|
|
345
|
-
calculateSMA(data, period) {
|
|
346
|
-
const sma = [];
|
|
347
|
-
for (let i = period - 1; i < data.length; i++) {
|
|
348
|
-
const sum2 = data.slice(i - period + 1, i + 1).reduce((a, b) => a + b, 0);
|
|
349
|
-
sma.push(sum2 / period);
|
|
350
|
-
}
|
|
351
|
-
return sma;
|
|
352
|
-
}
|
|
353
|
-
// Calculate Exponential Moving Average
|
|
354
|
-
calculateEMA(data, period) {
|
|
355
|
-
const multiplier = 2 / (period + 1);
|
|
356
|
-
const ema = [data[0]];
|
|
357
|
-
for (let i = 1; i < data.length; i++) {
|
|
358
|
-
ema.push(data[i] * multiplier + ema[i - 1] * (1 - multiplier));
|
|
359
|
-
}
|
|
360
|
-
return ema;
|
|
361
|
-
}
|
|
362
|
-
// Calculate RSI
|
|
363
|
-
calculateRSI(data, period = 14) {
|
|
364
|
-
if (data.length < period + 1) return [];
|
|
365
|
-
const changes = [];
|
|
366
|
-
for (let i = 1; i < data.length; i++) {
|
|
367
|
-
changes.push(data[i] - data[i - 1]);
|
|
368
|
-
}
|
|
369
|
-
const gains = changes.map((change) => change > 0 ? change : 0);
|
|
370
|
-
const losses = changes.map((change) => change < 0 ? Math.abs(change) : 0);
|
|
371
|
-
let avgGain = gains.slice(0, period).reduce((a, b) => a + b, 0) / period;
|
|
372
|
-
let avgLoss = losses.slice(0, period).reduce((a, b) => a + b, 0) / period;
|
|
373
|
-
const rsi = [];
|
|
374
|
-
for (let i = period; i < changes.length; i++) {
|
|
375
|
-
const rs = avgGain / avgLoss;
|
|
376
|
-
rsi.push(100 - 100 / (1 + rs));
|
|
377
|
-
avgGain = (avgGain * (period - 1) + gains[i]) / period;
|
|
378
|
-
avgLoss = (avgLoss * (period - 1) + losses[i]) / period;
|
|
379
|
-
}
|
|
380
|
-
return rsi;
|
|
381
|
-
}
|
|
382
|
-
// Calculate Bollinger Bands
|
|
383
|
-
calculateBollingerBands(data, period = 20, stdDev = 2) {
|
|
384
|
-
if (data.length < period) return [];
|
|
385
|
-
const sma = this.calculateSMA(data, period);
|
|
386
|
-
const bands = [];
|
|
387
|
-
for (let i = 0; i < sma.length; i++) {
|
|
388
|
-
const dataSlice = data.slice(i, i + period);
|
|
389
|
-
const mean = sma[i];
|
|
390
|
-
const variance = dataSlice.reduce((sum2, price) => sum2 + (price - mean) ** 2, 0) / period;
|
|
391
|
-
const standardDeviation = Math.sqrt(variance);
|
|
392
|
-
bands.push({
|
|
393
|
-
upper: mean + standardDeviation * stdDev,
|
|
394
|
-
middle: mean,
|
|
395
|
-
lower: mean - standardDeviation * stdDev
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
return bands;
|
|
399
|
-
}
|
|
400
|
-
// Calculate maximum drawdown
|
|
401
|
-
calculateMaxDrawdown(prices) {
|
|
402
|
-
let maxPrice = prices[0];
|
|
403
|
-
let maxDrawdown = 0;
|
|
404
|
-
for (let i = 1; i < prices.length; i++) {
|
|
405
|
-
if (prices[i] > maxPrice) {
|
|
406
|
-
maxPrice = prices[i];
|
|
407
|
-
}
|
|
408
|
-
const drawdown = (maxPrice - prices[i]) / maxPrice;
|
|
409
|
-
if (drawdown > maxDrawdown) {
|
|
410
|
-
maxDrawdown = drawdown;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
return maxDrawdown;
|
|
414
|
-
}
|
|
415
|
-
// Calculate price changes for volatility
|
|
416
|
-
calculatePriceChanges() {
|
|
417
|
-
const changes = [];
|
|
418
|
-
for (let i = 1; i < this.prices.length; i++) {
|
|
419
|
-
changes.push((this.prices[i] - this.prices[i - 1]) / this.prices[i - 1]);
|
|
420
|
-
}
|
|
421
|
-
return changes;
|
|
422
|
-
}
|
|
423
|
-
// Generate comprehensive market analysis
|
|
424
|
-
analyze() {
|
|
425
|
-
const currentPrice = this.prices[this.prices.length - 1];
|
|
426
|
-
const startPrice = this.prices[0];
|
|
427
|
-
const sessionHigh = Math.max(...this.highs);
|
|
428
|
-
const sessionLow = Math.min(...this.lows);
|
|
429
|
-
const totalVolume = sum(this.volumes);
|
|
430
|
-
const avgVolume = totalVolume / this.volumes.length;
|
|
431
|
-
const priceChanges = this.calculatePriceChanges();
|
|
432
|
-
const volatility = priceChanges.length > 0 ? Math.sqrt(
|
|
433
|
-
priceChanges.reduce((sum2, change) => sum2 + change ** 2, 0) / priceChanges.length
|
|
434
|
-
) * Math.sqrt(252) * 100 : 0;
|
|
435
|
-
const sessionReturn = (currentPrice - startPrice) / startPrice * 100;
|
|
436
|
-
const pricePosition = (currentPrice - sessionLow) / (sessionHigh - sessionLow) * 100;
|
|
437
|
-
const trueVWAP = this.prices.reduce((sum2, price, i) => sum2 + price * this.volumes[i], 0) / totalVolume;
|
|
438
|
-
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;
|
|
439
|
-
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;
|
|
440
|
-
const maxDrawdown = this.calculateMaxDrawdown(this.prices);
|
|
441
|
-
return {
|
|
442
|
-
currentPrice,
|
|
443
|
-
startPrice,
|
|
444
|
-
sessionHigh,
|
|
445
|
-
sessionLow,
|
|
446
|
-
totalVolume,
|
|
447
|
-
avgVolume,
|
|
448
|
-
volatility,
|
|
449
|
-
sessionReturn,
|
|
450
|
-
pricePosition,
|
|
451
|
-
trueVWAP,
|
|
452
|
-
momentum5,
|
|
453
|
-
momentum10,
|
|
454
|
-
maxDrawdown
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
// Generate technical indicators
|
|
458
|
-
getTechnicalIndicators() {
|
|
459
|
-
return {
|
|
460
|
-
sma5: this.calculateSMA(this.prices, 5),
|
|
461
|
-
sma10: this.calculateSMA(this.prices, 10),
|
|
462
|
-
ema8: this.calculateEMA(this.prices, 8),
|
|
463
|
-
ema21: this.calculateEMA(this.prices, 21),
|
|
464
|
-
rsi: this.calculateRSI(this.prices, 14),
|
|
465
|
-
bollinger: this.calculateBollingerBands(this.prices, 20, 2)
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
// Generate trading signals
|
|
469
|
-
generateSignals() {
|
|
470
|
-
const analysis = this.analyze();
|
|
471
|
-
let bullishSignals = 0;
|
|
472
|
-
let bearishSignals = 0;
|
|
473
|
-
const signals = [];
|
|
474
|
-
if (analysis.currentPrice > analysis.trueVWAP) {
|
|
475
|
-
signals.push(
|
|
476
|
-
`\u2713 BULLISH: Price above VWAP (+${((analysis.currentPrice - analysis.trueVWAP) / analysis.trueVWAP * 100).toFixed(2)}%)`
|
|
477
|
-
);
|
|
478
|
-
bullishSignals++;
|
|
479
|
-
} else {
|
|
480
|
-
signals.push(
|
|
481
|
-
`\u2717 BEARISH: Price below VWAP (${((analysis.currentPrice - analysis.trueVWAP) / analysis.trueVWAP * 100).toFixed(2)}%)`
|
|
482
|
-
);
|
|
483
|
-
bearishSignals++;
|
|
484
|
-
}
|
|
485
|
-
if (analysis.momentum5 > 0 && analysis.momentum10 > 0) {
|
|
486
|
-
signals.push("\u2713 BULLISH: Positive momentum on both timeframes");
|
|
487
|
-
bullishSignals++;
|
|
488
|
-
} else if (analysis.momentum5 < 0 && analysis.momentum10 < 0) {
|
|
489
|
-
signals.push("\u2717 BEARISH: Negative momentum on both timeframes");
|
|
490
|
-
bearishSignals++;
|
|
491
|
-
} else {
|
|
492
|
-
signals.push("\u25D0 MIXED: Conflicting momentum signals");
|
|
493
|
-
}
|
|
494
|
-
const currentVolume = this.volumes[this.volumes.length - 1];
|
|
495
|
-
const volumeRatio = currentVolume / analysis.avgVolume;
|
|
496
|
-
if (volumeRatio > 1.2 && analysis.sessionReturn > 0) {
|
|
497
|
-
signals.push("\u2713 BULLISH: Above-average volume supporting upward move");
|
|
498
|
-
bullishSignals++;
|
|
499
|
-
} else if (volumeRatio > 1.2 && analysis.sessionReturn < 0) {
|
|
500
|
-
signals.push("\u2717 BEARISH: Above-average volume supporting downward move");
|
|
501
|
-
bearishSignals++;
|
|
502
|
-
} else {
|
|
503
|
-
signals.push("\u25D0 NEUTRAL: Volume not providing clear direction");
|
|
504
|
-
}
|
|
505
|
-
if (analysis.pricePosition > 65 && analysis.volatility > 30) {
|
|
506
|
-
signals.push("\u2717 BEARISH: High in range with elevated volatility - reversal risk");
|
|
507
|
-
bearishSignals++;
|
|
508
|
-
} else if (analysis.pricePosition < 35 && analysis.volatility > 30) {
|
|
509
|
-
signals.push("\u2713 BULLISH: Low in range with volatility - potential bounce");
|
|
510
|
-
bullishSignals++;
|
|
511
|
-
} else {
|
|
512
|
-
signals.push("\u25D0 NEUTRAL: Price position and volatility not extreme");
|
|
513
|
-
}
|
|
514
|
-
return { bullishSignals, bearishSignals, signals };
|
|
515
313
|
}
|
|
516
|
-
// Generate comprehensive JSON analysis
|
|
517
|
-
generateJSONAnalysis(symbol) {
|
|
518
|
-
const analysis = this.analyze();
|
|
519
|
-
const indicators = this.getTechnicalIndicators();
|
|
520
|
-
const signals = this.generateSignals();
|
|
521
|
-
const currentSMA5 = indicators.sma5.length > 0 ? indicators.sma5[indicators.sma5.length - 1] : null;
|
|
522
|
-
const currentSMA10 = indicators.sma10.length > 0 ? indicators.sma10[indicators.sma10.length - 1] : null;
|
|
523
|
-
const currentEMA8 = indicators.ema8[indicators.ema8.length - 1];
|
|
524
|
-
const currentEMA21 = indicators.ema21[indicators.ema21.length - 1];
|
|
525
|
-
const currentRSI = indicators.rsi.length > 0 ? indicators.rsi[indicators.rsi.length - 1] : null;
|
|
526
|
-
const currentBB = indicators.bollinger.length > 0 ? indicators.bollinger[indicators.bollinger.length - 1] : null;
|
|
527
|
-
const currentVolume = this.volumes[this.volumes.length - 1];
|
|
528
|
-
const volumeRatio = currentVolume / analysis.avgVolume;
|
|
529
|
-
const currentDrawdown = (analysis.sessionHigh - analysis.currentPrice) / analysis.sessionHigh * 100;
|
|
530
|
-
const rangeWidth = (analysis.sessionHigh - analysis.sessionLow) / analysis.sessionLow * 100;
|
|
531
|
-
const priceVsVWAP = (analysis.currentPrice - analysis.trueVWAP) / analysis.trueVWAP * 100;
|
|
532
|
-
const totalScore = signals.bullishSignals - signals.bearishSignals;
|
|
533
|
-
const overallSignal = totalScore > 0 ? "BULLISH_BIAS" : totalScore < 0 ? "BEARISH_BIAS" : "NEUTRAL";
|
|
534
|
-
const targetEntry = Math.max(analysis.sessionLow * 1.005, analysis.trueVWAP * 0.998);
|
|
535
|
-
const stopLoss = analysis.sessionLow * 0.995;
|
|
536
|
-
const profitTarget = analysis.sessionHigh * 0.995;
|
|
537
|
-
const riskRewardRatio = (profitTarget - analysis.currentPrice) / (analysis.currentPrice - stopLoss);
|
|
538
|
-
return {
|
|
539
|
-
symbol,
|
|
540
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
541
|
-
marketStructure: {
|
|
542
|
-
currentPrice: analysis.currentPrice,
|
|
543
|
-
startPrice: analysis.startPrice,
|
|
544
|
-
sessionHigh: analysis.sessionHigh,
|
|
545
|
-
sessionLow: analysis.sessionLow,
|
|
546
|
-
rangeWidth,
|
|
547
|
-
totalVolume: analysis.totalVolume,
|
|
548
|
-
sessionPerformance: analysis.sessionReturn,
|
|
549
|
-
positionInRange: analysis.pricePosition
|
|
550
|
-
},
|
|
551
|
-
volatility: {
|
|
552
|
-
impliedVolatility: analysis.volatility,
|
|
553
|
-
maxDrawdown: analysis.maxDrawdown * 100,
|
|
554
|
-
currentDrawdown
|
|
555
|
-
},
|
|
556
|
-
technicalIndicators: {
|
|
557
|
-
sma5: currentSMA5,
|
|
558
|
-
sma10: currentSMA10,
|
|
559
|
-
ema8: currentEMA8,
|
|
560
|
-
ema21: currentEMA21,
|
|
561
|
-
rsi: currentRSI,
|
|
562
|
-
bollingerBands: currentBB ? {
|
|
563
|
-
upper: currentBB.upper,
|
|
564
|
-
middle: currentBB.middle,
|
|
565
|
-
lower: currentBB.lower,
|
|
566
|
-
position: (analysis.currentPrice - currentBB.lower) / (currentBB.upper - currentBB.lower) * 100
|
|
567
|
-
} : null
|
|
568
|
-
},
|
|
569
|
-
volumeAnalysis: {
|
|
570
|
-
currentVolume,
|
|
571
|
-
averageVolume: Math.round(analysis.avgVolume),
|
|
572
|
-
volumeRatio,
|
|
573
|
-
trueVWAP: analysis.trueVWAP,
|
|
574
|
-
priceVsVWAP
|
|
575
|
-
},
|
|
576
|
-
momentum: {
|
|
577
|
-
momentum5: analysis.momentum5,
|
|
578
|
-
momentum10: analysis.momentum10,
|
|
579
|
-
sessionROC: analysis.sessionReturn
|
|
580
|
-
},
|
|
581
|
-
tradingSignals: {
|
|
582
|
-
...signals,
|
|
583
|
-
overallSignal,
|
|
584
|
-
signalScore: totalScore
|
|
585
|
-
},
|
|
586
|
-
riskManagement: {
|
|
587
|
-
targetEntry,
|
|
588
|
-
stopLoss,
|
|
589
|
-
profitTarget,
|
|
590
|
-
riskRewardRatio
|
|
591
|
-
}
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
};
|
|
595
|
-
var createTechnicalAnalysisHandler = (marketDataPrices) => {
|
|
596
|
-
return async (args) => {
|
|
597
|
-
try {
|
|
598
|
-
const symbol = args.symbol;
|
|
599
|
-
const priceHistory = marketDataPrices.get(symbol) || [];
|
|
600
|
-
if (priceHistory.length === 0) {
|
|
601
|
-
return {
|
|
602
|
-
content: [
|
|
603
|
-
{
|
|
604
|
-
type: "text",
|
|
605
|
-
text: `No price data available for ${symbol}. Please request market data first.`,
|
|
606
|
-
uri: "technicalAnalysis"
|
|
607
|
-
}
|
|
608
|
-
]
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
const analyzer = new TechnicalAnalyzer(priceHistory);
|
|
612
|
-
const analysis = analyzer.generateJSONAnalysis(symbol);
|
|
613
|
-
return {
|
|
614
|
-
content: [
|
|
615
|
-
{
|
|
616
|
-
type: "text",
|
|
617
|
-
text: `Technical Analysis for ${symbol}:
|
|
618
|
-
|
|
619
|
-
${JSON.stringify(analysis, null, 2)}`,
|
|
620
|
-
uri: "technicalAnalysis"
|
|
621
|
-
}
|
|
622
|
-
]
|
|
623
|
-
};
|
|
624
|
-
} catch (error) {
|
|
625
|
-
return {
|
|
626
|
-
content: [
|
|
627
|
-
{
|
|
628
|
-
type: "text",
|
|
629
|
-
text: `Error performing technical analysis: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
630
|
-
uri: "technicalAnalysis"
|
|
631
|
-
}
|
|
632
|
-
],
|
|
633
|
-
isError: true
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
};
|
|
637
314
|
};
|
|
638
315
|
|
|
639
316
|
// src/tools/marketData.ts
|
|
@@ -642,63 +319,10 @@ var import_quickchart_js = __toESM(require("quickchart-js"), 1);
|
|
|
642
319
|
var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
643
320
|
return async (args) => {
|
|
644
321
|
try {
|
|
645
|
-
parser.logger.log({
|
|
646
|
-
level: "info",
|
|
647
|
-
message: `Sending market data request for symbols: ${args.symbols.join(", ")}`
|
|
648
|
-
});
|
|
649
322
|
const response = new Promise((resolve) => {
|
|
650
323
|
pendingRequests.set(args.mdReqID, resolve);
|
|
651
|
-
parser.logger.log({
|
|
652
|
-
level: "info",
|
|
653
|
-
message: `Registered callback for market data request ID: ${args.mdReqID}`
|
|
654
|
-
});
|
|
655
324
|
});
|
|
656
|
-
const entryTypes = args.mdEntryTypes || [
|
|
657
|
-
import_fixparser.MDEntryType.Bid,
|
|
658
|
-
import_fixparser.MDEntryType.Offer,
|
|
659
|
-
import_fixparser.MDEntryType.Trade,
|
|
660
|
-
import_fixparser.MDEntryType.IndexValue,
|
|
661
|
-
import_fixparser.MDEntryType.OpeningPrice,
|
|
662
|
-
import_fixparser.MDEntryType.ClosingPrice,
|
|
663
|
-
import_fixparser.MDEntryType.SettlementPrice,
|
|
664
|
-
import_fixparser.MDEntryType.TradingSessionHighPrice,
|
|
665
|
-
import_fixparser.MDEntryType.TradingSessionLowPrice,
|
|
666
|
-
import_fixparser.MDEntryType.VWAP,
|
|
667
|
-
import_fixparser.MDEntryType.Imbalance,
|
|
668
|
-
import_fixparser.MDEntryType.TradeVolume,
|
|
669
|
-
import_fixparser.MDEntryType.OpenInterest,
|
|
670
|
-
import_fixparser.MDEntryType.CompositeUnderlyingPrice,
|
|
671
|
-
import_fixparser.MDEntryType.SimulatedSellPrice,
|
|
672
|
-
import_fixparser.MDEntryType.SimulatedBuyPrice,
|
|
673
|
-
import_fixparser.MDEntryType.MarginRate,
|
|
674
|
-
import_fixparser.MDEntryType.MidPrice,
|
|
675
|
-
import_fixparser.MDEntryType.EmptyBook,
|
|
676
|
-
import_fixparser.MDEntryType.SettleHighPrice,
|
|
677
|
-
import_fixparser.MDEntryType.SettleLowPrice,
|
|
678
|
-
import_fixparser.MDEntryType.PriorSettlePrice,
|
|
679
|
-
import_fixparser.MDEntryType.SessionHighBid,
|
|
680
|
-
import_fixparser.MDEntryType.SessionLowOffer,
|
|
681
|
-
import_fixparser.MDEntryType.EarlyPrices,
|
|
682
|
-
import_fixparser.MDEntryType.AuctionClearingPrice,
|
|
683
|
-
import_fixparser.MDEntryType.SwapValueFactor,
|
|
684
|
-
import_fixparser.MDEntryType.DailyValueAdjustmentForLongPositions,
|
|
685
|
-
import_fixparser.MDEntryType.CumulativeValueAdjustmentForLongPositions,
|
|
686
|
-
import_fixparser.MDEntryType.DailyValueAdjustmentForShortPositions,
|
|
687
|
-
import_fixparser.MDEntryType.CumulativeValueAdjustmentForShortPositions,
|
|
688
|
-
import_fixparser.MDEntryType.FixingPrice,
|
|
689
|
-
import_fixparser.MDEntryType.CashRate,
|
|
690
|
-
import_fixparser.MDEntryType.RecoveryRate,
|
|
691
|
-
import_fixparser.MDEntryType.RecoveryRateForLong,
|
|
692
|
-
import_fixparser.MDEntryType.RecoveryRateForShort,
|
|
693
|
-
import_fixparser.MDEntryType.MarketBid,
|
|
694
|
-
import_fixparser.MDEntryType.MarketOffer,
|
|
695
|
-
import_fixparser.MDEntryType.ShortSaleMinPrice,
|
|
696
|
-
import_fixparser.MDEntryType.PreviousClosingPrice,
|
|
697
|
-
import_fixparser.MDEntryType.ThresholdLimitPriceBanding,
|
|
698
|
-
import_fixparser.MDEntryType.DailyFinancingValue,
|
|
699
|
-
import_fixparser.MDEntryType.AccruedFinancingValue,
|
|
700
|
-
import_fixparser.MDEntryType.TWAP
|
|
701
|
-
];
|
|
325
|
+
const entryTypes = args.mdEntryTypes || [import_fixparser.MDEntryType.Bid, import_fixparser.MDEntryType.Offer, import_fixparser.MDEntryType.TradeVolume];
|
|
702
326
|
const messageFields = [
|
|
703
327
|
new import_fixparser.Field(import_fixparser.Fields.MsgType, import_fixparser.Messages.MarketDataRequest),
|
|
704
328
|
new import_fixparser.Field(import_fixparser.Fields.SenderCompID, parser.sender),
|
|
@@ -720,10 +344,6 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
720
344
|
});
|
|
721
345
|
const mdr = parser.createMessage(...messageFields);
|
|
722
346
|
if (!parser.connected) {
|
|
723
|
-
parser.logger.log({
|
|
724
|
-
level: "error",
|
|
725
|
-
message: "Not connected. Cannot send market data request."
|
|
726
|
-
});
|
|
727
347
|
return {
|
|
728
348
|
content: [
|
|
729
349
|
{
|
|
@@ -735,16 +355,8 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
735
355
|
isError: true
|
|
736
356
|
};
|
|
737
357
|
}
|
|
738
|
-
parser.logger.log({
|
|
739
|
-
level: "info",
|
|
740
|
-
message: `Sending market data request message: ${JSON.stringify(mdr?.toFIXJSON())}`
|
|
741
|
-
});
|
|
742
358
|
parser.send(mdr);
|
|
743
359
|
const fixData = await response;
|
|
744
|
-
parser.logger.log({
|
|
745
|
-
level: "info",
|
|
746
|
-
message: `Received market data response for request ID: ${args.mdReqID}`
|
|
747
|
-
});
|
|
748
360
|
return {
|
|
749
361
|
content: [
|
|
750
362
|
{
|
|
@@ -793,9 +405,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
793
405
|
const offerData = priceHistory.map((point) => point.offer);
|
|
794
406
|
const spreadData = priceHistory.map((point) => point.spread);
|
|
795
407
|
const volumeData = priceHistory.map((point) => point.volume);
|
|
796
|
-
const tradeData = priceHistory.map((point) => point.trade);
|
|
797
|
-
const vwapData = priceHistory.map((point) => point.vwap);
|
|
798
|
-
const twapData = priceHistory.map((point) => point.twap);
|
|
799
408
|
const config = {
|
|
800
409
|
type: "line",
|
|
801
410
|
data: {
|
|
@@ -825,30 +434,6 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
825
434
|
fill: false,
|
|
826
435
|
tension: 0.4
|
|
827
436
|
},
|
|
828
|
-
{
|
|
829
|
-
label: "Trade",
|
|
830
|
-
data: tradeData,
|
|
831
|
-
borderColor: "#ffc107",
|
|
832
|
-
backgroundColor: "rgba(255, 193, 7, 0.1)",
|
|
833
|
-
fill: false,
|
|
834
|
-
tension: 0.4
|
|
835
|
-
},
|
|
836
|
-
{
|
|
837
|
-
label: "VWAP",
|
|
838
|
-
data: vwapData,
|
|
839
|
-
borderColor: "#17a2b8",
|
|
840
|
-
backgroundColor: "rgba(23, 162, 184, 0.1)",
|
|
841
|
-
fill: false,
|
|
842
|
-
tension: 0.4
|
|
843
|
-
},
|
|
844
|
-
{
|
|
845
|
-
label: "TWAP",
|
|
846
|
-
data: twapData,
|
|
847
|
-
borderColor: "#6610f2",
|
|
848
|
-
backgroundColor: "rgba(102, 16, 242, 0.1)",
|
|
849
|
-
fill: false,
|
|
850
|
-
tension: 0.4
|
|
851
|
-
},
|
|
852
437
|
{
|
|
853
438
|
label: "Volume",
|
|
854
439
|
data: volumeData,
|
|
@@ -894,7 +479,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
894
479
|
content: [
|
|
895
480
|
{
|
|
896
481
|
type: "text",
|
|
897
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate
|
|
482
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate chart"}`,
|
|
898
483
|
uri: "getStockGraph"
|
|
899
484
|
}
|
|
900
485
|
],
|
|
@@ -932,48 +517,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
932
517
|
bid: point.bid,
|
|
933
518
|
offer: point.offer,
|
|
934
519
|
spread: point.spread,
|
|
935
|
-
volume: point.volume
|
|
936
|
-
trade: point.trade,
|
|
937
|
-
indexValue: point.indexValue,
|
|
938
|
-
openingPrice: point.openingPrice,
|
|
939
|
-
closingPrice: point.closingPrice,
|
|
940
|
-
settlementPrice: point.settlementPrice,
|
|
941
|
-
tradingSessionHighPrice: point.tradingSessionHighPrice,
|
|
942
|
-
tradingSessionLowPrice: point.tradingSessionLowPrice,
|
|
943
|
-
vwap: point.vwap,
|
|
944
|
-
imbalance: point.imbalance,
|
|
945
|
-
openInterest: point.openInterest,
|
|
946
|
-
compositeUnderlyingPrice: point.compositeUnderlyingPrice,
|
|
947
|
-
simulatedSellPrice: point.simulatedSellPrice,
|
|
948
|
-
simulatedBuyPrice: point.simulatedBuyPrice,
|
|
949
|
-
marginRate: point.marginRate,
|
|
950
|
-
midPrice: point.midPrice,
|
|
951
|
-
emptyBook: point.emptyBook,
|
|
952
|
-
settleHighPrice: point.settleHighPrice,
|
|
953
|
-
settleLowPrice: point.settleLowPrice,
|
|
954
|
-
priorSettlePrice: point.priorSettlePrice,
|
|
955
|
-
sessionHighBid: point.sessionHighBid,
|
|
956
|
-
sessionLowOffer: point.sessionLowOffer,
|
|
957
|
-
earlyPrices: point.earlyPrices,
|
|
958
|
-
auctionClearingPrice: point.auctionClearingPrice,
|
|
959
|
-
swapValueFactor: point.swapValueFactor,
|
|
960
|
-
dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
|
|
961
|
-
cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
|
|
962
|
-
dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
|
|
963
|
-
cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
|
|
964
|
-
fixingPrice: point.fixingPrice,
|
|
965
|
-
cashRate: point.cashRate,
|
|
966
|
-
recoveryRate: point.recoveryRate,
|
|
967
|
-
recoveryRateForLong: point.recoveryRateForLong,
|
|
968
|
-
recoveryRateForShort: point.recoveryRateForShort,
|
|
969
|
-
marketBid: point.marketBid,
|
|
970
|
-
marketOffer: point.marketOffer,
|
|
971
|
-
shortSaleMinPrice: point.shortSaleMinPrice,
|
|
972
|
-
previousClosingPrice: point.previousClosingPrice,
|
|
973
|
-
thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
|
|
974
|
-
dailyFinancingValue: point.dailyFinancingValue,
|
|
975
|
-
accruedFinancingValue: point.accruedFinancingValue,
|
|
976
|
-
twap: point.twap
|
|
520
|
+
volume: point.volume
|
|
977
521
|
}))
|
|
978
522
|
},
|
|
979
523
|
null,
|
|
@@ -988,7 +532,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
988
532
|
content: [
|
|
989
533
|
{
|
|
990
534
|
type: "text",
|
|
991
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
535
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get stock price history"}`,
|
|
992
536
|
uri: "getStockPriceHistory"
|
|
993
537
|
}
|
|
994
538
|
],
|
|
@@ -1096,7 +640,7 @@ Parameters verified:
|
|
|
1096
640
|
- Symbol: ${args.symbol}
|
|
1097
641
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
1098
642
|
|
|
1099
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
643
|
+
To execute this order, call the executeOrder tool with these exact same parameters.`,
|
|
1100
644
|
uri: "verifyOrder"
|
|
1101
645
|
}
|
|
1102
646
|
]
|
|
@@ -1292,210 +836,48 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
1292
836
|
executeOrder: createExecuteOrderHandler(parser, verifiedOrders, pendingRequests),
|
|
1293
837
|
marketDataRequest: createMarketDataRequestHandler(parser, pendingRequests),
|
|
1294
838
|
getStockGraph: createGetStockGraphHandler(marketDataPrices),
|
|
1295
|
-
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
1296
|
-
technicalAnalysis: createTechnicalAnalysisHandler(marketDataPrices)
|
|
839
|
+
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
1297
840
|
});
|
|
1298
841
|
|
|
1299
842
|
// src/utils/messageHandler.ts
|
|
1300
843
|
var import_fixparser3 = require("fixparser");
|
|
1301
|
-
function getEnumValue(enumObj, name) {
|
|
1302
|
-
return enumObj[name] || name;
|
|
1303
|
-
}
|
|
1304
844
|
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
845
|
+
parser.logger.log({
|
|
846
|
+
level: "info",
|
|
847
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
848
|
+
});
|
|
1305
849
|
const msgType = message.messageType;
|
|
1306
|
-
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh
|
|
850
|
+
if (msgType === import_fixparser3.Messages.MarketDataSnapshotFullRefresh) {
|
|
1307
851
|
const symbol = message.getField(import_fixparser3.Fields.Symbol)?.value;
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
compositeUnderlyingPrice: 0,
|
|
1327
|
-
simulatedSellPrice: 0,
|
|
1328
|
-
simulatedBuyPrice: 0,
|
|
1329
|
-
marginRate: 0,
|
|
1330
|
-
midPrice: 0,
|
|
1331
|
-
emptyBook: 0,
|
|
1332
|
-
settleHighPrice: 0,
|
|
1333
|
-
settleLowPrice: 0,
|
|
1334
|
-
priorSettlePrice: 0,
|
|
1335
|
-
sessionHighBid: 0,
|
|
1336
|
-
sessionLowOffer: 0,
|
|
1337
|
-
earlyPrices: 0,
|
|
1338
|
-
auctionClearingPrice: 0,
|
|
1339
|
-
swapValueFactor: 0,
|
|
1340
|
-
dailyValueAdjustmentForLongPositions: 0,
|
|
1341
|
-
cumulativeValueAdjustmentForLongPositions: 0,
|
|
1342
|
-
dailyValueAdjustmentForShortPositions: 0,
|
|
1343
|
-
cumulativeValueAdjustmentForShortPositions: 0,
|
|
1344
|
-
fixingPrice: 0,
|
|
1345
|
-
cashRate: 0,
|
|
1346
|
-
recoveryRate: 0,
|
|
1347
|
-
recoveryRateForLong: 0,
|
|
1348
|
-
recoveryRateForShort: 0,
|
|
1349
|
-
marketBid: 0,
|
|
1350
|
-
marketOffer: 0,
|
|
1351
|
-
shortSaleMinPrice: 0,
|
|
1352
|
-
previousClosingPrice: 0,
|
|
1353
|
-
thresholdLimitPriceBanding: 0,
|
|
1354
|
-
dailyFinancingValue: 0,
|
|
1355
|
-
accruedFinancingValue: 0,
|
|
1356
|
-
twap: 0
|
|
1357
|
-
};
|
|
1358
|
-
for (const entry of entries) {
|
|
1359
|
-
const entryType = entry.MDEntryType;
|
|
1360
|
-
const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
|
|
1361
|
-
const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
|
|
1362
|
-
const enumValue = getEnumValue(import_fixparser3.MDEntryType, entryType);
|
|
1363
|
-
switch (enumValue) {
|
|
1364
|
-
case import_fixparser3.MDEntryType.Bid:
|
|
1365
|
-
data.bid = price;
|
|
1366
|
-
break;
|
|
1367
|
-
case import_fixparser3.MDEntryType.Offer:
|
|
1368
|
-
data.offer = price;
|
|
1369
|
-
break;
|
|
1370
|
-
case import_fixparser3.MDEntryType.Trade:
|
|
1371
|
-
data.trade = price;
|
|
1372
|
-
break;
|
|
1373
|
-
case import_fixparser3.MDEntryType.IndexValue:
|
|
1374
|
-
data.indexValue = price;
|
|
1375
|
-
break;
|
|
1376
|
-
case import_fixparser3.MDEntryType.OpeningPrice:
|
|
1377
|
-
data.openingPrice = price;
|
|
1378
|
-
break;
|
|
1379
|
-
case import_fixparser3.MDEntryType.ClosingPrice:
|
|
1380
|
-
data.closingPrice = price;
|
|
1381
|
-
break;
|
|
1382
|
-
case import_fixparser3.MDEntryType.SettlementPrice:
|
|
1383
|
-
data.settlementPrice = price;
|
|
1384
|
-
break;
|
|
1385
|
-
case import_fixparser3.MDEntryType.TradingSessionHighPrice:
|
|
1386
|
-
data.tradingSessionHighPrice = price;
|
|
1387
|
-
break;
|
|
1388
|
-
case import_fixparser3.MDEntryType.TradingSessionLowPrice:
|
|
1389
|
-
data.tradingSessionLowPrice = price;
|
|
1390
|
-
break;
|
|
1391
|
-
case import_fixparser3.MDEntryType.VWAP:
|
|
1392
|
-
data.vwap = price;
|
|
1393
|
-
break;
|
|
1394
|
-
case import_fixparser3.MDEntryType.Imbalance:
|
|
1395
|
-
data.imbalance = size;
|
|
1396
|
-
break;
|
|
1397
|
-
case import_fixparser3.MDEntryType.TradeVolume:
|
|
1398
|
-
data.volume = size;
|
|
1399
|
-
break;
|
|
1400
|
-
case import_fixparser3.MDEntryType.OpenInterest:
|
|
1401
|
-
data.openInterest = size;
|
|
1402
|
-
break;
|
|
1403
|
-
case import_fixparser3.MDEntryType.CompositeUnderlyingPrice:
|
|
1404
|
-
data.compositeUnderlyingPrice = price;
|
|
1405
|
-
break;
|
|
1406
|
-
case import_fixparser3.MDEntryType.SimulatedSellPrice:
|
|
1407
|
-
data.simulatedSellPrice = price;
|
|
1408
|
-
break;
|
|
1409
|
-
case import_fixparser3.MDEntryType.SimulatedBuyPrice:
|
|
1410
|
-
data.simulatedBuyPrice = price;
|
|
1411
|
-
break;
|
|
1412
|
-
case import_fixparser3.MDEntryType.MarginRate:
|
|
1413
|
-
data.marginRate = price;
|
|
1414
|
-
break;
|
|
1415
|
-
case import_fixparser3.MDEntryType.MidPrice:
|
|
1416
|
-
data.midPrice = price;
|
|
1417
|
-
break;
|
|
1418
|
-
case import_fixparser3.MDEntryType.EmptyBook:
|
|
1419
|
-
data.emptyBook = 1;
|
|
1420
|
-
break;
|
|
1421
|
-
case import_fixparser3.MDEntryType.SettleHighPrice:
|
|
1422
|
-
data.settleHighPrice = price;
|
|
1423
|
-
break;
|
|
1424
|
-
case import_fixparser3.MDEntryType.SettleLowPrice:
|
|
1425
|
-
data.settleLowPrice = price;
|
|
1426
|
-
break;
|
|
1427
|
-
case import_fixparser3.MDEntryType.PriorSettlePrice:
|
|
1428
|
-
data.priorSettlePrice = price;
|
|
1429
|
-
break;
|
|
1430
|
-
case import_fixparser3.MDEntryType.SessionHighBid:
|
|
1431
|
-
data.sessionHighBid = price;
|
|
1432
|
-
break;
|
|
1433
|
-
case import_fixparser3.MDEntryType.SessionLowOffer:
|
|
1434
|
-
data.sessionLowOffer = price;
|
|
1435
|
-
break;
|
|
1436
|
-
case import_fixparser3.MDEntryType.EarlyPrices:
|
|
1437
|
-
data.earlyPrices = price;
|
|
1438
|
-
break;
|
|
1439
|
-
case import_fixparser3.MDEntryType.AuctionClearingPrice:
|
|
1440
|
-
data.auctionClearingPrice = price;
|
|
1441
|
-
break;
|
|
1442
|
-
case import_fixparser3.MDEntryType.SwapValueFactor:
|
|
1443
|
-
data.swapValueFactor = price;
|
|
1444
|
-
break;
|
|
1445
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForLongPositions:
|
|
1446
|
-
data.dailyValueAdjustmentForLongPositions = price;
|
|
1447
|
-
break;
|
|
1448
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForLongPositions:
|
|
1449
|
-
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1450
|
-
break;
|
|
1451
|
-
case import_fixparser3.MDEntryType.DailyValueAdjustmentForShortPositions:
|
|
1452
|
-
data.dailyValueAdjustmentForShortPositions = price;
|
|
1453
|
-
break;
|
|
1454
|
-
case import_fixparser3.MDEntryType.CumulativeValueAdjustmentForShortPositions:
|
|
1455
|
-
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1456
|
-
break;
|
|
1457
|
-
case import_fixparser3.MDEntryType.FixingPrice:
|
|
1458
|
-
data.fixingPrice = price;
|
|
1459
|
-
break;
|
|
1460
|
-
case import_fixparser3.MDEntryType.CashRate:
|
|
1461
|
-
data.cashRate = price;
|
|
1462
|
-
break;
|
|
1463
|
-
case import_fixparser3.MDEntryType.RecoveryRate:
|
|
1464
|
-
data.recoveryRate = price;
|
|
1465
|
-
break;
|
|
1466
|
-
case import_fixparser3.MDEntryType.RecoveryRateForLong:
|
|
1467
|
-
data.recoveryRateForLong = price;
|
|
1468
|
-
break;
|
|
1469
|
-
case import_fixparser3.MDEntryType.RecoveryRateForShort:
|
|
1470
|
-
data.recoveryRateForShort = price;
|
|
1471
|
-
break;
|
|
1472
|
-
case import_fixparser3.MDEntryType.MarketBid:
|
|
1473
|
-
data.marketBid = price;
|
|
1474
|
-
break;
|
|
1475
|
-
case import_fixparser3.MDEntryType.MarketOffer:
|
|
1476
|
-
data.marketOffer = price;
|
|
1477
|
-
break;
|
|
1478
|
-
case import_fixparser3.MDEntryType.ShortSaleMinPrice:
|
|
1479
|
-
data.shortSaleMinPrice = price;
|
|
1480
|
-
break;
|
|
1481
|
-
case import_fixparser3.MDEntryType.PreviousClosingPrice:
|
|
1482
|
-
data.previousClosingPrice = price;
|
|
1483
|
-
break;
|
|
1484
|
-
case import_fixparser3.MDEntryType.ThresholdLimitPriceBanding:
|
|
1485
|
-
data.thresholdLimitPriceBanding = price;
|
|
1486
|
-
break;
|
|
1487
|
-
case import_fixparser3.MDEntryType.DailyFinancingValue:
|
|
1488
|
-
data.dailyFinancingValue = price;
|
|
1489
|
-
break;
|
|
1490
|
-
case import_fixparser3.MDEntryType.AccruedFinancingValue:
|
|
1491
|
-
data.accruedFinancingValue = price;
|
|
1492
|
-
break;
|
|
1493
|
-
case import_fixparser3.MDEntryType.TWAP:
|
|
1494
|
-
data.twap = price;
|
|
1495
|
-
break;
|
|
852
|
+
const entries = message.getField(import_fixparser3.Fields.NoMDEntries)?.value;
|
|
853
|
+
let bid = 0;
|
|
854
|
+
let offer = 0;
|
|
855
|
+
let volume = 0;
|
|
856
|
+
const entryTypes = message.getFields(import_fixparser3.Fields.MDEntryType);
|
|
857
|
+
const entryPrices = message.getFields(import_fixparser3.Fields.MDEntryPx);
|
|
858
|
+
const entrySizes = message.getFields(import_fixparser3.Fields.MDEntrySize);
|
|
859
|
+
if (entryTypes && entryPrices && entrySizes) {
|
|
860
|
+
for (let i = 0; i < entries; i++) {
|
|
861
|
+
const entryType = entryTypes[i]?.value;
|
|
862
|
+
const entryPrice = Number.parseFloat(entryPrices[i]?.value);
|
|
863
|
+
const entrySize = Number.parseFloat(entrySizes[i]?.value);
|
|
864
|
+
if (entryType === import_fixparser3.MDEntryType.Bid) {
|
|
865
|
+
bid = entryPrice;
|
|
866
|
+
} else if (entryType === import_fixparser3.MDEntryType.Offer) {
|
|
867
|
+
offer = entryPrice;
|
|
868
|
+
}
|
|
869
|
+
volume += entrySize;
|
|
1496
870
|
}
|
|
1497
871
|
}
|
|
1498
|
-
|
|
872
|
+
const spread = offer - bid;
|
|
873
|
+
const timestamp = Date.now();
|
|
874
|
+
const data = {
|
|
875
|
+
timestamp,
|
|
876
|
+
bid,
|
|
877
|
+
offer,
|
|
878
|
+
spread,
|
|
879
|
+
volume
|
|
880
|
+
};
|
|
1499
881
|
if (!marketDataPrices.has(symbol)) {
|
|
1500
882
|
marketDataPrices.set(symbol, []);
|
|
1501
883
|
}
|
|
@@ -1505,14 +887,6 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
|
|
|
1505
887
|
prices.splice(0, prices.length - maxPriceHistory);
|
|
1506
888
|
}
|
|
1507
889
|
onPriceUpdate?.(symbol, data);
|
|
1508
|
-
const mdReqID = message.getField(import_fixparser3.Fields.MDReqID)?.value;
|
|
1509
|
-
if (mdReqID) {
|
|
1510
|
-
const callback = pendingRequests.get(mdReqID);
|
|
1511
|
-
if (callback) {
|
|
1512
|
-
callback(message);
|
|
1513
|
-
pendingRequests.delete(mdReqID);
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
890
|
} else if (msgType === import_fixparser3.Messages.ExecutionReport) {
|
|
1517
891
|
const reqId = message.getField(import_fixparser3.Fields.ClOrdID)?.value;
|
|
1518
892
|
const callback = pendingRequests.get(reqId);
|
|
@@ -1525,39 +899,6 @@ function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPr
|
|
|
1525
899
|
|
|
1526
900
|
// src/MCPRemote.ts
|
|
1527
901
|
var transports = {};
|
|
1528
|
-
function jsonSchemaToZod(schema) {
|
|
1529
|
-
if (schema.type === "object") {
|
|
1530
|
-
const shape = {};
|
|
1531
|
-
for (const [key, prop] of Object.entries(schema.properties || {})) {
|
|
1532
|
-
const propSchema = prop;
|
|
1533
|
-
if (propSchema.type === "string") {
|
|
1534
|
-
if (propSchema.enum) {
|
|
1535
|
-
shape[key] = import_zod.z.enum(propSchema.enum);
|
|
1536
|
-
} else {
|
|
1537
|
-
shape[key] = import_zod.z.string();
|
|
1538
|
-
}
|
|
1539
|
-
} else if (propSchema.type === "number") {
|
|
1540
|
-
shape[key] = import_zod.z.number();
|
|
1541
|
-
} else if (propSchema.type === "boolean") {
|
|
1542
|
-
shape[key] = import_zod.z.boolean();
|
|
1543
|
-
} else if (propSchema.type === "array") {
|
|
1544
|
-
if (propSchema.items.type === "string") {
|
|
1545
|
-
shape[key] = import_zod.z.array(import_zod.z.string());
|
|
1546
|
-
} else if (propSchema.items.type === "number") {
|
|
1547
|
-
shape[key] = import_zod.z.array(import_zod.z.number());
|
|
1548
|
-
} else if (propSchema.items.type === "boolean") {
|
|
1549
|
-
shape[key] = import_zod.z.array(import_zod.z.boolean());
|
|
1550
|
-
} else {
|
|
1551
|
-
shape[key] = import_zod.z.array(import_zod.z.any());
|
|
1552
|
-
}
|
|
1553
|
-
} else {
|
|
1554
|
-
shape[key] = import_zod.z.any();
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
return shape;
|
|
1558
|
-
}
|
|
1559
|
-
return {};
|
|
1560
|
-
}
|
|
1561
902
|
var MCPRemote = class extends MCPBase {
|
|
1562
903
|
/**
|
|
1563
904
|
* Port number the server will listen on.
|
|
@@ -1600,7 +941,7 @@ var MCPRemote = class extends MCPBase {
|
|
|
1600
941
|
*/
|
|
1601
942
|
marketDataPrices = /* @__PURE__ */ new Map();
|
|
1602
943
|
/**
|
|
1603
|
-
* Maximum number of price
|
|
944
|
+
* Maximum number of price points to store per symbol
|
|
1604
945
|
* @private
|
|
1605
946
|
*/
|
|
1606
947
|
MAX_PRICE_HISTORY = 1e5;
|
|
@@ -1622,7 +963,31 @@ var MCPRemote = class extends MCPBase {
|
|
|
1622
963
|
this.parser,
|
|
1623
964
|
this.pendingRequests,
|
|
1624
965
|
this.marketDataPrices,
|
|
1625
|
-
this.MAX_PRICE_HISTORY
|
|
966
|
+
this.MAX_PRICE_HISTORY,
|
|
967
|
+
(symbol, data) => {
|
|
968
|
+
this.mcpServer?.tool(
|
|
969
|
+
"priceUpdate",
|
|
970
|
+
{
|
|
971
|
+
description: "Price update notification",
|
|
972
|
+
schema: import_zod.z.object({
|
|
973
|
+
symbol: import_zod.z.string(),
|
|
974
|
+
timestamp: import_zod.z.number(),
|
|
975
|
+
bid: import_zod.z.number(),
|
|
976
|
+
offer: import_zod.z.number(),
|
|
977
|
+
spread: import_zod.z.number(),
|
|
978
|
+
volume: import_zod.z.number()
|
|
979
|
+
})
|
|
980
|
+
},
|
|
981
|
+
() => ({
|
|
982
|
+
content: [
|
|
983
|
+
{
|
|
984
|
+
type: "text",
|
|
985
|
+
text: JSON.stringify({ symbol, ...data })
|
|
986
|
+
}
|
|
987
|
+
]
|
|
988
|
+
})
|
|
989
|
+
);
|
|
990
|
+
}
|
|
1626
991
|
);
|
|
1627
992
|
}
|
|
1628
993
|
});
|
|
@@ -1684,15 +1049,7 @@ var MCPRemote = class extends MCPBase {
|
|
|
1684
1049
|
);
|
|
1685
1050
|
return;
|
|
1686
1051
|
}
|
|
1687
|
-
|
|
1688
|
-
await transport.handleRequest(req, res, parsed);
|
|
1689
|
-
} catch (error) {
|
|
1690
|
-
this.logger?.log({
|
|
1691
|
-
level: "error",
|
|
1692
|
-
message: `Error handling request: ${error}`
|
|
1693
|
-
});
|
|
1694
|
-
throw error;
|
|
1695
|
-
}
|
|
1052
|
+
await transport.handleRequest(req, res, parsed);
|
|
1696
1053
|
});
|
|
1697
1054
|
} else if (req.method === "GET" || req.method === "DELETE") {
|
|
1698
1055
|
if (!sessionId || !transports[sessionId]) {
|
|
@@ -1701,20 +1058,8 @@ var MCPRemote = class extends MCPBase {
|
|
|
1701
1058
|
return;
|
|
1702
1059
|
}
|
|
1703
1060
|
const transport = transports[sessionId];
|
|
1704
|
-
|
|
1705
|
-
await transport.handleRequest(req, res);
|
|
1706
|
-
} catch (error) {
|
|
1707
|
-
this.logger?.log({
|
|
1708
|
-
level: "error",
|
|
1709
|
-
message: `Error handling ${req.method} request: ${error}`
|
|
1710
|
-
});
|
|
1711
|
-
throw error;
|
|
1712
|
-
}
|
|
1061
|
+
await transport.handleRequest(req, res);
|
|
1713
1062
|
} else {
|
|
1714
|
-
this.logger?.log({
|
|
1715
|
-
level: "error",
|
|
1716
|
-
message: `Method not allowed: ${req.method}`
|
|
1717
|
-
});
|
|
1718
1063
|
res.writeHead(405);
|
|
1719
1064
|
res.end("Method Not Allowed");
|
|
1720
1065
|
}
|
|
@@ -1748,40 +1093,69 @@ var MCPRemote = class extends MCPBase {
|
|
|
1748
1093
|
});
|
|
1749
1094
|
return;
|
|
1750
1095
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1096
|
+
this.mcpServer.tool(
|
|
1097
|
+
"tools/list",
|
|
1098
|
+
{
|
|
1099
|
+
description: "List available tools",
|
|
1100
|
+
schema: import_zod.z.object({})
|
|
1101
|
+
},
|
|
1102
|
+
async () => {
|
|
1103
|
+
return {
|
|
1104
|
+
content: [
|
|
1105
|
+
{
|
|
1106
|
+
type: "text",
|
|
1107
|
+
text: JSON.stringify(
|
|
1108
|
+
Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
1109
|
+
name,
|
|
1110
|
+
description,
|
|
1111
|
+
inputSchema: schema
|
|
1112
|
+
}))
|
|
1113
|
+
)
|
|
1114
|
+
}
|
|
1115
|
+
]
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1756
1118
|
);
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1119
|
+
this.mcpServer.tool(
|
|
1120
|
+
"tools/call",
|
|
1121
|
+
{
|
|
1122
|
+
description: "Call a tool",
|
|
1123
|
+
schema: import_zod.z.object({
|
|
1124
|
+
name: import_zod.z.string(),
|
|
1125
|
+
arguments: import_zod.z.any(),
|
|
1126
|
+
_meta: import_zod.z.object({
|
|
1127
|
+
progressToken: import_zod.z.number()
|
|
1128
|
+
}).optional()
|
|
1129
|
+
})
|
|
1130
|
+
},
|
|
1131
|
+
async (request) => {
|
|
1132
|
+
const { name, arguments: args } = request;
|
|
1133
|
+
const toolHandlers = createToolHandlers(
|
|
1134
|
+
this.parser,
|
|
1135
|
+
this.verifiedOrders,
|
|
1136
|
+
this.pendingRequests,
|
|
1137
|
+
this.marketDataPrices
|
|
1138
|
+
);
|
|
1139
|
+
const handler = toolHandlers[name];
|
|
1140
|
+
if (!handler) {
|
|
1778
1141
|
return {
|
|
1779
|
-
content:
|
|
1780
|
-
|
|
1142
|
+
content: [
|
|
1143
|
+
{
|
|
1144
|
+
type: "text",
|
|
1145
|
+
text: `Tool not found: ${name}`,
|
|
1146
|
+
uri: name
|
|
1147
|
+
}
|
|
1148
|
+
],
|
|
1149
|
+
isError: true
|
|
1781
1150
|
};
|
|
1782
1151
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1152
|
+
const result = await handler(args);
|
|
1153
|
+
return {
|
|
1154
|
+
content: result.content,
|
|
1155
|
+
isError: result.isError
|
|
1156
|
+
};
|
|
1157
|
+
}
|
|
1158
|
+
);
|
|
1785
1159
|
}
|
|
1786
1160
|
};
|
|
1787
1161
|
// Annotate the CommonJS export names for ESM import in node:
|