thinkscript if语句失败

时间:2019-10-10 11:30:41

标签: thinkscript

在某些情况下,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语句中的哪一条将失败或不失败。

1 个答案:

答案 0 :(得分:0)

在少数情况下,可以使用if-expression代替if语句。但是,if表达式仅覆盖用例的一个子集,并且可能在扫描中以较低的性能执行。更重要的是

it defeats the purpose of the if statement in an important case