文档

Deepwick Script 参考

Deepwick Script 是 Deepwick 图表和回测所用的语言。它运行 Pine Script 的一个子集:ta.*、math.*、str.*、input.*、plot* 和 strategy.* 的多数函数都与 Pine 中完全一致,不支持的代码行会标出行号和列号。这一页列出了引擎目前支持的一切,以及它不支持什么。

第一次用 Deepwick?先看这份分步指南: 如何免费回测一个 Pine Script 策略.

在做一个会写 Deepwick Script 的 AI 助手? 把这份参考当成一份 Markdown 文档.

更新时间:

语言

Deepwick Script 运行 Pine Script 的一个子集,包括枚举、用户自定义类型、方法和 map;//@version 这一行不会被强制校验。脚本按 K 线逐根运行,从最老的一根到最新的一根,每个变量都保留自己的历史。

语法作用
x = expr / x := expr声明一个变量,然后用 := 重新赋值。名字前面可以加一个可选的类型(int、float、bool、string、color、series、simple、const、line、label)。
var / varip在第一根 K 线上初始化一次,之后各根 K 线沿用这个值。由于脚本运行在已收盘的 K 线上,varip 的行为和 var 一样。
x[n]历史运算符:n 根之前 x 的值(第一根之前为 na)。
if / else条件块,缩进四个空格。if 也可以当作表达式使用。
cond ? a : b三元运算符。
switch多路分支,可以带一个用于比较的值,也可以不带。
for i = a to b [by step]计数循环。支持 break 和 continue。
while cond条件成立时持续循环。
f(x, y) => expr用户自定义函数,可以写在一行,也可以写成缩进块并返回最后一个表达式。和 Pine 一样,每个调用位置各自保留 ta.* 的状态。
[a, b] = f()元组:函数可以返回多个值,ta.macd() 和 ta.bb() 这类内置函数就是这样。
and / or / not逻辑运算符。算术:+ - * / %;比较:== != < <= > >=。

声明

语法作用
indicator(title, shorttitle, overlay, precision)声明一个指标:它在图上绘制,没有可回测的对象。study() 作为别名也可以。
strategy(title, overlay, initial_capital, default_qty_type, default_qty_value, commission_type, commission_value, slippage, pyramiding)声明一个策略。默认值:initial_capital 100000、每单 1 张合约、手续费 0、滑点 0 个 tick、金字塔加仓 1。process_orders_on_close 等其他参数会被忽略。

输入

输入会显示在编辑器旁边和指标的设置里,这样不用改代码就能调整它们。

语法作用
input.int(defval, title, minval, maxval, step)整数。
input.float(defval, title, minval, maxval, step)小数。
input.bool(defval, title)复选框。
input.string(defval, title, options)文本,或者一组选项。
input.session(defval, title)一个交易时段,比如 "0930-1600",或者一组星期,比如 "23456"。把它传给 session.ismarket() 和其它 session.* 判断。
input.source(defval, title)一个价格来源:open、high、low、close、hl2、hlc3、ohlc4 或 hlcc4。
input.color(defval, title)取色器。
input(defval, title)通用输入,类型由默认值决定。

K 线数据与时间

时间是 UTC 毫秒。hour() 和其它时间函数可以传入一个时间;hour() 还可以传入一个时区,取自固定的偏移量列表,不含夏令时。

语法作用
open, high, low, close, volume当前 K 线的价格和成交量。
hl2, hlc3, ohlc4, hlcc4常用的价格均值。
bar_index, last_bar_index当前 K 线的序号(0 是最老的一根)和最后一根的序号。
time, time_closeK 线的开盘和收盘时间。作为函数 —— time("D")、time(timeframe.period, "0000-0900:23456", "UTC") —— 返回包含当前这根的高周期 K 线的开始(或结束)时间;如果这根 K 线在时段之外,则返回 na。时段写法:"HHMM-HHMM",也可以跨夜,逗号分隔多个窗口,冒号后可跟星期(1 = 周日 … 7 = 周六),以及 "24x7"。
timeframe.change(timeframe)在每个新周期的第一根 K 线上为真,例如 timeframe.change("D") 在每天的第一根上为真(每周从周一开始)。
timestamp(timezone?, year, month, day, hour, minute, second)由各部分组成毫秒时间,或由日期字符串得到:timestamp("2026-01-05T09:30:00Z")。
dayofweek.sunday … dayofweek.saturday用来和 dayofweek(1 … 7)比较的星期常量。
session.ismarket, isfirstbar, islastbar, ispremarket, ispostmarket时段状态。这里的市场几乎全天交易,所以每根 K 线都在交易时段内;isfirstbar / islastbar 标出每个 UTC 日的第一根和最后一根。
year, month, weekofyear, dayofmonth, dayofweek, hour, minute, secondK 线时间的日历字段;也可以传入一个时间来调用,例如 hour(time, "America/New_York")。dayofweek:1 = 周日 … 7 = 周六。
barstate.isfirst, islast, isnew, isconfirmed, ishistory, isrealtime脚本在 K 线历史中的位置。
timeframe.period, multiplier, isintraday, isdaily, isweekly, ismonthly图表的周期。
syminfo.ticker, tickerid, mintick, pointvalue图表的品种、最小价格变动和一个点的价值。

技术分析(ta.*)

和 Pine 一样,每个调用位置各自保留状态:写在两行里的两次 ta.ema() 调用是两个互不相干的平均值。K 线不够多之前,结果是 na。

语法作用
ta.sma(source, length)简单移动平均。
ta.ema(source, length)指数移动平均。
ta.rma(source, length)Wilder 移动平均,RSI 和 ATR 用的是它。
ta.wma(source, length)加权移动平均。
ta.vwma(source, length)成交量加权移动平均。
ta.hma(source, length)Hull 移动平均。
ta.linreg(source, length, offset)线性回归线的数值。
ta.vwap(source)成交量加权平均价,每天 00:00 UTC 重新开始。
ta.rsi(source, length)相对强弱指数,0 到 100。
ta.macd(source, fastlen, slowlen, siglen)返回 [macd, signal, histogram]。
ta.stoch(source, high, low, length)随机指标 %K,0 到 100。
ta.cci(source, length)商品通道指数。
ta.mfi(series, length)资金流量指数。
ta.wpr(length)威廉指标 %R,-100 到 0。
ta.dmi(diLength, adxSmoothing)返回 [+DI, -DI, ADX]。
ta.supertrend(factor, atrPeriod)返回 [supertrend, direction];上涨趋势中 direction 为 -1,下跌趋势中为 1。
ta.sar(start, inc, max)抛物线 SAR。
ta.mom(source, length)动量:source 减去 length 根之前的 source。
ta.roc(source, length)变动率,以百分比表示。
ta.change(source, length)与 length 根之前的差值(默认为 1)。
ta.tr / ta.tr(handle_na)真实波幅。
ta.atr(length)平均真实波幅(Wilder)。
ta.bb(series, length, mult)布林带:返回 [middle, upper, lower]。
ta.bbw(series, length, mult)布林带宽度:(upper - lower) / middle。
ta.kc(series, length, mult)肯特纳通道:返回 [middle, upper, lower],使用真实波幅的 EMA。
ta.stdev(source, length, biased)标准差。
ta.variance(source, length, biased)方差。
ta.dev(source, length)平均绝对偏差。
ta.median(source, length)中位数。
ta.highest(source, length) / ta.highest(length)最近 length 根里的最高值(默认为 high)。
ta.lowest(source, length) / ta.lowest(length)最近 length 根里的最低值(默认为 low)。
ta.highestbars(source, length)相对最高值的偏移:0 或负数。
ta.lowestbars(source, length)相对最低值的偏移:0 或负数。
ta.rising(source, length)如果 source 高于它之前 length 个值中的每一个,则为真。
ta.falling(source, length)如果 source 低于它之前 length 个值中的每一个,则为真。
ta.crossover(source1, source2)在 source1 上穿 source2 的那根 K 线上为真。
ta.crossunder(source1, source2)在 source1 下穿 source2 的那根 K 线上为真。
ta.cross(source1, source2)任意方向的交叉都为真。
ta.pivothigh(source, leftbars, rightbars)枢轴高点的价格,要等枢轴之后 rightbars 根才能确定,在此之前是 na。source 可选(默认为 high)。
ta.pivotlow(source, leftbars, rightbars)枢轴低点的价格,要等枢轴之后 rightbars 根才能确定,在此之前是 na。source 可选(默认为 low)。
ta.valuewhen(condition, source, occurrence)在最近第 occurrence 根满足 condition 的 K 线上,source 的取值。
ta.barssince(condition)自 condition 上一次为真以来经过的 K 线数。
ta.cum(source)从第一根 K 线开始的累计值。

其他周期(request.*)

高周期是用图表自己的 K 线拼出来的,所以它不需要引擎手里没有的数据。高周期一根 K 线的值,要等它收盘之后的图表 K 线上才看得见:一根 4 小时 K 线永远无法从自己内部读到,这正是回测保持诚实的原因。

语法作用
request.security(symbol, timeframe, expression)在同一个品种的高周期上运行 expression,返回最后一个已收盘的值。它只对图表自己的品种有效(也可以是 syminfo.tickerid 或空品种);换成别的品种会返回 na,因为引擎手里始终只有图表的 K 线。周期写法接受 Pine 的("60"、"240"、"D"、"W"、"M")和 Deepwick 的("1h"、"4h"、"1d")。expression 可以是一次 ta.* 调用,这时会在高周期序列上求值。在这样一根 K 线收盘之前,返回 na。
request.security(..., lookahead)接受但忽略。打开 lookahead_on 会让回测读到正在形成的高周期 K 线,那就是偷看未来;引擎从不偷看。gaps 只影响 K 线内部的绘制,这里用不上。

策略(strategy.*)

市价单在下一根 K 线开盘时成交。止损单和限价单沿着这根 K 线成交:开盘价,然后是离开盘更近的那个极值,再是另一个极值,最后是收盘价。如果价格跳空越过订单,就按开盘价成交。每次成交都收手续费;滑点适用于市价单和止损单。

语法作用
strategy.entry(id, direction, qty, limit, stop, comment)开仓或加仓;没有指定 limit 或 stop 时就是市价单。
strategy.order(id, direction, qty, limit, stop, comment)参数和 strategy.entry() 相同。
strategy.exit(id, from_entry, qty_percent, profit, limit, loss, stop, trail_points, trail_offset, comment)针对某次入场的止盈、止损和移动止损:止盈和止损以 tick 计,limit 和 stop 用价格。trail_points 是距已到过的最好价格的距离(以 tick 计),trail_offset 是移动止损生效之前需要先走出的盈利(以 tick 计)。止损只会向对你有利的方向移动,而且只在已收盘的 K 线上移动,所以任何一根 K 线都不可能触发它自己的最高价所设下的止损。
strategy.close(id, comment, qty_percent)在下一根 K 线以市价平掉一次入场。
strategy.close_all(comment)平掉所有持仓。
strategy.cancel(id) / strategy.cancel_all()撤掉未成交的订单。
strategy.position_size, position_avg_price当前持仓(多头为正,空头为负)及其均价。
strategy.opentrades.entry_bar_index(n), entry_price, entry_time, entry_id, size, profit, commission, max_runup, max_drawdown第 n 笔未平仓交易的详情(0 为最老的一笔);没有则为 na。空头的 size 为负数。例如持有 10 根 K 线后平仓:bar_index - strategy.opentrades.entry_bar_index(0) >= 10。
strategy.closedtrades.entry_bar_index(n), exit_bar_index, entry_price, exit_price, entry_time, exit_time, entry_id, size, profit, commission, max_runup, max_drawdown第 n 笔已平仓交易的详情(0 为最老的一笔;最后一笔是 strategy.closedtrades - 1)。
strategy.equity, netprofit, openprofit, grossprofit, grossloss, initial_capital账户数值。
strategy.closedtrades, opentrades, wintrades, losstrades交易笔数。
strategy.long, strategy.short方向。
strategy.fixed, strategy.cash, strategy.percent_of_equitydefault_qty_type 的取值。
strategy.commission.percent, cash_per_order, cash_per_contractcommission_type 的取值。

绘图与提醒

语法作用
plot(series, title, color, linewidth, style)在图表上或独立窗格中绘制一条序列。
plotshape(series, title, style, location, color, text)在 series 为真的那些 K 线上绘制图形。
plotchar(series, title, char, location, color)在 series 为真的那些 K 线上绘制字符。
hline(price, title, color, linestyle)固定水平上的水平线。
fill(plot1, plot2, color)在两条绘图线或两条 hline 之间填充。
bgcolor(color)给 K 线背景上色。
barcolor(color)给 K 线本身上色。
alertcondition(condition, title, message)声明一个条件,可以把它变成邮件、Telegram、Discord 或 webhook 提醒。
plot.style_*line、linebr、stepline、histogram、columns、circles、cross、area。
hline.style_*solid、dashed、dotted。
shape.*triangleup, triangledown, arrowup, arrowdown, circle, xcross, cross, diamond, square, flag, labelup, labeldown.
location.*abovebar、belowbar、top、bottom、absolute。
size.*auto、tiny、small、normal、large、huge。可以接受,但图形只按一种大小绘制。

线与方框

语法作用
line.new(x1, y1, x2, y2, extend, color, style, width)在两个 K 线序号和两个价格之间画一条线,返回它的 id。
line.set_x1, set_y1, set_x2, set_y2, set_xy1, set_xy2, set_color, set_style, set_width修改一条线。
line.delete(id)删除一条线。
box.new(left, top, right, bottom, border_color, bgcolor, extend)画一个矩形,返回它的 id。
box.set_left, set_top, set_right, set_bottom, set_bgcolor, set_border_color, set_extend修改一个方框。
box.delete(id)删除一个方框。
line.style_*, box.style_*solid、dashed、dotted。
extend.*none、left、right、both。

数学、字符串与颜色

语法作用
math.abs, ceil, floor, round(number, precision), sign, sqrt, exp, log, log10, pow(base, exponent)算术。
math.max(...), math.min(...), math.avg(...)对任意多个值。
math.sum(source, length)最近 length 根 K 线的总和。
math.pi, math.e常量。
na, na(x), nz(x, replacement), fixnan(x)缺失值、对它的判断、对它的替换,以及最后一个非 na 的值。
int(x), float(x), bool(x)类型转换。
str.tostring(value, format), str.format(text, ...), str.length(s), str.contains(s, part)字符串。str.format 用参数替换 {0}、{1}…。
color.new(color, transp), color.rgb(red, green, blue, transp)构造一种颜色;透明度从 0 到 100。
color.*red, green, blue, orange, yellow, purple, aqua, lime, fuchsia, teal, maroon, navy, olive, gray, silver, white, black.

数组(array.*)

语法作用
array.new_float, new_int, new_bool, new_string, new_color, new_line, new_box, new_label, new_table(size)创建一个数组。
array.get, set, insert, push, pop, shift, unshift读取和修改元素。
array.size, first, last, sum, avg, min, max, stdev长度与统计。

Map 与用户自定义类型

支持用户自定义类型和 `map.<fn>` 集合。两者都是顶层声明;作用于某个值的方法用 `obj.method(args...)` 的写法。

语法作用
enum Name Member Member = N ...顶层枚举声明。没有写值的成员从 0 开始自动递增;显式值可以是数字或字符串。在任何表达式位置都可以用 `Name.Member` 访问。枚举值就是普通的数字(或字符串),所以可以直接和比较运算符配合,也可以不转换就传给 `int()`。
type Name field1 field2: int field3 = default顶层用户自定义类型。字段一行一个;`: type` 和 `= default` 这两部分为了向前兼容被接受,但目前还没有校验。用 `Type.new(arg1, arg2, ...)` 构造,用 `instance.field` 读取字段。
m = map.new<int, float>()创建一个空的 map。类型参数 `<K, V>` 会被接受,但运行时忽略。
m = map.put(m, key, value)设置一个键。返回这个 map,所以调用可以链式书写或重新赋值。
v = map.get(m, key)读取一个值。键不存在时返回 na。
n = map.size(m)条目数量。
keys = map.keys(m), values = map.values(m)以 Pine 数组返回键或值(按插入顺序)。
map.contains(m, key), map.remove(m, key)成员判断和删除。两者都返回这个 map。

还不支持

调用引擎不认识的函数时,脚本会带着「Unknown function」以及行号和列号停下来。

语法作用
label.new(), table.new()还不可用。线和方框可以。
import, matrix.*, array.new<type>()库、矩阵和带类型的数组构造函数还没有实现。
strategy.risk.*风控规则(max_position_size、max_intraday_loss、max_drawdown、allow_entry_in)还不支持。strategy.exit() 里的移动止损支持:用 trail_points 和 trail_offset。

常见问题

Deepwick Script 和 Pine Script 是一样的吗?

不是。它是 Deepwick 自己的引擎,运行 Pine Script 的一个子集:就是这一页上的函数。ta.*、math.*、str.*、input.*、plot* 和 strategy.* 的大部分调用都能照常运行;不支持的代码行会标出行号和列号。Deepwick 与 TradingView 无隶属关系;Pine Script 是 TradingView, Inc. 的商标。

Deepwick Script 支持 Pine Script 的哪些功能?

Deepwick Script 运行 Pine Script 的一个子集,包括枚举、用户自定义类型(`type`)、方法声明和 `map.*` 集合。还没有实现的有:库(`import`)、`matrix.*` 以及带类型的 `array.new<type>()` 构造函数;编辑器会用准确的行号和列号指出来。//@version 这一行不会被强制校验。把脚本粘进编辑器就能看到哪些行会运行。

Deepwick 支持 request.security() 吗?

支持,但只针对图表自己品种的高周期。request.security(syminfo.tickerid, "240", close) 返回最近一根已收盘的 4 小时 K 线的收盘价,expression 也可以是一次 ta.* 调用。换成别的品种仍然返回 na:引擎手里始终只有图表的 K 线,一个看起来合理但错误的数字比没有数字更糟。

为什么 request.security() 在最开始的几根 K 线上返回 na?

因为还没有任何高周期 K 线收盘。4 小时 K 线只有在它收盘之后的那根图表 K 线上才读得到,而这正是让回测读不到正在形成的 K 线的机制。一旦有一根收盘,这个值就会一直重复到下一根收盘为止。

回测里策略订单是怎么成交的?

市价单在下一根 K 线开盘时成交。止损单和限价单沿着这根 K 线成交(开盘价、离开盘更近的极值、更远的极值、收盘价),价格跳空越过订单时按开盘价成交。每次成交都收手续费,市价单和止损单还会计入滑点,都由 strategy() 设定,默认都是 0。

脚本在哪里运行?

在图表上,在你的浏览器里,基于图表已加载的 K 线运行。保存的回测在 Deepwick 的服务器上运行,最多 5,000 根 K 线。