关于 Kandle
Kandle 是面向交易者和 AI Agent 的浏览器图表应用,支持加密货币、股票和外汇。其 MCP 服务让 Agent 查看并操作实时图表,图表数据和设置保留在浏览器中。
主要功能
- 01加密货币、股票和外汇实时图表
- 0236 种可编辑指标及绘图工具
- 03自定义脚本与策略回测
- 04提醒、K 线回放及最多四张图表
- 05浏览器内存储与图表分享
适用场景
- 01与 Agent 一起查看行情蜡烛图和指标值
- 02标注支撑位、阻力位或斐波那契水平
- 03测试脚本策略并检查交易记录
- 04设置价格或指标提醒并回放 K 线
MCP 相关
`kandle-mcp` 服务通过本地 WebSocket 桥接连接 AI Agent 与 Kandle 浏览器标签页。它提供图表数据,以及符号、指标、绘图、提醒、截图、回放、布局、脚本和自选列表的控制工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Kandle
面向加密货币、股票和外汇的免费开源图表,你的 AI Agent 还能操控它们。
指标、绘图工具、自定义脚本与策略回测、提醒、K 线回放,以及最多同时显示四张图表。无需账户,没有付费墙,指标数量也不受限制。它运行在浏览器中,所有内容都保存在你的设备上。
Claude Code、Codex、Cursor 或 Gemini CLI 可以读取图表、绘制支撑位和阻力位、添加指标、编写脚本并设置提醒,整个过程你都能实时查看。
在浏览器中打开 Kandle · 连接你的 Agent · 编写脚本

一行命令连接你的 Agent
claude mcp add kandle -- npx -y --package=https://github.com/Kernel-Hunter/kandle/releases/download/v0.10.1/kandle-mcp-0.10.1.tgz kandle-mcp
然后打开 Kandle,点击 Agent,粘贴你的 Agent 提供的配对码,并开启 Agent bridge。可以向它提出这样的请求:“标记 BTC 最近的摆动高点和低点,并在两者之间绘制斐波那契回撤线”。其他 Agent 的设置方法见下文。

功能
- 通过 Binance、Coinbase、Bybit、OKX 和 Kraken 的公开市场数据获取实时加密货币蜡烛图,无需密钥。历史数据通过 REST 加载,后续更新通过 WebSocket 流式传输。
- 通过 Twelve Data、Alpaca 或 Polygon 获取美国及全球股票、ETF 和外汇数据,需使用你自己的免费 API 密钥。请参阅数据源。
- 从 CSV 文件导入你自己的 OHLCV 数据,并将其保存在浏览器中。请参阅CSV 导入。
- 搜索所选数据源中的交易品种,并显示 Crypto、Stock、ETF、Forex、Index 和 CSV 标签。
- 时间周期:1m、5m、15m、1H、4H、1D、1W。向左滚动可加载更早的历史数据。
- 图表类型:蜡烛图、空心蜡烛图、柱状图(OHLC)、折线图、面积图和 Heikin Ashi,并支持普通、对数或百分比价格刻度。布局中的每张图表都有各自的设置。Heikin Ashi 仅改变柱线的绘制方式:指标、脚本、回测、提醒和 Agent 工具仍使用真实价格,图例则在单独一行显示 Heikin Ashi 数值。
- 提供 36 种指标,图表上可添加任意数量:MA、EMA、SMA、WMA、HMA、Bollinger Bands、Donchian Channel、VWAP、Supertrend、Parabolic SAR、Ichimoku Cloud、Volume Profile、Volume、MACD、RSI、Stochastic RSI、KDJ、ATR、OBV、CCI、DMI/ADX、Williams %R、ROC、Momentum、TRIX、Awesome Oscillator 等。所有参数均可编辑。
- Ichimoku Cloud 会绘制在最后一根蜡烛之前;成交量分布图则基于屏幕上显示的柱线,并标出控制点和价值区间。滚动和缩放时,分布图会随之更新。
- 绘图工具:趋势线、射线、延长线、水平线和射线、垂直线、平行通道、矩形、斐波那契回撤、价格区间、文本注释和价格标签。选择绘图即可移动或删除。可选磁吸功能会将点吸附到蜡烛价格。
- 重新加载后,你的交易品种、时间周期、图表类型、价格刻度、主题、指标和绘图(按交易品种保存)都会恢复。
- 深色和浅色主题。
- 大多数操作都有键盘快捷键。在应用中按
?可查看所有快捷键。 - 将图表导出为 PNG 图片。
- 通过链接分享图表:可包含交易品种、时间周期、图表类型、指标和绘图,还可按需包含脚本和多图表布局。链接中包含图表本身。请参阅分享图表。同一个弹出窗口还提供 iframe,可在博客或文档页面中显示图表,请参阅嵌入图表。
- 脚本:使用 Kandle Script 编写自己的指标,图表下方配有编辑器,并提供 14 个示例脚本。脚本可通过
request.security读取其他时间周期和其他交易品种的数据。 - 策略回测:编写策略脚本,在图表上查看交易,并获取净利润、回撤、胜率、权益曲线和交易列表。
- 可针对价格水平、绘制的线和指标值设置提醒,并接收浏览器通知。
- K线回放:逐根蜡烛查看历史数据。
- 屏幕上可显示 1、2 或 4 张图表,每张图表都有各自的交易品种、时间周期和指标。
- 图表旁的自选列表会显示加密货币的实时价格和 24 小时涨跌幅,以及股票和外汇自上次收盘以来的涨跌幅。点击交易品种即可打开。
- 提供 MCP 服务,让 AI Agent 可以读取图表、在图表上绘图、设置提醒和截取屏幕截图。
- 支持桌面、平板和手机。在窄屏上,顶部栏会固定显示交易品种、时间周期和价格,并将其他工具移至 ... 菜单中。

键盘快捷键
| 按键 | 操作 |
|---|---|
| 任意字母或数字 | 搜索符号 |
/ 或 Alt+I | 指标 |
Alt+S | 脚本编辑器 |
Ctrl+Enter 或 Cmd+Enter | 在图表上添加或更新脚本(在编辑器中) |
Alt+1 至 Alt+7 | 时间周期 1m 至 1W |
Alt+C | 切换到下一个图表类型 |
Alt+T | 趋势线 |
Alt+R | 射线 |
Alt+H | 水平线 |
Alt+V | 垂直线 |
Alt+B | 矩形 |
Alt+F | 斐波那契回撤 |
Alt+P | 价格范围 |
Alt+N | 文本注释 |
Alt+M | 开启或关闭磁吸 |
Delete | 删除所选绘图 |
Esc | 取消当前绘图或关闭对话框 |
Alt+L | 在浅色和深色模式之间切换 |
Alt+W | 显示或隐藏自选列表 |
Alt+K | 分享此图表的链接 |
与 AI Agent 搭配使用
Kandle 附带 MCP 服务 kandle-mcp。你的 Agent 会启动它,而浏览器中的 Kandle 标签页会通过 WebSocket 连接到 127.0.0.1。之后,Agent 就能读取图表并对其进行更改,同时你可以实时查看。
设置
- 将此服务添加到你的 Agent(配置片段见下方)。
- 向 Agent 索取 Kandle 配对码。它会调用
get_bridge_status并显示类似K7QD-9MXR-2HPA的代码。此代码也会保存到~/.kandle/bridge-token。 - 在 Kandle 中,点击顶部栏里的 Agent,粘贴代码,然后开启 Agent bridge。Agent 连接后,按钮上的圆点会变成绿色。
代码会保存在浏览器和 ~/.kandle/bridge-token 中,因此只需配对一次。
此功能适用于托管应用以及你自行运行的副本。使用托管应用时,浏览器可能会询问是否允许此页面访问本地网络上的设备;请允许访问,这样页面才能与 127.0.0.1 上的 kandle-mcp 通信。
npx 会从 GitHub 发布版本运行 kandle-mcp,因此你只需要 Node.js 22.12 或更高版本。Kandle 发布新版本时,请更改 URL 中的版本;如果应用版本高于服务版本,get_bridge_status 会通知你的 Agent。若要从克隆的仓库运行,请使用 pnpm install && pnpm build,并将 Agent 指向 node /path/to/kandle/packages/mcp/bin/kandle-mcp.js。
Claude Code:
claude mcp add kandle -- npx -y --package=https://github.com/Kernel-Hunter/kandle/releases/download/v0.10.1/kandle-mcp-0.10.1.tgz kandle-mcp
Codex(~/.codex/config.toml):
[mcp_servers.kandle]
command = "npx"
args = ["-y", "--package=https://github.com/Kernel-Hunter/kandle/releases/download/v0.10.1/kandle-mcp-0.10.1.tgz", "kandle-mcp"]
Cursor(~/.cursor/mcp.json 或项目中的 .cursor/mcp.json)和 Gemini CLI(~/.gemini/settings.json):
{
"mcpServers": {
"kandle": {
"command": "npx",
"args": ["-y", "--package=https://github.com/Kernel-Hunter/kandle/releases/download/v0.10.1/kandle-mcp-0.10.1.tgz", "kandle-mcp"]
}
}
}
Claude Desktop:下载 kandle-mcp-0.10.1.mcpb 并打开文件以安装服务。
Kandle 也已列入 MCP Registry,名称为 io.github.Kernel-Hunter/kandle,因此能够浏览该注册表的客户端可以找到它。
工具
| 工具 | 功能 |
|---|---|
get_bridge_status | 连接状态和配对码 |
get_chart_state | 交易品种、时间周期、最新柱线、可见范围、含最新数值的指标、带 ID 的绘图、警报、回放和布局。备注文本最多包含 20 条,每条限 120 个字符,并标记为不可信 |
set_symbol, set_timeframe | 更改市场或柱线大小。交易所 csv 会打开你导入的数据集 |
get_candles | 按数量或时间范围获取 OHLCV 柱线,可选择获取每根柱线的指标数值 |
add_indicator, remove_indicator, list_indicators | 管理指标并列出 36 个可用指标 |
draw | 趋势线、水平线或射线、垂直线、射线、延长线、矩形、斐波那契回撤、文本备注、价格区间,均按价格和时间绘制 |
remove_drawing, clear_drawings | 移除绘图 |
screenshot | 返回图表的 PNG 图片 |
set_alert, list_alerts, remove_alert | 针对价格、绘制线条和指标设置警报 |
start_replay, step_replay, stop_replay | 柱线回放 |
set_layout | 1、2 或 4 张图表,以及同步选项、每张图表的交易品种和时间周期 |
set_chart_style | 设置图表类型(蜡烛图、空心蜡烛图、柱状图、折线图、面积图、Heikin Ashi)和价格刻度(普通、对数、百分比) |
get_watchlist, add_to_watchlist, remove_from_watchlist | 查看包含最新价格、涨跌额和涨跌幅的关注列表交易品种,并添加或移除交易品种 |
run_script | 将 Kandle 脚本添加到主图表,并返回其 ID、输入值和最新绘图值;发生错误时则返回行号和列号。inputs 按标题设置输入值,id 则替换先前添加的脚本。对于策略,还会返回回测摘要和最近 20 笔交易;strategy 用于更改其回测设置 |
get_backtest | 获取图表上策略脚本的设置(以及与脚本不同的设置)、摘要和最多 500 笔交易 |
get_share_link | 生成一个任何人都能打开主图表的链接。include 用于选择除交易所、交易品种和时间周期外,链接还包含哪些内容。embed: true 会为其他网页添加 iframe |
同时显示多张图表时,大多数工具都可选用 pane(1 到 4)。时间可以是 ISO 8601 日期,也可以是以秒或毫秒为单位的 Unix 时间。输入会经过验证,错误信息会说明需要修正的内容。
skills/kandle/SKILL.md 是一项 Agent 技能,包含图表分析工作流:支撑位和阻力位、趋势、指标共振,以及为图表添加说明性注释。将其复制到 Agent 的技能文件夹(对于 Claude Code,路径为 ~/.claude/skills/kandle/)。

安全模型
- 桥接程序只监听
127.0.0.1。其他机器无法访问。 - 应用会连接到服务,而不是由服务连接应用;只有在你开启 Agent bridge 后才会连接。该功能默认关闭,你可以随时将其关闭。
- 每个连接都必须先发送配对码。配对码约有 59 位随机性,比较时采用恒定时间算法;连续输错 5 次后,服务会停止接受配对码一分钟。
- 服务会拒绝来自非
localhost、127.0.0.1或[::1]网页的 WebSocket 连接,因此你访问的网站即使猜到端口,也无法连接。托管应用https://kernel-hunter.github.io也在允许范围内。若要添加其他来源(例如你自己托管的副本),请使用KANDLE_ALLOWED_ORIGINS。 - 服务会拒绝
Host标头不是环回地址的请求,从而防止 DNS 重绑定。 - 绘图备注可能来自他人分享的链接,因此
get_chart_state最多会返回 20 条备注的文本,每条不超过 120 个字符,并标记untrusted_text: true。工具描述和服务指令会告知 Agent:绘图文本、脚本代码和提醒消息都是数据,而非指令。 - Agent 只能执行工具允许的操作:读取图表数据、更改代码、图表类型、指标、绘图、提醒、回放、布局和自选列表,截取图表并创建分享链接。它无法读取其他标签页、你的文件或浏览器存储。
- 一次只能连接一个 Kandle 标签页。更新的标签页会接管连接,较旧的标签页会显示已被替换。
- 在同一台计算机上以你的用户身份运行的程序可以读取
~/.kandle/bridge-token。这与 Agent 本身的信任级别相同。
设置:--port 或 KANDLE_PORT(默认值为 7457,请在 Agent 对话框中更改端口以匹配)、KANDLE_TOKEN(用于固定配对码)、KANDLE_HOME(用于指定配对码文件夹)。
脚本
Kandle Script 让你能够编写自己的指标并回测策略。它兼容许多图表用户已经熟悉的脚本语言,因此许多现有指标脚本无需修改或只需少量修改即可运行。
点击 Scripts(或按 Alt+S)即可在图表下方打开编辑器。编写脚本,或从 Examples 中选择一个,然后按 Ctrl+Enter(Mac 上按 Cmd+Enter)将其添加到图表。输入时,错误会以带下划线的形式标出,编辑器下方会显示行号、列号和错误消息。之后可在编辑器左上方的列表中选择脚本来切换。
//@version=5
indicator("EMA cross", overlay = true)
fastLen = input.int(9, "Fast", minval = 1)
slowLen = input.int(21, "Slow", minval = 1)
fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)
plot(fast, "Fast", color.orange, 2)
plot(slow, "Slow", color.blue, 2)
plotshape(ta.crossover(fast, slow), "Up", shape.triangleup, location.belowbar, color.green)
设置了 overlay = true 的脚本会绘制在价格图表上;其他脚本则会显示在单独的窗格中。输入项会显示在 Indicators 对话框中,你可以在那里修改,而无需触碰代码。脚本及其输入值会与布局一同保存。新蜡烛出现或最后一根蜡烛发生变化时,只会重新计算最后一根柱线;对于典型脚本,完整计算 1,500 根柱线只需几毫秒。
脚本的一次运行最多可使用 10,000,000 次操作(每根柱线和每次循环迭代各计为一次,包括 request.security 内部的循环),运行时间上限为 1 秒。单根柱线上循环最多可重复 100,000 次,数组最多可包含 100,000 个元素。示例在 5,000 根柱线上约使用 5,000 次操作。超出限制的脚本会停止并报错;只有在你修改脚本、输入项或交易品种后才会再次运行,因此高负载脚本不会持续占用标签页。
指标示例包括均线交叉、带通道的 RSI、MACD、Bollinger Bands、Supertrend、VWAP 通道、Stochastic、ATR 移动止损、Donchian 突破、成交量飙升,以及使用 request.security 的日线 EMA 趋势过滤器。策略示例包括始终持仓的 EMA 交叉、带止损和目标价的 RSI 均值回归、Donchian 通道突破,以及一种区间突破策略:在区间上方设置买入止损单、在下方设置卖出止损单,将两者放入同一订单组,并在达到设定的回撤后停止交易。

策略与回测
使用 strategy() 而非 indicator() 声明脚本,即可将其转为回测。通过 strategy.entry、strategy.exit 和 strategy.close 下达的订单,会由经纪商模拟器根据图表中已加载的柱线进行成交。每笔成交都会在价格图表上绘制为带有信号名称的箭头,并用虚线连接入场与出场(盈利为绿色,亏损为红色)。图表下方的 Strategy 标签页包含两个视图:
- Overview:净利润、已平仓交易数、盈利百分比、利润因子、最大回撤、平均每笔交易、夏普比率和买入并持有表现;相较于买入并持有的权益曲线;以及一张列出毛利和毛损、平均和最大盈亏、已付佣金的表格。脚本设置风险规则时,表格会列出这些规则;停止交易的规则会显示在权益曲线上方,并在曲线上标出触发位置。
- List of trades:每笔交易的方向、入场和出场信号、时间和价格、数量、利润、累计利润、运行上涨幅度和回撤。点击某笔交易可将图表滚动到该交易的位置。
//@version=5
strategy("EMA cross", overlay = true, initial_capital = 10000,
default_qty_type = strategy.percent_of_equity, default_qty_value = 100,
commission_type = strategy.commission.percent, commission_value = 0.05)
fast = ta.ema(close, input.int(12, "Fast"))
slow = ta.ema(close, input.int(26, "Slow"))
if ta.crossover(fast, slow)
strategy.entry("Long", strategy.long)
// Stop 3% below and target 6% above the signal bar's close.
strategy.exit("Exit", "Long", stop = close * 0.97, limit = close * 1.06)
if ta.crossunder(fast, slow)
strategy.close("Long")
plot(fast, "Fast", color.orange)
plot(slow, "Slow", color.blue)
strategy() 调用中的值是脚本的默认值。若想尝试其他值而不修改代码,可打开 Indicators 对话框:策略的输入项下方有一个 Backtest settings 分组,其中包含初始资金、订单规模及其类型、佣金及其类型、以跳动点计的滑点、加仓次数,以及是否在柱线收盘时成交市价单。更改设置后会重新运行回测,图表中的交易记录和 Strategy 标签页也会随之更新。更改后的设置会高亮显示,并像输入值一样与布局一同保存;点击 Reset 可恢复脚本中的默认值。
订单如何成交:
- 脚本会在每根 K 线收盘时运行一次。在某根 K 线上下单,会在后续 K 线上成交:市价单在下一根 K 线开盘时成交;限价单或止损单则在 K 线的价格范围触及其价格时成交。启用
process_orders_on_close = true后,市价单会在下单所在 K 线收盘时成交。 - Kandle 无法获取 K 线内部的数据,因此假设价格从开盘价移动到距离更近的最高价或最低价,再移动到另一个价位,最后到收盘价(两者距离相同时先到最高价)。当一根 K 线同时触及退出单的止损价和目标价时,距离开盘价较近的价位会先成交。这只是一种假设,真实交易在这种 K 线上可能会有不同结果。
- 如果限价单或止损单的价格在开盘时已经被越过(跳空),则会在开盘价成交。
- 限价单按其价格成交。市价单和止损单会以更差的价格成交,偏差为
slippage个跳动点。每笔入场和每笔退出都会收取佣金。 - 反向入场会平掉当前持仓并开立新仓。同方向允许多次入场,但最多不超过
pyramiding(默认值为 0,表示只允许一次)。 strategy.exit中以跳动点为单位指定的价位(profit、loss、trail_points、trail_offset),均以每笔交易的成交价为基准。在入场所在 K 线上下达的退出单会保护该笔交易,使其在成交所在 K 线上生效。- 除非指定
qty,否则订单数量由default_qty_type和default_qty_value决定。现金数量和权益百分比数量使用成交价计算。数量不会四舍五入到手数,也不会发生追加保证金通知。 - 新数据到达时会重新计算全部历史数据,因此结果始终与图表上的 K 线一致。向左滚动以加载更早的 K 线,回测也会涵盖这些数据。
订单组:strategy.entry 和 strategy.order 接受 oca_name 和 oca_type。具有相同 oca_name 的待成交订单会组成一个订单组;其中一个订单成交时,oca_type 会决定其他订单的处理方式:
strategy.oca.cancel:取消组内其他订单。这是常见的括号订单:一个买入止损单设在区间上方,一个卖出止损单设在区间下方;其中一个先成交后,另一个就会被取消。strategy.oca.reduce:将每个其他订单的数量减去已成交订单的数量(对于反向平仓的入场单,已平仓合约也计入),数量变为 0 的订单会被取消。未指定qty的订单会先按成交价应用其默认数量。strategy.oca.none(默认值):其他订单不会受到影响;名称不起作用。
此操作会在成交时立即发生,因此,被取消的订单即使价格路径在同一根 K 线上触及其价格,也不会再成交。组内订单应使用相同类型;如果类型不同,则以成交订单的类型为准。只有实际成交才会产生影响:如果入场单因 pyramiding 或风险规则而未执行,订单组不会受到影响。使用待成交订单的 ID 下单,会替换该订单及其所在的组。strategy.exit 创建的退出括号仍会像之前一样,对已成交的交易继续生效。
风险规则:strategy.risk.* 调用属于设置。它们必须位于脚本顶层,从下一次成交开始生效;再次调用时,以最新值为准。常量参数会在脚本编译时检查;输入值会在脚本运行时检查。两种错误都会指出所在行和列。
strategy.risk.allow_entry_in(strategy.direction.all | strategy.direction.long | strategy.direction.short):如果strategy.entry的方向不被允许,则只会平掉反方向的未平仓头寸;如果没有头寸,则不执行任何操作。strategy.order在该方向上可以减少头寸,但不能开仓。strategy.risk.max_position_size(contracts):如果某笔入场或订单会使头寸超过contracts,则会将其缩减至剩余可用空间;如果没有可用空间,则不执行任何操作。反转会完全平掉原有头寸,并最多开仓contracts。strategy.risk.max_drawdown(value, type):type为strategy.percent_of_equity(默认值)或strategy.cash。回撤根据每根 K 线收盘时的权益相对于此前最高点计算,从初始资金开始统计。达到value时,回测剩余时间内停止交易。strategy.risk.max_intraday_loss(value, type):亏损是 UTC 日内每根 K 线收盘时的权益低于当日开始时权益的部分,以该权益的百分比或现金金额表示。达到value时,停止交易直至下一个 UTC 日。strategy.risk.max_intraday_filled_orders(count):统计 UTC 日内成交的订单。反转算作一笔订单,每笔成交的退出单算作一笔订单,风险规则触发的平仓不计入。达到count时,停止交易直至下一个 UTC 日。strategy.risk.max_cons_loss_days(count):如果某个 UTC 日最后一次收盘时的权益低于前一日结束时的权益,则该日计为亏损日。盈利日会重置计数;权益未变的日期则跳过。某日的结果会在下一日开始时确认,因此连续亏损日达到count后,会从下一日的第一根 K 线开始停止回测剩余时间内的交易。
触发规则时,所有待处理订单和 strategy.exit 止盈止损单都会被取消,未平仓头寸会通过一笔带有规则名称标签(例如“最大回撤”)的市价单平仓;在交易恢复前,新的入场单、订单和退出单都会被忽略;strategy.close 和 strategy.cancel 仍可正常使用。平仓单的成交方式与任何市价单相同:在下一根 K 线开盘时成交,或者在设置 process_orders_on_close = true 时于同一根 K 线收盘时成交。max_cons_loss_days 会在新的一天开始时触发,因此会在该根 K 线开盘时平仓。由于 Kandle 没有交易时段数据,日期按 UTC 日历日计算,并以 K 线的开盘时间为准。按收盘权益计算的规则不会捕捉只在一根 K 线内部发生的亏损。
数据指标的计算方式:最大回撤是每根 K 线收盘时权益相对于此前峰值的最大跌幅。夏普比率使用每个 UTC 日结束时的权益(在日线和周线图表上使用每根 K 线的权益),计算收益率均值除以其标准差,并按 365 天年化,风险无风险利率为 0。买入并持有收益是从首个已加载收盘价到最后一个收盘价的价格变化,并以初始资金为基数计算。未平仓利润会计入入场时已支付的佣金。
支持:strategy() 及其 initial_capital(默认值为 100000)、default_qty_type(strategy.fixed、strategy.cash、strategy.percent_of_equity)、default_qty_value、commission_type(strategy.commission.percent、cash_per_contract、cash_per_order)、commission_value、slippage、pyramiding 和 process_orders_on_close。订单:strategy.entry 和 strategy.order(含 oca_name 和 oca_type:strategy.oca.cancel、reduce 和 none)、strategy.exit(profit、limit、loss、stop、trail_price 或 trail_points 及 trail_offset、qty、qty_percent、comment_profit、comment_loss、comment_trailing)、strategy.close(含 qty、qty_percent 和 immediately)、strategy.close_all、strategy.cancel 和 strategy.cancel_all,以及 strategy.long 和 strategy.short。风险规则:strategy.risk.allow_entry_in(strategy.direction.all、long、short)、max_position_size、max_drawdown、max_intraday_loss、max_intraday_filled_orders 和 max_cons_loss_days。状态:strategy.position_size、position_avg_price、equity、netprofit、openprofit、grossprofit、grossloss、max_drawdown、closedtrades、opentrades、wintrades、losstrades、eventrades、initial_capital,以及每笔交易的值,例如 strategy.closedtrades.profit(i) 和 strategy.opentrades.entry_price(i)。currency、calc_on_every_tick 和 alert_message 参数会被接受但忽略。strategy.exit 中的 oca_name 会被接受但不起作用,因为退出订单中的目标价和止损价会自动相互取消。
Agent 获得的结果相同:run_script 会返回策略回测摘要和最近 20 笔交易,get_backtest 最多返回 500 笔交易。run_script 还接受 strategy 和以 strategy() 参数命名的回测设置,例如 {"initial_capital": 5000, "commission_value": 0.1};null 会将设置恢复为脚本中的值,若提供 id,则会重新运行图表上已有的策略。在页面中,window.kandle.setStrategySettings(id, settings) 可为图表上的脚本执行相同操作,listScripts() 会显示每个策略自身的设置及当前使用的设置,getBacktest() 则会在 changedSettings 中列出不同的设置。脚本设置的风险规则位于 settings.risk 中;riskStop 会记录停止交易的规则名称及原因(若未停止则为 null),riskHalts 会统计日内规则暂停交易的天数。

其他符号和时间周期
request.security(symbol, timeframe, expression, gaps, lookahead) 返回在其他时间周期上,或在图表数据源中的其他符号上计算的 expression 值。
//@version=5
indicator("Daily EMA trend", overlay = true)
dailyEma = request.security(syminfo.tickerid, "D", ta.ema(close, 20))
ethClose = request.security("ETHUSDT", "60", close)
plot(dailyEma, "Daily EMA", color.orange, 2, plot.style_stepline)
symbol可以是图表符号的syminfo.tickerid(或syminfo.ticker),也可以是同一数据源中的符号,例如在 Binance 上查看 BTCUSDT 时使用"ETHUSDT"。如果 Kandle 有相应数据源,前缀(如"BINANCE:ETHUSDT")会指定该数据源;否则会被忽略。timeframe可以是"1"、"5"、"15"、"60"、"240"、"D"或"W"("1D"、"1W"、"1h"和"4h"也可用),也可以是timeframe.period或"",表示图表自身的时间周期。- 符号和时间周期在整个运行过程中必须保持不变,因为 Kandle 会在脚本运行前加载数据。它们可以是字符串、输入项(
input.symbol、input.timeframe、input.string)、一次性设为上述某个值的变量,或由这些内容拼接而成的文本,例如"BINANCE:" + sym。任何可能随每根柱线变化的内容,例如close > open ? "ETHUSDT" : "SOLUSDT",都会报错:"request.security needs constant symbol and timeframe"。脚本最多可以请求 5 组不同的符号和时间周期;无论输入项当前取值为何,都只计为一组。 - 表达式会在请求的柱线上运行,并使用自身的历史数据,因此,在
"D"请求中使用ta.ema(close, 20)会得到 20 日 EMA。它使用的变量、输入项和函数会在请求的柱线上重新计算。不能在表达式中使用以var声明的变量、通过:=修改的变量、函数参数和循环变量。元组可用:[o, c] = request.security(syminfo.tickerid, "D", [open, close])。
输入项可让你在 Indicators 对话框中选择序列。更改输入项会重新运行脚本并加载新序列;之前加载的序列会保留在缓存中,因此切换回来时可立即显示。
//@version=5
indicator("HTF close", overlay = true)
tf = input.timeframe("D", "Higher timeframe")
sym = input.symbol("ETHUSDT", "Symbol")
plot(request.security(sym, tf, close))
默认不使用前瞻。使用 lookahead = barmerge.lookahead_off 时,图表柱线会获取截至该图表柱线收盘时,最近一根已收盘的请求柱线的值。在 1H 图表上,每天最后一根小时柱线会更新日线值,而此前的柱线显示前一天的值。历史数据永远不会看到未来数据。只有在当前交易日尚未结束时,最新的图表柱线才会显示当天不断变化的值。
lookahead = barmerge.lookahead_on会使用包含该图表柱线的请求柱线,即使该请求柱线尚未收盘也是如此。在历史数据上,这会造成前瞻:09:00 的柱线会看到当天的收盘价。request.security(syminfo.tickerid, "D", close[1], lookahead = barmerge.lookahead_on)是在今天的每根柱线上获取前一天收盘价且不产生前瞻的常用方法。gaps = barmerge.gaps_on除了新请求柱线收盘时对应的图表柱线(启用 lookahead 时,则为每根请求柱线内的第一根图表柱线)外,其他情况均返回 na。- 低于或等于图表时间周期的请求:每根图表柱线会获取其内部最近一根已收盘请求柱线的值,lookahead 不起作用。最多加载 5,000 根请求柱线,因此在日线图上,1 分钟请求只覆盖最近几天。
请求的序列会通过图表的数据源加载,并采用相同的缓存和速率限制;加载范围从图表第一根柱线之前的 500 根柱线开始,向前滚动时会加载更多数据。无需密钥的数据源会实时更新;需要密钥的数据源则每隔几分钟刷新一次,以符合免费方案的限制。序列加载期间,其值为 na;如果无法加载,脚本会显示错误。run_script 会等待数据加载完毕后再返回。
支持的功能
- 语法:
//@version=5和//@version=6标头、注释、缩进代码块、在括号内或运算符后换行、var和varip、声明中的类型名称(float x = na)、=、:=和+= -= *= /= %=、?:、and、or、not、if/else if/else、带值或不带值的switch、for i = a to b by step、for x in array、for [i, x] in array、while、break、continue、单行或多行函数、默认参数和命名参数、元组([a, b] = f())、用户方法(method f(float x) =>)以及values.push(x)等方法调用。 - 序列:每个值都有历史记录,可通过
x[n]读取。na、na()、nz()和fixnan()。使用var声明的变量会在每根柱线之间保留其值。每次函数调用都会保留各自的历史记录。 - 数据:
open、high、low、close、volume、hl2、hlc3、ohlc4、hlcc4、time、bar_index、last_bar_index、year、month、dayofmonth、dayofweek、hour、minute、barstate.*、syminfo.ticker、syminfo.mintick、timeframe.period、timeframe.change()。 ta.*:sma、ema、rma、wma、vwma、hma、rsi、macd、stoch、atr、tr、bb、bbw、kc、cci、mfi、obv、vwap(可选锚点和带)、supertrend、dmi、wpr、change、mom、roc、highest、lowest、highestbars、lowestbars、crossover、crossunder、cross、rising、falling、stdev、variance、dev、cum、valuewhen、barssince、pivothigh、pivotlow、linreg、correlation、percentrank、median。math.*:abs、max、min、avg、sum、round、floor、ceil、sqrt、pow、log、log10、exp、sign、三角函数、pi和e。input、input.int、input.float、input.bool、input.string(带options)、input.source、input.color、input.price、input.timeframe(Kandle 时间周期的下拉菜单,或其options,以及跟随图表时间周期的 Chart)和input.symbol(文本字段,可根据图表的数据源建议交易品种;留空时跟随图表的交易品种)。input.timeframe(timeframe.period)和input.symbol(syminfo.tickerid)初始时会跟随图表。color.*常量、color.new、color.rgb、color.from_gradient以及#RRGGBB或#RRGGBBAA字面量。str.tostring、str.format、str.length、str.contains、str.upper、str.lower等其他函数。适用于 float、int、bool、string 和 color 数组的array.*。- 其他交易品种和时间周期:
request.security支持barmerge.gaps_on、gaps_off、lookahead_on和lookahead_off。请参阅其他交易品种和时间周期。 - 策略:请参阅策略与回测。
- 输出:
indicator()支持title、shorttitle、overlay、format和precision;plot支持线条、阶梯线、直方图、柱形、圆形、十字和面积样式,以及逐柱颜色、linewidth和offset;plotshape;plotchar;hline;两个 plot 或两条 hline 之间的fill;bgcolor;barcolor(用于价格图表脚本)。
目前尚不支持:除 request.security 外的 request.* 函数(例如 request.security_lower_tf 和 request.financial)、绘图对象(label、line、box、table)、用户定义的类型和枚举、import、matrix 和 map,以及渐变填充。使用这些功能时,会显示明确的“尚不支持”错误,并指出对应的代码行。
警报
点击 Alerts,为主图表的品种创建和管理警报:
- 价格穿越、向上穿越、向下穿越或触及某个价位。
- 价格穿越或触及你绘制的水平线、水平射线、趋势线、射线或延长线。移动线条时,警报会跟随移动。
- RSI 或 MACD 等指标线穿越某个价位。
每个警报触发一次,或每次都触发(每根 K 线最多一次)。触发时,你会收到浏览器通知、应用内消息和一段短提示音。创建第一个警报时,Kandle 会请求通知权限。警报保存在浏览器中,并在 Kandle 标签页打开时根据实时数据进行检查;关闭标签页后,警报不会运行。屏幕上任何图表显示的品种都会进行警报检查。
K 线回放
点击 Replay,然后点击主图表上的一根 K 线。此后的所有 K 线都会隐藏,指标也只根据可见数据计算。使用回放栏播放、暂停、逐根前进,并选择 1x 到 10x 的速度(每秒 K 线数)。键盘操作:空格键播放或暂停,右箭头逐根前进,Esc 退出。退出后,图表会恢复实时数据。更改品种或时间周期也会结束回放。回放最远可追溯到交易所提供的历史数据;需要时,Kandle 会加载更早的 K 线。
布局
点击 Layout,选择显示 1 个图表、2 个并排图表或 4 个网格图表。第一个图表是主图表,使用顶部栏和绘图工具。其他图表各自都有独立的品种、时间周期、图表类型和指标,并显示在小型标题栏中。开启同步后,可在所有图表间同步十字光标、时间周期或品种。布局和各图表的设置都会保存在浏览器中。
自选列表
点击 Watchlist(或按 Alt+W),在图表右侧显示列表。点击某个品种,即可将其加载到你上次点击的图表中;同时显示多个图表时,该图表会以蓝色边框标示。点击 + 按钮可添加该图表的品种;点击搜索按钮可查找任意数据源上的品种。拖动行的拖动手柄可调整顺序;也可选中该行并按 Alt+Up 或 Alt+Down;按 Delete 可将其移除。首次打开 Kandle 时,列表中会显示 Binance 上的 BTCUSDT、ETHUSDT 和 SOLUSDT。
每一行都会保留自己的数据源,其显示的涨跌幅取决于该数据源:
- Binance、Coinbase、Bybit、OKX 和 Kraken:显示最近一次成交价以及过去 24 小时的涨跌幅(滚动时间段,而非从午夜开始计算),并实时推送数据。Kandle 会为每个交易所建立一个 websocket 连接,以获取该交易所所有品种的数据。
- Twelve Data、Alpaca 和 Polygon:显示相对于前一日收盘价的涨跌幅。为遵守免费方案的限制,Kandle 会从 Twelve Data 每 10 分钟、从 Alpaca 每 2 分钟、从 Polygon 每 30 分钟读取最近两根日线 K 线,每次只发送一个请求。当屏幕上的图表显示相同品种时,该行会跟随图表的实时价格变化。
- CSV:显示导入数据的最近收盘价与前一根 K 线收盘价的对比。
只有显示自选列表时,价格才会更新。隐藏列表,或将标签页切换到后台一分钟后,Kandle 会关闭连接;返回时会重新建立连接。在手机上,点击绘图工具栏底部的列表按钮,列表会覆盖在图表上方。列表内容及其显示状态都会保存在浏览器中。
分享图表
点击顶部栏中的分享按钮,或按 Alt+K,然后选择 Copy link,即可复制主图表的链接。链接始终包含交易所、交易品种和时间周期。其他内容由你选择:图表类型、价格刻度和可见范围、指标、绘图、脚本(包括其输入值和策略设置),以及布局中的其他图表。脚本默认关闭,因为它们会让链接变长。弹出窗口会显示链接长度,并在超过 8,000 个字符时发出警告,因为某些聊天应用会截断链接。
Kandle 会将图表压缩后存储在链接中 # 之后。浏览器不会将这部分发送到任何服务器,因此 GitHub Pages 永远不会看到你分享的内容。无法分享导入的 CSV 文件图表,因为数据只在你的浏览器中。
打开链接后,图表会在 Shared chart 栏下以临时视图显示,不会更改你自己保存的图表。点击 Keep it 可将共享图表保存为自己的图表:其中的图表设置和指标会替换你原来的设置,而你自己的绘图和脚本会保留。点击 Back to my chart 可关闭该视图。链接中的脚本在你点击 Run scripts 之前不会运行,点击 Show code 可先查看脚本。它们的运行方式与你粘贴到编辑器中的脚本相同。Twelve Data、Alpaca 或 Polygon 的图表会使用你自己保存的 API 密钥,因此在共享视图中,它们会等待你点击 Load it;在此之前,不会向相应服务提供商发送任何内容。点击 Keep it 后,它们会照常加载。如果链接已损坏或被编辑,页面会显示提示并打开你自己的图表。
Agent 可以使用 get_share_link 工具创建链接。在页面中,await window.kandle.share({ include: { scripts: true } }) 会返回 URL。
嵌入图表
在博客、文档页面或任何允许使用 iframe 的网站上放置实时图表。打开 Share(Alt+K),切换到 Embed,选择尺寸和主题,然后点击 Copy code:
<iframe src="https://kernel-hunter.github.io/kandle/?embed=1#s=zFcixCsIwFIbRd_nmf0gLBbmbWjfFweoS7hDbDmKM0Kog4ruLZzwfXlglZozzpaTSj4g3xqpbHw9th3hgVC3iitGnMuRxRiSMcp9uKSMmLJZnzlq4uGAxstktUayDmqA6BHdFTvstio2qf7m7GLDo3x8" title="Kandle chart: BTCUSDT 1D on Binance" width="640" height="400" style="border:0" loading="lazy"></iframe>
嵌入内容会显示图表及其指标和绘图工具;如果布局链接中包含其他图表,也会一并显示。查看者可以平移、缩放并使用十字光标。页脚会显示标的、时间周期和最新价格,而 Open in Kandle 会在新标签页中以普通分享链接的形式打开同一张图表。width="100%" 会填满所在列。docs/embed-example.html 是一个包含单个嵌入内容的最简页面。
嵌入 URL 是在 # 前加上 ?embed=1 的分享链接。图表仍以相同格式保存在片段中,因此服务器只能看到查询部分,其中不包含任何图表信息。添加 &theme=light 或 &theme=dark 可固定颜色;如果不添加,嵌入内容会遵循查看者的系统设置。
嵌入内容不会包含以下内容:
- 脚本。嵌入链接从不包含脚本。即使链接中带有脚本,嵌入内容也不会运行脚本,而是提示打开 Kandle 中的图表来运行脚本。
- 浏览器存储。嵌入内容不会读取或写入浏览器存储,因此无法看到查看者自己的图表或 API 密钥。需要密钥的数据源(Twelve Data、Alpaca、Polygon)会显示提示,因此请嵌入加密货币交易所的图表。
- 控件。嵌入内容没有顶部栏、绘图工具栏、面板、警报、Agent 桥接、
window.kandle或postMessageAPI,因此嵌入内容所在页面无法控制图表。
只有嵌入链接可以在框架中运行。GitHub Pages 无法发送禁止框架嵌入的标头,否则页面可能会在完整应用的按钮上覆盖自己的按钮,例如 Run scripts 或 Keep it。当其他页面在框架中加载完整应用时,Kandle 会显示提示,并附上一个链接,可在独立标签页中打开应用。嵌入内容可以安全地放入框架:Kandle 没有账户,也不在服务器上存储任何内容;当前浏览器会为框架中的页面提供独立于查看者 Kandle 标签页的存储;而嵌入内容没有任何会更改或删除内容的操作。GitHub 不会在 README 文件中显示 iframe,因此请在其中链接到图表。
Agent 可通过 get_share_link 获取 iframe,并设置 embed: true。在页面中,await window.kandle.share({ embed: true, theme: 'dark' }) 会返回嵌入 URL,而 await window.kandle.embedCode({ width: 800, height: 450 }) 会返回 iframe。
路线图
- 支持 macOS、Windows 和 Linux 的桌面应用。
- 使用 IndexedDB 存储更大的 CSV 导入文件。
在本地运行
你需要 Node.js 22.12 或更高版本,以及 pnpm。
pnpm install
pnpm dev
然后打开 Vite 打印的 URL,通常是 http://localhost:5173。
其他命令:
pnpm test # unit tests
pnpm build # type check, production build in dist/, and build kandle-mcp
pnpm preview # serve the production build
pnpm mcp # build and run kandle-mcp (normally your agent runs it)
要为子路径构建(例如 GitHub Pages 项目站点),请设置 BASE_PATH:
BASE_PATH=/kandle/ pnpm build
项目结构
src/
config.ts app name and identifiers
data/ market data adapters behind a DataSource interface, API keys, rate limits
chart/ chart engine glue, extra indicators, extra drawing tools
store/ layout persistence
script/ Kandle Script: lexer, parser, runtime, built-ins, chart renderer
ui/ symbol search, indicator panel, dialogs
agent/ agent bridge client, request handlers, Agent dialog
alerts/ alert evaluation, notifications, alert manager
replay/ bar replay and the data loader it sits behind
layout/ multi-chart layouts
watchlist/ watchlist panel, quotes and their persistence
share/ share links: encoding, the Share popover and the shared chart view
embed/ embed mode: the chart alone in an iframe on another site
features/ connects the above to the app
packages/mcp/ kandle-mcp, the MCP server
skills/kandle/ agent skill for chart analysis
tests/ unit tests
要添加交易所,请在 src/data/types.ts 中实现 DataSource 接口,并在 src/data/sources.ts 中注册。
数据源
点击顶部栏中的 数据,即可查看所有数据源、添加密钥并测试。在搜索代码时,从结果上方选择数据源。
| 数据源 | 市场 | 是否需要密钥 | 更新频率 |
|---|---|---|---|
| Binance | 加密货币 | 否 | 实时 |
| Coinbase | 加密货币 | 否 | 实时 |
| Bybit | 加密货币 | 否 | 实时 |
| OKX | 加密货币 | 否 | 实时 |
| Kraken | 加密货币 | 否 | 实时。历史数据最多只提供每个时间周期最新的 720 根柱线。 |
| Twelve Data | 股票、ETF、外汇、加密货币 | 免费密钥 | 对你的套餐所提供实时数据的代码实时更新;否则每分钟刷新一次 |
| Alpaca | 美国股票和 ETF | 免费密钥 ID 和密钥 | 来自 IEX 数据流的实时数据(成交量仅包含 IEX 交易) |
| Polygon | 股票、ETF、外汇、加密货币、指数 | 免费密钥 | 免费套餐提供日终数据,标记为延迟 |
| CSV | 你自己的数据 | 否 | 不更新。请参阅 CSV 导入 |
免费密钥:
- Twelve Data:在 twelvedata.com 注册。免费套餐每分钟允许 8 次请求,每天允许 800 次请求。
- Alpaca:在 alpaca.markets 开设免费账户(模拟交易账户即可),并创建 API 密钥。免费套餐使用 IEX 数据流,每分钟允许 200 次请求。
- Polygon:在 polygon.io 注册。免费套餐提供 2 年日终数据,每分钟允许 5 次请求。
不包含 Finnhub:其免费套餐不提供历史蜡烛数据,因此无法绘制图表。
密钥的处理方式:
- 密钥保留在此浏览器中,并保存于
kandle:apikey:<source>本地存储中;除发送给对应提供方的 API 外,绝不会发送到其他地方。Kandle 没有服务器。 - 在提供方支持的情况下,密钥会放在请求标头中。Twelve Data 的 WebSocket 仅接受放在 URL 中的密钥,而该 URL 只会发送给 Twelve Data。
- 在“数据”对话框中点击 删除密钥,即可从浏览器中删除密钥。
免费套餐的限额较低,因此 Kandle 会缓存响应、按各套餐的每分钟限额统计请求,并在提供方返回 429 时降低请求频率。达到限额时,图表会显示“已达到免费套餐限额,请在 N 秒后重试”,而不会循环重试。
股票图表仅在交易时段显示柱线。夜间、周末和节假日不会显示空柱线,图表会将柱线并排放置,因此时间轴上不会出现间隙。
市场数据直接通过浏览器从各提供方的官方公共 API 获取。Kandle 不会存储或再分发这些数据;各提供方的条款均适用。交易所的可用性取决于你所在的地区;对于 Binance,应用会优先使用公共市场数据主机。

CSV 导入
加载自己的 OHLCV 数据:在品种搜索中或 Data 对话框的 CSV 卡片中点击 Import CSV 并选择文件,也可以将文件拖到图表上。Kandle 会在浏览器中读取文件并显示识别结果;为数据集命名后,它就会在图表中打开。数据不会上传。
支持的文件:
- 包含标题行,且有时间列(
time、date、datetime、timestamp或open time)、open、high、low、close和可选的volume,列顺序和大小写不限。分开的date和time列会合并。没有标题行的文件会按时间、开盘价、最高价、最低价、收盘价和成交量的顺序读取。 - 使用逗号、分号或制表符分隔。分号分隔的文件支持小数逗号(
1234,5)。 - 时间格式支持 ISO 8601(
2024-03-05T14:30:00Z,带时区)、YYYY-MM-DD、YYYY-MM-DD HH:mm或YYYY-MM-DD HH:mm:ss(按 UTC 读取),以及 Unix 秒或毫秒时间戳。 - 数据行会按时间排序。若两行的时间相同,则保留较晚的一行。时间或价格无法读取,或最高价低于最低价的行会被跳过并计数。
时间周期根据柱线间隔的中位数确定,因此不含周末数据的日线股票数据仍会识别为 1D。无法匹配任何时间周期、但能整除某个时间周期的柱线(例如 30 分钟线)会合并到下一个时间周期(1H)。图表可以按数据集自身的时间周期及更长的时间周期显示数据,后者根据数据集的柱线生成;更短的时间周期按钮会被禁用。
数据集会保存在此浏览器的本地存储中(每个最多 2.5 MB,总计 4 MB,约为每个数据集 40,000 根柱线),并会在品种搜索的 CSV 分类下显示,带有 CSV 徽标。重新加载后数据仍会保留,也可以在 Data 对话框中删除。脚本、策略回测、对更高时间周期的 request.security 调用、绘图、柱线回放和多图表布局均可用于这些数据。数据不会更新,因此 CSV 图表上的提醒不会触发。Agent 可以通过 set_symbol 和交易所 csv 打开数据集。

许可证
MIT。请参阅 LICENSE。
图表使用 KLineChart 绘制,采用 Apache-2.0 许可证。脚本编辑器使用 CodeMirror,采用 MIT 许可证。相关声明见 public/third-party-notices.txt。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。