Вводный курс по языку PINE Inventor Quantitative

Создано: 2022-05-30 16:23:43, Обновлено: 2022-09-28 17:10:21
comments   0
hits   8860

n error! plot(ma)


При выполнении этого сценария в Trading View будет создаваться ошибка компиляции, потому что:`adjustedLength = lenInput * factor`После умножения получаем`series int`Тип (серия), однако`ta.ema`Второй параметр функции не поддерживает этот тип. Однако на FMZ нет таких строгих ограничений, и вышеуказанный код может работать нормально.

Давайте рассмотрим, как используются различные операторы.

***

##### Оператор присвоения

Существует два типа операторов присвоения:`=`、`:=`Мы видели это в некоторых примерах в начале урока.

`=`Оператор для присвоения значения переменной при инициализации или декларировании.`=`Инициализация, заявление, присвоение значения после переменной начинается с этого значения на каждом последующем Bar. Все это являются действительными заявлениями:

a = close // 使用内置变量赋值给a b = 10000 // 使用数值赋值 c = “test” // 使用字符串赋值 d = color.green // 使用颜色值赋值 plot(a, title=“a”) plot(b, title=“b”) plotchar(true, title=“c”, char=str.tostring©, color=d, overlay=true)


Уведомление`a = close`Присвоенное выражение, где переменная a на каждом Bar является текущей ценой закрытия этого Bar ((close) ⋅ другие переменные`b`、`c`、`d`Не изменяется, может быть протестировано в системе отклика на FMZ, результаты можно увидеть на рисунке.

`:=`Используется для переоценки существующих переменных.`:=`Оператор используется для изменения уже заявленных и инициализированных значений переменных.
При использовании`:=`Операторы, присваивающие значение неизменной, которая не инициирована или не объявлена, вызывают ошибки, например:

```pine
a := 0

Так что…:=Операторы присвоения обычно используются для переоценки существующих переменных, например:

a = close > open 
b = 0 
if a
    b := b + 1

plot(b)

Если быclose > open(т.е. текущий BAR - солнечная линия), а переменная a - истинное значение ((true)) ¦ выполняет код в локальном блоке if-заявленияb := b + 1, используя оператор присвоения:=Переоценить b, добавив 1 ◦, а затем использовать функцию plot, чтобы начертить на графике значения переменной b на каждом BAR в временной последовательности, соединенной в линию ◦.

Предполагаем ли мы, что если появится солнечный луч BAR, то b будет продолжать накапливать 1? Конечно нет, здесь мы не используем никаких ключевых слов, когда объявляем переменную b и инициализируем ее как 0.b=0Это выполняется на каждом BAR, так что вы можете видеть, что результат этого кода - это перенастройка b на 0 каждый раз, если a - истинное значение, то это соответствуетclose > openТак что в этом раунде выполнения кода b будет складывать 1, в графическом рисунке функции b будет 1, но в следующем раунде выполнения кода b будет переоценен в 0. Это также место, где начинающим языку Pine легко попасть в яму.

Если говорить об ассигнованиях, то здесь необходимо расширить объяснение двух ключевых слов:varvarip

  • var

Это ключевое слово, которое мы уже видели и использовали в предыдущих уроках, но не обсуждали подробно. Давайте посмотрим на его описание:

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

Мы все равно используем этот пример, но мы используем его, когда мы присваиваем b.varКлючевые слова:

  a = close > open 
  var b = 0 
  if a
      b := b + 1

  plot(b)

varКлючевое слово позволяет переменной b выполнять только первоначальное первое присвоение, после чего каждый раз при выполнении логики стратегии b не будет перенастраиваться на 0, так что из рисованной во время выполнения линии можно наблюдать b, то есть количество иных BAR, появившихся при измерении текущей K-линии BAR.

Изменные в var-декларации могут быть написаны не только в глобальном масштабе, но и в блоках кода, например в этом примере:

  strategy(overlay=true)
  var a = close
  var b = 0.0
  var c = 0.0
  var green_bars_count = 0
  if close > open
      var x = close
      b := x
      green_bars_count := green_bars_count + 1
      if green_bars_count >= 10
          var y = close
          c := y
  plot(a, title = "a")
  plot(b, title = "b")
  plot(c, title = "c")

Переменная ‘a’ сохраняет закрытие первого столбца серии. Переменная ‘b’ сохраняет ценовую оценку на закрытие первой в серии ценовой палки на зеленый кремний. Переменная ‘c’ сохраняет закрытие десятой в серии зеленой картошки.

  • varip

varipЭто ключевое слово мы увидели впервые, и мы можем посмотреть на его описание:

varip ((var intrabar persist) - ключевое слово, используемое для распределения и разовой инициализации переменных. Оно похоже на ключевое слово var, но переменные с использованием декларации varip сохраняют свои значения между обновлениями K-линий в реальном времени.

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

  strategy(overlay=true)

  // 测试 var varip
  var i = 0
  varip ii = 0  

  // 将策略逻辑每轮改变的i、ii打印在图上
  plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red)
  plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green)  

  // 每轮逻辑执行都给i、ii递增1
  i := i + 1
  ii := ii + 1

Этот тест-код работает по-разному в модели закрытия цены и в модели реального времени:

Модели цены в реальном времени: Помните, как мы говорили ранее о том, что время выполнения стратегии делится на историческую фазу BAR и реальную фазу BAR?varvaripОбъявленные переменныеiiiВ каждом раунде выполнения кода стратегии выполняется увеличивающая операция. Таким образом, можно увидеть, что цифры, отображаемые на линии KBAR в результате обратной измерения, увеличиваются по 1. Когда историческая фаза K-линии заканчивается, начинается фаза K-линии в реальном времени.i := i + 1иii := ii + 1Все выполняется один раз。 отличие состоит в том, что ii изменяется каждый раз。 хотя i изменяется каждый раз, но при следующем раунде логики стратегии выполнения возвращается к предыдущему значению ((помнишь механизм прокрутки, описанный нами в предыдущей главе “Модельное выполнение”?)), до тех пор, пока текущая KBAR не будет завершена, чтобы обновить определённое значение i ((то есть при следующем раунде логики стратегии выполнения больше не будет возвращаться к предыдущему значению。). Таким образом, можно увидеть, что переменная i по-прежнему увеличивается на 1 на каждый BAR。 но переменная ii накапливается на BAR несколько раз。

Модель закрытия цен: Поскольку модель закрытия цены выполняет стратегическую логику только после того, как каждый K-линия BAR заканчивается. Таким образом, в модели закрытия цены этапы исторической K-линии и этапы реальной K-линии, переменные заявлений var, varp в приведенном выше примере показывают совершенно то же самое, увеличивая 1 на каждую K-линию BAR.


Оператор
Оператор проиллюстрировать
+ Добавление
- Снижение
* Умножение
/ Отмена закона
% Поиск примеров

+-Операторы могут быть использованы как двоичные операторы, так и как единичные операторы. Другие алгоритмические операторы могут быть использованы только как двоичные операторы. Если они будут использоваться как единичные операторы, они будут ошибаться.

1 , числовой оператор обе стороны являются числовыми типами, результатом является числовой тип, целое или число плавающих точек в зависимости от результата операции. 2, если число операций - это строка, то оператор - это+, вычисляется как строка, число преобразуется в строку, затем строка склеивается вместе. Если это другой арифметический оператор, то он пытается преобразовать строку в числовое значение, а затем работает. 3, если число операций na, то вычислим нулевое значение na, и при печати на FMZ будет показано NaN.

a = 1 + 1 
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na 

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)   
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN

Пинский язык на FMZ немного отличается от Пинского языка на Trading View. Пинский язык на FMZ не очень требователен к типам переменных. Например:

a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A" 

plot(a)
plot(b)
plot(c)

На FMZ это возможно, но в trading view будет сообщаться о ошибке типа. Для операторов алгоритма, когда операционные числа на обеих сторонах являются строками, система будет рассчитывать строки после их преобразования в числовые значения. Если нецифровые строки не могут быть рассчитаны, система будет рассчитывать нулевые значения na.


Оператор сравнения

Операторы сравнения являются двоичными операторами.

Оператор проиллюстрировать
< меньше
> Больше чем
<= меньше, чем равно
>= Больше, чем равно
== Равным
!= Неравенство

Пример теста:

a = 1 > 2 
b = 1 < 2 
c = "1" <= 2 
d = "1" >= 2 
e = 1 == 1 
f = 2 != 1 
g = open > close 
h = na > 1 
i = 1 > na

runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)   
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false

Как видно, сравнительный оператор очень прост в использовании, но это также один из наиболее часто используемых операторов при написании стратегий. Можно сравнивать как числовые значения, так и встроенные переменные, напримерcloseopenждать. Как и в случае с операторами, в отличие от Pine в Trading View, в FMZ нет особо строгих типов требований, поэтому такие заявленияd = "1" >= 2На FMZ не будет сообщений об ошибках, при выполнении сначала будет преобразована строка в числовое значение, а затем сравнивается. На Trading View будет сообщений об ошибках.


Логические операторы
Оператор Кодовые знаки проиллюстрировать
Нет, нет not Одномерный оператор, не оператор
и and Бинарный оператор, с (и)
или or Бинарные операторы, или операции

Если говорить о логических операторах, то обязательно надо говорить о таблице истинных значений. Как и в школе, только здесь мы тестируем и учимся в системе обратной связи:

a = 1 == 1  // 使用比较运算符构成的表达式,结果为布尔值
b = 1 != 1
c = not b   // 逻辑非操作符
d = not a   // 逻辑非操作符

runtime.log("测试逻辑操作符:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)

runtime.log("测试逻辑操作符:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)

runtime.error("stop")

Для того, чтобы не замечать влияние непрерывного печати информации в системе отслеживания, мы используемruntime.error("stop")Сказание после выполнения одного печати, бросается аномальная ошибка, чтобы остановить отсчет, после чего можно наблюдать за выходной информацией, можно обнаружить, что содержание печати и таблицы истинных значений фактически одинаковы.


Трехмерный оператор

Использование треугольных операторов? :Трехмерные выражения с комбинацией операционных чиселcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseМы уже знакомы с этим в предыдущих уроках. Так называемые триединые выражения, триединые операторы означают, что их число операций составляет три.

condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseВнутренниеconditionЭто критерий, если значение истинного выражения:valueWhenConditionIsTrueЕслиconditionВыражение, используемое в качестве гипотезы, имеет значениеvalueWhenConditionIsFalse

Пример, который, хотя и не имеет практического применения, может быть полезен для демонстрации:

a = close > open
b = a ? "阳线" : "阴线"
c = not a ? "阴线" : "阳线"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

Если вы столкнетесь со звездочкой, это не будет иметь значения! Тривиальные выражения также могут быть встроены, мы уже делали это в предыдущих уроках.

a = close > open
b = a ? math.abs(close-open) > 30 ? "阳线" : "十字星" : math.abs(close-open) > 30 ? "阴线" : "十字星"
c = not a ? math.abs(close-open) > 30 ? "阴线" : "十字星" : math.abs(close-open) > 30 ? "阳线" : "十字星"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)

Это равносильно тому, чтоcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseВvalueWhenConditionIsTruevalueWhenConditionIsFalseВместо этого используются другие тривиальные выражения:


Исторический оператор

Использование оператора истории[], ссылаясь на исторические значения в временной последовательности. Эти исторические значения являются значениями переменных на K-линии BAR перед текущей K-линией BAR во время выполнения сценария.[]Оператор используется после вызова переменной, выражения, функции.[]Значение в этой квадратной скобке - это отклонение исторической информации от текущей K-линии BAR. Например, если я хочу указать закрытие цены на последнюю K-линию BAR, я напишу:close[1]

В предыдущих уроках мы видели, как пишется:

high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)

[]Оператор может быть использован только один раз на одном и том же значении, так что это будет ошибочно:

a = close[1][2]   // 错误

Возможно, вы увидите здесь, что некоторые из ваших учеников говорят, что оператор[]Это то, что мы используем для серийных структур, которые выглядят почти так же, как и массивы! В следующей статье мы примером покажем, что в языке Пайн есть разница между сериями и массивами.

strategy("test", overlay=true)

a = close
b = close[1]
c = b[1]

plot(a, title="a")
plot(b, title="b")
plot(c, title="c")

Хотяa = close[1][2]Я не могу сказать, что это было бы неправильно, но:

b = close[1]
c = b[1]

Если мы рассмотрим это как обычный массив, то мы не ошибимся.b = close[1]После присвоения значения b должно быть числовым, ноc = b[1],b может быть снова использовано с использованием исторического оператора для ссылки на историческую величину. Видно, что в языке Pine понятие серии не так просто, как массив. Можно понимать как историческую величину на верхней строке close Bar (присвоение значения b), b также является структурой временной последовательности (time series), которая может продолжать ссылку на историческую величину.

Мы можем перетащить диаграмму на левую сторону и обнаружить, что в первой K-линии значения b и c являются пустыми ((na). Это связано с тем, что когда сценарий выполняется на первой K-линии BAR, исторические значения, ссылающиеся на один или два цикла вперед, отсутствуют. Поэтому нам нужно постоянно следить при написании стратегии, будет ли ссылаться на пустые значения при ссылке на исторические данные.nanzВстроенные функции, которые мы рассматривали в предыдущих уроках,nznaФункции, помните, в какой главе?) конкретно рассматривают ситуации с пустыми значениями, например:

close > nz(close[1], open)    // 当引用close内置变量前一个BAR的历史值时,如果不存在,则使用open内置变量

Это обработка возможных цитируемых нулевых значений ((na)).


Приоритет оператора

Мы уже выучили много операторов языка Пайн, которые формируют выражения с помощью различных комбинаций операторов и чисел. Что же делать с приоритетом этих операций при вычислении в выражениях?

Приоритеты Оператор
9 []
8 +- и `not
7 */%
6 Двузначный оператор +-
5 ><>=<=
4 ==!=
3 and
2 or
1 ?:

Если вы хотите заставить произвести операцию сначала на какой-то части выражения, используйте()Замкнутое выражение, которое требует, чтобы его часть была обработана первой.

Переменные

Заявление переменной

Мы уже изучали концепцию кода идентификатора кода, кода идентификатора кода - это имя переменной, которое дается переменной. Так что переменная - это идентификатор сохраненной величины.

  • Форма заявления: Первое, что пишется при декларировании переменной, - это “мода декларирования”. Существует три вида моделей декларирования переменной:
    1. Использование ключевых словvar
    2. Использование ключевых словvarip
    3. Ничего не пишите.

varvaripКлючевые слова мы уже изучали в предыдущем разделе “Операторы присвоения” и не будем их здесь обсуждать. Если модель объявления переменной ничего не пишет, например:i = 1, как мы уже говорили ранее, такие объявленные переменные и присвоенные значения выполняются на каждой K-линии BAR.

  • тип Язык Pine на FMZ не является строгим в отношении требований к типам и, как правило, может быть отменен. Однако, для совместимости со сценарием в Trading View, можно также использовать тип при декларировании переменных. Например:
  int i = 0 
  float f = 1.1

Типы в Trading View требуют более строгих требований, и если использовать следующий код в Trading View, то будет ошибка:

  baseLine0 = na          // compile time error!
  • Идентификатор Идентификатор - это имя переменной, название идентификатора уже упоминалось в предыдущих главах, и его можно посмотреть: https://www.fmz.com/bbs-topic/9390#%E6%A0%87%E8%AF%86%E7%AC%A6

В заключение, заявление о переменной может быть написано так:

// [<declaration_mode>] [<type>] <identifier> = value 
   声明模式             类型     标识符       = 值

Здесь используется оператор присвоения:=При объявлении переменной присваивается значение. При присваивании значение может быть строкой, числом, выражением, вызовом функции,ifforwhileилиswitchСтруктура и т. д. (эти структурные ключевые слова и фразы будут подробно описаны в следующих уроках, но мы уже узнали об этом в предыдущих уроках.)

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

Входные функции:

input函数,参数defval、title、tooltip、inline、group

Функция input в FMZ немного отличается от функции в Trading View, но она используется в качестве ввода значения параметров стратегии. Давайте рассмотрим пример использования функции input в FMZ:

param1 = input(10, title="参数1名称", tooltip="参数1的描述信息", group="分组名称A")
param2 = input("close", title="参数2名称", tooltip="参数2的描述信息", group="分组名称A")
param3 = input(color.red, title="参数3名称", tooltip="参数3的描述信息", group="分组名称B")
param4 = input(close, title="参数4名称", tooltip="参数4的描述信息", group="分组名称B")
param5 = input(true, title="参数5名称", tooltip="参数5的描述信息", group="分组名称C")

ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)

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

Вводный курс по языку PINE Inventor Quantitative

Мы расскажем о некоторых основных параметрах входных функций:

  • defval: по умолчанию для параметров политики в качестве параметров вводной функции, поддерживает встроенные переменные, значения и строки языка Pine
  • title: Название параметра, показываемого в интерфейсе стратегии на диске / в реверсе.
  • tooltip: Пособие к параметру политики, показывающее текстовую информацию о его установке, когда мышь подвешена над параметром политики.
  • group: название группы параметров стратегии, которую можно дать группе параметров。

Помимо объявления и присвоения отдельных переменных, в языке Пайн существует также написание для объявления и присвоения целого ряда переменных:

[变量A,变量B,变量C] = 函数 或者 ```if```、 ```for```、```while```或```switch```等结构

Самый распространенный из них - это то, что мы используем.ta.macdФункция вычисляет MACD-индикатор, и, поскольку MACD-индикатор - это многолинейный индикатор, вычисляет три группы данных. Поэтому можно написать:

[dif,dea,column] = ta.macd(close, 12, 26, 9)

plot(dif, title="dif")
plot(dea, title="dea")
plot(column, title="column", style=plot.style_histogram)

Мы можем легко нарисовать MACD-графику с помощью вышеприведенного кода. Встроенные функции могут возвращать не только несколько переменных, но и пользовательские функции могут возвращать несколько данных.

twoEMA(data, fastPeriod, slowPeriod) =>
    fast = ta.ema(data, fastPeriod)
    slow = ta.ema(data, slowPeriod)
    [fast, slow]

[ema10, ema20] = twoEMA(close, 10, 20)
plot(ema10, title="ema10", overlay=true)
plot(ema20, title="ema20", overlay=true)

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

[ema10, ema20] = if true
    fast = ta.ema(close, 10)
    slow = ta.ema(close, 20)
    [fast, slow]

plot(ema10, title="ema10", color=color.fuchsia, overlay=true)
plot(ema20, title="ema20", color=color.aqua, overlay=true)

Условная структура

Некоторые функции не могут быть записаны в блоках локального кода с условным разветвлением, в основном следующие:

barcolor(), fill(), hline(), indicator(), plot(), plotcandle(), plotchar(), plotshape()

На Trading View компилируется сообщение об ошибке. На FMZ ограничения не столь строгие, но также рекомендуется писать в соответствии с правилами на Trading View. Например, хотя в FMZ не сообщается об ошибке, но не рекомендуется писать так.

strategy("test", overlay=true)
if close > open 
    plot(close, title="close")
else 
    plot(open, title="open")

if-соглашение

Пример:

var lineColor = na

n = if bar_index > 10 and bar_index <= 20
    lineColor := color.green
else if bar_index > 20 and bar_index <= 30
    lineColor := color.blue
else if bar_index > 30 and bar_index <= 40
    lineColor := color.orange
else if bar_index > 40
    lineColor := color.black
else 
    lineColor := color.red
    
plot(close, title="close", color=n, linewidth=5, overlay=true)
plotchar(true, title="bar_index", char=str.tostring(bar_index), location=location.abovebar, color=color.red, overlay=true)

Примечание: выражение, используемое для определения, возвращает значение бура. Обратите внимание на сжатие.

x = if close > open
    close
plot(x, title="x")

Поскольку, когда K-линия BAR является отрицательной линией, то есть close < open, если выражение после фразы false, то локальный блок if не выполняется. В этом случае нет никакой ветви else, и фраза if возвращает na. x присваивается как na.

Справка switch

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

1, как и в случае с if, ссылка switch возвращает значение. В отличие от других языковых ссылок, ссылочная структура выполняет только один локальный блок в своем коде, поэтому объявление break не требуется (то есть не нужно писать ключевые слова break и т. д.). 3. Каждая ветвь switch может быть записана как локальный блок, и последняя строка этого локального блока является возвращаемым значением (((который может быть элементом значений)). Если ни один из ветвей не выполнен, то возвращается na。 4., расположение выражения в структуре коммутатора, можно написать строку, переменную, выражение или вызов функции. 5. switch позволяет задать возвращаемое значение, которое используется в качестве значения по умолчанию, когда в структуре нет других условий выполнения.

switch состоит из двух форм, и мы рассмотрим примеры, чтобы понять, как их использовать.

1, с выражениемswitchПример:

// input.string: defval, title, options, tooltip
func = input.string("EMA", title="指标名称", tooltip="选择要使用的指标函数名称", options=["EMA", "SMA", "RMA", "WMA"])

// input.int: defval, title, options, tooltip
// param1 = input.int(10, title="周期参数")
fastPeriod = input.int(10, title="快线周期参数", options=[5, 10, 20])
slowPeriod = input.int(20, title="慢线周期参数", options=[20, 25, 30])

data = input(close, title="数据", tooltip="选择使用收盘价、开盘价、最高价...")
fastColor = color.red
slowColor = color.red

[fast, slow] = switch func
    "EMA" =>
        fastLine = ta.ema(data, fastPeriod)
        slowLine = ta.ema(data, slowPeriod)
        fastColor := color.red
        slowColor := color.red
        [fastLine, slowLine]
    "SMA" =>
        fastLine = ta.sma(data, fastPeriod)
        slowLine = ta.sma(data, slowPeriod)
        fastColor := color.green
        slowColor := color.green
        [fastLine, slowLine]
    "RMA" =>
        fastLine = ta.rma(data, fastPeriod)
        slowLine = ta.rma(data, slowPeriod)
        fastColor := color.blue
        slowColor := color.blue
        [fastLine, slowLine]
    =>
        runtime.error("error")
        
plot(fast, title="fast" + fastPeriod, color=fastColor, overlay=true)
plot(slow, title="slow" + slowPeriod, color=slowColor, overlay=true)

Ранее мы изучали функцию input, а здесь мы продолжаем изучать две функции, похожие на input:input.stringinput.intфункция. input.stringВместо этого используйте другие символы.input.intФункция возвращает целое число. В нашем примере мы добавили новую функцию.optionsИспользование параметровoptionsПараметры могут быть перенесены в массив, состоящий из выборных значений. Например, в примереoptions=["EMA", "SMA", "RMA", "WMA"]иoptions=[5, 10, 20](Обратите внимание, что один из них является типом строки, а другой - типом числа). Таким образом, вместо того, чтобы вводить конкретные числа, контроллер в интерфейсе политики становится выдвижной панелью, выбирая опции, предоставленные в параметре options.

Значение переменной func представляет собой строку, где переменная function является выражением switch (может быть переменной, вызовом функции, выражением), для определения того, какая часть switch выполняется. Если переменная func не может совпадать с выражением на любой части switch (то есть равнозначна), то выполняется блок кода по умолчанию.runtime.error("error")Функция приводит к тому, что политика бросает исключения и останавливается.

В нашем тестовом коде мы не включили после runtime.error после последней строки в блоке кода по умолчанию в switch[Для совместимости кода na, na] с возвращаемыми значениями в trading view необходимо учитывать эту проблему, если тип не соответствует, то он будет ошибаться. Однако на FMZ, поскольку нет строгих требований к типам, такой совместимый код может быть пропущен. Поэтому на FMZ не нужно учитывать тип совместимости if, switch branch возвращаемых значений.

strategy("test", overlay=true)
x = if close > open
    close
else
    "open"
plotchar(true, title="x", char=str.tostring(x), location=location.abovebar, color=color.red)

В FMZ ошибок не будет, в trading view они будут, потому что if-отделения возвращают несовместимые типы.

2, без выраженияswitch

Давайте посмотрим.switchДругой вариант написания слова “и” - без выражения.

up = close > open     // up = close < open 
down = close < open 
var upOfCount = 0 
var downOfCount = 0 

msgColor = switch
    up  => 
        upOfCount += 1 
        color.green 
    down => 
        downOfCount += 1
        color.red

plotchar(up, title="up", char=str.tostring(upOfCount), location=location.abovebar, color=msgColor, overlay=true)
plotchar(down, title="down", char=str.tostring(downOfCount), location=location.belowbar, color=msgColor, overlay=true)

В примере с испытуемым кодом видно, что switch будет соответствовать выполнению локального блока с условием разделения на истинный локальный блок. В общем случае после слова switch условия разделения должны быть взаимосвязанными. То есть в примере up и down не могут быть одновременно истинными.up = close > open // up = close < openПомимо этого, необходимо обратить внимание на то, чтобы не вводить вызов функции в ответвление switch, так как вызов функции на каждом BAR может вызвать некоторые проблемы с вычислением данных, если только:switch“В примере, исполнительная ветвь определена и не изменяется в процессе выполнения стратегии”.)

Циклическая структура

Фраза for

返回值 = for 计数 = 起始计数 to 最终计数 by 步长
    语句                                            // 注释:语句里可以有break,continue
    语句                                            // 注释:最后一条语句为返回值

Использование фразы “for” очень просто, цикл “for” может в конечном итоге возвращать одно значение или возвращать несколько значений, чтобы[a, b, c] и т. д.). Как и в предыдущем примере, переменная, присвоенная позиции “возвращаемой стоимости” в коде. За словами “for” следует переменная “счет” для управления количеством циклов, ссылки на другие значения и т. д. Переменная “счет” присваивается в качестве “первоначального счета” до начала цикла, а затем возрастает в соответствии с настройкой “шага”, и цикл останавливается, когда переменная “счет” больше “конечного счета”.

используется в цикле forbreakКлючевое слово: когда исполняетсяbreakПосле слов цикл прекращается. используется в цикле forcontinueКлючевое слово: когда исполняетсяcontinueПосле высказывания цикл проигнорируетcontinueПоследующий код выполняет следующий цикл. Заявление for возвращает значение, полученное при выполнении последнего цикла. Если код не выполнен, возвращается пустое значение.

Вот простой пример:

ret = for i = 0 to 10       // 可以增加by关键字修改步长,暂时FMZ不支持 i = 10 to 0 这样的反向循环
    // 可以增加条件设置,使用continue跳过,break跳出
    runtime.log("i:", i)
    i                       // 如果这行不写,就返回空值,因为没有可返回的变量
    
runtime.log("ret:", ret)
runtime.error("stop")

for … in высказывания

for ... inСуществуют две формы предложения, которые обозначаются следующими кодами:

返回值 = for 数组元素 in 数组 
    语句                        // 注释:语句里可以有break,continue
    语句                        // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组
    语句                        // 注释:语句里可以有break,continue
    语句                        // 注释:最后一条语句为返回值 

Основное различие между этими двумя формами заключается в том, что они следуют за ключевым словом “for”, то есть используют одну из переменных в качестве ссылки на элементы массива. Другая - использует структуру, содержащую подмножество переменных, индексирующих элементы массива.

testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
for ele in testArray            // 修改成 [i, ele]的形式:for [i, ele] in testArray , runtime.log("ele:", ele, ", i:", i)
    runtime.log("ele:", ele)

runtime.error("stop")

Используйте индексы, когда это необходимо.for [i, ele] in testArrayКак пишется

for циклическое применение

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

1 . Расчет среднего значения

При использовании циклических конструкций:

length = 5
var a = array.new(length)
array.push(a, close)

if array.size(a) >= length
	array.remove(a, 0)
	
sum = 0 	
for ele in a
    sum += ele 

avg = sum / length
plot(avg, title="avg", overlay=true)

В примере используется циклическое суммирование for, а затем рассчитывается среднее значение.

Вычислить среднюю линию прямо с помощью встроенной функции:

plot(ta.sma(close, length), title="ta.sma", overlay=true)

Использование встроенных функцийta.smaДля вычисления среднелинейных показателей, очевидно, проще использовать встроенные функции. На диаграмме можно увидеть, что результаты вычислений полностью совпадают.

  1. Сравнение

Или используйте приведенные выше примеры.

При использовании циклических конструкций:

length = 5
var a = array.new(length)
array.push(a, close)

if array.size(a) >= length
	array.remove(a, 0)
	
sum = 0 	
for ele in a
    sum += ele 

avg = sum / length
plot(avg, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)

Для вычисления суммы всех элементов массива можно использовать цикл, а также можно использовать встроенную функциюarray.sumЯ не знаю, что делать. Вы