trading-platform/apps/mcp-binance-connector/src/tools/account.ts
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
Changes include:
- Updated architecture documentation
- Enhanced module definitions (OQI-001 to OQI-008)
- ML integration documentation updates
- Trading strategies documentation
- Orchestration and inventory updates
- Docker configuration updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:33:35 -06:00

266 lines
6.9 KiB
TypeScript

/**
* Binance Account Tools
*
* - binance_get_account: Get account balance and status
* - binance_get_open_orders: Get all open orders
*
* @version 1.0.0
* @author OrbiQuant Trading Platform
*/
import { z } from 'zod';
import { getBinanceClient, BinanceAccount, BinanceOrder } from '../services/binance-client';
// ==========================================
// binance_get_account
// ==========================================
/**
* Tool: binance_get_account
* Get account balance and status
*/
export const binanceGetAccountSchema = {
name: 'binance_get_account',
description: 'Get Binance account balance and status. Shows all assets with non-zero balance.',
inputSchema: {
type: 'object' as const,
properties: {},
required: [] as string[],
},
};
export const BinanceGetAccountInputSchema = z.object({});
export type BinanceGetAccountInput = z.infer<typeof BinanceGetAccountInputSchema>;
export interface BinanceGetAccountResult {
success: boolean;
data?: BinanceAccount & { totalUsdtEstimate?: number };
error?: string;
}
export async function binance_get_account(
_params: BinanceGetAccountInput
): Promise<BinanceGetAccountResult> {
try {
const client = getBinanceClient();
if (!client.isConfigured()) {
return {
success: false,
error: 'Binance API keys are not configured',
};
}
const connected = await client.isConnected();
if (!connected) {
return {
success: false,
error: 'Cannot connect to Binance. Please check your network.',
};
}
const account = await client.getAccount();
// Estimate total value in USDT
let totalUsdtEstimate = 0;
for (const balance of account.balances) {
if (balance.asset === 'USDT' || balance.asset === 'BUSD' || balance.asset === 'USDC') {
totalUsdtEstimate += balance.total;
} else if (balance.total > 0) {
try {
const price = await client.getCurrentPrice(`${balance.asset}USDT`);
totalUsdtEstimate += balance.total * price;
} catch {
// Skip if no USDT pair exists
}
}
}
return {
success: true,
data: {
...account,
totalUsdtEstimate,
},
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
};
}
}
export async function handleBinanceGetAccount(
params: unknown
): Promise<{ content: Array<{ type: string; text: string }> }> {
const validatedParams = BinanceGetAccountInputSchema.parse(params);
const result = await binance_get_account(validatedParams);
if (result.success && result.data) {
const d = result.data;
// Sort balances by total value
const sortedBalances = [...d.balances].sort((a, b) => {
// USDT first, then by total
if (a.asset === 'USDT') return -1;
if (b.asset === 'USDT') return 1;
return b.total - a.total;
});
let balancesStr = sortedBalances
.slice(0, 20) // Top 20 assets
.map((b) => {
const lockedStr = b.locked > 0 ? ` (Locked: ${b.locked.toFixed(8)})` : '';
return ` ${b.asset.padEnd(8)} Free: ${b.free.toFixed(8)}${lockedStr}`;
})
.join('\n');
const formattedOutput = `
Binance Account Information
${'='.repeat(35)}
Account Type: ${d.accountType}
Can Trade: ${d.canTrade ? 'Yes' : 'No'}
Can Withdraw: ${d.canWithdraw ? 'Yes' : 'No'}
Estimated Total Value
---------------------
~$${d.totalUsdtEstimate?.toFixed(2) ?? 'N/A'} USDT
Asset Balances (${d.balances.length} with balance)
${'='.repeat(35)}
${balancesStr}
${d.balances.length > 20 ? `\n ... and ${d.balances.length - 20} more assets` : ''}
Last Update: ${new Date(d.updateTime).toISOString()}
`.trim();
return {
content: [{ type: 'text', text: formattedOutput }],
};
}
return {
content: [{ type: 'text', text: `Error: ${result.error}` }],
};
}
// ==========================================
// binance_get_open_orders
// ==========================================
/**
* Tool: binance_get_open_orders
* Get all open (pending) orders
*/
export const binanceGetOpenOrdersSchema = {
name: 'binance_get_open_orders',
description: 'Get all open (pending) orders. Optionally filter by symbol.',
inputSchema: {
type: 'object' as const,
properties: {
symbol: {
type: 'string',
description: 'Optional: Filter by trading pair symbol (e.g., BTCUSDT)',
},
},
required: [] as string[],
},
};
export const BinanceGetOpenOrdersInputSchema = z.object({
symbol: z.string().min(1).max(20).transform((s) => s.toUpperCase()).optional(),
});
export type BinanceGetOpenOrdersInput = z.infer<typeof BinanceGetOpenOrdersInputSchema>;
export interface BinanceGetOpenOrdersResult {
success: boolean;
data?: {
orders: BinanceOrder[];
count: number;
};
error?: string;
}
export async function binance_get_open_orders(
params: BinanceGetOpenOrdersInput
): Promise<BinanceGetOpenOrdersResult> {
try {
const client = getBinanceClient();
if (!client.isConfigured()) {
return {
success: false,
error: 'Binance API keys are not configured',
};
}
const orders = await client.getOpenOrders(params.symbol);
return {
success: true,
data: {
orders,
count: orders.length,
},
};
} catch (error) {
return {
success: false,
error: error instanceof Error ? error.message : 'Unknown error occurred',
};
}
}
export async function handleBinanceGetOpenOrders(
params: unknown
): Promise<{ content: Array<{ type: string; text: string }> }> {
const validatedParams = BinanceGetOpenOrdersInputSchema.parse(params);
const result = await binance_get_open_orders(validatedParams);
if (result.success && result.data) {
const d = result.data;
if (d.count === 0) {
return {
content: [
{
type: 'text',
text: `No open orders${validatedParams.symbol ? ` for ${validatedParams.symbol}` : ''}`,
},
],
};
}
let ordersStr = d.orders
.map((o) => {
const priceStr = o.price ? `$${o.price.toFixed(8)}` : 'MARKET';
const filledPct = o.amount > 0 ? ((o.filled / o.amount) * 100).toFixed(1) : '0';
return ` #${o.id}
Symbol: ${o.symbol} | ${o.side.toUpperCase()} | ${o.type.toUpperCase()}
Price: ${priceStr} | Amount: ${o.amount.toFixed(8)}
Filled: ${o.filled.toFixed(8)} (${filledPct}%) | Remaining: ${o.remaining.toFixed(8)}
Status: ${o.status} | Created: ${new Date(o.createdAt).toISOString()}`;
})
.join('\n\n');
const formattedOutput = `
Open Orders${validatedParams.symbol ? ` - ${validatedParams.symbol}` : ''}
${'='.repeat(35)}
Total Orders: ${d.count}
${ordersStr}
`.trim();
return {
content: [{ type: 'text', text: formattedOutput }],
};
}
return {
content: [{ type: 'text', text: `Error: ${result.error}` }],
};
}