Tradovate MCP Server

by alexanimal
Verified
import * as logger from "./logger.js"; import { tradovateRequest } from './auth.js'; import { Contract, Position, Order, Account } from './types.js'; // Data storage for caching API responses export let contractsCache: { [id: string]: Contract } = {}; export let positionsCache: { [id: string]: Position } = {}; export let ordersCache: { [id: string]: Order } = {}; export let accountsCache: { [id: string]: Account } = {}; /** * Fetch contracts from Tradovate API */ export async function fetchContracts(): Promise<{ [id: string]: Contract }> { try { // Get all contracts const contractsList = await tradovateRequest('GET', 'contract/list'); // Convert array to object with id as key const contractsMap: { [id: string]: Contract } = {}; contractsList.forEach((contract: Contract) => { contractsMap[contract.id.toString()] = contract; }); // Update cache contractsCache = contractsMap; return contractsMap; } catch (error) { logger.error('Error fetching contracts:', error); // Return cache if available, otherwise empty object return contractsCache || {}; } } /** * Fetch positions from Tradovate API */ export async function fetchPositions(): Promise<{ [id: string]: Position }> { try { // Get all positions const positionsList = await tradovateRequest('GET', 'position/list'); // Convert array to object with id as key const positionsMap: { [id: string]: Position } = {}; positionsList.forEach((position: Position) => { positionsMap[position.id.toString()] = position; }); // Update cache positionsCache = positionsMap; return positionsMap; } catch (error) { logger.error('Error fetching positions:', error); // Return cache if available, otherwise empty object return positionsCache || {}; } } /** * Fetch orders from Tradovate API */ export async function fetchOrders(): Promise<{ [id: string]: Order }> { try { // Get all orders const ordersList = await tradovateRequest('GET', 'order/list'); // Convert array to object with id as key const ordersMap: { [id: string]: Order } = {}; ordersList.forEach((order: Order) => { ordersMap[order.id.toString()] = order; }); // Update cache ordersCache = ordersMap; return ordersMap; } catch (error) { logger.error('Error fetching orders:', error); // Return cache if available, otherwise empty object return ordersCache || {}; } } /** * Fetch accounts from Tradovate API */ export async function fetchAccounts(): Promise<{ [id: string]: Account }> { try { // Get all accounts const accountsList = await tradovateRequest('GET', 'account/list'); // Convert array to object with id as key const accountsMap: { [id: string]: Account } = {}; accountsList.forEach((account: Account) => { accountsMap[account.id.toString()] = account; }); // Update cache accountsCache = accountsMap; return accountsMap; } catch (error) { logger.error('Error fetching accounts:', error); // Return cache if available, otherwise empty object return accountsCache || {}; } } /** * Initialize data by fetching from API */ export async function initializeData() { try { logger.info('Initializing data from Tradovate API...'); // Fetch all data in parallel await Promise.all([ fetchContracts(), fetchPositions(), fetchOrders(), fetchAccounts() ]); logger.info('Data initialization complete'); } catch (error) { logger.error('Error initializing data:', error); logger.warn('Using mock data as fallback'); // Use mock data as fallback if (Object.keys(contractsCache).length === 0) { contractsCache = { "1": { id: 1, name: "ESZ4", contractMaturityId: 12345, productId: 473, productType: "Future", description: "E-mini S&P 500 Future December 2024", status: "Active" }, "2": { id: 2, name: "NQZ4", contractMaturityId: 12346, productId: 474, productType: "Future", description: "E-mini NASDAQ-100 Future December 2024", status: "Active" } }; } if (Object.keys(positionsCache).length === 0) { positionsCache = { "1": { id: 1, accountId: 12345, contractId: 1, timestamp: "2024-03-10T12:00:00Z", tradeDate: { year: 2024, month: 3, day: 10 }, netPos: 2, netPrice: 5200.25, realizedPnl: 0, openPnl: 150.50, markPrice: 5275.50 }, "2": { id: 2, accountId: 12345, contractId: 2, timestamp: "2024-03-10T12:30:00Z", tradeDate: { year: 2024, month: 3, day: 10 }, netPos: -1, netPrice: 18250.75, realizedPnl: 0, openPnl: -75.25, markPrice: 18326.00 } }; } if (Object.keys(ordersCache).length === 0) { ordersCache = { "1": { id: 1, accountId: 12345, contractId: 1, timestamp: "2024-03-10T11:55:00Z", action: "Buy", ordStatus: "Filled", orderQty: 2, orderType: "Market" }, "2": { id: 2, accountId: 12345, contractId: 2, timestamp: "2024-03-10T12:25:00Z", action: "Sell", ordStatus: "Filled", orderQty: 1, orderType: "Market" } }; } if (Object.keys(accountsCache).length === 0) { accountsCache = { "12345": { id: 12345, name: "Demo Account", userId: 67890, accountType: "Customer", active: true, clearingHouseId: 1, riskCategoryId: 1, autoLiqProfileId: 1, marginAccountType: "Regular", legalStatus: "Individual" } }; } } }