外观
限制
约 4129 字大约 14 分钟
简介
如果您使用Mine Script®开发复杂脚本,迟早会遇到我们设定的某些限制。本节概述了您可能遇到的限制类型。目前Mine Script程序员无法获取其脚本消耗资源的数据,我们希望未来能有所改进。
在此期间,当您规划大型项目时,最稳妥的方式是先进行概念验证,以评估脚本在项目后期遇到限制的可能性。
下文将介绍Mine Script环境中实施的各项限制。
时间
脚本执行
脚本编译完成后即可执行。有关触发脚本执行的事件列表,请参阅触发脚本执行的事件。脚本在数据集所有K线上执行的时间限制为40秒。
循环执行
任何循环在单根K线上的执行时间限制为500毫秒。嵌套循环的外层循环按单个循环计算,因此会先超时。请注意,即使某个循环在特定K线上的执行时间低于500毫秒限制,但其在整个数据集所有K线上的累计执行时间仍可能导致脚本超出总执行时间限制。例如,若在20,000根K线的数据集上每根K线执行400毫秒的循环,脚本将需要8000秒才能完成执行,这将超出总执行时间限制。
图表视觉效果
绘图限制
每个脚本最多允许64个绘图数量。生成绘图计数的函数包括:
- plot()
- plotarrow()
- plotbar()
- plotcandle()
- plotchar()
- plotshape()
- alertcondition()
- bgcolor()
- fill(),但仅当其颜色属于系列类型
以下函数不生成绘图计数:
一次函数调用最多可生成七个绘图计数,具体数量取决于函数及其调用方式。当您的脚本超出64个绘图计数的上限时,运行时错误消息将显示由您的脚本生成的绘图计数。达到该限制后,您可以通过在脚本中注释掉某行代码来判断该函数调用生成了多少绘图计数。只要您的脚本仍然报错,您就能观察到注释掉某行后实际绘图计数的减少情况。
以下示例展示了不同的函数调用及各自生成的绘图计数数量:
Mine Script®
已复制
此示例生成56个绘图计数。若我们再添加两个最后调用plotcandle()的实例,脚本将抛出错误提示当前使用了70个绘图计数,因为每次额外调用plotcandle()会生成7个绘图计数,56 + (7 * 2) 等于70。
线条、方框、折线和标签限制
与可覆盖图表整个数据集的绘图不同,脚本默认仅显示图表上最近的50条线条、方框、折线和标签。可通过脚本的indicator()或strategy()声明语句中的max_lines_count、max_boxes_count、max_polylines_count和max_labels_count参数,分别增加这些绘图类型的最大数量。线条、方框和标签ID的最大数量为500,折线ID的最大数量为100。
在此示例中,我们将图表上显示的最近标签最大数量设置为100:
Mine Script®
已复制
需要注意的是,当将绘图对象的任何属性设置为na时,其ID仍然存在,因此会计入脚本的绘图总数。为演示此行为,以下脚本在每个K线上绘制一个“买入”和“卖出”标签,其x值由longCondition和shortCondition变量确定。
当K线索引为偶数时,“买入”标签的x值为na;当K线索引为奇数时,“卖出”标签的x值为na。尽管此示例中max_labels_count设置为10,但我们可以看到图表上显示的标签少于10个,因为具有na值的标签也会计入总数:

Mine Script®
已复制
要显示所需数量的标签,我们必须消除不希望显示的标签绘图,而不是将其属性设置为na。以下示例使用if结构有条件地绘制“买入”和“卖出”标签,从而避免在不需要时创建新的标签ID:
Mine Script®
已复制
表格限制
脚本最多可在图表上显示九个表格,每个表格对应一个可能的位置:position.bottom_center、position.bottom_left、position.bottom_right、position.middle_center、position.middle_left、position.middle_right、position.top_center、position.top_left和position.top_right。当尝试在同一位置放置两个表格时,仅最新实例会显示在图表上。
request.*() 调用
调用次数
一个脚本最多可使用40次对request.*()命名空间函数的唯一调用。使用相同参数对同一request.*()函数的后续调用不视为唯一调用。此限制适用于所有request.*()函数,包括:
当脚本执行两个或更多相同的request.*()函数调用时,只有第一次调用计入此限制。重复调用不会计入,因为它们会复用第一次调用的数据,而非执行冗余请求。
以下脚本在for循环中使用相同参数调用了50次request.security()。尽管脚本包含超过40次request.*()调用,但不会引发错误,因为每次调用完全相同。在这种情况下,它会复用第一次迭代中request.security()调用的数据,用于所有后续迭代中的重复调用:
Mine Script®
已复制
此处我们修改了上述脚本,在每次迭代中使用不同的时间帧参数调用request.security(),这意味着所有50次调用现在都是唯一的。此时,脚本将在执行循环时达到request.*()调用限制并引发运行时错误,因为每次迭代都请求一个不同的数据集:
Mine Script®
已复制
盘中K线数
脚本可通过request.security()或request.security_lower_tf()函数检索最多200,000根盘中K线(较低时间帧K线),具体取决于用户权限。
request.*()函数通过calc_bars_count参数限制请求的数据量。若未指定此参数,则使用默认值10,0000根K线。如果权限允许更多,可通过传递更大值提高此限制。
100,000根盘中K线所覆盖的图表时间帧K线数因每根图表K线包含的盘中K线数量而异。例如,在60分钟图表上运行脚本时请求1分钟时间帧数据,意味着每根图表K线最多可包含60根盘中K线。此时,盘中K线请求覆盖的最小图表K线数为1,666根,因为100,000 / 60 = 1,666.67。但需注意,数据提供商可能不会报告每小时内的每一分钟数据。因此,此类请求覆盖的图表K线数可能更多,具体取决于可用数据。
元组元素限制
脚本中所有request.*()函数调用返回的元组元素总数不得超过127个。当所有request.*()调用的合并元组大小超过127个元素时,可改用用户自定义类型(UDT)来请求更多数值。
以下示例概述了此限制及解决方法。第一个request.security()调用表示使用包含128个元素的元组作为expression参数。由于元素数量超过127,这将导致错误。
为避免错误,我们可以将这些相同值作为UDT对象的字段,并将其ID传递给expression参数:
Mine Script®
已复制
脚本大小与内存
每个作用域变量数量
脚本在每个作用域中最多可包含1,000个变量。Mine脚本始终包含一个全局作用域(由非缩进代码表示),并可能包含零个或多个局部作用域。局部作用域是由缩进代码表示的段落在函数和方法内执行的过程,以及if、switch、for、for…in和while结构(允许包含一个或多个局部代码块)。每个局部代码块计为一个局部作用域。
使用?:三元运算符的条件表达式分支不计为局部代码块。
作用域数量
脚本中的总作用域数量(包括其全局作用域以及用户自定义函数、方法、条件结构中的每个局部作用域)不得超过550个。
需要注意的是,request.security()、request.security_lower_tf()函数会在另一个上下文中复制计算其expression参数值所需的作用域。每次调用这些request.*()函数所产生的作用域也会计入脚本的作用域限制。
例如,假设我们创建了一个脚本,其中全局变量依赖于300个if结构的局部作用域。该脚本的总作用域数量为301个(1个全局作用域 + 300个局部作用域):
Mine Script®
已复制
由于总作用域数量在限制范围内,脚本将成功编译。现在,假设我们调用request.security()从另一个上下文计算x的值并绘制该值。这种情况下,由于x的值依赖于脚本的所有作用域,实际作用域数量将翻倍:
Mine Script®
已复制
我们可以通过将if代码块封装到用户自定义函数中来解决此问题,因为函数作用域仅计为一个嵌入作用域:
Mine Script®
已复制
集合
Mine Script集合(数组、矩阵和映射)最多可包含100,000个元素。映射中的每个键值对包含两个元素,这意味着映射最多可包含50,000个键值对。
其他限制
最大回溯K线数
使用[]历史引用运算符引用过去值时,取决于Mine Script运行时维护的历史缓冲区大小,该缓冲区限制为最多5000根K线。
最大前瞻K线数
使用xloc.bar_index定位绘图时,可使用大于当前K线的K线索引值作为x坐标。最多可引用未来500根K线。
此示例展示如何在input.int()函数调用中使用[maxval]参数来限制用户定义的前瞻绘图K线数,确保其永不超出限制:
Mine Script®
已复制
图表K线数
图表上显示的K线数取决于该品种和时间帧的可用历史数据量,以及您持有的账户类型。当所需历史数据可用时,最小图表K线数为:
会员:20,000根历史K线 普通用户:5,000根历史K线
回测中的交易订单
回测策略时最多可下9,000笔订单。