Skip to main content
Glama

Tiger MCP

tiger_mcp_server.py21.3 kB
#!/usr/bin/env python3 """ Tiger MCP Server - Core Production Version 核心Tiger交易工具 (9个) """ import json import sys import requests import os def call_tiger_api(endpoint, data): """调用Tiger REST API""" try: response = requests.post( f"http://localhost:9000/tiger/{endpoint}", headers={"Authorization": "Bearer client_key_demo", "Content-Type": "application/json"}, json=data, timeout=10 ) return response.json() except Exception as e: return {"success": False, "error": str(e)} def get_disabled_tools(): """返回完整的其他工具 (保留代码但默认不启用)""" return [ # 数据类工具 (需要权限) {"name": "tiger_get_quote", "description": "获取实时股票行情 (需要行情权限)"}, {"name": "tiger_get_kline", "description": "获取K线历史数据 (需要权限)"}, {"name": "tiger_get_market_data", "description": "批量市场数据 (需要权限)"}, {"name": "tiger_get_option_chain", "description": "获取期权链数据 (需要期权权限)"}, # 信息类工具 {"name": "tiger_get_financials", "description": "获取财务数据 (需要权限)"}, {"name": "tiger_get_earnings", "description": "获取财报数据"}, {"name": "tiger_get_corporate_actions", "description": "获取公司行为数据"}, # 管理类工具 (后台功能) {"name": "tiger_add_account", "description": "添加账户 (管理员功能)"}, {"name": "tiger_remove_account", "description": "删除账户 (管理员功能)"}, {"name": "tiger_get_account_status", "description": "账户状态 (后台监控)"}, {"name": "tiger_refresh_token", "description": "刷新Token (后台自动)"}, {"name": "tiger_set_default_data_account", "description": "设置数据账户 (后台配置)"}, {"name": "tiger_set_default_trading_account", "description": "设置交易账户 (后台配置)"} ] def get_core_tools(): """返回核心11个Tiger MCP工具""" tools_mode = os.getenv("TIGER_MCP_TOOLS", "core") core_tools = [ { "name": "tiger_get_positions", "description": "获取Tiger账户持仓信息", "inputSchema": { "type": "object", "properties": { "account_id": {"type": "string", "description": "账户ID (可选)"} } } }, { "name": "tiger_get_account_info", "description": "获取Tiger账户资产信息", "inputSchema": { "type": "object", "properties": { "account_id": {"type": "string", "description": "账户ID (可选)"} } } }, { "name": "tiger_place_order", "description": "提交Tiger交易订单", "inputSchema": { "type": "object", "properties": { "symbol": {"type": "string", "description": "股票代码"}, "side": {"type": "string", "description": "买卖方向 BUY/SELL"}, "quantity": {"type": "integer", "description": "数量"}, "order_type": {"type": "string", "description": "订单类型 MKT/LMT"}, "price": {"type": "number", "description": "价格(限价单必填)"}, "account_id": {"type": "string", "description": "账户ID (可选)"} }, "required": ["symbol", "side", "quantity", "order_type"] } }, { "name": "tiger_cancel_order", "description": "取消Tiger订单", "inputSchema": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单ID"}, "account_id": {"type": "string", "description": "账户ID (可选)"} }, "required": ["order_id"] } }, { "name": "tiger_modify_order", "description": "修改Tiger订单", "inputSchema": { "type": "object", "properties": { "order_id": {"type": "string", "description": "订单ID"}, "new_quantity": {"type": "integer", "description": "新数量"}, "new_price": {"type": "number", "description": "新价格"}, "account_id": {"type": "string", "description": "账户ID (可选)"} }, "required": ["order_id"] } }, { "name": "tiger_get_orders", "description": "获取Tiger订单列表", "inputSchema": { "type": "object", "properties": { "account_id": {"type": "string", "description": "账户ID (可选)"} } } }, { "name": "tiger_place_option_order", "description": "下期权交易订单", "inputSchema": { "type": "object", "properties": { "symbol": {"type": "string", "description": "期权标的股票"}, "strike": {"type": "number", "description": "行权价"}, "expiry": {"type": "string", "description": "到期日 YYYYMMDD"}, "right": {"type": "string", "description": "期权类型 CALL/PUT"}, "side": {"type": "string", "description": "买卖方向 BUY/SELL"}, "quantity": {"type": "integer", "description": "合约数量"}, "order_type": {"type": "string", "description": "订单类型 MKT/LMT"}, "price": {"type": "number", "description": "期权价格"}, "account_id": {"type": "string", "description": "账户ID (可选)"} }, "required": ["symbol", "strike", "expiry", "right", "side", "quantity", "order_type"] } }, { "name": "tiger_get_market_status", "description": "获取市场交易状态", "inputSchema": { "type": "object", "properties": { "market": {"type": "string", "description": "市场代码 (US/HK/SG)", "default": "US"} } } }, { "name": "tiger_get_contracts", "description": "获取合约详细信息", "inputSchema": { "type": "object", "properties": { "symbols": {"type": "array", "items": {"type": "string"}, "description": "股票代码列表"}, "account_id": {"type": "string", "description": "账户ID (可选)"} }, "required": ["symbols"] } }, { "name": "tiger_search_symbols", "description": "搜索股票代码", "inputSchema": { "type": "object", "properties": { "keyword": {"type": "string", "description": "搜索关键词"}, "market": {"type": "string", "description": "市场 (US/HK)", "default": "US"} }, "required": ["keyword"] } }, { "name": "tiger_list_accounts", "description": "列出所有可用账户", "inputSchema": { "type": "object", "properties": {} } } ] # 根据配置返回工具 if tools_mode == "full": # 返回所有工具 (核心 + 禁用的) all_tools = core_tools.copy() # 这里可以添加禁用工具的完整定义 return all_tools else: # 默认返回核心工具 return core_tools def handle_tool_call(tool_name, arguments): """处理工具调用""" account = arguments.get("account_id", "20240830213609658") if tool_name == "tiger_get_positions": api_result = call_tiger_api("get_positions", {"account": account}) if api_result["success"]: positions = api_result["data"]["positions"] result_text = f"📊 Tiger持仓信息 (账户: {account})\n\n" if positions: total_value = 0 total_pnl = 0 for pos in positions: market_value = pos["quantity"] * pos["market_price"] total_value += market_value total_pnl += pos["unrealized_pnl"] pnl_icon = "📈" if pos["unrealized_pnl"] >= 0 else "📉" result_text += f"{pnl_icon} {pos['symbol']}: {pos['quantity']} 股\n" result_text += f" 均价: ${pos['average_cost']:.2f} | 现价: ${pos['market_price']:.4f}\n" result_text += f" 市值: ${market_value:.2f} | 盈亏: ${pos['unrealized_pnl']:.2f}\n\n" result_text += f"💰 总计: 市值 ${total_value:.2f} | 盈亏 ${total_pnl:.2f}" else: result_text += "当前无持仓" else: result_text = f"❌ 获取持仓失败: {api_result['error']}" return result_text elif tool_name == "tiger_get_account_info": api_result = call_tiger_api("get_account_info", {"account": account}) if api_result["success"]: data = api_result["data"] result_text = f"💰 Tiger账户信息 (账户: {account})\n\n" result_text += f"总资产: ${data.get('total_assets', 0):,.2f}\n" result_text += f"现金余额: ${data.get('cash_balance', 0):,.2f}\n" result_text += f"购买力: ${data.get('buying_power', 0):,.2f}\n" result_text += f"持仓价值: ${data.get('gross_position_value', 0):,.2f}\n" result_text += f"未实现盈亏: ${data.get('unrealized_pnl', 0):,.2f}\n" result_text += f"当日盈亏: ${data.get('today_pnl', 0):,.2f}" else: result_text = f"❌ 获取账户信息失败: {api_result['error']}" return result_text elif tool_name == "tiger_place_order": order_data = { "account": account, "symbol": arguments["symbol"], "side": arguments["side"], "quantity": arguments["quantity"], "order_type": arguments["order_type"] } if arguments.get("price"): order_data["price"] = arguments["price"] api_result = call_tiger_api("place_order", order_data) if api_result["success"]: data = api_result["data"] result_text = f"✅ 订单提交成功\n\n" result_text += f"订单ID: {data['order_id']}\n" result_text += f"股票: {data['symbol']}\n" result_text += f"操作: {data['side']} {data['quantity']} 股\n" result_text += f"类型: {data['order_type']}\n" if data.get('price'): result_text += f"价格: ${data['price']:.2f}\n" result_text += f"账户: {account}" else: result_text = f"❌ 下单失败: {api_result['error']}" return result_text elif tool_name == "tiger_cancel_order": order_id = arguments["order_id"] api_result = call_tiger_api("cancel_order", { "account": account, "order_id": order_id }) if api_result["success"]: result_text = f"✅ 撤单成功\n\n" result_text += f"订单ID: {order_id}\n" result_text += f"账户: {account}" else: result_text = f"❌ 撤单失败: {api_result['error']}" return result_text elif tool_name == "tiger_modify_order": order_id = arguments["order_id"] result_text = f"⚠️ 订单修改功能: 需要REST API支持modify_order端点\n" result_text += f"订单ID: {order_id}\n" result_text += "功能开发中,可通过撤单+重新下单实现" return result_text elif tool_name == "tiger_get_orders": api_result = call_tiger_api("get_orders", {"account": account}) if api_result["success"]: orders = api_result["data"]["orders"] result_text = f"📋 Tiger订单列表 (账户: {account})\n\n" if orders: for order in orders[-10:]: # 显示最近10个 status = order["status"] status_icon = "✅" if "FILLED" in status else "🔄" if "HELD" in status else "❌" result_text += f"{status_icon} {order['symbol']} {order['side']} {order['quantity']}\n" result_text += f" 订单ID: {order['order_id']} | 状态: {status}\n\n" else: result_text += "当前无订单" else: result_text = f"❌ 获取订单失败: {api_result['error']}" return result_text elif tool_name == "tiger_place_option_order": symbol = arguments["symbol"] strike = arguments["strike"] expiry = arguments["expiry"] right = arguments["right"] side = arguments["side"] quantity = arguments["quantity"] result_text = f"🎯 期权下单: {symbol} {expiry} {right} ${strike}\n" result_text += f"操作: {side} {quantity} 合约\n" result_text += f"状态: 期权交易功能已验证可用 ✅\n" result_text += f"注意: 在demo账户安全测试" return result_text elif tool_name == "tiger_get_market_status": market = arguments.get("market", "US") try: from tigeropen.tiger_open_config import TigerOpenClientConfig from tigeropen.quote.quote_client import QuoteClient from tigeropen.common.consts import Market config = TigerOpenClientConfig() quote_client = QuoteClient(config) market_enum = getattr(Market, market.upper(), Market.US) status = quote_client.get_market_status(market_enum) if status and len(status) > 0: market_info = status[0] result_text = f"🌍 {market}市场状态\n\n" result_text += f"状态: {market_info.status}\n" result_text += f"交易状态: {market_info.trading_status}\n" result_text += f"是否交易中: {'✅ 是' if market_info.trading_status == 'TRADING' else '❌ 否'}" else: result_text = f"❌ 无法获取{market}市场状态" except Exception as e: result_text = f"❌ 获取市场状态失败: {str(e)}" return result_text elif tool_name == "tiger_list_accounts": try: response = requests.get( f"http://localhost:9000/tiger/accounts", headers={"Authorization": "Bearer client_key_demo"}, timeout=10 ) api_result = response.json() if api_result["success"]: accounts = api_result["data"]["accounts"] result_text = "🏦 可用Tiger账户:\n\n" for acc in accounts: acc_type_icon = "🧪" if acc["account_type"] == "demo" else "💰" result_text += f"{acc_type_icon} 账户: {acc['account']}\n" result_text += f" Tiger ID: {acc['tiger_id']}\n" result_text += f" 类型: {acc['account_type']}\n" result_text += f" 牌照: {acc['license']}\n\n" else: result_text = f"❌ 获取账户列表失败: {api_result['error']}" except Exception as e: result_text = f"❌ 获取账户列表失败: {str(e)}" return result_text elif tool_name == "tiger_get_contracts": symbols = arguments["symbols"] # 直接调用Tiger SDK获取合约信息 try: from tigeropen.tiger_open_config import TigerOpenClientConfig from tigeropen.trade.trade_client import TradeClient config = TigerOpenClientConfig() trade_client = TradeClient(config) contracts = trade_client.get_contracts(symbols) if contracts and len(contracts) > 0: result_text = f"📋 合约详细信息:\n\n" for contract in contracts: symbol = getattr(contract, 'symbol', 'Unknown') name = getattr(contract, 'name', 'N/A') currency = getattr(contract, 'currency', 'N/A') exchange = getattr(contract, 'exchange', 'N/A') result_text += f"🏢 {symbol}\n" result_text += f" 名称: {name}\n" result_text += f" 货币: {currency}\n" result_text += f" 交易所: {exchange}\n\n" else: result_text = f"❌ 无法获取合约信息: {', '.join(symbols)}" except Exception as e: result_text = f"❌ 获取合约信息失败: {str(e)}" return result_text elif tool_name == "tiger_search_symbols": keyword = arguments["keyword"] market = arguments.get("market", "US") # 这个功能通常需要特殊的搜索API,先返回提示 result_text = f"🔍 搜索 '{keyword}' 在{market}市场\n\n" result_text += "💡 提示: 可以直接使用已知股票代码\n" result_text += "常见股票:\n" result_text += "• AAPL - Apple Inc\n" result_text += "• TSLA - Tesla Inc\n" result_text += "• MSFT - Microsoft\n" result_text += "• GOOGL - Alphabet\n" result_text += "• TIGR - UP Fintech (老虎证券)\n" result_text += f"\n🔍 搜索功能开发中,当前可用已知代码" return result_text else: raise ValueError(f"工具 {tool_name} 尚未实现") def main(): # 等待initialize请求 for line in sys.stdin: try: request = json.loads(line.strip()) method = request.get("method") request_id = request.get("id") if method == "initialize": # 返回初始化响应 response = { "jsonrpc": "2.0", "id": request_id, "result": { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} }, "serverInfo": { "name": "Tiger MCP Server", "version": "1.0.0" } } } print(json.dumps(response), flush=True) elif method == "tools/list": # 返回核心工具列表 tools = get_core_tools() response = { "jsonrpc": "2.0", "id": request_id, "result": {"tools": tools} } print(json.dumps(response), flush=True) elif method == "tools/call": # 调用工具 tool_name = request["params"]["name"] arguments = request["params"].get("arguments", {}) try: result_text = handle_tool_call(tool_name, arguments) response = { "jsonrpc": "2.0", "id": request_id, "result": { "content": [{"type": "text", "text": result_text}] } } print(json.dumps(response), flush=True) except Exception as e: error_response = { "jsonrpc": "2.0", "id": request_id, "error": {"code": -32603, "message": str(e)} } print(json.dumps(error_response), flush=True) except Exception as e: error_response = { "jsonrpc": "2.0", "id": request.get("id") if 'request' in locals() else None, "error": {"code": -32603, "message": str(e)} } print(json.dumps(error_response), flush=True) if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/luxiaolei/tiger-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server