用 Claude 写 Pine
不会 code 也能自动化交易
90% 的散户有自己一套盯盘习惯,但讲不清楚—脑袋里知道「什么时候会进场」, 但要把它写成 if-then 规则就卡住。Claude 解这个问题:你用人话描述、它输出 Pine Script v6。
本文目标:看完你能用 claude.ai 免费版,把任何你想得到的策略逻辑 变成可以在 TradingView 跑回测、可以丢给 TVSBot 自动下单的 Pine。
为什么用 Claude,不用 ChatGPT / Copilot?
三个工具我都试过写 Pine,差别很实际:
- Copilot:适合补 code、不适合从零生成。你已经写了一半的 Pine 它能补得很好,但你「没写任何 code」叫它从策略描述生成,常常会给你一个指标而不是 strategy。
- ChatGPT:可以生 Pine,但 Pine 各版语法差异常常混淆。要明讲「Pine Script v6」+ 在输出时加
//@version=6,否则出来的 code 在 TV 编译器会直接报错。 - Claude:对结构化 code + 长文上下文最稳。你可以一次把策略逻辑、风控规则、TVSBot JSON 规格、回测注意事项全部贴进去,它能消化整个 context 一致地输出 Pine。实测 claude.ai 免费版(Sonnet 4.5)写 5 个策略 prompt 都能一次过。
三步流程概览
先把整套自动化流程的 mental model 建好:
- 策略口述 → Claude prompt:你用 5 段结构讲清楚(后面教)。
- Claude → Pine Script v6:得到含
strategy()下单指令的完整 code(Pine 里不放 JSON、不放 webhook secret)。 - Pine → TradingView 图表回测:贴进 Pine Editor、Add to chart、看 Strategy Tester 标签的 Net Profit、Max Drawdown、Win Rate。
- Alert + TVSBot webhook:图表右上时钟 → Add Alert → 条件选你的策略(strategy() 的 alert 由成交触发)→ Message 栏贴 TVSBot 策略页「TV 模板」的单行 JSON → Notifications 勾 Webhook → 贴 dashboard 给的 URL。webhook secret 只在这个 alert 窗口填。
全程不需要你自己写一行 Pine。
提示词模板:5 段结构
好的 Pine prompt 一定包含这 5 段。少一段,Claude 就要猜, 猜错你就要花 3-4 轮对话重来:
【1. 我是谁、我在交易什么】
我是 BTC 永续合约交易者,主要看 1 小时线,
资金 USD 10,000,交易所是 Binance USDT-M Futures。
【2. 进场条件】
当 K 棒收盘价突破过去 20 根 K 棒的最高 high
(不含当前 K 棒)且当下 RSI(14) > 50 时,
我会进多单。
【3. 出场条件】
当 K 棒收盘跌破过去 10 根 K 棒的最低 low 时,
我会出场。或者价格从进场以来最高点回落 ATR(14) × 2 也出场。
【4. 风控规则】
止损:进场 K 棒的 low - ATR(14) × 0.5。
每笔交易最大风险 = 账户 1%。
任何时刻最多持 1 个方向,不加码(pyramiding=0)。
【5. 输出规格】
请输出完整 Pine Script v6 strategy(),不要加 alertcondition()
(strategy() 的 alert 由成交触发,alertcondition() 只给 indicator() 用)。
Pine 里不要写 alert()、JSON 或 webhook secret。
我会在 TradingView 的 alert 窗口贴 TVSBot「TV 模板」的单行 JSON,格式像这样:
{"secret":"<你的 webhook secret>","strategy":"<TVSBot 策略名称>","action":"{{strategy.order.alert_message}}","symbol":"BTCUSDT","exchange":"binance","market_type":"futures","qty_type":"margin_usdt","qty":50,"leverage":3}
secret 我自己在 TradingView 填。
action 的填法:策略完全没有出场逻辑时用 {{strategy.order.action}};
只要策略有出场(strategy.close/strategy.exit/止损止盈),
每一个 strategy.entry/strategy.close/strategy.exit 都要设 alert_message
(进场 "buy"/"sell"、出场 "close",只放动作字;
翻仓时先 strategy.close(..., alert_message="close")、再 strategy.entry 新方向(送它自己的 "buy"/"sell"):两张单成交 = 两则 alert,TVSBot 先完整平仓再开新仓;
不要只靠相反方向的 strategy.entry 翻仓,TVSBot 每张单都用自己的 qty,带固定保证金的 "sell" 不一定能把多单干净翻成空单),
alert 窗口 JSON 的 action 改填 {{strategy.order.alert_message}}
({{strategy.order.action}} 只会送 buy/sell、不会送 close,出场会被当成一般买卖、平不干净)。把这 5 段直接贴给 Claude,它 95% 的机率会一次给你能直接用的 Pine。
study(),v5 起要用 indicator())。{{ticker}}(永续合约会变成 BTCUSDT.P)。 最省事的做法是到 TVSBot 策略页按「TV 模板」直接复制,secret、策略名、交易所都已填好。5 个常用策略 — 直接抄 prompt
策略 1:Donchian Breakout(突破)
人话:K 棒收盘突破 20 根新高就买、跌破 10 根新低就出场。止损在进场 K 棒 low 下方 0.5 倍 ATR。
Pine Script v6 strategy()。
进场:close 突破过去 20 根 K 棒的 ta.highest(high, 20)[1](不含当前)。
出场:close 跌破过去 10 根 K 棒的 ta.lowest(low, 10)[1]。
止损:进场 K 棒的 low - 0.5 × ta.atr(14)。
每次下单用 100% equity (default_qty_value=100, default_qty_type=strategy.percent_of_equity)。
不要用 alertcondition(),Pine 里也不要写 alert() 或 JSON(alert 由成交触发,JSON 我在 alert 窗口贴)。
每一个 strategy.entry/strategy.close/strategy.exit 都要设 alert_message,只放动作字、不放 secret:
多单进场 alert_message="buy"、空单进场 alert_message="sell"、明确调用 strategy.close/strategy.exit 的出场(止损、止盈、平仓)alert_message="close"。
翻仓请先 strategy.close(..., alert_message="close"),再用 strategy.entry 开新方向(alert_message="buy"/"sell");两张单成交 = 两则 alert,TVSBot 先完整平仓、再开新仓。
不要只靠相反方向的 strategy.entry 翻仓:TVSBot 每张单都用自己的 qty 下单,带固定保证金的 "sell" 不一定能把多单干净翻成空单(视持仓模式,可能只减仓一部分,或翻仓后数量不对)。
因为 {{strategy.order.action}} 只会送 buy/sell、不会送 close,
我在 alert 窗口贴的单行 JSON,action 要换成 {{strategy.order.alert_message}}:
{"secret":"<你的 webhook secret>","strategy":"<TVSBot 策略名称>","action":"{{strategy.order.alert_message}}","symbol":"BTCUSDT","exchange":"binance","market_type":"futures","qty_type":"margin_usdt","qty":50,"leverage":3}
pyramiding=0、process_orders_on_close=true。为什么这策略适合练手:逻辑极简(两条规则)、回测结果稳定、不需要过滤杂讯。 BTC 1H 跑近 1 年胜率通常 35-45% 但 R:R 1:3 以上,净利为正。
策略 2:EMA Cross(均线交叉)
人话:EMA20 由下穿上 EMA60 就买、反过来就空。止损用 EMA60 本身。
Pine v6 strategy()。
进场多单:ta.crossover(ta.ema(close, 20), ta.ema(close, 60))。
进场空单:ta.crossunder(ta.ema(close, 20), ta.ema(close, 60))。
止损:多单在 ema60 下方 0.3%、空单反向。
止盈:1:2 风险报酬比(risk × 2 = target)。
pyramiding=0。反向讯号先平仓再反手(做法见下)。
不要用 alertcondition(),Pine 里也不要写 alert() 或 JSON(alert 由成交触发,JSON 我在 alert 窗口贴)。
每一个 strategy.entry/strategy.close/strategy.exit 都要设 alert_message,只放动作字、不放 secret:
多单进场 alert_message="buy"、空单进场 alert_message="sell"、明确调用 strategy.close/strategy.exit 的出场(止损、止盈、平仓)alert_message="close"。
翻仓请先 strategy.close(..., alert_message="close"),再用 strategy.entry 开新方向(alert_message="buy"/"sell");两张单成交 = 两则 alert,TVSBot 先完整平仓、再开新仓。
不要只靠相反方向的 strategy.entry 翻仓:TVSBot 每张单都用自己的 qty 下单,带固定保证金的 "sell" 不一定能把多单干净翻成空单(视持仓模式,可能只减仓一部分,或翻仓后数量不对)。
因为 {{strategy.order.action}} 只会送 buy/sell、不会送 close,
我在 alert 窗口贴的单行 JSON,action 要换成 {{strategy.order.alert_message}}:
{"secret":"<你的 webhook secret>","strategy":"<TVSBot 策略名称>","action":"{{strategy.order.alert_message}}","symbol":"BTCUSDT","exchange":"binance","market_type":"futures","qty_type":"margin_usdt","qty":50,"leverage":3}注意:EMA20/60 适合 1H 以上周期。5 分线杂讯太多会被洗到怀疑人生。
策略 3:RSI Mean Revert(过买过卖回归)
人话:RSI(14) 低于 30 反弹到 30 上就买、回到 50 出场。空单反向。加大趋势过滤:只在 EMA200 上方做多、下方做空。
Pine v6 strategy()。
RSI period 14。
条件变量:
rsiLong = ta.crossover(ta.rsi(close, 14), 30) and close > ta.ema(close, 200)
rsiShort = ta.crossunder(ta.rsi(close, 14), 70) and close < ta.ema(close, 200)
进场多:rsiLong
进场空:rsiShort
出场多:ta.rsi(close, 14) >= 50 or close < ta.ema(close, 200)
出场空:ta.rsi(close, 14) <= 50 or close > ta.ema(close, 200)
止损:固定 -1.5%(不用 ATR,因为这策略是震荡市用)。
不要用 alertcondition(),Pine 里也不要写 alert() 或 JSON(alert 由成交触发,JSON 我在 alert 窗口贴)。
每一个 strategy.entry/strategy.close/strategy.exit 都要设 alert_message,只放动作字、不放 secret:
多单进场 alert_message="buy"、空单进场 alert_message="sell"、明确调用 strategy.close/strategy.exit 的出场(止损、止盈、平仓)alert_message="close"。
翻仓请先 strategy.close(..., alert_message="close"),再用 strategy.entry 开新方向(alert_message="buy"/"sell");两张单成交 = 两则 alert,TVSBot 先完整平仓、再开新仓。
不要只靠相反方向的 strategy.entry 翻仓:TVSBot 每张单都用自己的 qty 下单,带固定保证金的 "sell" 不一定能把多单干净翻成空单(视持仓模式,可能只减仓一部分,或翻仓后数量不对)。
因为 {{strategy.order.action}} 只会送 buy/sell、不会送 close,
我在 alert 窗口贴的单行 JSON,action 要换成 {{strategy.order.alert_message}}:
{"secret":"<你的 webhook secret>","strategy":"<TVSBot 策略名称>","action":"{{strategy.order.alert_message}}","symbol":"BTCUSDT","exchange":"binance","market_type":"futures","qty_type":"margin_usdt","qty":50,"leverage":3}case study:没加 EMA200 过滤的版本回测 BTC 1H 过去 1 年胜率 47%、净利 -3%。加了之后胜率 51%、净利 +8.2%。 一条过滤线值得整支策略。
策略 4:Bollinger 带 + MACD 动量
人话:K 棒实体收破 Bollinger 上轨 + MACD 线在 0 轴之上 → 进多。下轨反向 → 空。 双重确认、过滤大部分杂讯。
Pine v6 strategy()。
BB(20, 2.0):用解构取值 [bbMiddle, bbUpper, bbLower] = ta.bb(close, 20, 2.0)
MACD(12, 26, 9)。
进场多:close > bbUpper AND MACD line > MACD signal AND MACD line > 0
进场空:close < bbLower AND MACD line < MACD signal AND MACD line < 0
(注意 ta.bb() 回传的是 [middle, upper, lower] tuple,顺序是中轨在前,
不能用索引取值,一定要用解构)
止损:ta.atr(14) × 1.5
止盈:ATR trailing stop using ta.atr(14) × 3
不要用 alertcondition(),Pine 里也不要写 alert() 或 JSON(alert 由成交触发,JSON 我在 alert 窗口贴)。
每一个 strategy.entry/strategy.close/strategy.exit 都要设 alert_message,只放动作字、不放 secret:
多单进场 alert_message="buy"、空单进场 alert_message="sell"、明确调用 strategy.close/strategy.exit 的出场(止损、止盈、平仓)alert_message="close"。
翻仓请先 strategy.close(..., alert_message="close"),再用 strategy.entry 开新方向(alert_message="buy"/"sell");两张单成交 = 两则 alert,TVSBot 先完整平仓、再开新仓。
不要只靠相反方向的 strategy.entry 翻仓:TVSBot 每张单都用自己的 qty 下单,带固定保证金的 "sell" 不一定能把多单干净翻成空单(视持仓模式,可能只减仓一部分,或翻仓后数量不对)。
因为 {{strategy.order.action}} 只会送 buy/sell、不会送 close,
我在 alert 窗口贴的单行 JSON,action 要换成 {{strategy.order.alert_message}}:
{"secret":"<你的 webhook secret>","strategy":"<TVSBot 策略名称>","action":"{{strategy.order.alert_message}}","symbol":"BTCUSDT","exchange":"binance","market_type":"futures","qty_type":"margin_usdt","qty":50,"leverage":3}策略 5:时段过滤(叠在现有策略上)
人话:策略只想在亚洲时段 08:00-16:00 UTC+8 跑(= UTC 0:00-08:00),欧美波动太大避开。
在我现有的 EMA Cross 策略上加时段过滤:
- 用 hour(time, 'UTC') 取得当前 UTC 小时
- 变量 inSession = hour >= 0 and hour < 8
- 进场条件多加一条 and inSession
- 持仓中不受时段限制,止损止盈照原本逻辑
- 不要改动原有的 strategy() 宣告与下单逻辑时段过滤是高胜率策略常见招式。叫 Claude 一次包进去比你自己查时区查半天快。
风控表达 — 4 句话决定能不能上线
Claude 写策略写得「能上真钱」,这 4 个风控指令一定要写在 prompt:
| 规则 | 写法 |
|---|---|
| 止损 | 每笔交易止损 = 进场价 ± ATR(14) × 1.5 |
| 部位大小 | 每笔交易最大风险 = 账户 1% |
| 最大持仓 | pyramiding=0,不加码,反向讯号自动翻仓 |
| Alert 内容 | {secret, strategy, action, symbol, exchange, market_type, qty_type:"margin_usdt", qty, leverage} |
把盯盘习惯翻成 Claude 听得懂的话
这是新手最大卡点:你知道你会在某个时刻进场,但讲不清楚。下面 5 组对照可以参考:
| 人话 | Claude prompt |
|---|---|
| 「K 棒长一根很大的红 K」 | 当根 K 棒 (close - open) > ta.atr(14) × 1.0 且 close < open |
| 「均线多头排列」 | EMA(20) > EMA(50) > EMA(200) 同时成立 |
| 「站上颈线」 | close 突破过去 N 根 K 棒最高 high(N 预设 20) |
| 「拉回到关键支撑」 | low 触及前 30 根低点 ±0.5%;定义「支撑」具体一点(前低 / swing low / 某 EMA) |
| 「量价齐扬」 | close > close[1] 且 volume > ta.sma(volume, 20) |
实战 case study:把「我看新闻跟单」变策略
一个朋友的真实案例。他平常会看新闻、看大 K 拉到突破近期高点就跟。我问他:「具体什么条件?」 他答不出来。所以我跟他一起做了下面这段拆解:
- 「大 K」量化:K 棒实体(close - open)大于过去 14 根的 ATR × 1.5。
- 「突破近期高点」量化:K 棒 high > 过去 50 根 high 的最大值(不含当前)。
- 「跟单」量化:下一根 K 开盘进场,不追。
- 「适时止损」加上:进场 K 棒 low 下方 1 倍 ATR。没有止盈,靠 trailing stop(ATR × 3)。
这段描述贴给 Claude,它输出的策略 BTC 1H 过去 6 个月回测:
Net Profit: +$4,820 (48.2% on $10K)
Total Trades: 31
Win Rate: 38.7% (12W / 19L)
Avg Win: +$543
Avg Loss: -$132
R:R: 4.1
Max Drawdown: -$1,210 (-12.1%)
Sharpe: 1.82Win rate 不高但 R:R 够大,净利为正。比他原本「看新闻跟单」凭感觉进场好得多 — 至少有明确的 entry/exit 规则,赔钱时知道为什么。
常见坑 — Claude 写 Pine 翻车 top 6
1. 叫 AI 在 strategy 里写 alertcondition() — 最安静的失败
这是所有坑里唯一「完全不报错」的:alertcondition() 只能用在 indicator。 TradingView 官方文档逐字写的是——放进 strategy 脚本「不会造成编译错误,但无法从中建立 alert」。 所以代码编译过、回测跑得好好的,你打开 Create Alert 对话框却永远找不到那个条件, 而且没有任何讯息告诉你为什么。 strategy 的 alert 由成交事件(order fill events)触发:Create Alert 时条件选你的策略, 在 Message 栏贴 TVSBot「TV 模板」的单行 JSON,action 用 {{strategy.order.action}}。alert() 虽然也能用, 但讯息写在 Pine 源代码里,webhook secret 就得跟着写进代码,不建议。细节见 AI 生成 Pine Script 到实盘的落差。
2. Pine 版本语法混用
没明讲版本 → Claude 偶尔写 study()(旧版用法)或漏掉 //@version=6 第一行。 一定要在 prompt 开头写「请用 Pine Script v6」。v5 到 v6 也有破坏性变更——例如官方 migration guide 逐字写的「下单函数的 when 参数在 v5 已标为弃用,到 v6 直接移除」——混版写出来的代码会在编译器直接报错。AI 生成 Pine Script 到实盘的落差那篇有完整的 v5→v6 变更清单。
3. Alert message 多行 → TradingView 拒收
贴进 TradingView alert 窗口的 JSON 一定要是单行有效 JSON: 多行、或少一个引号,webhook 都会回 400。最稳的做法是到 TVSBot 策略页按「TV 模板」直接复制, 不要请 Claude 重写。
4. ta. prefix 漏写
Pine v5 起强制要 ta. 前缀。Claude 偶尔会写 ema() 而非 ta.ema()。 编译器报 Could not find function or function reference 'ema'。 解:在 prompt 结尾加一句「所有内建函数请用 ta.* 完整前缀」。
5. strategy() vs indicator() 搞错
你要自动下单就要 strategy(),不能 indicator()。indicator() 没有 strategy.entry / strategy.close 函数。 Claude 写指标版会给你 plot(),看起来像有策略其实没下单逻辑。
6. 重绘(repaint)— 最隐蔽的坑
如果进场条件用了当前未收盘 K 棒的值,TV 在 K 棒收盘前后会闪烁。 回测看到「进场价就是高点」就是重绘。 解:所有条件用 [1] 索引前一根(已收盘)K 棒。 或在 strategy() 加 process_orders_on_close=true。
// ❌ 重绘:用当前未收盘 high
entrySignal = high > ta.highest(high, 20)
// ✅ 正确:用前一根 K 的条件
entrySignal = high[1] > ta.highest(high[1], 20)接到 TVSBot — 3 步走完
- 准备 TVSBot 的 alert JSON:到 TVSBot 策略页按「TV 模板」复制 (secret、策略名、交易所都已填好;动作选
{{strategy.order.action}};策略有出场就改选{{strategy.order.alert_message}},并让 Pine 里每个strategy.entry/strategy.close/strategy.exit都设alert_message("buy" / "sell" / "close"))。 现货策略的出场 alert_message 一定要送 "sell",不能送 "close":close 只用于永续(futures)。 自己改的话至少要有 secret、strategy、action、symbol、exchange、qty_type、qty。 symbol 写交易所格式(例如 BTCUSDT),exchange 要跟你 API key 所在的交易所一致。 - TV 设 Alert:图表右上时钟 → Add Alert → Condition 选你的 Pine 策略 (strategy() 的 alert 由成交触发)→ Message 栏贴上面那则单行 JSON。 出场若用
strategy.close/strategy.exit,{{strategy.order.action}}只会送 buy/sell、不会送 close, 请照 /docs/pine-templates 最后一个范本用alert_message送 close。 - 贴 TVSBot webhook URL:Notifications 分页 → 勾 Webhook URL → 贴 dashboard 给的 URL → Create。webhook secret 只填在这个 alert 窗口, 不要写进 Pine 源代码、不要贴给 Claude。
进阶:把整本策略书翻译成 Claude prompt
有些朋友手上有国外交易书(《海龟法则》、《市场奇才》)想实作。可以这样跟 Claude 对话:
我手上有《海龟法则》海龟系统 2(System 2)的描述:
- 进场:突破过去 55 天最高 high(多)/ 最低 low(空)
- 出场:突破过去 20 天反向(多单看 20 天最低)
- 止损:2N 法则(N = 20 日 ATR),单一风险限 2%
- 加码:每 0.5N 加 1 单位、最多 4 单位
- 部位上限:单市场 4、相关市场合计 6、总方向 12
请帮我把 System 2 写成 Pine v6 strategy()。
标的设定为 BTC/USDT 1D。pyramiding 设 4。
N 用 ta.atr(20) 计算。每笔风险 2%,用 strategy.percent_of_equity 对应。
保留所有原系统规则的 inline 注解,方便我之后微调。Claude 能直接把书本逻辑翻成 code,附完整注解。比你自己读完书再学 Pine 快数十倍。
常见 Q&A
Q:免费版额度够吗?
A:实测每天额度写 3-5 个策略没问题。如果你密集 iterate(一天改 20 次同支策略), 会需要付 Pro USD 20/月。
Q:Claude 写的策略赔钱怎么办?
A:先看 Strategy Tester 的回测结果。如果胜率 < 30% 且 R:R < 1:2,逻辑本身有问题, 别改 code 直接砍掉重练。如果胜率 > 40% 但净利为负,是手续费吃掉,加进场条件过滤、 减少交易次数。
Q:我可以把策略 prompt 给别人用吗?
A:可以。其实 TVSBot 市集就鼓励这个 — 你写好策略发布,订阅者跟单你抽 70% 分润。 看市集。
Q:Claude vs TradingView 内建 AI(Pine Genie)?
A:Pine Genie 是 TV 内建工具,免费但有额度。Claude 更灵活(你能整段策略 + 风控一次给), 但需要切换 tab。实务上:简单修改用 Pine Genie,复杂策略生成用 Claude。