在某些情况下,thinkscript if statement无法分支。以下测试用例可用于重现此错误/缺陷。
长话短说,在某些情况下,一种可行的解决方法是使用if-expression这个函数,该函数可能会更慢,从而可能导致扫描中脚本执行超时。
thinkscript中的这个非常讨厌的错误使我无法进行一些扫描和研究所需的方式。
以下是一些示例代码,它们在图表上显示了问题。
input price = close;
input smoothPeriods = 20;
def output = Average(price, smoothPeriods);
# Get the current offset from the right edge from BarNumber()
# BarNumber(): The current bar number. On a chart, we can see that the number increases
# from left 1 to number of bars e.g. 140 at the right edge.
def barNumber = BarNumber();
def barCount = HighestAll(barNumber);
# rightOffset: 0 at the right edge, i.e. at the rightmost bar,
# increasing from right to left.
def rightOffset = barCount - barNumber;
# Prepare a lookup table:
def lookup;
if (barNumber == 1) {
lookup = -1;
} else {
lookup = 53;
}
# This script gets the minimum value from data in the offset range between startIndex
# and endIndex. It serves as a functional but not direct replacement for the
# GetMinValueOffset function where a dynamic range is required. Expect it to be slow.
script getMinValueBetween {
input data = low;
input startIndex = 0;
input endIndex = 0;
plot minValue = fold index = startIndex to endIndex with minRunning = Double.POSITIVE_INFINITY do Min(GetValue(data, index), minRunning);
}
# Call this only once at the last bar.
script buildValue {
input lookup = close;
input offsetLast = 0;
# Do an indirect lookup
def lookupPosn = 23;
def indirectLookupPosn = GetValue(lookup, lookupPosn);
# lowAtIndirectLookupPosn is assigned incorrectly. The if statement APPEARS to be executed
# as if indirectLookupPosn was 0 but indirectLookupPosn is NOT 0 so the condition
# for the first branch should be met!
def lowAtIndirectLookupPosn;
if (indirectLookupPosn > offsetLast) {
lowAtIndirectLookupPosn = getMinValueBetween(low, offsetLast, indirectLookupPosn);
} else {
lowAtIndirectLookupPosn = close[offsetLast];
}
plot testResult = lowAtIndirectLookupPosn;
}
plot debugLower;
if (rightOffset == 0) {
debugLower = buildValue(lookup);
} else {
debugLower = 0;
}
declare lower;
要准备股票ADT的图表,请设置自定义时间范围:
19/09/19至18/09/19,汇总期1天。
该脚本的目的是在2019年8月14日找到4.25的低值。
我确实知道在Thinkscript中有多种方法可以做到这一点,例如GetMinValueOffset()
。
让我们不要讨论实现目标的其他方法,以找到所附脚本的替代方法。
因为我不是在寻求帮助以实现目标。我正在报告一个错误,我想知道出了什么问题以及可能如何解决。换句话说,在此处找到最低值只是使脚本易于遵循的一个示例。可能还需要脚本来进行计算。
请让我描述一下脚本。
首先,它使用移动平均线进行平滑。结果是:
def output;
然后脚本定义了距右边缘的距离,因此我们可以使用偏移量:
def rightOffset;
然后该脚本将建立一个查找表:
def lookup;
脚本getMinValueBetween {}
是一个小功能,可以动态地找到两个偏移位置之间的低点。之所以需要它是因为GetMinValueOffset()
不接受动态参数。
然后我们有了脚本buildValue {}
这是发生错误的地方。该脚本在右边缘执行。
buildValue {}
进行如下间接查找:
首先进入查找,在lookupPosn
= 23处找到值53。
对于53,通过调用脚本函数getMinValueBetween()
在偏移53和0之间找到低点。
它将值存储在def lowAtIndirectLookupPosn;
如您所见,这确实非常简单-只有38行代码!
问题是lowAtIndirectLookupPosn
包含错误的值,就像执行了if语句的错误分支一样。
plot testResult
应该推出最低价4.25。而是显示close[offsetLast]
,即6.26。
坦白地说,这是一场灾难,因为无法预测程序中的任何if
语句中的哪一条将失败或不失败。
答案 0 :(得分:0)
在少数情况下,可以使用if-expression代替if语句。但是,if表达式仅覆盖用例的一个子集,并且可能在扫描中以较低的性能执行。更重要的是
it defeats the purpose of the if statement in an important case