如何优化Pine Script双参数函数调用代码以解决内存超限问题?
Pine Script 内存超限警告的优化方案
你编写了一个接收_src(源数据)和_lbL(左侧蜡烛数量)两个参数的Pine Script函数function_Macd,分别传入10和20作为_lbL调用函数后用or合并结果,但脚本出现「Memory limits exceeded. Study allocates: 1.1 times more than allowed.」的内存超限警告。原始代码如下:
lbR = 4 rangeUpper = 60 rangeLower = 5 _inRange(cond) => = ta.barssince(cond == true) rangeLower <= bars and bars <= rangeUpper function_Macd(_src, _lbL) => plFound = na(ta.pivotlow(_src, _lbL, lbR)) ? false : true phFound = na(ta.pivothigh(_src, _lbL, lbR)) ? false : true oscLL = _src[lbR] < ta.valuewhen(plFound, _src[lbR], 1) and _inRange(plFound[1]) priceHL = close[lbR] > ta.valuewhen(plFound, close[lbR], 1) bull = priceHL and oscLL and plFound result = function_Macd(macd, 10) or function_Macd(macd, 20)
核心优化思路
内存超限的主要原因是两次调用function_Macd时,重复执行了ta.pivotlow、ta.valuewhen这类需要回溯大量历史数据的函数,额外占用了内存。我们可以通过抽离公共计算逻辑、移除无用代码来降低内存消耗:
- 移除无用变量:原始代码中
phFound完全未被使用,直接删除减少内存分配 - 抽离公共计算:将两次调用中重复的计算只执行一次,再分别处理
_lbL=10和_lbL=20的情况 - 修正并简化辅助函数:修复
_inRange的语法错误,减少函数调用开销
优化后的代码
lbR = 4 rangeUpper = 60 rangeLower = 5 // 修正并简化范围判断函数 _inRange(cond) => bars = ta.barssince(cond == true) rangeLower <= bars and bars <= rangeUpper // 重构逻辑:先计算公共部分,再分别处理两种_lbL情况 getBullSignal(_src, lbLList) => // 分别计算两种lbL对应的pivotlow标记 plFound_10 = not na(ta.pivotlow(_src, lbLList[0], lbR)) plFound_20 = not na(ta.pivotlow(_src, lbLList[1], lbR)) // 公共计算:只获取一次最近pivotlow对应的源数据和收盘价 last_pl_src = ta.valuewhen(plFound_10 or plFound_20, _src[lbR], 1) last_pl_close = ta.valuewhen(plFound_10 or plFound_20, close[lbR], 1) // 生成_lbL=10的信号 oscLL_10 = _src[lbR] < last_pl_src and _inRange(plFound_10[1]) priceHL_10 = close[lbR] > last_pl_close bull_10 = priceHL_10 and oscLL_10 and plFound_10 // 生成_lbL=20的信号 oscLL_20 = _src[lbR] < last_pl_src and _inRange(plFound_20[1]) priceHL_20 = close[lbR] > last_pl_close bull_20 = priceHL_20 and oscLL_20 and plFound_20 // 合并两个信号 bull_10 or bull_20 // 调用函数,传入需要的_lbL取值列表 result = getBullSignal(macd, [10, 20])
额外优化细节
- 将
na(...) ? false : true简化为not na(...),逻辑更简洁且减少计算步骤 - 公共数据(
last_pl_src、last_pl_close)只计算一次,避免重复回溯历史数据,大幅降低内存占用 - 合并信号计算逻辑,减少函数重复调用的额外开销
内容的提问来源于stack exchange,提问作者fred lopez
相关产品推荐
相关产品推荐

