TradingView Webhook 自动化交易的仓位怎么定?
百分比配置 vs 固定数量的取舍
假设你的回测用 10 万美元 initial_capital 跑,default_qty_type 设成 strategy.percent_of_equity、 数值 10(即 10%)。你实际的交易所账户里只有 2,000 美元。 当 alert 触发、webhook 打到你的执行服务器,实际会发送多少数量?
答案是:TradingView 会用「这根 K 线当下的 strategy.equity」 的 10% 去算这笔单的数量——而 strategy.equity 是 Pine 策略 完全在 TradingView 服务器上模拟出来的一个数字。它不知道你真实账户里 只有 2,000 美元。Alert 里发送的数量,是根据回测的内部模拟余额算的, 不是你交易所里的余额。
策略声明里的那一行,就是这件事的关键——而它正好是「你不讲,AI 就会替你默默决定」 的那种细节。所以这篇不讲语法,只讲两件事:怎么跟 AI 讲清楚你要哪一种配置方式, 以及拿到代码后、真钱进场前该怎么验收。下面有可以直接复制的指令。
default_qty_type 和 strategy.equity怎么运作。但官方文档从头到尾没有任何一处讨论这跟你交易所真实余额的关系 ——因为两者本来就没有联动。这个落差,正是把 TradingView alert 接到实盘下单时,仓位大小最容易出问题的根本原因。决定你下单大小的,就是那一个设置
声明策略时,strategy() 函数的 default_qty_type 参数只有三个合法值,而 default_qty_value 在每一种底下的 意思都不一样。在你拿到的代码里把那一行找出来——它通常就在最上面几行—— 对着下面这张表看一眼。验收就这么一件事。
| default_qty_type | default_qty_value 的单位 | 精确语义 |
|---|---|---|
strategy.fixed | 手数 / 股数 / 张数 | 默认值。每次进场用固定的手数/股数/张数。 |
strategy.cash | 账户货币现金金额 | 以 strategy.account_currency 的现金金额计算。 数量换算方式是 default_qty_value / 收盘价——TradingView 官方文档给的示例:收盘价 $5、数值设 50, 数量 = 50 / 5 = 10。 |
strategy.percent_of_equity | 百分比(0–100) | 用 strategy.equity——策略当下的模拟权益—— 的某个百分比去决定这笔单的大小。 |
来源:Pine Script Language Reference Manual v6,strategy() 与三个 default_qty_type 常量(查证日期 2026 年 7 月)。
还有一个细节值得知道:如果 strategy.entry() 或 strategy.order() 调用时明确指定了非 na 的 qty 参数,这个值会完全覆盖该笔单的 default_qty_type/default_qty_value 设置 ——strategy 层级的默认值只在调用本身没给 qty 时才生效。 TradingView 官方文档用一个示例演示这件事:策略声明了 default_qty_type = strategy.cash,但 entry 调用仍自己 带了 qty,结果那笔单完全不理会 strategy 层级的默认设置。
这个「覆盖」规则在验收 AI 产出时特别重要:最上面那行声明写的是一回事, 底下的下单调用可能悄悄做另一回事。所以直接问它一句就好:「这支脚本里有没有任何 entry 或 order 调用自己带了 qty?列出来。」
为什么「权益的 10%」不是你钱的 10%
官方定义,逐字引用自 Pine Script 语言参考手册——放在这里是让你看得懂,不是要你背:
strategy.equity = strategy.initial_capital + strategy.netprofit + strategy.openprofitnetprofit 是已平仓交易的累计已实现盈亏;openprofit 是目前未平仓持仓的浮动盈亏。 两者都会随着每笔交易平仓、每次价格变动而改变,这使得 strategy.equity 是一个持续变动的序列——几乎每根 K 线 都可能是不同的值。
这也是为什么 percent_of_equity 这种配置方式在结构上 必然会复利。default_qty_value 设成 10,永远代表 「这根 K 线当下 strategy.equity 的 10%」。 连续几笔盈利平仓之后,equity 变大,同样的 10% 换算出来的绝对数量 也跟着变大;亏损之后则反过来缩小。TradingView 官方使用手册里的 Commission Demo 示例策略,用的正是这个设置(default_qty_value = 2, default_qty_type = strategy.percent_of_equity),就是用来展示「仓位大小随 equity 变动而缩放」这个效果。
strategy.equity 跟你交易所 真实账户余额之间的关系。根据上面的定义——initial_capital 是你自己在 strategy() 声明里填的任意数字,而 netprofit/openprofit 完全是在 TradingView 服务器上模拟出来的——可以合理推得 strategy.equity 跟你 真实账户余额没有任何联动。这是由官方定义推导出的结论, 不是 TradingView 自己白纸黑字写出来的一句话。你该指定哪一种,各要付出什么代价
两种配置方式都不是「正确答案」,它们优化的目标不一样。与其猜哪一种 在某次回测里看起来比较漂亮,不如把取舍摊开来看。这张表可以当菜单看: 你想要哪一列,就在指令里把它讲出来。
| percent_of_equity | fixed | |
|---|---|---|
| 下单量会随 equity 变动而缩放 | ||
| 下单量的绝对数字事先就能预测 | ||
| 依赖一个你在执行当下无法控制的内部模拟余额 | ||
| 账户余额变大或变小时需要自己手动调整数量 | ||
| 模拟余额跟真实余额差距大时,回测与实盘下单容易脱节 |
这张表要看的是「各自依赖什么」:percent_of_equity 会缩放, 但缩放的基准是 TradingView 内部模拟的一个数字;fixed 可预测, 代价是不会自己随账户调整。这个依赖关系,决定了你 webhook payload 里那个数字 是不是真的跟你以为的意思一样。
两段指令:一段拿来要、一段拿来验
要代码的时候贴这段
下面这版是「用固定数量、把数量决定权留给执行端」——也就是不依赖模拟余额的那种配置。 你要的是相反的方向,就把配置那一段换掉;重点是你要讲明白你要哪一种、以及为什么, 而不是让它替你选:
帮我写一支 TradingView 用的 Pine Script v6 策略,它会触发 webhook 到我的实盘交易所账户。
策略逻辑:[用白话描述你的开仓与平仓条件]
仓位配置——这一段没有商量余地:
- 用 default_qty_type = strategy.fixed,default_qty_value = 1。
不要用 strategy.percent_of_equity。原因:percent_of_equity 是拿 strategy.equity
去算下单量,而那是回测的模拟余额,跟我交易所账户的实际大小不一样。
我不要回测算出来的数字跑到我的交易所去。
- 除非我明说,否则任何 strategy.entry() 或 strategy.order() 调用都不要自己带 qty 参数。
如果你哪里带了,要主动告诉我。
- Alert message 必须是单行、合法的 JSON,内容包含方向({{strategy.order.action}})
以及以下字段,多的不要:
[贴上你接收端要求的字段清单]
不要放 {{strategy.order.contracts}}——数量由我的执行服务器决定,不是 TradingView。
最后用一行一句告诉我:你用的 default_qty_type 是哪个、在这个设置下 default_qty_value
代表什么意思、以及有没有任何下单调用覆盖掉它们。配置那一段要把「原因」写进去,不是为了客气——是为了避免它好心地把你换回 percent_of_equity,只因为那样回测曲线比较好看。
拿到代码之后贴这段
把代码贴回去,加上这四题。其中三题的答案,你看完上面几节就已经知道了—— 这正是重点:
这是我的策略。在你动手改任何东西之前,先回答我:
1. default_qty_type 设成什么?在这个设置下,default_qty_value 代表什么单位?
2. 有没有任何 strategy.entry() 或 strategy.order() 调用自己带了 qty?
列出来——那些会覆盖掉 strategy 层级的默认值。
3. 如果我用 initial_capital = 100000 跑这支策略,但我交易所账户里实际只有 2000,
最后发送进 {{strategy.order.contracts}} 的数字是根据哪一个算出来的?
4. 我的 alert message 里,有哪些字段是从回测模拟余额推导出来的、
而不是来自我的真实账户?
[把你的脚本贴在这里]第 3 题是关键。会从 initial_capital 一路推给你看数量怎么来的, 说明它懂这个情况;回答「策略会用你那 2,000 去算」的,就是不懂—— 那条回复里其他内容你都得重新检查一遍。
怎么跟 AI 交代 alert message 里要放什么
以下是 TradingView 官方文档列出、专属于 strategy order fill event 的 placeholder——这是唯一能在 alert message 里取得数量信息的地方。 你不是要自己手写这些,而是在指令里点名你要哪几个, 再检查回来的东西有没有多放、少放:
| Placeholder | 代表的意思 |
|---|---|
{{strategy.order.contracts}} | 该笔成交单的手数/股数 |
{{strategy.position_size}} | 触发当下的目前持仓大小,带正负号(+多 / −空) |
{{strategy.market_position_size}} | 目前持仓绝对值大小 |
{{strategy.prev_market_position_size}} | 前一个持仓绝对值大小 |
{{strategy.order.action}} | "buy" 或 "sell" |
{{strategy.order.price}} | 成交价 |
{{strategy.order.alert_message}} | 读取该笔 strategy.entry()/strategy.exit()/strategy.order() 调用的 alert_message 参数值 |
仅限 strategy order fill event 使用——不能用在 alertcondition() 或独立的 alert() 消息里。来源:Pine Script 使用手册,Strategies / Strategy alerts(查证日期 2026 年 7 月)。
{{strategy.order.alert_message}} 有一点值得特别提醒: 官方文档明确讲,这个 placeholder 只有在该笔下单调用确实传了 alert_message 参数时才会被替换成你的自定义文字。 如果策略里有多个 strategy.entry()/strategy.order() 调用,只有部分用了 alert_message,那些没用到的下单事件 触发时,这个 placeholder 会变成空字符串。
这也可以变成一句具体、可验收的要求:「如果你在 alert message 里用到 {{strategy.order.alert_message}}, 请确认这支脚本里每一个下单调用都有传 alert_message 参数。」JSON payload 里出现空字段这种事,通常不会在你检查的时候出问题,会在半夜出问题。
一、代码里的
alert() 调用——消息是程序当场拼出来的, 你不需要在对话框里再打一次。二、下单函数的
alert_message= 参数——这段文字只有在成交事件 触发、且消息里用了 {{strategy.order.alert_message}} 时才会被读出来。三、TradingView「Create Alert」对话框的 Message 栏——这是唯一能用
{{strategy.*}} placeholder 的地方,前提是这个 alert 建立在 strategy 上。界面上的逐步操作(图表右上时钟 → Add Alert → Condition 选你的策略 → Notifications 勾 Webhook URL)在 用 Claude 写 Pine 那篇有完整走过一遍。
唯一一个 AI 没办法帮你做的决定
既然 percent_of_equity 是拿模拟余额去算的,而 fixed/cash 完全不知道你的账户大小, 任何 TradingView 接交易所的自动化都会遇到一个实际的设计决定: 最终下单数量,是由 TradingView 端决定,还是执行端决定?
这正是两层问题交汇的地方。以上讲的都是 TradingView 怎么决定 alert 里要放哪个数字。等这个数字——或只是一个方向信号——打到执行服务器之后, 还有第二层、完全独立的问题:这台服务器怎么把它变成一笔真正的交易所 下单,包括杠杆跟保证金、名义仓位大小之间的关系。这第二层我们在 qty_type 语义陷阱那篇文章 里有详细拆解——等你想清楚「谁来算数量」之后,值得接着看那篇, 它讲的是这个数字送到之后会发生什么事。
举例来说,TVSBot 的执行端是在下单当下才解析数量,提供 5 种计算方式 (fixed / usdt / percent / margin_pct / margin_usdt),而不是单纯转发一个 从回测模拟 equity 算出来的数字。其中 percent 与 margin_pct 会在下单当下查询你交易所真实、当下的可用余额再换算;usdt 与 margin_usdt 用实时报价把你指定的 USDT 金额换成数量;fixed 则直接按你给的币数量下单。
要确认实际会解析出什么数量,可以先用 dry-run 模式跑一次,用虚拟资金看发出的数字对不对。 账户层级的风控设置(单笔金额上限、单笔百分比上限、最大持仓数、日亏损熔断、最大杠杆) 加上一键 kill switch,则是不管你用哪种配置逻辑都会生效的一层防护。
常见问题
percent_of_equity 会自动考虑我交易所里的真实余额吗?
strategy.percent_of_equity 是用 strategy.equity 的百分比去算下单量,而官方定义 strategy.equity = initial_capital + netprofit + openprofit——这三个值全部是 Pine 策略内部模拟出来的,不是查询你交易所 账户得到的。TradingView 官方文档没有描述任何读取真实账户 余额的机制。我可以直接叫 AI 用我交易所的真实余额去算仓位吗?
strategy.equity 算仓位的策略——顶多是把 initial_capital 填成今天跟你账户差不多的数字, 但模拟 equity 一开始复利,两边又会拉开。 要用「当下的真实余额」算仓位,这件事只能发生在 alert 之后的执行端。如果我把 default_qty_type 设成 strategy.fixed,数量会自己变吗?
strategy.fixed 用的是 default_qty_value 定义的固定手数/股数/张数, 不会随账户表现而自动变大或变小,除非你自己去改这个输入值。我可以在 strategy.entry() 里直接指定 qty,不靠 default_qty_type 吗?
strategy.entry() 或 strategy.order() 只要给了非 na 的 qty 参数,这个值会完全优先于 strategy 层级的 default_qty_type/default_qty_value 设置,只作用于那一笔单。哪个 placeholder 能拿到实际成交的数量?
{{strategy.order.contracts}} 对应该笔单实际 成交的手数/股数。这只在 strategy order fill event 的 alert 里才有,不能用在 alertcondition() 或独立的 alert() 消息里。数量该在 TradingView 端算、还是执行端算比较好?
initial_capital 差得越远, 这点就越重要。Get started
TVSBot 是非托管的 TradingView → 交易所自动下单桥接,支持 7 家交易所,用你自己的 API key 跟资金。百分比类的计算方式会在下单当下查你真实的实时余额,并提供 dry-run 测试与账户层级风控。
免费开始使用