如何自动获取CCXT库中类方法签名未声明的必填参数?
解决CCXT跨交易所未声明必填参数自动获取的高效方案
我在用Python的CCXT库,它通过基类统一了Coinbase、Binance等多交易所接口。但部分子类方法(比如Coinbase的fetch_ledger)内部调用的函数需要在params字典里传入方法签名未声明的必填参数(比如account_id/accountId或code),不传就会抛出ArgumentsRequired异常。现在需要实现跨交易所自动获取这类未声明的必填参数,用于自动化流程及GUI组件开发,试过运行时捕获异常、源码解析、修改库代码等方案,求更高效的实现方法。
相关CCXT代码片段:
def fetch_ledger(self, code=None, since=None, limit=None, params={}): self.load_markets() currency = None if code is not None: currency = self.currency(code) request = self.prepare_account_request_with_currency_code(code, limit, params) # REQUIRES "accountId" in params query = self.omit(params, ['account_id', 'accountId']) response = self.v2PrivateGetAccountsAccountIdTransactions(self.extend(request, query)) return self.parse_ledger(response['data'], currency, since, limit) def prepare_account_request_with_currency_code(self, code=None, limit=None, params={}): accountId = self.safe_string_2(params, 'account_id', 'accountId') if accountId is None: if code is None: raise ArgumentsRequired(self.id + ' prepareAccountRequestWithCurrencyCode() method requires an account_id(or accountId) parameter OR a currency code argument') accountId = self.find_account_id(code) if accountId is None: raise ExchangeError(self.id + ' prepareAccountRequestWithCurrencyCode() could not find account id for ' + code) request = { 'account_id': accountId, } if limit is not None: request['limit'] = limit return request
高效实现方案
1. 基于异常信息的结构化解析(轻量无侵入)
CCXT抛出的ArgumentsRequired异常信息已经明确标注了所需参数(比如示例中的account_id(or accountId) parameter OR a currency code argument),可以做一个通用解析逻辑:
- 先以空参数调用目标方法,捕获
ArgumentsRequired异常 - 用正则提取异常信息中的必填参数(支持
OR多选项逻辑) - 结合交易所自身的
fetch_accounts()、fetch_currencies()接口自动填充参数选项
代码示例:
import re from ccxt.base.errors import ArgumentsRequired def extract_required_params(exchange, method_name, *args, **kwargs): required_rules = [] try: getattr(exchange, method_name)(*args, **kwargs) except ArgumentsRequired as e: # 匹配异常信息中的参数规则,兼容"X(or Y) parameter"或"Z argument"格式 pattern = r'(?:(\w+)(?:\(or (\w+)\))? parameter|(\w+) argument)' matches = re.findall(pattern, str(e)) for match in matches: # 合并OR关联的参数选项 param_group = [p for p in match if p] required_rules.append(param_group) return required_rules # 使用示例 exchange = ccxt.coinbase({"apiKey": "...", "secret": "..."}) required = extract_required_params(exchange, 'fetch_ledger') # 返回结果:[['account_id', 'accountId'], ['code']]
2. 利用CCXT内置describe()元数据查询(官方推荐)
CCXT多数交易所类实现了describe()方法,返回包含接口元数据的字典,其中可能包含方法的参数定义:
- 调用
exchange.describe()获取完整接口描述 - 定位到目标方法的元数据节点(比如
['api']['private']['fetchLedger']路径) - 提取
params字段中的必填项
注意:部分交易所的元数据可能不完善,但这是官方提供的标准方式,兼容性最优。
3. 动态钩子拦截参数检查(无侵入补丁)
通过猴子补丁给参数检查类方法加钩子,提前收集必填参数规则,无需修改库源码:
- 替换目标方法,在原逻辑执行前记录所需参数
- 运行时动态注入,不影响原库代码
代码示例:
def hook_param_check(func): def wrapper(self, code=None, limit=None, params={}): # 记录fetch_ledger对应的必填参数规则 if not hasattr(self, '_required_params'): self._required_params = {} self._required_params['fetch_ledger'] = [['account_id', 'accountId'], ['code']] return func(self, code, limit, params) return wrapper # 给Coinbase的检查方法打补丁 ccxt.coinbase.prepare_account_request_with_currency_code = hook_param_check(ccxt.coinbase.prepare_account_request_with_currency_code) # 使用时直接从实例获取规则 exchange = ccxt.coinbase({"apiKey": "...", "secret": "..."}) required = exchange._required_params.get('fetch_ledger', [])
4. 静态源码解析(适合批量预处理)
如果需要离线批量获取所有方法的必填参数,可以用Python的ast模块解析CCXT源码:
- 遍历交易所子类的方法源码
- 查找
raise ArgumentsRequired语句,提取异常信息中的参数 - 生成全局参数映射表,运行时直接查表使用
这种方式适合提前做GUI组件的参数配置,不需要运行时动态触发异常。
方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 异常解析 | 轻量无侵入、兼容性强 | 需要一次调用触发异常 |
| describe()元数据 | 官方支持、无侵入 | 部分交易所元数据不完善 |
| 动态钩子 | 实时获取、无需触发异常 | 需针对不同方法单独补丁 |
| 静态源码解析 | 离线批量处理 | 依赖源码结构,版本更新可能失效 |
内容的提问来源于stack exchange,提问作者LMM
相关产品推荐
相关产品推荐

