mcpField
C
ctrader-mcp-servers

ctrader-mcp-servers

github.com/spotware其他11544 次安装10 周前更新
代码仓库

关于 ctrader-mcp-servers

面向使用 cTrader Local 和 Remote MCP 服务的 Agent,说明如何识别服务、处理单位与行为差异,并依据已记录的问题安全恢复。

主要功能

  1. 01识别 Local 与 Remote 服务
  2. 02比较单位和标识符格式
  3. 03执行操作前后检查
  4. 04使用脚本计算点值、保证金和汇率
  5. 05管理带验证及移除条件的问题记录

适用场景

  1. 01为图表操作或无头交易选择服务
  2. 02换算止损距离与交易单位
  3. 03核验订单修改并从错误中恢复

MCP 相关

介绍 cTrader Local 和 Remote MCP 服务的行为与操作方法;工具结构以各服务的 MCP JSON Schema 为准。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/spotware/ctrader-skills --skill ctrader-mcp-servers

安装后在 Claude Code 中输入/ctrader-mcp-servers确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

LICENSE.txt
assets/
symbol_precision_table.json
references/
known-quirks.md
local-http-server.md
remote-http-server.md
self-healing-playbook.md
trader-workflows.md
scripts/
conversion_rate.py
pip_math.py
position_sizing.py
tiered_margin.py
units_encoding.py

详细介绍

五大关键问题(行内预览)

截至审计日期,以下五个问题影响最大。完整的检测/处理方法/验证修复/移除标准内容位于 references/known-quirks.md;下方各行仅提供链接预览。另请参阅 references/self-healing-playbook.md,了解命名的恢复模式。

问题服务端一句话说明链接
Q-R10远程amend_position 中省略某个交易腿会将其移除(而非保留)Q-R10
Q-R4远程MARKET 不接受绝对 SL/TP——使用 relativeStopLoss/relativeTakeProfit(单次调用),或使用 P-REMOTE-MARKET-2STEP(备用方案)Q-R4
Q-R1远程period 枚举有 9 个值,而非 26 个(删除有关细粒度选项的声明)Q-R1
Q-L2本地SL 是绝对价格,TP 是原始点数(get_pending_orders 的行为不对称)Q-L2
Q-K19两者点值单位与显示值容易混淆——市价单会无提示地成交Q-K19

自我修复原则

ctrader-remote-mcp 和 ctrader-local-mcp 均按原样发布,其中记录的运行时行为最近一次重新验证是在 2026-05-14,分别针对 rest-proxy 1.0.18(Remote)和 2026-05-14 观察到的本地构建(Local)。在 1.0.18 上,Remote 仍有六项异常处于 ACTIVE 状态(Q-R1、Q-R2、Q-R3、Q-R5、Q-R8、Q-R10)。两项异常的错误消息格式已优化(Q-R4 和 Q-R7 现在返回带有可操作提示的纯字符串错误信封,而不是 JSON 信封——两者的 DETECT 特征都涵盖这两种格式)。一项异常可能已修复(Q-R11——get_deals 传播延迟——在第 1/5 次会话中通过了 Verify-fixed;尚未移除,待再确认 4 次)。本技能说明语义、注意事项和恢复方法;MCP JSON-Schema 是数据结构的唯一准据。本技能中不得重复 Schema 内容。本技能中关于运行时行为的所有说明都带有构建标记——可以是参考文件中的 as-of: 标头,也可以是 references/known-quirks.md 中异常条目的 Observed-on: 行。

记录表中的每项异常都包含自我弃用机制:它包含一个 Verify-fixed 探测(Agent 可运行的会话内检查)和一个 Removal criteria 条件(服务器已修复、应删除该条目的明确信号)。服务器修复后,删除 references/known-quirks.md 中对应的条目即可——这就是全部清理工作。可选后续操作:使用 grep 搜索参考文件中是否有过时的 QUIRK 提示,并将其删除。

如果服务器行为异常(与 MCP JSON-Schema 和记录表均不一致),请勿自行猜测——遵循 references/self-healing-playbook.md。该手册列出预检关卡(报价合理性、方向、SL/TP 方向、交易量步长、仅使用 Schema 字段、pipettes 与显示值检测、必填字段)、飞行后验证规则(每次变更后重新读取;对于 Remote amend_position,务必重新读取,确认 SL 和 TP 两个部分都保留,参见 Q-R10)、错误分类矩阵(Zod / INVALID_REQUEST / 502 uProxy / 纯文本 Local / available:false / truncated / hasMore)、未知异常决策树(从 STOP 到临时记录条目的 4 个步骤),以及命名模式(P-AMEND-SAFE、P-REMOTE-MARKET-RELATIVE(MARKET+SL/TP 的首选方案)、P-REMOTE-MARKET-2STEP(MARKET 上使用绝对价格 SL/TP 时的备用方案)、P-REMOTE-MARKET-RANGE、P-LOCAL-OLDEST-FIRST、P-REMOTE-HISTORY-CHUNK)。

按经纪商扩展的预留接口

本技能的异常记录表使用 Q-B<n> 前缀作为未来按经纪商覆盖项的预留位置(lotSize 差异、品种命名变体、经纪商特定的 SL/TP 行为)。未来的 assets/broker_overrides.example.json 覆盖文件可用于承载这些按经纪商划分的值,而无需重构本技能。本次迭代未发布——只有在经纪商特定差异成为阻塞问题时才按需添加。

工具表面路由:本地 HTTP(ctrader-local-mcp)与远程 HTTP(ctrader-remote-mcp)

绑定的工具表面决定了当前使用的是哪种 cTrader MCP 服务。检查工具名称和响应 DTO 形状,以识别所属类型。在每次与 cTrader 相关的交互开始时应用以下路由规则;在本次会话中缓存结果。

服务类型识别特征最适合的用途默认路由规则
本地 HTTP(ctrader-local-mcp)ping、get_accounts_list、list_charts、listChartIndicators、listPlugins、show_notification、get_server_time;交易量以单位表示;采用 ISO 8601 格式,且必须带 Z;通过字符串名称("EURUSD")标识品种。HTTP 传输绑定到 cTrader 桌面应用。图表、绘图、指标、自选列表、警报、新闻、cBot、UI 通知、多账户操作。任何涉及 UI / 可视化 / cBot / 图表的工作流都路由至此。
远程 HTTP(ctrader-remote-mcp)get_version、get_assets、以整数 symbolId 为键的工具(get_spot_prices(symbolId)、get_trendbars(symbolId));资金响应中包含 moneyDigits 字段;交易量以分表示(1 手外汇 = 10 000 000);价格以 pipette 为单位。HTTP 传输通过远程 REST 代理(rest-proxy)进行。无头交易、广泛扫描品种、追踪止损、MARKET_RANGE、精细粒度的时间框架历史数据。不需要图表 / UI 时路由至此。
两种表面均已绑定可以看到两种类型的识别特征。视操作而定。按功能选择:绘图 / cBot / 图表使用本地;追踪 SL / MARKET_RANGE / 多品种批量报价 / 精细粒度时间框架使用远程。

两个服务之间的单位约定

两个服务对相同交易概念采用不同的单位和标识符类型;将 Local 值传给 Remote(或反过来)会悄无声息地导致数量、价格错误或架构校验失败。

维度Local HTTP 编码Remote HTTP 编码转换脚本
交易量单位(整数;外汇通常为 1 手 = 100 000 单位,但取决于经纪商 — 始终读取 get_symbol_details.lotSize)。分(整数;1 手外汇 = 10 000 000 分)。scripts/units_encoding.py lots-to-units / lots-to-cents
价格显示值(例如,1.21345)。点值(整数;除以 10^pipDigits 即为显示值)。scripts/pip_math.py(支持双向转换)
货币金额(余额、佣金、掉期、盈亏)显示值(例如,12345.67)。以 10^moneyDigits 为单位的整数(响应中的 moneyDigits 字段;通常为 2)。scripts/units_encoding.py display-money / parse-money
时间戳ISO 8601 格式,必须带 Z 后缀(2026-01-15T14:30:00Z)。expirationTimestamp 使用纪元毫秒(自 rest-proxy 1.0.13 起仅支持整数);历史窗口端点可使用任一格式。Local 原样传递;Remote 请检查字段类型。
商品标识符字符串名称("EURUSD"、"XAUUSD")。整数 symbolId(通过 get_symbols 解析,并在会话期间缓存)。不适用(按 ID 查找)
place_*_order / amend_order 中的止损 / 止盈点差整数(stopLossPips、takeProfitPips)。绝对价格(stopLoss、takeProfit)。scripts/pip_math.py pips-to-price / price-to-pips

止损和止盈:点数距离与绝对价格

下单工具将 SL / TP 设为距离入场价的点数;持仓修改工具将 SL / TP 设为绝对价格。具体约定取决于调用的工具,而非服务器。

工具服务器SL / TP 形式
place_market_order, place_limit_order, place_stop_order, place_stop_limit_orderLocal点数距离(stopLossPips, takeProfitPips)。
amend_order(挂单)Local点数距离(stopLossPips, takeProfitPips)。
amend_position(未平仓持仓)Local绝对价格(stopLoss, takeProfit)。
create_orderRemote绝对价格(stopLoss, takeProfit)。关于 MARKET 订单的 SL / TP 拒绝,请参阅 references/remote-http-server.md(P-REMOTE-MARKET-2STEP)。
amend_orderRemote绝对价格(stopLoss, takeProfit)。
amend_positionRemote绝对价格(stopLoss, takeProfit)。
close_positionBoth不适用(无 SL / TP 参数)。

当用户说“SL 比入场价低 30 点”时,运行 scripts/pip_math.py,将其转换为目标工具所需的形式。输入:--pip-size <float> --digits <int> --reference-price <float> --pips <int>。输出:{"absolute_price": <float>, "pip_size_used": <float>}。该脚本会处理两个方向。

动态杠杆保证金计算

经纪商采用动态杠杆档位:当敞口超过档位上限时,杠杆会降低。所需保证金按档位分别计算后求和。无论交易品种是什么,档位敞口量都以 USD 表示;所得 USD 保证金随后会转换为账户币种。

示例。 账户币种为 USD。订单:做多 1 000 000 EURUSD,价格为 1.21345。USD 名义价值 = 1 000 000 × 1.21345 = 1 213 450 USD。杠杆档位:最高 1 000 000 USD 为 1:500,1 000 000 至 5 000 000 USD 为 1:200,超过 5 000 000 USD 为 1:100。保证金 = (1 000 000 / 500) + (213 450 / 200) = 2 000 + 1 067.25 = 3 067.25 USD。

调用 scripts/tiered_margin.py compute,即可针对任意档位曲线进行计算。输入:--volume-base-units <int> --quote-rate-usd <float> --tiers '[{"upper":1000000,"leverage":500},{"upper":5000000,"leverage":200},{"upper":null,"leverage":100}]'。输出:{"margin_usd": <float>, "per_tier_breakdown": [...]}。使用 scripts/conversion_rate.py compute-chain 将 USD 保证金转换为账户币种。

货币转换:报价货币与账户货币

当交易品种的报价货币与账户货币不同时,服务返回的每个金额(佣金、隔夜利息、已实现盈亏、点值、保证金)都需要通过一条即期汇率链进行转换。例如:EUR 账户的 USDJPY 盈亏需要经过 JPY -> USD -> EUR(使用 USDJPY 和 EURUSD);NZD 账户的 AUDCAD 盈亏需要经过 CAD -> USD -> NZD,或者直接经过 AUD -> NZD。cTrader 后端会构建可用的最短汇率链;使用 scripts/conversion_rate.py 在本地复现此逻辑。

调用 scripts/conversion_rate.py compute-chain 计算汇率。输入:--from-asset <CCY> --to-asset <CCY> --quotes '{"EURUSD":1.0850,"USDJPY":150.3,...}'。输出:{"rate": <float>, "chain": ["EURUSD","USDJPY",...], "warnings": [...]}。通过 get_spot_prices 预先获取报价映射:Local 每次调用一个交易品种,Remote 则使用 get_spot_prices(symbolId:[...]) 批量获取。

对冲账户与净额结算账户

对冲账户允许同一交易品种同时持有多头和空头头寸(各自拥有一个 positionId)。净额结算账户会将它们合并:开立反向头寸会自动平仓(或部分平仓)已有头寸,以形成净头寸。开立对冲的第二笔交易前,读取现有头寸和账户的对冲模式(可在 get_balance 和账户信息响应中查看);如果账户采用净额结算,则无法“开立对冲”——应向用户说明这一点,并建议调整止损或完全平仓。

强制平仓与保证金水平

当保证金水平 =(净值 / 已用保证金)× 100%降至强制平仓水平或以下时,经纪商会强制平仓。强制平仓水平通常为 50% 或 30%,由经纪商设定。存在两种策略:公平策略(平掉占用保证金最多的单个头寸)和智能策略(平掉足以使保证金水平恢复至强制平仓水平以上的最少头寸)。增加风险敞口前,读取当前净值和已用保证金;如果(净值 − 新增所需保证金)/ 开仓后已用保证金 × 100%低于强制平仓水平的 2 倍,则在继续前警告用户。

隔夜利息计提时间

隔夜利息(隔夜融资费用)在经纪商服务器时间的结转时点计提(通常为服务器时间 23:59:59)。许多经纪商会在周三收取三倍隔夜利息(周三 -> 周四的结转会计入周末的起息日价值,适用于外汇等 T+2 交割的工具)。按持仓周期预估隔夜利息时,对周期内的每个周三乘以 3。直接读取 get_positions 和 get_deals 响应中的隔夜利息和佣金数值(这些数值由服务器计算);不要根据费率表重新推算。

可组合的交易工作流

references/trader-workflows.md 中按步骤介绍了七种端到端交易工作流。W0(会话启动)会在会话开始时自动运行一次;W1–W6 则由用户意图触发。当用户请求符合任一触发条件时,请阅读 references/trader-workflows.md 并遵循相应流程,不要从头自行发挥。

  1. W0 — 会话启动 — 在会话开始时自动运行;识别服务系列,探测实时构建版本,从 assets/symbol_precision_table.json 缓存品种精度基准,解析当前活动账户,并设置幂等键前缀。无需用户触发。
  2. 按风险百分比计算仓位 — 当用户询问“买入/卖出多少”“止损距离为 N 点时的仓位”“这笔交易承担账户 X% 的风险”,或任何同时提及风险比例和止损距离的句子时,选择此流程。
  3. 交易前简报 — 当用户询问“我该交易 X 吗”“入场前给我看看 X 的概况”“X 现在是什么情况”,或将品种详情、价格和近期历史记录请求合并为一个问题时,选择此流程。
  4. 交易成本比较 — 当用户询问“A 和 B 哪个交易成本更低”“比较不同品种的点差/佣金/隔夜利息”,或按成本对可交易工具进行排序时,选择此流程。
  5. 下单并在图表上标注风险/收益 — 当用户询问“下单并在图表上显示”“在 EURUSD 上绘制风险/收益比”,且已绑定 Local HTTP 服务时,选择此流程(此工作流需要绘图功能)。
  6. 多窗口历史数据回填 — 当用户请求的 K 线数量超过单次 get_trendbars 调用的返回上限时,选择此流程(Local 的上限为 1000),例如“给我 5000 根 XAUUSD 的 H1 K 线”或“显示过去一年的 D1 K 线”。
  7. 安全平仓 — 当用户询问“全部平仓”“取消我的所有订单”“清空我的持仓”,或要求批量关闭一个或多个品种的待处理订单和未平仓头寸时,选择此流程。

特定服务的参考文件

当已绑定的工具接口包含 Local HTTP 工具(ping、get_accounts_list、list_charts、listChartIndicators、listPlugins、show_notification、get_server_time)时,请阅读 references/local-http-server.md,了解 Local 的功能映射、编码规则、分页上限、标识符类型、活动图表定位、绘图对象锚点要求以及破坏性操作检查清单。

当已绑定的工具接口包含 Remote HTTP 工具(get_version、get_assets、以整数 symbolId 为键的工具、响应中的 moneyDigits)时,请阅读 references/remote-http-server.md,了解 Remote 的功能映射、编码规则、包含 9 个值的 period 枚举、服务端校验、timeInForce 语义、dealStatus 枚举,以及 get_symbols 的缓存规则。

当两种接口都已绑定时,请阅读两个文件。

内置脚本

复杂计算位于 scripts/ 中。当计算超出一次乘法或加法时,请调用脚本。所有脚本仅接受 CLI 标志(非交互式),将 JSON 输出到 stdout,将诊断信息输出到 stderr,并通过 --help 提供说明。

脚本用途调用方式输出格式
scripts/pip_math.py在 pip 距离与绝对价格之间进行转换(显示值;在解码 pipette 后,可处理两个服务的编码方式)。python scripts/pip_math.py pips-to-price --pip-size 0.0001 --digits 5 --reference-price 1.0850 --pips 30{"absolute_price": 1.08800, "pip_size_used": 0.0001}
scripts/position_sizing.py根据风险百分比或风险金额目标计算订单规模,并计入 pip 价值以及报价货币 -> 账户货币的转换。python scripts/position_sizing.py from-risk-percent --balance 10000 --risk-pct 1 --sl-pips 30 --pip-value-per-lot 10 --conversion-rate 1.0{"units": 33333, "cents": 3333333, "risk_currency_amount": 100.0, "warnings": []}
scripts/tiered_margin.py根据分层曲线复现 cTrader 的动态杠杆保证金公式。python scripts/tiered_margin.py compute --volume-base-units 1000000 --quote-rate-usd 1.21345 --tiers '[{"upper":1000000,"leverage":500},{"upper":5000000,"leverage":200},{"upper":null,"leverage":100}]'{"margin_usd": 3067.25, "per_tier_breakdown": [...]}
scripts/conversion_rate.py构建两个货币之间最短的即期汇率转换链。python scripts/conversion_rate.py compute-chain --from-asset JPY --to-asset USD --quotes '{"USDJPY":150.3}'{"rate": 0.006653, "chain": ["USDJPY"], "warnings": []}
scripts/units_encoding.py在显示手数与各服务的线路编码(units / cents)之间转换;在显示金额与 moneyDigits 整数之间转换。python scripts/units_encoding.py lots-to-cents --lots 0.1 --lot-size 100000{"cents": 1000000}

下单后验证循环

任何修改操作(place_*_order、create_order、amend_order、amend_position、close_position、cancel_order)后,重新获取受影响的实体(get_positions、get_pending_orders 或 get_position_details),并验证成交量、方向、入场价格(针对已成交订单)、SL、TP 和 dealStatus 是否符合用户表达的意图。如果任何值不匹配,请确定不匹配的类别:

  • 编码错误 -> 重新运行 scripts/units_encoding.py 或 scripts/pip_math.py,并使用修正后的输入重试。
  • 经纪商拒绝(dealStatus: REJECTED / INTERNALLY_REJECTED / ERROR)-> 向用户说明服务器响应中的拒绝原因,然后停止。

不要仅因调用未抛出异常就认定订单已成交。

评论

支持 Markdown