[TOC]
В этом видео-уроке:С помощью торгового просмотра язык Пайн начинает изучать язык от белого до квантового бога.
Изобретательная квантовая платформа поддерживает язык Пина, поддерживает рецензирование, работает на диске с языком Пина, совместим с более низкими версиями языка Пина.FMZ.COMВ этом случаеПлощадь стратегииВ этом разделе представлены различные стратегии Pine для поиска и переноса.
FMZ не только поддерживает язык Pine, но и поддерживает мощные графические функции языка Pine. Функции на платформе FMZ, богатые практическими инструментами, эффективное и удобное управление, также еще больше улучшают полезность стратегии (скриптов) Pine. FMZ основан на совместимости с языком Pine, а также делает некоторые расширения, оптимизации и обрезания языка Pine.
Например, в Китае, где в 2010 году было зарегистрировано более чем 100 тысяч человек, в 2010 году - около 1 миллиона.
1, Политика Pine на FMZ, значок версии в начале кода//@version
И начинается кодstrategy
、indicator
ФМЗ пока не поддерживает обязательное написание слов.import
Импортlibrary
В этом случае мы должны быть готовы.
Возможно, вы увидите, что некоторые стратегии написаны так:
//@version=5
indicator("My Script", overlay = true)
src = close
a = ta.sma(src, 5)
b = ta.sma(src, 50)
c = ta.cross(a, b)
plot(a, color = color.blue)
plot(b, color = color.black)
plotshape(c, color = color.red)
Или, может быть, он написал:
//@version=5
strategy("My Strategy", overlay=true)
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
На FMZ можно упростить:
src = close
a = ta.sma(src, 5)
b = ta.sma(src, 50)
c = ta.cross(a, b)
plot(a, color = color.blue, overlay=true)
plot(b, color = color.black, overlay=true)
plotshape(c, color = color.red, overlay=true)
Или:
longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
2, Политика (скрипт) Некоторые настройки, связанные с транзакциями, устанавливаются параметрами "Пиновой языковой библиотеки транзакций" в интерфейсе политики FMZ.
Модели закрытия и модели реального времени
В торговом виде мы можем использоватьstrategy
Функцииcalc_on_every_tick
Параметры для настройки сценария стратегии для выполнения стратегии в режиме реального времени при каждом изменении цены.calc_on_every_tick
Параметры должны быть настроены наtrue
‒ По умолчанию.calc_on_every_tick
Параметрыfalse
Это означает, что логика не выполняется до тех пор, пока стратегия не закончится.
В FMZ это можно сделать с помощью параметров шаблона "Pine Language Exchange Library".
Количественная точность контроля при выполнении стратегии, таких как цена, объем загрузки и т. д. требуется для указания на FMZ. В торговом просмотре нет проблем с точностью в режиме реального времени, поскольку можно проводить только имитационные тесты. В FMZ можно реализовать стратегию Pine. Тогда нужна стратегия, которая может гибко указывать ценовую точность, точность количества заказов. Эти настройки точности контролируют дробные числа соответствующих данных, чтобы избежать того, что данные не соответствуют требованиям биржевого объявления и поэтому не могут быть размещены.
Фьючерсные контракты
В FMZ торговая разновидность, если она является контрактом, имеет два свойства. Отдельно, "двойка сделки" и "код контракта" требуют четкого настройки пары сделки на диске и в ретроспекции, а также установки конкретного кода контракта в параметре "код разновидности" шаблона "Пайн-языковой библиотеки".swap
Контрактный код зависит от того, есть ли такой контракт на бирже.quarter
; эти контрактные коды совпадают с кодами фьючерсных контрактов, определенными в документации FMZ на языке JavaScript/python/c++ API;
Другие настройки, например, минимальная величина подстроек, величина подстроек по умолчанию и т.д., можно найти в документации на языке Pine."Пиновый язык"Введение в параметры.
3、runtime.debug
、runtime.log
、runtime.error
Функция FMZ, используемая для дешифровки.
В платформе FMZ добавлены три функции для дешифровки.
runtime.debug
: для печати информации о переменных на контроллере, обычно не используется эта функция.
runtime.log
: в журнале выводит содержимое.
runtime.log(1, 2, 3, close, high, ...),可以传多个参数。
runtime.error
: при вызове, приводит к ошибкам при запуске и содержит ошибочные сообщения, указанные в параметрах сообщения.
runtime.error(message)
4, частично расширенная в графикеoverlay
Параметры
Язык Pine на FMZ, графическая функцияplot
、plotshape
、plotchar
И так далее.overlay
Поддержка параметров, позволяющих указать картинки в тематике или подкартинке.overlay
Настройкаtrue
Сделайте рисунок в тематике, настроив его наfalse
Рисование на подвиде. При выполнении политики Pine на FMZ можно рисовать на подвиде и на подвиде.
5、syminfo.mintick
Применение встроенных переменных
syminfo.mintick
Встроенная переменная определяется как наименьшее зафиксированное значение текущей разновидности; в FMZФизическая диска/ПроверкаВ интерфейсе "Pine Language Trading Library" шаблонный параметр ценообразования валюты позволяет контролировать это значение. Ценообразование валюты устанавливается на 2, то есть цена является точной до второго знака клочка, при этом минимальная единица изменения цены составляет 0.01.syminfo.mintick
Это означает, что 0.01 {\displaystyle 0.0_{1}}
Средняя цена в FMZ PINE Script включает в себя расходы на обслуживание
Например: цена заказа 8000, направление продажи, количество 1 руки, средняя цена после сдачи не 8000, менее 8000 (в стоимости включены процедурные сборы).
Начиная изучать основы языка Pine, мы можем не быть знакомы с инструкциями, кодовой грамматикой в некоторых примерах. Неважно, мы можем сначала ознакомиться с концепцией, понять цель тестирования, а также обратиться к документации FMZ на язык Pine для получения инструкции. Затем следуйте пошаговому последовательности урока, чтобы постепенно ознакомиться с различными грамматиками, инструкциями, функциями и встроенными переменными.
При изучении языка Пайн очень важно знать такие понятия, как процесс выполнения сценариев языка Пайн. Политика языка Пайн основана на графике, которая может быть понята как серия вычислений и операций, выполняемых на графике в предшествующем порядке временных последовательностей, начиная с самых ранних данных, которые уже загружены на графике. Первоначально загружается ограниченное количество данных.bar_index
Ссылка на индекс K-линииBar, который был в настоящее время, когда выполнялся скрипт Pine.
plot(bar_index, "bar_index")
plot
Функция является одной из тех, которые мы будем использовать больше в будущем. Использование очень простое, это рисование линий на графике в соответствии с параметрами, которые передаются.bar_index
Именно поэтому мы и назвали егоbar_index
│ Можно увидеть, что в первом Bar-именном строке, называемом bar_index, значение 0 увеличивается с правой стороной с увеличением Bar.
В зависимости от настройки стратегии, модель стратегии также отличается в том, как она выполняется.收盘价模型
и实时价模型
Мы также кратко рассказали о концепции модели закрытия, модели реального времени.
Модель закрытия
При выполнении кода-политики цикл текущей K-линии Bar полностью выполняется, а к закрытию K-линии цикл K-линии завершается. При этом выполняется снова логика политики Pine, а триггерный торговый сигнал выполняется при начале следующей K-линии Bar.
Модель цены в реальном времени
При выполнении кода стратегии, текущий K-линейный Bar выполняет логику стратегии Пина один раз при каждом изменении рынка, независимо от того, закрыт он или нет, и триггерный торговый сигнал выполняется незамедлительно.
Когда политика языка Pine выполняется слева направо на графике, K-линия Bar на графике разделена на历史Bar
и实时Bar
Название:
Исторический бар
Когда политика настройки "Реальная модель цены" начинает выполняться, все K-линии Bar на графике, кроме одной K-линии Bar в самом правом углу, являются K-линией Bar.历史Bar
│ Стратегическая логика в каждом корне.历史Bar
В этом случае вы можете использовать только один раз.
При запуске стратегии, настроенной на "Модель закрытия", все Bar на графике будут历史Bar
│ Стратегическая логика в каждом корне.历史Bar
В этом случае вы можете использовать только один раз.
Расчеты, основанные на историческом баре: Политика выполняется один раз в состоянии закрытия History Bar, а затем продолжается в следующем History Bar до тех пор, пока все History Bar не будут выполнены один раз.
Бар в реальном времени
Когда политика выполняется до последнего K-линия Bar в правом углу, этот Bar становится Real-Time Bar. После закрытия Real-Time Bar этот Bar становится прошедшим Real-Time Bar (превращается в исторический Bar). В правом углу графика создается новый Real-Time Bar.
При запуске стратегии, настроенной на "Реальную модель цены", в режиме реального времени на Bar будет выполняться одна стратегия логики на каждое изменение рынка. При запуске политики, настроенной на "Модель закрытия", на графике не отображается Bar в режиме реального времени.
На основе расчетов Bar в реальном времени:
Если параметр "Модель закрытия" не показывает Bar в режиме реального времени, код будет выполняться только один раз при закрытии текущего Bar.
Если настроить политику на "Реальную ценовую модель", то расчеты в реальном времени в Bar будут совершенно разными от расчетов в историческом Bar, в котором каждый рыночный переход в Bar будет выполняться одним кодом политики; например, встроенная переменная.high
、low
、close
В историческом баре определено, что в реальном баре эти значения изменяются при каждом возможном изменении рынка. Так что данные, такие как показатели, на основе которых рассчитываются эти значения, также изменяются в реальном времени.close
Всегда представляет собой текущую цену, но не всегда соответствует текущему уровню.high
иlow
Всегда представляет наивысшие и наименьшие максимумы, достигнутые с начала текущего Live Bar. Эти встроенные переменные представляют собой конечные значения, когда Live Bar был последний раз обновлен.
Механизм отката при выполнении стратегии в режиме реального времени на Bar (модель цены в режиме реального времени): При выполнении Bar в реальном времени перезагрузка переменных пользовательского определения перед выполнением каждого нового игрового цикла политики называется реверсом. Чтобы понять механизм реверса, давайте попробуем использовать следующий тест-код.
Обратите внимание:
/*backtest
...
..
.
*/
Содержимое пакета - это информация о конфигурации, сохраненная в кодовом виде на платформе FMZ.
/*backtest
start: 2022-06-03 09:00:00
end: 2022-06-08 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
var n = 0
if not barstate.ishistory
runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index)
n := n + 1
runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index)
plot(n, title="n")
Мы рассматривали только сцены, выполненные в режиме реального времени, поэтому мы использовалиnot barstate.ishistory
Ограничение выражения применяется только при наполнении n переменных в режиме реального времени Bar и перед выполнением операций наполненияruntime.log
Функция выводит информацию в журнале стратегии.plot
Нарисованная кривая n показывает, что n всегда 0 при выполнении политики в историческом Bar. При выполнении до реального времени Bar действия n плюс 1 были задействованы, и n плюс 1 выполнялись при каждом раунде выполнения политики в реального времени Bar. Из информации журнала можно наблюдать, что n переставляется на значение, которое было окончательно представлено при каждом повторном выполнении политики Bar.
В итоге: 1, когда политика начинает выполняться в режиме реального времени Bar, один код политики выполняется при каждом обновлении. 2, при выполнении в режиме реального времени на Bar перескакивает переменную до каждого выполнения кода политики. 3, при выполнении в режиме реального времени Bar, переменная подается один раз при обновлении в закрытии.
Из-за того, что данные перескакивают, операции с графиком, такие как кривые на графике, также могут вызвать перечерк, например, мы изменили тест-код, который мы только что провели, тест на диске:
var n = 0
if not barstate.ishistory
runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index)
n := open > close ? n + 1 : n
runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index)
plot(n, title="n")
Скриншот момента А
Скриншот момента B
Мы просто изменили это предложение:n := open > close ? n + 1 : n
В первом графике можно увидеть, что в момент А, поскольку цена открытия была выше цены закрытия, n добавлено 1, и графическая кривая n показывает значение 5. Затем изменение состояния, обновление цены, как и во втором графике, показывается. В этом случае цена открытия ниже цены закрытия, n реверсируется и не добавляется 1. В графике кривая n также немедленно перерисовывается, в этом случае n на криве 4; поэтому сигналы, показанные в режиме реального времени на Bar, такие как вилки, вилки и т. д., неопределены и могут измениться.
Контекст переменных в функциях
Ниже мы вместе рассмотрим переменные в функциях языка Pine. Согласно описаниям в некоторых уроках Pine, переменные в функциях различаются от переменных вне функции следующим образом:
История последовательности переменных, используемых в функции Pine, создается каждым последовательным вызовом функции. Если не вызвать функцию на каждом столбце, который выполняется в скрипте, это приведет к различию между историческими значениями внутри локального блока функции и историческими значениями внешней последовательности. Таким образом, если не вызвать функцию на каждом столбце, серия с одинаковыми индексными значениями внутри функции и с внешними ссылками не будет ссылаться на одинаковые исторические точки.
Не так ли? Все в порядке, мы разобрались в этом с помощью тестового кода, который работает на FMZ:
/*backtest
start: 2022-06-03 09:00:00
end: 2022-06-08 15:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}]
*/
f(a) => a[1]
f2() => close[1]
oneBarInTwo = bar_index % 2 == 0
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
plot(close[2], title = "close[2]", color = color.red, overlay = true)
plot(close[1], title = "close[1]", color = color.green, overlay = true)
Скриншот запуска
Тест-код прост и предназначен для изучения данных, которые цитируются двумя способами:f(a) => a[1]
иf2() => close[1]
。
f(a) => a[1]
Использование параметров передачи: как функция возвращается в концеa[1]
。
f2() => close[1]
Прямое использование встроенных переменных:close
Функция возвращается в конце.close[1]
。
[]
Символы используются для ссылки на исторические значения переменных в серии данных, close[1] - это ссылка на данные о цене закрытия на Bar до текущей цены закрытия. Наш тестовый код изображает 4 вида данных на графике:
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
Нарисуйте символ Af(close)
Возвращается значение.
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
Нарисуйте букву B, цвет зеленый, только когда oneBarInTwo является истинным, и начертайте местоположение (на оси Y):f2()
Возвращается значение.
plot(close[2], title = "close[2]", color = color.red, overlay = true)
Рисунок красный и расположен (на Y-осе):close[2]
То есть цена закрытия на Bar, которая находится на 2-й строке перед числом Bar в данный момент (две строки слева).
plot(close[1], title = "close[1]", color = color.green, overlay = true)
Рисунок, цвет которого зеленый, расположен (на Y-осе):close[1]
То есть цена закрытия на Bar, которая находится в первом ряду перед числом Bar в данный момент (один налево).
Скриншоты, выполненные с помощью стратегии ретроспекции, можно увидеть, хотя на картинке A указаны функции, используемыеf(a) => a[1]
Функции, используемые для обозначения рисунка Bf2() => close[1]
Все используются[1] для ссылки на исторические данные в серии данных, но местонахождение знаков "A" и "B" на графике совершенно разное. Местонахождение знаков "A" всегда на красной линии, то есть код в стратегии.plot(close[2], title = "close[2]", color = color.red, overlay = true)
На рисунке, который он использует, данные, которые он использует,close[2]
。
Это происходит потому, что мы используем индекс K-линии Bar, или встроенную переменную.bar_index
Вычислить, рисуют ли "A" и "B" знаки. Знаки "A" и "B" не рисуют графы на каждой K-линии Bar.f(a) => a[1]
В этом случае значение, которое вызывается таким образом, будет отождествлено с функцией, если она не будет вызвана на каждом Bar.f2() => close[1]
В этом способе цитируются разные значения (даже при использовании одного и того же индекса, например, [1]).
Некоторые встроенные функции требуют расчета на каждом Баре, чтобы правильно рассчитать их результаты.
Например, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае.
res = close > close[1] ? ta.barssince(close < close[1]) : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
Мы называем эту функцию кодом.ta.barssince(close < close[1])
Написать в трехмерном операторе.condition ? value1 : value2
Это привело к тому, что в 2010 годуclose > close[1]
时去调用ta.barssince函数。可偏偏ta.barssince
Функция вычисляется с последнего.close < close[1]
Количество строк K при вызове; при вызове функции ta.barssince closed > close[1], то есть текущая цена закрытия больше, чем цена закрытия предыдущего бара. При вызове функции ta.barssince условие close < close[1] не действует, и не имеет последней позиции создания.
ta.barssince: при вызове функция возвращает na, если условие никогда не выполнялось до текущего K-строка.
Например:
Таким образом, когда вы рисуете, вы рисуете только данные, когда значение переменной res ((-1) ‒).
Чтобы избежать этой проблемы, мы просто используемta.barssince(close < close[1])
Вызов функции извлекается из трёхстороннего оператора и записывается на любой возможной условийной ветви; он выполняет расчеты на каждой строке KBar.
a = ta.barssince(close < close[1])
res = close > close[1] ? a : -1
plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
Концепция временной последовательности очень важна в языке Pine и является понятием, которое мы должны понять, когда изучаем язык Pine. Временная последовательность не является типом, а является основной структурой последовательности, используемой для хранения переменных со временем.open
Это встроенная переменная языка Pine, которая содержит временные последовательности для хранения цены открытия каждой строки KBar.open
Эта структура временной последовательности представляет собой начальную цену всех K-уровней Bar в текущем K-уровне от первого Bar в начале до этого Bar при выполнении текущего сценария. Если текущий K-уровне 5-минутный цикл, то мы цитируем (или используем) в коде стратегии Pine.open
время - это начальная цена K-линии Bar при текущем выполнении с помощью кода стратегии. Если необходимо использовать исторические значения в последовательности времен для ссылки.[]
Оператор. Используется, когда политика Pine выполняется на каких-либо K-линиях Bar.open[1]
Ссылкиopen
Открытая цена K-линии Bar (т. е. цена за последний цикл K-линии) на предыдущий K-линий Bar, выполненный текущим сценарием в временной последовательности.
Переменные в временных последовательностях очень удобны для вычисления.
Мы используем встроенные функции.ta.cum
Например:
ta.cum
Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`.
ta.cum(source) → series float
RETURNS
Total sum series.
ARGUMENTS
source (series int/float)
SEE ALSO
math.sum
Проверка кода:
v1 = 1
v2 = ta.cum(v1)
plot(v1, title="v1")
plot(v2, title="v2")
plot(bar_index+1, title="bar_index")
Есть много подобных.ta.cum
Такие встроенные функции могут обрабатывать данные прямо из временных последовательностей, например:ta.cum
Это добавление соответствующих значений переданных переменных на каждом из K-линий Bar, а затем мы используем график для простого понимания.
Процесс реализации стратегии | Встроенная переменная bar_index | v1 | v2 |
---|---|---|---|
Стратегия работает на первом K-линии Bar. | 0 | 1 | 1 |
Стратегия работает на 2-м K-линии Bar. | 1 | 1 | 2 |
Стратегия работает на 3-м K-линии Bar. | 2 | 1 | 3 |
… | … | … | … |
Стратегия работает на N + 1 корне K-линии Bar | N | 1 | N+1 |
Как видно, на самом деле v1, v2 и даже bar_index - это структуры временных последовательностей с соответствующими данными на каждом Bar. Этот тест-код отличает "реальную модель цены" от "модели цены закрытия" только тем, показывает ли он на графике реальную Bar. Для измерения скорости мы используем "модель цены закрытия" для повторного тестирования.
Потому что эта переменная v1 на каждом бара - 1.ta.cum(v1)
Когда функция выполняется на первой K-линии Bar, результат вычисления 1, поскольку есть только первая Bar, присваивается переменной v2.
Когдаta.cum(v1)
При выполнении на второй K-линии Bar, уже есть 2 K-линии Bar (первая соответствующая встроенная переменная bar_index равна 0, вторая соответствующая встроенная переменная bar_index равна 1), поэтому результат вычисления 2, присвоение значения переменной v2, и так далее.bar_index
Если мы начинаем с нуля и увеличиваемся,bar_index + 1
На самом деле это количество K-линий Bar.v2
иbar_index
Это действительно совпадает.
И я могу использовать их.ta.cum
Встроенная функция вычисляет сумму цены закрытия всех Bar на текущем графике, и тогда можно просто написать:ta.cum(close)
, когда политика работает в правую сторону в режиме реального времени Barta.cum(close)
Результат вычисления - сумма цены закрытия всех Бар на графике (если не работать в правую сторону, просто добавлять к текущему Бар).
Переменные в временной последовательности также могут быть рассчитаны с помощью операторов, например, код:ta.sma(high - low, 14)
Встроенные переменныеhigh
(К-линия Bar) минусlow
(K-линия Bar минимальная цена), используется в последний разta.sma
Функция требует среднего значения.
Результаты вызовов также оставляют следы значений в временной последовательности.
v1 = ta.highest(high, 10)[1]
v2 = ta.highest(high[1], 10)
plot(v1, title="v1", overlay=true)
plot(v2, title="v2", overlay=true)
Этот тест-код выполняется при повторном тестировании, и можно наблюдать:v1
иv2
В результате вызова функции вычисляемые результаты оставляют следы значения в временной последовательности, например, код.ta.highest(high, 10)[1]
В том числеta.highest(high, 10)
Результаты вычислений при вызове функции также могут быть использованы[1] для ссылки на их исторические значения.ta.highest(high, 10)
И результатом будет:ta.highest(high[1], 10)
‒ Так что.ta.highest(high[1], 10)
иta.highest(high, 10)[1]
В этом случае мы не будем делать никаких ошибок.
Используйте другую функцию рисунка для вывода информации:
a = ta.highest(close, 10)[1]
b = ta.highest(close[1], 10)
plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red, overlay=true)
plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)
Видно, что значения переменных a и b в временной последовательности отображаются в верхней и нижней частях соответствующего Bar. Этот графический код можно сохранить в процессе обучения, поскольку во время тестов и экспериментов часто может потребоваться вывести информацию на графике для наблюдения.
В начале урока мы подвели некоторые различия в использовании языка Pine на FMZ и на Trading View.indicator()
、strategy()
В этом случае мы не будем поддерживать их.library()
Конечно, для совместимости с более ранними версиями сценария Pine, при написании стратегии следует писать://@version=5
,indicator()
,strategy()
В этом случае вы можете использовать некоторые параметры политики, которые вы можете установить на своем компьютере.strategy()
Установка параметров в функциях.
<version>
<declaration_statement>
<code>
<version>
Информация о контроле версий может быть исключена.
Использование языка Pine//
Как однострочный комментатор, поскольку язык Pine не имеет многострочных комментаторов. FMZ расширяет комментатор/**/
Для многострочных комментариев.
В сценарии строка, не содержащая комментариев или компиляторных инструкций, является предложением, которое реализует алгоритм сценария.
if
,for
,while
илиswitch
и т.д.Слов можно составить разными способами.
空格
или制表符
(tab) начинается. Их первый символ также должен быть первым символом строки. Строки, начинающиеся с первого места в строке, по определению являются частью глобального диапазона сценария.local block
; локальный блок должен сокращаться до одного табличного знака или четырех пробелов (в противном случае он будет расшифрован как последовательное содержание предыдущей строки), и каждый локальный блок определяет различный локальный диапазон;Например, включает в себя три локальных блока, один в декларации настройки функции, два в декларации переменной используют структуру if, следующий код:
indicator("", "", true) // 声明语句(全局范围),可以省略不写
barIsUp() => // 函数声明(全局范围)
close > open // 本地块(本地范围)
plotColor = if barIsUp() // 变量声明 (全局范围)
color.green // 本地块 (本地范围)
else
color.red // 本地块 (本地范围)
runtime.log("color", color = plotColor) // 调用一个内置函数输出日志 (全局范围)
Длинные строки могут быть разделены на несколько строк или "завязаны" друг на друга. Завязанные строки должны сокращаться в любое количество пробелов, если это не кратное 4.
a = open + high + low + close
Можно упаковать в (примечание: количество пространств, сокращенных на каждую строку, не является кратным четырём):
a = open +
high +
low +
close
Долгий призыв к сюжету может быть упакован в.
close1 = request.security(syminfo.tickerid, "D", close) // syminfo.tickerid 当前交易对的日线级别收盘价数据系列
close2 = request.security(syminfo.tickerid, "240", close) // syminfo.tickerid 当前交易对的240分钟级别收盘价数据系列
plot(ta.correlation(close, open, 100), // 一行长的plot()调用可以被包装
color = color.new(color.purple, 40),
style = plot.style_area,
trackprice = true)
Строки в user-defined function declarations также могут быть упакованы. Однако, поскольку локальный блок должен начаться с замыкания ((4 пространства или 1 значок), когда его делят на следующую строку, продолжение строк должно начинаться с более чем одним замыканием ((не равняется кратному количеству 4 пространств); например:
test(c, o) =>
ret = c > o ?
(c > o+5000 ?
1 :
0):
(c < o-5000 ?
-1 :
0)
a = test(close, open)
plot(a, title="a")
Перед тем, как понять переменные, мы должны сначала понять концепцию знаков знака.ФункциииПеременныеНазвание (название переменных, функции) ≠ФункцииКак мы увидим в следующем уроке, сначала мы должны выучить знаки знаков.
(A-Z)
Или почеркнуть.(a-z)
Буквы или подчеркивания(_)
Начало, первый символ идентификатора.Например, идентификаторы с такими названиями:
fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown // 错误的命名!使用了数字字符作为标识符的开头字符
Как и в большинстве языков программирования, в языке Pine есть рекомендации по написанию.
// 命名变量、常量
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// 命名函数
zeroOne(boolValue) => boolValue ? 1 : 0
Операторы - это некоторые символы, используемые в языке программирования для построения выражений, а выражения - это вычислительные правила, которые мы разрабатываем для какой-то вычислительной цели, когда пишем политику. Операторы в языке Pine классифицируются по функциональности как:
Операторы присвоения, операторы расчёта, операторы сравнения, операторы логики,? :
Триумфальные операторы[]
Исторические ссылки на операторы.
Операторы с арифметикой*
К примеру, для различения типа проблем, в результате которых операторы языка Pine на Trading View возвращают результаты, используется следующий тест-код:
//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength) // Compilation 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(c), color=d, overlay=true)
Осторожно.a = close
Призначение, что на каждом Bar переменная a является текущей ценой закрытия этого Bar (close); другие переменныеb
、c
、d
В результате, в результате испытаний на FMZ, результаты можно увидеть на рисунке.
:=
Используется для переназначения значений существующим переменным.:=
Операторы используются для изменения уже заявленных, инициированных значений переменных.
Если используется:=
Операторы могут вызвать ошибки при назначении неинтилированных или объявленных переменных, например:
a := 0
Так что::=
Операторы назначения обычно используются для переназначения существующих переменных, например:
a = close > open
b = 0
if a
b := b + 1
plot(b)
Судить, еслиclose > open
(т.е. текущий BAR - полярная линия), а переменная - истинное значение (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.
Если говорить об ассигнованиях, то здесь необходимо расширить объяснение двух ключевых слов:var
、varip
Вар
На самом деле это ключевое слово, которое мы видели и использовали в предыдущих уроках, но не обсуждали в деталях.
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")
Переменная
разновидности
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-этап?var
、varip
Переменные заявленияi
、ii
Каждый раунд выполнения стратегии выполняется с нарастающей операцией. Таким образом, можно увидеть, что цифры, отображаемые на K-линии BAR, увеличиваются по 1 раз. Когда исторический K-линий заканчивается, начинается реальный K-линий.i := i + 1
иii := ii + 1
Различие заключается в том, что ii изменяется каждый раз. i, хотя и изменяется каждый раз, возвращается к предыдущему значению при следующем раунде выполнения логики стратегии (помнишь механизм обратного отвода, о котором мы рассказывали в главе "Модель выполнения" ранее?), и не определяется до тех пор, пока текущий K-линий BAR не будет обновлен (т.е. не вернется к предыдущему значению при следующем раунде выполнения логики стратегии).
Модель закрытия: Поскольку в модели закрытия цена выполняется только один раз после завершения каждой линии K BAR. Так что в модели закрытия стоимости переменные на стадии истории линии K и стадии реального времени линии K, var,varip заявления в приведенном выше примере полностью совпадают в инкреационном выражении, причем каждой линии K BAR инкреация 1.
Операторы | Объяснение |
---|---|
+ | Гафа |
- | Снижение |
* | Умножение |
/ | Исключение |
% | Поиск модели |
+
、-
Операторы могут быть использованы как бинарные, так и как первичные операторы. Другие алгоритмические операторы могут использоваться только как бинарные операторы и возвращают ошибки, если они используются как первичные операторы.
1, на обеих сторонах оператора есть типы чисел, результатом является тип чисел, целый тип или пломбированный номер в зависимости от результата операции.
2, если число операторов является строкой, то оператор является+
, то результат вычисления будет строкой, число будет преобразовано в форму строки, а затем строки будут сложены вместе. Если это другие операторы, то будет предпринята попытка преобразовать строку в число, а затем будет выполнена операция.
3, если число операций на одной из них на, то результат вычисления будет пустым на, который будет отображаться на NaN при печати на FMZ.
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
Здесь существует небольшое различие между языком Pine на FMZ и языком Pine на Trading View.
a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A"
plot(a)
plot(b)
plot(c)
В FMZ это возможно, но в торговом просмотре это дает типные ошибки. Для операторов с двумя сторонами, где число операций является строкой, система будет переводить строку в числовое значение. Если не-цифровые строки не могут быть вычислены, результат системы будет null 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
Как видите, сравнительный оператор очень прост в использовании, но это самый распространенный оператор, который мы используем при написании стратегии.close
、open
И так далее.
Как и операционные операторы, на FMZ отличаются от Pine в Trading View тем, что FMZ не имеет особо строгих типов требований, поэтому такие заявления могут быть использованы в качестве инструмента для определения типа.d = "1" >= 2
В FMZ нет ошибок, при выполнении строки сначала преобразуются в цифры, а затем сравниваются операции. В Trading View ошибки.
Операторы | Кодовые символы | Объяснение |
---|---|---|
Не | Нет, нет. | Одноличные операторы, необрабатываемые |
и | и | Бинарные операторы, работающие с ((и) |
или | или | Бинарные операторы, или операции |
Если мы говорим о логических операторах, то мы должны говорить о таблицах истинных значений. Как мы учились в старших классах, только здесь мы проводим тесты в системе обратной связи.
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
ВнутриvalueWhenConditionIsTrue
、valueWhenConditionIsFalse
Вместо этого используется еще одно трехзначное выражение.
Использование исторических операторов[]
, ссылка на исторические значения временной последовательности. Эти исторические значения являются значениями переменных на 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] // 错误
Вы можете видеть здесь, некоторые из ваших учеников могут сказать, что операторы[]
Если вы используете строку, то она выглядит так же, как строка и матрица.
Ниже мы приведем пример, показывающий, что серия и матрица в языке Pine отличаются друг от друга.
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 не так проста, как в матрицах. Можно понять, что история Bar на предыдущем Bar, который был присвоен b, также является структурой временной серии, и можно продолжать ссылаться на ее историю. Так что мы видим, что в трех выведенных линиях a, b и c линия b медленнее, чем линия a, одна BAR, линия c медленнее, чем линия b, одна BAR. Схема c медленнее, чем линия a, две BAR.
Мы можем перетащить график вверх налево, и заметить, что на первой K-линии значения b и c являются пустыми. Это потому, что когда скрипт выполняется на первой K-линии BAR, он ссылается вперед на один, два цикла исторических значений, которые отсутствуют. Поэтому мы часто должны быть осторожны при написании стратегии, если мы ссылаемся на исторические данные.na
、nz
Мы уже говорили об этом в предыдущих исследованиях.nz
、na
Функции, помните, в каком разделе?) конкретно обрабатывают ситуации с пустыми значениями, например:
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, ничего не написано.
var
、varip
Ключевые слова мы уже изучали в предыдущей главе "Операторы присвоения", и мы больше не будем говорить о них.i = 1
, а мы уже говорили, что такие заявленные переменные и ассигнования выполняются на каждой строке KBAR.
Тип Язык 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#标识符
В общем, заявление о переменной может быть написано так:
// [<declaration_mode>] [<type>] <identifier> = value
声明模式 类型 标识符 = 值
Здесь используется оператор присвоения:=
При объявлении переменной присваивается значение. При присвоении значение может быть строкой, числовым значением, выражением, вызовом функции,if
、 for
、while
илиswitch
В следующем уроке мы рассмотрим эти структурные ключевые слова и способы использования предложений, хотя в предыдущих уроках мы уже изучали простые значения предложений if.
Здесь мы сосредоточились на работе над функцией ввода, которая часто используется при разработке стратегии.
Вводная функция:
input函数,参数defval、title、tooltip、inline、group
Функция ввода на FMZ немного отличается от функции в Trading View, однако она используется как ввод значения параметров стратегии. Ниже мы рассмотрим пример, который подробно описывает использование функции ввода на 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)
При декларировании переменных часто используется функция ввода. В FMZ функция ввода автоматически отображает в интерфейсе политики FMZ элементы, которые используются для настройки параметров политики. В настоящее время поддерживаемые в FMZ элементы имеют встроенные входные рамки, текстовые входные рамки, разъемные рамки, отметки для вывода, а также функции для настройки раздела параметров политики, указания текстовой информации о настройке параметров.
Мы расскажем о нескольких основных параметрах входных функций:
В дополнение к заявлению отдельных переменных, ассигнования, язык Пайн также заявляет набор переменных и придает их значения:
[变量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.
strategy("test", overlay=true)
if close > open
plot(close, title="close")
else
plot(open, title="open")