ThinkScript, если заявление провал - PullRequest
0 голосов
/ 10 октября 2019

Сценарий мыслителя , если оператор не может переходить, как ожидалось, в некоторых случаях. Следующий тестовый пример может быть использован для воспроизведения этой ошибки / дефекта.

Короче говоря, возможный обходной путь в некоторых случаях заключается в использовании выражения if, которое является функцией, которая может быть медленнее,потенциально может привести к тайм-ауту выполнения скрипта при сканировании.

Эта довольно неприятная ошибка в thinkcript не позволяет мне писать некоторые сканы и изучает так, как мне нужно.

Ниже приведен пример кода, который показывает проблемуна графике.

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 акций, установите пользовательские временные рамки:

с 10/09/19 по 10/09/18, период агрегации 1 день.

Цель сценария - найти низкое значение 4,25 на 14/14/2019.

Я действительно знаю, что для этого есть разные методы, например * 1018. *.

Давайте не будем обсуждать альтернативные методы достижения цели, чтобы найти минимальные альтернативы для прилагаемого сценария.

Потому что я не прошу помощи в достижении цели,Я сообщаю об ошибке, и я хочу знать, что идет не так и, возможно, как это исправить. Другими словами, поиск минимума здесь - это всего лишь пример, чтобы сделать скрипт более легким для подражания. Это может быть что-то еще, что нужно, чтобы скрипт вычислялся.

Пожалуйста, позвольте мне описать сценарий.

Сначала он делает некоторое сглаживание с помощью скользящей средней. Результат:

def output;

Затем сценарий определяет расстояние от правого края, чтобы мы могли работать со смещениями:

def rightOffset;

Затем сценарий создает таблицу соответствия:

def lookup;

script getMinValueBetween {} - небольшая функция, которая динамически находит минимум между двумя позициями смещения. Это необходимо, потому что GetMinValueOffset() не принимает динамические параметры.

Тогда у нас есть скрипт buildValue {}

Здесь происходит ошибка. Этот скрипт выполняется по правому краю.

buildValue {} выполняет косвенный поиск следующим образом:

Сначала он переходит к поиску, где находит значение 53 при lookupPosn = 23.

С 53, если находит минимум между смещением 53 и 0, вызывая функцию скрипта getMinValueBetween(). Он сохраняет значение в def lowAtIndirectLookupPosn;

Как видите, это действительно очень просто - всего 38 строк кода!

Проблема в том, что lowAtIndirectLookupPosn содержит неправильное значение,как если бы неправильная ветвь оператора if была выполнена.

plot testResult должен дать минимум 4.25. Вместо этого он выдает close[offsetLast], что составляет 6,26.

Честно говоря, это катастрофа, потому что невозможно предсказать, какой из операторов if в вашей программе потерпит неудачу.

1 Ответ

0 голосов
/ 10 октября 2019

В ограниченном числе случаев вместо выражения if можно использовать выражение if. Однако выражение if охватывает только подмножество вариантов использования и может выполняться с более низкой производительностью при сканировании. Что еще более важно,

это противоречит цели оператора if в важном случае

...