fixparser-plugin-mcp 9.1.7-bfafe1e3 → 9.1.7-c213f7c6
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 +445 -143
- package/build/cjs/MCPLocal.js.map +4 -4
- package/build/cjs/MCPRemote.js +1284 -435
- package/build/cjs/MCPRemote.js.map +4 -4
- package/build/cjs/index.js +1583 -0
- package/build/cjs/index.js.map +7 -0
- package/build/esm/MCPLocal.mjs +445 -143
- package/build/esm/MCPLocal.mjs.map +4 -4
- package/build/esm/MCPRemote.mjs +1274 -444
- package/build/esm/MCPRemote.mjs.map +4 -4
- package/build/esm/index.mjs +1545 -0
- package/build/esm/index.mjs.map +7 -0
- package/build-examples/cjs/example_mcp_local.js +7 -7
- package/build-examples/cjs/example_mcp_local.js.map +4 -4
- package/build-examples/cjs/example_mcp_remote.js +16 -0
- package/build-examples/cjs/example_mcp_remote.js.map +7 -0
- package/build-examples/esm/example_mcp_local.mjs +7 -7
- package/build-examples/esm/example_mcp_local.mjs.map +4 -4
- package/build-examples/esm/example_mcp_remote.mjs +16 -0
- package/build-examples/esm/example_mcp_remote.mjs.map +7 -0
- package/package.json +6 -6
- package/types/MCPBase.d.ts +49 -0
- package/types/MCPLocal.d.ts +25 -9
- package/types/MCPRemote.d.ts +25 -27
- package/types/schemas/index.d.ts +3 -19
- package/types/schemas/marketData.d.ts +48 -0
- package/types/tools/index.d.ts +2 -11
- package/types/tools/marketData.d.ts +7 -28
- package/types/tools/order.d.ts +4 -3
- package/types/tools/parse.d.ts +2 -2
- package/types/tools/parseToJSON.d.ts +2 -2
- package/types/utils/messageHandler.d.ts +12 -0
package/build/esm/MCPLocal.mjs
CHANGED
|
@@ -1,9 +1,51 @@
|
|
|
1
1
|
// src/MCPLocal.ts
|
|
2
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
-
import { Fields as Fields3, MDEntryType as MDEntryType2, Messages as Messages3 } from "fixparser";
|
|
5
4
|
import { z } from "zod";
|
|
6
5
|
|
|
6
|
+
// src/MCPBase.ts
|
|
7
|
+
var MCPBase = class {
|
|
8
|
+
/**
|
|
9
|
+
* Optional logger instance for diagnostics and output.
|
|
10
|
+
* @protected
|
|
11
|
+
*/
|
|
12
|
+
logger;
|
|
13
|
+
/**
|
|
14
|
+
* FIXParser instance, set during plugin register().
|
|
15
|
+
* @protected
|
|
16
|
+
*/
|
|
17
|
+
parser;
|
|
18
|
+
/**
|
|
19
|
+
* Called when server is setup and listening.
|
|
20
|
+
* @protected
|
|
21
|
+
*/
|
|
22
|
+
onReady = void 0;
|
|
23
|
+
/**
|
|
24
|
+
* Map to store verified orders before execution
|
|
25
|
+
* @protected
|
|
26
|
+
*/
|
|
27
|
+
verifiedOrders = /* @__PURE__ */ new Map();
|
|
28
|
+
/**
|
|
29
|
+
* Map to store pending market data requests
|
|
30
|
+
* @protected
|
|
31
|
+
*/
|
|
32
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
33
|
+
/**
|
|
34
|
+
* Map to store market data prices
|
|
35
|
+
* @protected
|
|
36
|
+
*/
|
|
37
|
+
marketDataPrices = /* @__PURE__ */ new Map();
|
|
38
|
+
/**
|
|
39
|
+
* Maximum number of price history entries to keep per symbol
|
|
40
|
+
* @protected
|
|
41
|
+
*/
|
|
42
|
+
MAX_PRICE_HISTORY = 1e5;
|
|
43
|
+
constructor({ logger, onReady }) {
|
|
44
|
+
this.logger = logger;
|
|
45
|
+
this.onReady = onReady;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
7
49
|
// src/schemas/schemas.ts
|
|
8
50
|
var toolSchemas = {
|
|
9
51
|
parse: {
|
|
@@ -87,7 +129,7 @@ var toolSchemas = {
|
|
|
87
129
|
}
|
|
88
130
|
},
|
|
89
131
|
executeOrder: {
|
|
90
|
-
description: "Executes a verified order. verifyOrder must be called before executeOrder.
|
|
132
|
+
description: "Executes a verified order. verifyOrder must be called before executeOrder.",
|
|
91
133
|
schema: {
|
|
92
134
|
type: "object",
|
|
93
135
|
properties: {
|
|
@@ -243,7 +285,52 @@ var createMarketDataRequestHandler = (parser, pendingRequests) => {
|
|
|
243
285
|
const response = new Promise((resolve) => {
|
|
244
286
|
pendingRequests.set(args.mdReqID, resolve);
|
|
245
287
|
});
|
|
246
|
-
const entryTypes = args.mdEntryTypes || [
|
|
288
|
+
const entryTypes = args.mdEntryTypes || [
|
|
289
|
+
MDEntryType.Bid,
|
|
290
|
+
MDEntryType.Offer,
|
|
291
|
+
MDEntryType.Trade,
|
|
292
|
+
MDEntryType.IndexValue,
|
|
293
|
+
MDEntryType.OpeningPrice,
|
|
294
|
+
MDEntryType.ClosingPrice,
|
|
295
|
+
MDEntryType.SettlementPrice,
|
|
296
|
+
MDEntryType.TradingSessionHighPrice,
|
|
297
|
+
MDEntryType.TradingSessionLowPrice,
|
|
298
|
+
MDEntryType.VWAP,
|
|
299
|
+
MDEntryType.Imbalance,
|
|
300
|
+
MDEntryType.TradeVolume,
|
|
301
|
+
MDEntryType.OpenInterest,
|
|
302
|
+
MDEntryType.CompositeUnderlyingPrice,
|
|
303
|
+
MDEntryType.SimulatedSellPrice,
|
|
304
|
+
MDEntryType.SimulatedBuyPrice,
|
|
305
|
+
MDEntryType.MarginRate,
|
|
306
|
+
MDEntryType.MidPrice,
|
|
307
|
+
MDEntryType.EmptyBook,
|
|
308
|
+
MDEntryType.SettleHighPrice,
|
|
309
|
+
MDEntryType.SettleLowPrice,
|
|
310
|
+
MDEntryType.PriorSettlePrice,
|
|
311
|
+
MDEntryType.SessionHighBid,
|
|
312
|
+
MDEntryType.SessionLowOffer,
|
|
313
|
+
MDEntryType.EarlyPrices,
|
|
314
|
+
MDEntryType.AuctionClearingPrice,
|
|
315
|
+
MDEntryType.SwapValueFactor,
|
|
316
|
+
MDEntryType.DailyValueAdjustmentForLongPositions,
|
|
317
|
+
MDEntryType.CumulativeValueAdjustmentForLongPositions,
|
|
318
|
+
MDEntryType.DailyValueAdjustmentForShortPositions,
|
|
319
|
+
MDEntryType.CumulativeValueAdjustmentForShortPositions,
|
|
320
|
+
MDEntryType.FixingPrice,
|
|
321
|
+
MDEntryType.CashRate,
|
|
322
|
+
MDEntryType.RecoveryRate,
|
|
323
|
+
MDEntryType.RecoveryRateForLong,
|
|
324
|
+
MDEntryType.RecoveryRateForShort,
|
|
325
|
+
MDEntryType.MarketBid,
|
|
326
|
+
MDEntryType.MarketOffer,
|
|
327
|
+
MDEntryType.ShortSaleMinPrice,
|
|
328
|
+
MDEntryType.PreviousClosingPrice,
|
|
329
|
+
MDEntryType.ThresholdLimitPriceBanding,
|
|
330
|
+
MDEntryType.DailyFinancingValue,
|
|
331
|
+
MDEntryType.AccruedFinancingValue,
|
|
332
|
+
MDEntryType.TWAP
|
|
333
|
+
];
|
|
247
334
|
const messageFields = [
|
|
248
335
|
new Field(Fields.MsgType, Messages.MarketDataRequest),
|
|
249
336
|
new Field(Fields.SenderCompID, parser.sender),
|
|
@@ -318,14 +405,18 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
318
405
|
};
|
|
319
406
|
}
|
|
320
407
|
const chart = new QuickChart();
|
|
321
|
-
chart.setWidth(
|
|
322
|
-
chart.setHeight(
|
|
408
|
+
chart.setWidth(1200);
|
|
409
|
+
chart.setHeight(600);
|
|
410
|
+
chart.setBackgroundColor("transparent");
|
|
323
411
|
const labels = priceHistory.map((point) => new Date(point.timestamp).toLocaleTimeString());
|
|
324
412
|
const bidData = priceHistory.map((point) => point.bid);
|
|
325
413
|
const offerData = priceHistory.map((point) => point.offer);
|
|
326
414
|
const spreadData = priceHistory.map((point) => point.spread);
|
|
327
415
|
const volumeData = priceHistory.map((point) => point.volume);
|
|
328
|
-
|
|
416
|
+
const tradeData = priceHistory.map((point) => point.trade);
|
|
417
|
+
const vwapData = priceHistory.map((point) => point.vwap);
|
|
418
|
+
const twapData = priceHistory.map((point) => point.twap);
|
|
419
|
+
const config = {
|
|
329
420
|
type: "line",
|
|
330
421
|
data: {
|
|
331
422
|
labels,
|
|
@@ -354,69 +445,67 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
354
445
|
fill: false,
|
|
355
446
|
tension: 0.4
|
|
356
447
|
},
|
|
448
|
+
{
|
|
449
|
+
label: "Trade",
|
|
450
|
+
data: tradeData,
|
|
451
|
+
borderColor: "#ffc107",
|
|
452
|
+
backgroundColor: "rgba(255, 193, 7, 0.1)",
|
|
453
|
+
fill: false,
|
|
454
|
+
tension: 0.4
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
label: "VWAP",
|
|
458
|
+
data: vwapData,
|
|
459
|
+
borderColor: "#17a2b8",
|
|
460
|
+
backgroundColor: "rgba(23, 162, 184, 0.1)",
|
|
461
|
+
fill: false,
|
|
462
|
+
tension: 0.4
|
|
463
|
+
},
|
|
464
|
+
{
|
|
465
|
+
label: "TWAP",
|
|
466
|
+
data: twapData,
|
|
467
|
+
borderColor: "#6610f2",
|
|
468
|
+
backgroundColor: "rgba(102, 16, 242, 0.1)",
|
|
469
|
+
fill: false,
|
|
470
|
+
tension: 0.4
|
|
471
|
+
},
|
|
357
472
|
{
|
|
358
473
|
label: "Volume",
|
|
359
474
|
data: volumeData,
|
|
360
475
|
borderColor: "#007bff",
|
|
361
476
|
backgroundColor: "rgba(0, 123, 255, 0.1)",
|
|
362
477
|
fill: true,
|
|
363
|
-
tension: 0.4
|
|
364
|
-
yAxisID: "volume"
|
|
478
|
+
tension: 0.4
|
|
365
479
|
}
|
|
366
480
|
]
|
|
367
481
|
},
|
|
368
482
|
options: {
|
|
483
|
+
responsive: true,
|
|
369
484
|
plugins: {
|
|
370
485
|
title: {
|
|
371
486
|
display: true,
|
|
372
|
-
text: `${symbol} Market Data
|
|
373
|
-
font: {
|
|
374
|
-
size: 16,
|
|
375
|
-
weight: "bold"
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
legend: {
|
|
379
|
-
display: true
|
|
487
|
+
text: `${symbol} Market Data`
|
|
380
488
|
}
|
|
381
489
|
},
|
|
382
490
|
scales: {
|
|
383
491
|
y: {
|
|
384
|
-
beginAtZero: false
|
|
385
|
-
grid: {
|
|
386
|
-
color: "#e9ecef"
|
|
387
|
-
}
|
|
388
|
-
},
|
|
389
|
-
volume: {
|
|
390
|
-
position: "right",
|
|
391
|
-
beginAtZero: true,
|
|
392
|
-
grid: {
|
|
393
|
-
display: false
|
|
394
|
-
}
|
|
395
|
-
},
|
|
396
|
-
x: {
|
|
397
|
-
grid: {
|
|
398
|
-
display: false
|
|
399
|
-
}
|
|
492
|
+
beginAtZero: false
|
|
400
493
|
}
|
|
401
494
|
}
|
|
402
495
|
}
|
|
403
|
-
}
|
|
496
|
+
};
|
|
497
|
+
chart.setConfig(config);
|
|
404
498
|
const imageBuffer = await chart.toBinary();
|
|
405
|
-
const
|
|
406
|
-
console.log("-------------------------------------------");
|
|
407
|
-
console.log("b64", base64Image);
|
|
408
|
-
console.log("-------------------------------------------");
|
|
499
|
+
const base64 = imageBuffer.toString("base64");
|
|
409
500
|
return {
|
|
410
501
|
content: [
|
|
411
502
|
{
|
|
412
|
-
type: "
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
}
|
|
418
|
-
uri: "getStockGraph",
|
|
419
|
-
mimeType: "image/png"
|
|
503
|
+
type: "resource",
|
|
504
|
+
resource: {
|
|
505
|
+
uri: "resource://graph",
|
|
506
|
+
mimeType: "image/png",
|
|
507
|
+
blob: base64
|
|
508
|
+
}
|
|
420
509
|
}
|
|
421
510
|
]
|
|
422
511
|
};
|
|
@@ -425,7 +514,7 @@ var createGetStockGraphHandler = (marketDataPrices) => {
|
|
|
425
514
|
content: [
|
|
426
515
|
{
|
|
427
516
|
type: "text",
|
|
428
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to generate
|
|
517
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to generate graph"}`,
|
|
429
518
|
uri: "getStockGraph"
|
|
430
519
|
}
|
|
431
520
|
],
|
|
@@ -463,7 +552,48 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
463
552
|
bid: point.bid,
|
|
464
553
|
offer: point.offer,
|
|
465
554
|
spread: point.spread,
|
|
466
|
-
volume: point.volume
|
|
555
|
+
volume: point.volume,
|
|
556
|
+
trade: point.trade,
|
|
557
|
+
indexValue: point.indexValue,
|
|
558
|
+
openingPrice: point.openingPrice,
|
|
559
|
+
closingPrice: point.closingPrice,
|
|
560
|
+
settlementPrice: point.settlementPrice,
|
|
561
|
+
tradingSessionHighPrice: point.tradingSessionHighPrice,
|
|
562
|
+
tradingSessionLowPrice: point.tradingSessionLowPrice,
|
|
563
|
+
vwap: point.vwap,
|
|
564
|
+
imbalance: point.imbalance,
|
|
565
|
+
openInterest: point.openInterest,
|
|
566
|
+
compositeUnderlyingPrice: point.compositeUnderlyingPrice,
|
|
567
|
+
simulatedSellPrice: point.simulatedSellPrice,
|
|
568
|
+
simulatedBuyPrice: point.simulatedBuyPrice,
|
|
569
|
+
marginRate: point.marginRate,
|
|
570
|
+
midPrice: point.midPrice,
|
|
571
|
+
emptyBook: point.emptyBook,
|
|
572
|
+
settleHighPrice: point.settleHighPrice,
|
|
573
|
+
settleLowPrice: point.settleLowPrice,
|
|
574
|
+
priorSettlePrice: point.priorSettlePrice,
|
|
575
|
+
sessionHighBid: point.sessionHighBid,
|
|
576
|
+
sessionLowOffer: point.sessionLowOffer,
|
|
577
|
+
earlyPrices: point.earlyPrices,
|
|
578
|
+
auctionClearingPrice: point.auctionClearingPrice,
|
|
579
|
+
swapValueFactor: point.swapValueFactor,
|
|
580
|
+
dailyValueAdjustmentForLongPositions: point.dailyValueAdjustmentForLongPositions,
|
|
581
|
+
cumulativeValueAdjustmentForLongPositions: point.cumulativeValueAdjustmentForLongPositions,
|
|
582
|
+
dailyValueAdjustmentForShortPositions: point.dailyValueAdjustmentForShortPositions,
|
|
583
|
+
cumulativeValueAdjustmentForShortPositions: point.cumulativeValueAdjustmentForShortPositions,
|
|
584
|
+
fixingPrice: point.fixingPrice,
|
|
585
|
+
cashRate: point.cashRate,
|
|
586
|
+
recoveryRate: point.recoveryRate,
|
|
587
|
+
recoveryRateForLong: point.recoveryRateForLong,
|
|
588
|
+
recoveryRateForShort: point.recoveryRateForShort,
|
|
589
|
+
marketBid: point.marketBid,
|
|
590
|
+
marketOffer: point.marketOffer,
|
|
591
|
+
shortSaleMinPrice: point.shortSaleMinPrice,
|
|
592
|
+
previousClosingPrice: point.previousClosingPrice,
|
|
593
|
+
thresholdLimitPriceBanding: point.thresholdLimitPriceBanding,
|
|
594
|
+
dailyFinancingValue: point.dailyFinancingValue,
|
|
595
|
+
accruedFinancingValue: point.accruedFinancingValue,
|
|
596
|
+
twap: point.twap
|
|
467
597
|
}))
|
|
468
598
|
},
|
|
469
599
|
null,
|
|
@@ -478,7 +608,7 @@ var createGetStockPriceHistoryHandler = (marketDataPrices) => {
|
|
|
478
608
|
content: [
|
|
479
609
|
{
|
|
480
610
|
type: "text",
|
|
481
|
-
text: `Error: ${error instanceof Error ? error.message : "Failed to get
|
|
611
|
+
text: `Error: ${error instanceof Error ? error.message : "Failed to get price history"}`,
|
|
482
612
|
uri: "getStockPriceHistory"
|
|
483
613
|
}
|
|
484
614
|
],
|
|
@@ -586,7 +716,7 @@ Parameters verified:
|
|
|
586
716
|
- Symbol: ${args.symbol}
|
|
587
717
|
- TimeInForce: ${args.timeInForce} (${timeInForceNames[args.timeInForce]})
|
|
588
718
|
|
|
589
|
-
To execute this order, call the executeOrder tool with these exact same parameters
|
|
719
|
+
To execute this order, call the executeOrder tool with these exact same parameters. Important: The user has to explicitly confirm before executeOrder is called!`,
|
|
590
720
|
uri: "verifyOrder"
|
|
591
721
|
}
|
|
592
722
|
]
|
|
@@ -785,9 +915,261 @@ var createToolHandlers = (parser, verifiedOrders, pendingRequests, marketDataPri
|
|
|
785
915
|
getStockPriceHistory: createGetStockPriceHistoryHandler(marketDataPrices)
|
|
786
916
|
});
|
|
787
917
|
|
|
918
|
+
// src/utils/messageHandler.ts
|
|
919
|
+
import { Fields as Fields3, MDEntryType as MDEntryType2, Messages as Messages3 } from "fixparser";
|
|
920
|
+
function handleMessage(message, parser, pendingRequests, marketDataPrices, maxPriceHistory, onPriceUpdate) {
|
|
921
|
+
parser.logger.log({
|
|
922
|
+
level: "info",
|
|
923
|
+
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
924
|
+
});
|
|
925
|
+
const msgType = message.messageType;
|
|
926
|
+
if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.MarketDataIncrementalRefresh) {
|
|
927
|
+
const symbol = message.getField(Fields3.Symbol)?.value;
|
|
928
|
+
const fixJson = message.toFIXJSON();
|
|
929
|
+
const entries = fixJson.Body?.NoMDEntries || [];
|
|
930
|
+
const data = {
|
|
931
|
+
timestamp: Date.now(),
|
|
932
|
+
bid: 0,
|
|
933
|
+
offer: 0,
|
|
934
|
+
spread: 0,
|
|
935
|
+
volume: 0,
|
|
936
|
+
trade: 0,
|
|
937
|
+
indexValue: 0,
|
|
938
|
+
openingPrice: 0,
|
|
939
|
+
closingPrice: 0,
|
|
940
|
+
settlementPrice: 0,
|
|
941
|
+
tradingSessionHighPrice: 0,
|
|
942
|
+
tradingSessionLowPrice: 0,
|
|
943
|
+
vwap: 0,
|
|
944
|
+
imbalance: 0,
|
|
945
|
+
openInterest: 0,
|
|
946
|
+
compositeUnderlyingPrice: 0,
|
|
947
|
+
simulatedSellPrice: 0,
|
|
948
|
+
simulatedBuyPrice: 0,
|
|
949
|
+
marginRate: 0,
|
|
950
|
+
midPrice: 0,
|
|
951
|
+
emptyBook: 0,
|
|
952
|
+
settleHighPrice: 0,
|
|
953
|
+
settleLowPrice: 0,
|
|
954
|
+
priorSettlePrice: 0,
|
|
955
|
+
sessionHighBid: 0,
|
|
956
|
+
sessionLowOffer: 0,
|
|
957
|
+
earlyPrices: 0,
|
|
958
|
+
auctionClearingPrice: 0,
|
|
959
|
+
swapValueFactor: 0,
|
|
960
|
+
dailyValueAdjustmentForLongPositions: 0,
|
|
961
|
+
cumulativeValueAdjustmentForLongPositions: 0,
|
|
962
|
+
dailyValueAdjustmentForShortPositions: 0,
|
|
963
|
+
cumulativeValueAdjustmentForShortPositions: 0,
|
|
964
|
+
fixingPrice: 0,
|
|
965
|
+
cashRate: 0,
|
|
966
|
+
recoveryRate: 0,
|
|
967
|
+
recoveryRateForLong: 0,
|
|
968
|
+
recoveryRateForShort: 0,
|
|
969
|
+
marketBid: 0,
|
|
970
|
+
marketOffer: 0,
|
|
971
|
+
shortSaleMinPrice: 0,
|
|
972
|
+
previousClosingPrice: 0,
|
|
973
|
+
thresholdLimitPriceBanding: 0,
|
|
974
|
+
dailyFinancingValue: 0,
|
|
975
|
+
accruedFinancingValue: 0,
|
|
976
|
+
twap: 0
|
|
977
|
+
};
|
|
978
|
+
for (const entry of entries) {
|
|
979
|
+
const entryType = entry.MDEntryType;
|
|
980
|
+
const price = entry.MDEntryPx ? Number.parseFloat(entry.MDEntryPx) : 0;
|
|
981
|
+
const size = entry.MDEntrySize ? Number.parseFloat(entry.MDEntrySize) : 0;
|
|
982
|
+
if (entryType === MDEntryType2.Bid || entryType === MDEntryType2.Offer || entryType === MDEntryType2.TradeVolume) {
|
|
983
|
+
parser.logger.log({
|
|
984
|
+
level: "info",
|
|
985
|
+
message: `Market Data Entry - Type: ${entryType}, Price: ${price}, Size: ${size}`
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
switch (entryType) {
|
|
989
|
+
case MDEntryType2.Bid:
|
|
990
|
+
data.bid = price;
|
|
991
|
+
break;
|
|
992
|
+
case MDEntryType2.Offer:
|
|
993
|
+
data.offer = price;
|
|
994
|
+
break;
|
|
995
|
+
case MDEntryType2.Trade:
|
|
996
|
+
data.trade = price;
|
|
997
|
+
break;
|
|
998
|
+
case MDEntryType2.IndexValue:
|
|
999
|
+
data.indexValue = price;
|
|
1000
|
+
break;
|
|
1001
|
+
case MDEntryType2.OpeningPrice:
|
|
1002
|
+
data.openingPrice = price;
|
|
1003
|
+
break;
|
|
1004
|
+
case MDEntryType2.ClosingPrice:
|
|
1005
|
+
data.closingPrice = price;
|
|
1006
|
+
break;
|
|
1007
|
+
case MDEntryType2.SettlementPrice:
|
|
1008
|
+
data.settlementPrice = price;
|
|
1009
|
+
break;
|
|
1010
|
+
case MDEntryType2.TradingSessionHighPrice:
|
|
1011
|
+
data.tradingSessionHighPrice = price;
|
|
1012
|
+
break;
|
|
1013
|
+
case MDEntryType2.TradingSessionLowPrice:
|
|
1014
|
+
data.tradingSessionLowPrice = price;
|
|
1015
|
+
break;
|
|
1016
|
+
case MDEntryType2.VWAP:
|
|
1017
|
+
data.vwap = price;
|
|
1018
|
+
break;
|
|
1019
|
+
case MDEntryType2.Imbalance:
|
|
1020
|
+
data.imbalance = size;
|
|
1021
|
+
break;
|
|
1022
|
+
case MDEntryType2.TradeVolume:
|
|
1023
|
+
data.volume = size;
|
|
1024
|
+
break;
|
|
1025
|
+
case MDEntryType2.OpenInterest:
|
|
1026
|
+
data.openInterest = size;
|
|
1027
|
+
break;
|
|
1028
|
+
case MDEntryType2.CompositeUnderlyingPrice:
|
|
1029
|
+
data.compositeUnderlyingPrice = price;
|
|
1030
|
+
break;
|
|
1031
|
+
case MDEntryType2.SimulatedSellPrice:
|
|
1032
|
+
data.simulatedSellPrice = price;
|
|
1033
|
+
break;
|
|
1034
|
+
case MDEntryType2.SimulatedBuyPrice:
|
|
1035
|
+
data.simulatedBuyPrice = price;
|
|
1036
|
+
break;
|
|
1037
|
+
case MDEntryType2.MarginRate:
|
|
1038
|
+
data.marginRate = price;
|
|
1039
|
+
break;
|
|
1040
|
+
case MDEntryType2.MidPrice:
|
|
1041
|
+
data.midPrice = price;
|
|
1042
|
+
break;
|
|
1043
|
+
case MDEntryType2.EmptyBook:
|
|
1044
|
+
data.emptyBook = 1;
|
|
1045
|
+
break;
|
|
1046
|
+
case MDEntryType2.SettleHighPrice:
|
|
1047
|
+
data.settleHighPrice = price;
|
|
1048
|
+
break;
|
|
1049
|
+
case MDEntryType2.SettleLowPrice:
|
|
1050
|
+
data.settleLowPrice = price;
|
|
1051
|
+
break;
|
|
1052
|
+
case MDEntryType2.PriorSettlePrice:
|
|
1053
|
+
data.priorSettlePrice = price;
|
|
1054
|
+
break;
|
|
1055
|
+
case MDEntryType2.SessionHighBid:
|
|
1056
|
+
data.sessionHighBid = price;
|
|
1057
|
+
break;
|
|
1058
|
+
case MDEntryType2.SessionLowOffer:
|
|
1059
|
+
data.sessionLowOffer = price;
|
|
1060
|
+
break;
|
|
1061
|
+
case MDEntryType2.EarlyPrices:
|
|
1062
|
+
data.earlyPrices = price;
|
|
1063
|
+
break;
|
|
1064
|
+
case MDEntryType2.AuctionClearingPrice:
|
|
1065
|
+
data.auctionClearingPrice = price;
|
|
1066
|
+
break;
|
|
1067
|
+
case MDEntryType2.SwapValueFactor:
|
|
1068
|
+
data.swapValueFactor = price;
|
|
1069
|
+
break;
|
|
1070
|
+
case MDEntryType2.DailyValueAdjustmentForLongPositions:
|
|
1071
|
+
data.dailyValueAdjustmentForLongPositions = price;
|
|
1072
|
+
break;
|
|
1073
|
+
case MDEntryType2.CumulativeValueAdjustmentForLongPositions:
|
|
1074
|
+
data.cumulativeValueAdjustmentForLongPositions = price;
|
|
1075
|
+
break;
|
|
1076
|
+
case MDEntryType2.DailyValueAdjustmentForShortPositions:
|
|
1077
|
+
data.dailyValueAdjustmentForShortPositions = price;
|
|
1078
|
+
break;
|
|
1079
|
+
case MDEntryType2.CumulativeValueAdjustmentForShortPositions:
|
|
1080
|
+
data.cumulativeValueAdjustmentForShortPositions = price;
|
|
1081
|
+
break;
|
|
1082
|
+
case MDEntryType2.FixingPrice:
|
|
1083
|
+
data.fixingPrice = price;
|
|
1084
|
+
break;
|
|
1085
|
+
case MDEntryType2.CashRate:
|
|
1086
|
+
data.cashRate = price;
|
|
1087
|
+
break;
|
|
1088
|
+
case MDEntryType2.RecoveryRate:
|
|
1089
|
+
data.recoveryRate = price;
|
|
1090
|
+
break;
|
|
1091
|
+
case MDEntryType2.RecoveryRateForLong:
|
|
1092
|
+
data.recoveryRateForLong = price;
|
|
1093
|
+
break;
|
|
1094
|
+
case MDEntryType2.RecoveryRateForShort:
|
|
1095
|
+
data.recoveryRateForShort = price;
|
|
1096
|
+
break;
|
|
1097
|
+
case MDEntryType2.MarketBid:
|
|
1098
|
+
data.marketBid = price;
|
|
1099
|
+
break;
|
|
1100
|
+
case MDEntryType2.MarketOffer:
|
|
1101
|
+
data.marketOffer = price;
|
|
1102
|
+
break;
|
|
1103
|
+
case MDEntryType2.ShortSaleMinPrice:
|
|
1104
|
+
data.shortSaleMinPrice = price;
|
|
1105
|
+
break;
|
|
1106
|
+
case MDEntryType2.PreviousClosingPrice:
|
|
1107
|
+
data.previousClosingPrice = price;
|
|
1108
|
+
break;
|
|
1109
|
+
case MDEntryType2.ThresholdLimitPriceBanding:
|
|
1110
|
+
data.thresholdLimitPriceBanding = price;
|
|
1111
|
+
break;
|
|
1112
|
+
case MDEntryType2.DailyFinancingValue:
|
|
1113
|
+
data.dailyFinancingValue = price;
|
|
1114
|
+
break;
|
|
1115
|
+
case MDEntryType2.AccruedFinancingValue:
|
|
1116
|
+
data.accruedFinancingValue = price;
|
|
1117
|
+
break;
|
|
1118
|
+
case MDEntryType2.TWAP:
|
|
1119
|
+
data.twap = price;
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
data.spread = data.offer - data.bid;
|
|
1124
|
+
if (!marketDataPrices.has(symbol)) {
|
|
1125
|
+
marketDataPrices.set(symbol, []);
|
|
1126
|
+
}
|
|
1127
|
+
const prices = marketDataPrices.get(symbol);
|
|
1128
|
+
prices.push(data);
|
|
1129
|
+
if (prices.length > maxPriceHistory) {
|
|
1130
|
+
prices.splice(0, prices.length - maxPriceHistory);
|
|
1131
|
+
}
|
|
1132
|
+
onPriceUpdate?.(symbol, data);
|
|
1133
|
+
const mdReqID = message.getField(Fields3.MDReqID)?.value;
|
|
1134
|
+
if (mdReqID) {
|
|
1135
|
+
const callback = pendingRequests.get(mdReqID);
|
|
1136
|
+
if (callback) {
|
|
1137
|
+
callback(message);
|
|
1138
|
+
pendingRequests.delete(mdReqID);
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
} else if (msgType === Messages3.ExecutionReport) {
|
|
1142
|
+
const reqId = message.getField(Fields3.ClOrdID)?.value;
|
|
1143
|
+
const callback = pendingRequests.get(reqId);
|
|
1144
|
+
if (callback) {
|
|
1145
|
+
callback(message);
|
|
1146
|
+
pendingRequests.delete(reqId);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
788
1151
|
// src/MCPLocal.ts
|
|
789
|
-
var MCPLocal = class {
|
|
790
|
-
|
|
1152
|
+
var MCPLocal = class extends MCPBase {
|
|
1153
|
+
/**
|
|
1154
|
+
* Map to store verified orders before execution
|
|
1155
|
+
* @private
|
|
1156
|
+
*/
|
|
1157
|
+
verifiedOrders = /* @__PURE__ */ new Map();
|
|
1158
|
+
/**
|
|
1159
|
+
* Map to store pending requests and their callbacks
|
|
1160
|
+
* @private
|
|
1161
|
+
*/
|
|
1162
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
1163
|
+
/**
|
|
1164
|
+
* Map to store market data prices for each symbol
|
|
1165
|
+
* @private
|
|
1166
|
+
*/
|
|
1167
|
+
marketDataPrices = /* @__PURE__ */ new Map();
|
|
1168
|
+
/**
|
|
1169
|
+
* Maximum number of price history entries to keep per symbol
|
|
1170
|
+
* @private
|
|
1171
|
+
*/
|
|
1172
|
+
MAX_PRICE_HISTORY = 1e5;
|
|
791
1173
|
server = new Server(
|
|
792
1174
|
{
|
|
793
1175
|
name: "fixparser",
|
|
@@ -809,90 +1191,13 @@ var MCPLocal = class {
|
|
|
809
1191
|
}
|
|
810
1192
|
);
|
|
811
1193
|
transport = new StdioServerTransport();
|
|
812
|
-
onReady = void 0;
|
|
813
|
-
pendingRequests = /* @__PURE__ */ new Map();
|
|
814
|
-
verifiedOrders = /* @__PURE__ */ new Map();
|
|
815
|
-
marketDataPrices = /* @__PURE__ */ new Map();
|
|
816
|
-
MAX_PRICE_HISTORY = 1e5;
|
|
817
|
-
// Maximum number of price points to store per symbol
|
|
818
1194
|
constructor({ logger, onReady }) {
|
|
819
|
-
|
|
1195
|
+
super({ logger, onReady });
|
|
820
1196
|
}
|
|
821
1197
|
async register(parser) {
|
|
822
1198
|
this.parser = parser;
|
|
823
1199
|
this.parser.addOnMessageCallback((message) => {
|
|
824
|
-
this.parser
|
|
825
|
-
level: "info",
|
|
826
|
-
message: `MCP Server received message: ${message.messageType}: ${message.description}`
|
|
827
|
-
});
|
|
828
|
-
const msgType = message.messageType;
|
|
829
|
-
if (msgType === Messages3.MarketDataSnapshotFullRefresh || msgType === Messages3.ExecutionReport || msgType === Messages3.Reject || msgType === Messages3.MarketDataIncrementalRefresh) {
|
|
830
|
-
this.parser?.logger.log({
|
|
831
|
-
level: "info",
|
|
832
|
-
message: `MCP Server handling message type: ${msgType}`
|
|
833
|
-
});
|
|
834
|
-
let id;
|
|
835
|
-
if (msgType === Messages3.MarketDataIncrementalRefresh || msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
836
|
-
const symbol = message.getField(Fields3.Symbol);
|
|
837
|
-
const entryType = message.getField(Fields3.MDEntryType);
|
|
838
|
-
const price = message.getField(Fields3.MDEntryPx);
|
|
839
|
-
const size = message.getField(Fields3.MDEntrySize);
|
|
840
|
-
const timestamp = message.getField(Fields3.MDEntryTime)?.value || Date.now();
|
|
841
|
-
if (symbol?.value && price?.value) {
|
|
842
|
-
const symbolStr = String(symbol.value);
|
|
843
|
-
const priceNum = Number(price.value);
|
|
844
|
-
const sizeNum = size?.value ? Number(size.value) : 0;
|
|
845
|
-
const priceHistory = this.marketDataPrices.get(symbolStr) || [];
|
|
846
|
-
const lastEntry = priceHistory[priceHistory.length - 1] || {
|
|
847
|
-
timestamp: 0,
|
|
848
|
-
bid: 0,
|
|
849
|
-
offer: 0,
|
|
850
|
-
spread: 0,
|
|
851
|
-
volume: 0
|
|
852
|
-
};
|
|
853
|
-
const newEntry = {
|
|
854
|
-
timestamp: Number(timestamp),
|
|
855
|
-
bid: entryType?.value === MDEntryType2.Bid ? priceNum : lastEntry.bid,
|
|
856
|
-
offer: entryType?.value === MDEntryType2.Offer ? priceNum : lastEntry.offer,
|
|
857
|
-
spread: entryType?.value === MDEntryType2.Offer ? priceNum - lastEntry.bid : entryType?.value === MDEntryType2.Bid ? lastEntry.offer - priceNum : lastEntry.spread,
|
|
858
|
-
volume: entryType?.value === MDEntryType2.TradeVolume ? sizeNum : lastEntry.volume
|
|
859
|
-
};
|
|
860
|
-
priceHistory.push(newEntry);
|
|
861
|
-
if (priceHistory.length > this.MAX_PRICE_HISTORY) {
|
|
862
|
-
priceHistory.shift();
|
|
863
|
-
}
|
|
864
|
-
this.marketDataPrices.set(symbolStr, priceHistory);
|
|
865
|
-
this.parser?.logger.log({
|
|
866
|
-
level: "info",
|
|
867
|
-
message: `MCP Server added ${symbol}: ${JSON.stringify(newEntry)}`
|
|
868
|
-
});
|
|
869
|
-
this.server.notification({
|
|
870
|
-
method: "priceUpdate",
|
|
871
|
-
params: {
|
|
872
|
-
symbol: symbolStr,
|
|
873
|
-
...newEntry
|
|
874
|
-
}
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
if (msgType === Messages3.MarketDataSnapshotFullRefresh) {
|
|
879
|
-
const mdReqID = message.getField(Fields3.MDReqID);
|
|
880
|
-
if (mdReqID) id = String(mdReqID.value);
|
|
881
|
-
} else if (msgType === Messages3.ExecutionReport) {
|
|
882
|
-
const clOrdID = message.getField(Fields3.ClOrdID);
|
|
883
|
-
if (clOrdID) id = String(clOrdID.value);
|
|
884
|
-
} else if (msgType === Messages3.Reject) {
|
|
885
|
-
const refSeqNum = message.getField(Fields3.RefSeqNum);
|
|
886
|
-
if (refSeqNum) id = String(refSeqNum.value);
|
|
887
|
-
}
|
|
888
|
-
if (id) {
|
|
889
|
-
const callback = this.pendingRequests.get(id);
|
|
890
|
-
if (callback) {
|
|
891
|
-
callback(message);
|
|
892
|
-
this.pendingRequests.delete(id);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
}
|
|
1200
|
+
handleMessage(message, this.parser, this.pendingRequests, this.marketDataPrices, this.MAX_PRICE_HISTORY);
|
|
896
1201
|
});
|
|
897
1202
|
this.addWorkflows();
|
|
898
1203
|
await this.server.connect(this.transport);
|
|
@@ -907,18 +1212,15 @@ var MCPLocal = class {
|
|
|
907
1212
|
if (!this.server) {
|
|
908
1213
|
return;
|
|
909
1214
|
}
|
|
910
|
-
this.server.setRequestHandler(
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
};
|
|
920
|
-
}
|
|
921
|
-
);
|
|
1215
|
+
this.server.setRequestHandler(z.object({ method: z.literal("tools/list") }), async () => {
|
|
1216
|
+
return {
|
|
1217
|
+
tools: Object.entries(toolSchemas).map(([name, { description, schema }]) => ({
|
|
1218
|
+
name,
|
|
1219
|
+
description,
|
|
1220
|
+
inputSchema: schema
|
|
1221
|
+
}))
|
|
1222
|
+
};
|
|
1223
|
+
});
|
|
922
1224
|
this.server.setRequestHandler(
|
|
923
1225
|
z.object({
|
|
924
1226
|
method: z.literal("tools/call"),
|
|
@@ -930,7 +1232,7 @@ var MCPLocal = class {
|
|
|
930
1232
|
}).optional()
|
|
931
1233
|
})
|
|
932
1234
|
}),
|
|
933
|
-
async (request
|
|
1235
|
+
async (request) => {
|
|
934
1236
|
const { name, arguments: args } = request.params;
|
|
935
1237
|
const toolHandlers = createToolHandlers(
|
|
936
1238
|
this.parser,
|